@rulemetric/local 0.7.41 → 0.7.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/meta.json +2 -2
- package/dist/server.mjs +227 -227
- package/dist/supabase/migrations/00161_instruction_suggestion_kind.sql +52 -0
- package/dist/web/assets/{index-BsLMMfkE.js → index-B8TF1AGr.js} +3 -3
- package/dist/web/assets/index-DL6P9bHa.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +2 -2
- package/dist/web/assets/index-BzzkWFIU.css +0 -1
package/dist/server.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
`).filter(g=>g.trim()),r=[];for(let g of n)try{r.push(JSON.parse(g))}catch{}let o=r.filter(g=>g.type==="user"||g.type==="assistant"),s=null,i=null,c={},a=r.find(g=>g.type==="user");a&&(s=a.cwd??null,i=a.gitBranch??null,a.version&&(c.claudeCodeVersion=a.version),a.sessionId&&(c.sessionId=a.sessionId));let l=r.find(g=>g.type==="assistant");l?.message?.model&&(c.model=l.message.model);let p=[],m=0;for(let g of o){let h=g.timestamp??new Date().toISOString();if(g.type==="user"){let w=g.message?.content;if(typeof w=="string")p.push({sequence:m++,eventType:"user_message",content:w,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:h,metadata:{}});else if(Array.isArray(w))for(let
|
|
1
|
+
var vf=Object.defineProperty;var u=(e,t)=>vf(e,"name",{value:t,configurable:!0}),Td=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Xe=(e,t)=>()=>(e&&(t=e(e=0)),t);var no=(e,t)=>{for(var n in t)vf(e,n,{get:t[n],enumerable:!0})};var ME,LE,M_=Xe(()=>{"use strict";ME=["claude_code","cursor","vscode_copilot","copilot_agent","rulemetric_mcp","codex","pi","opencode","antigravity"],LE=["user_message","assistant_message","tool_call","tool_result","thinking","error"]});var ds,op=Xe(()=>{"use strict";ds=class{static{u(this,"ClaudeCodeAdapter")}tool="claude_code";parse(t){let n=t.split(`
|
|
2
|
+
`).filter(g=>g.trim()),r=[];for(let g of n)try{r.push(JSON.parse(g))}catch{}let o=r.filter(g=>g.type==="user"||g.type==="assistant"),s=null,i=null,c={},a=r.find(g=>g.type==="user");a&&(s=a.cwd??null,i=a.gitBranch??null,a.version&&(c.claudeCodeVersion=a.version),a.sessionId&&(c.sessionId=a.sessionId));let l=r.find(g=>g.type==="assistant");l?.message?.model&&(c.model=l.message.model);let p=[],m=0;for(let g of o){let h=g.timestamp??new Date().toISOString();if(g.type==="user"){let w=g.message?.content;if(typeof w=="string")p.push({sequence:m++,eventType:"user_message",content:w,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:h,metadata:{}});else if(Array.isArray(w))for(let b of w)b.type==="tool_result"&&p.push({sequence:m++,eventType:"tool_result",content:typeof b.content=="string"?b.content:JSON.stringify(b.content),toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:h,metadata:{toolUseId:b.tool_use_id}})}else if(g.type==="assistant"){let w=Array.isArray(g.message?.content)?g.message.content:[],b=g.message?.usage,I=b?{input:b.input_tokens??0,output:b.output_tokens??0,cacheRead:b.cache_read_input_tokens??0,cacheWrite:b.cache_creation_input_tokens??0}:null,S={};g.message?.model&&(S.model=g.message.model),g.message?.stop_reason&&(S.stopReason=g.message.stop_reason),g.requestId&&(S.requestId=g.requestId),b?.service_tier&&(S.serviceTier=b.service_tier),b?.speed&&(S.speed=b.speed),b?.cache_creation&&(S.cacheCreationDetail=b.cache_creation),b?.server_tool_use&&(S.serverToolUse=b.server_tool_use);for(let A of w)A.type==="text"?p.push({sequence:m++,eventType:"assistant_message",content:A.text??"",toolName:null,toolInput:null,toolOutput:null,tokenUsage:I,timestamp:h,metadata:S}):A.type==="thinking"?p.push({sequence:m++,eventType:"thinking",content:A.thinking??"",toolName:null,toolInput:null,toolOutput:null,tokenUsage:I,timestamp:h,metadata:S}):A.type==="tool_use"&&p.push({sequence:m++,eventType:"tool_call",content:null,toolName:A.name??"unknown",toolInput:A.input??null,toolOutput:null,tokenUsage:I,timestamp:h,metadata:{...S,toolUseId:A.id}})}}let y=p.map(g=>g.timestamp).sort(),v=new Date().toISOString();return{tool:"claude_code",projectPath:s,gitBranch:i,startedAt:y[0]??v,endedAt:y[y.length-1]??null,events:p,metadata:c}}}});var ls,sp=Xe(()=>{"use strict";ls=class{static{u(this,"CursorAdapter")}tool="cursor";parse(t){let n=Td("better-sqlite3"),r=new n(t,{readonly:!0});try{let o=r.prepare("SELECT value FROM ItemTable WHERE key = 'composer.composerData'").get();return o?this.parseComposerJson(o.value):this.emptySession()}finally{r.close()}}parseComposerJson(t){let n;try{n=JSON.parse(t)}catch{return this.emptySession()}let r=Object.values(n.allComposers??{});if(r.length===0)return this.emptySession();let o=r.sort((l,p)=>{let m=l.createdAt?new Date(l.createdAt).getTime():0;return(p.createdAt?new Date(p.createdAt).getTime():0)-m})[0],s=o.conversation??[],i=[];for(let l=0;l<s.length;l++){let p=s[l],m=p.createdAt??new Date().toISOString();i.push({sequence:l,eventType:p.type===1?"user_message":"assistant_message",content:p.text,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:m,metadata:{}})}let c=i.map(l=>l.timestamp).sort(),a=new Date().toISOString();return{tool:"cursor",projectPath:null,gitBranch:null,startedAt:c[0]??a,endedAt:c[c.length-1]??null,events:i,metadata:{composerId:o.composerId}}}emptySession(){return{tool:"cursor",projectPath:null,gitBranch:null,startedAt:new Date().toISOString(),endedAt:null,events:[],metadata:{}}}}});var ps,ip=Xe(()=>{"use strict";ps=class{static{u(this,"VSCodeCopilotAdapter")}tool="vscode_copilot";parse(t){let n;try{n=JSON.parse(t)}catch{return this.emptySession()}let r=n.requests??[],o=[],s=0;for(let a of r){let l=a.timestamp?new Date(a.timestamp).toISOString():new Date().toISOString();if(o.push({sequence:s++,eventType:"user_message",content:a.message,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:l,metadata:{}}),a.response){let p=a.response.timestamp?new Date(a.response.timestamp).toISOString():l;o.push({sequence:s++,eventType:"assistant_message",content:a.response.message,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:p,metadata:{}})}}let i=o.map(a=>a.timestamp).sort(),c=new Date().toISOString();return{tool:"vscode_copilot",projectPath:null,gitBranch:null,startedAt:i[0]??c,endedAt:i[i.length-1]??null,events:o,metadata:{...n.requesterUsername&&{username:n.requesterUsername},...n.customTitle&&{title:n.customTitle}}}}emptySession(){return{tool:"vscode_copilot",projectPath:null,gitBranch:null,startedAt:new Date().toISOString(),endedAt:null,events:[],metadata:{}}}}});var ms,ap=Xe(()=>{"use strict";ms=class{static{u(this,"CopilotAgentAdapter")}tool="copilot_agent";parse(t){let n;try{n=JSON.parse(t)}catch{return this.emptySession()}let r=n.requests??[],o=[],s=0;for(let a of r){let l=a.timestamp?new Date(a.timestamp).toISOString():new Date().toISOString();if(o.push({sequence:s++,eventType:"user_message",content:a.message,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:l,metadata:{}}),a.toolCalls)for(let p of a.toolCalls){let m=p.timestamp?new Date(p.timestamp).toISOString():l;o.push({sequence:s++,eventType:"tool_call",content:null,toolName:p.name??"unknown",toolInput:p.input??null,toolOutput:p.output??null,tokenUsage:null,timestamp:m,metadata:{}})}if(a.response){let p=a.response.timestamp?new Date(a.response.timestamp).toISOString():l;o.push({sequence:s++,eventType:"assistant_message",content:a.response.message,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:p,metadata:{}})}}let i=o.map(a=>a.timestamp).sort(),c=new Date().toISOString();return{tool:"copilot_agent",projectPath:null,gitBranch:null,startedAt:i[0]??c,endedAt:i[i.length-1]??null,events:o,metadata:{...n.requesterUsername&&{username:n.requesterUsername},...n.customTitle&&{title:n.customTitle},...n.agentMode!=null&&{agentMode:n.agentMode}}}}emptySession(){return{tool:"copilot_agent",projectPath:null,gitBranch:null,startedAt:new Date().toISOString(),endedAt:null,events:[],metadata:{}}}}});var fs,cp=Xe(()=>{"use strict";fs=class{static{u(this,"RuleMetricMcpAdapter")}tool="rulemetric_mcp";parse(t){let n;try{n=JSON.parse(t)}catch{return this.emptySession()}let o=(n.events??[]).map((i,c)=>({sequence:i.sequence??c,eventType:this.normalizeEventType(i.eventType),content:i.content??null,toolName:i.toolName??null,toolInput:i.toolInput??null,toolOutput:i.toolOutput??null,tokenUsage:i.tokenUsage??null,timestamp:i.timestamp??new Date().toISOString(),metadata:i.metadata??{}})),s=new Date().toISOString();return{tool:"rulemetric_mcp",projectPath:n.projectPath??null,gitBranch:n.gitBranch??null,startedAt:n.startedAt??o[0]?.timestamp??s,endedAt:n.endedAt??o[o.length-1]?.timestamp??null,events:o,metadata:n.metadata??{}}}normalizeEventType(t){return t&&["user_message","assistant_message","tool_call","tool_result","thinking","error"].includes(t)?t:"assistant_message"}emptySession(){return{tool:"rulemetric_mcp",projectPath:null,gitBranch:null,startedAt:new Date().toISOString(),endedAt:null,events:[],metadata:{}}}}});function $E(e){try{return JSON.parse(e)}catch{return e}}function L_(e,t){return Array.isArray(e)?e.filter(n=>n.type&&t.includes(n.type)).map(n=>n.text??"").filter(Boolean).join(`
|
|
3
3
|
|
|
4
|
-
`):""}function
|
|
5
|
-
`).filter(p=>p.trim()),o=[],s={},i=n.callNames,c=null,a=null,l=null;for(let p of r){let m;try{m=JSON.parse(p)}catch{continue}let
|
|
4
|
+
`):""}function qE(e){if(!e)return null;let t=e.cached_input_tokens??0,n=Math.max(0,(e.input_tokens??0)-t),r=(e.output_tokens??0)+(e.reasoning_output_tokens??0);return n===0&&r===0&&t===0?null:{input:n,output:r,cacheRead:t,cacheWrite:0}}function UE(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isFinite(t.getTime())?t.toISOString():new Date().toISOString()}function up(){return{sequence:0,model:null,prevCumulativeTotal:0,callNames:{}}}var gs,dp=Xe(()=>{"use strict";u($E,"safeJsonParse");u(L_,"textFromBlocks");u(qE,"tokenUsageFromCodex");u(UE,"normalizeTimestamp");u(up,"freshCodexState");gs=class{static{u(this,"CodexAdapter")}tool="codex";parse(t){let n=up(),{events:r,projectPath:o,gitBranch:s,metadata:i}=this.parseLines(t,n),c=r.map(l=>l.timestamp).sort(),a=new Date().toISOString();return{tool:"codex",projectPath:o,gitBranch:s,startedAt:c[0]??a,endedAt:c[c.length-1]??null,events:r,metadata:i}}parseAppend(t,n){let r={...n,callNames:{...n.callNames}},{events:o}=this.parseLines(t,r);return{events:o,state:r}}parseLines(t,n){let r=t.split(`
|
|
5
|
+
`).filter(p=>p.trim()),o=[],s={},i=n.callNames,c=null,a=null,l=null;for(let p of r){let m;try{m=JSON.parse(p)}catch{continue}let y=m.payload;if(!y)continue;let v=UE(m.timestamp);if(m.type==="session_meta"){l=y.session_id??y.id??l,c=y.cwd??c,y.git_branch&&(a=y.git_branch),y.model&&(n.model=y.model),s.sessionId=l,s.codexSessionId=l,s.originator=y.originator,s.source=y.source,s.modelProvider=y.model_provider,s.codexCliVersion=y.cli_version;continue}if(m.type==="turn_context"){c=y.cwd??c,y.model&&(n.model=y.model,s.model=y.model);continue}if(m.type==="response_item"&&y.type==="message"){if(y.role==="user"){let g=L_(y.content,["input_text"]);if(!g)continue;o.push({sequence:n.sequence++,eventType:"user_message",content:g,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:v,metadata:{}})}else if(y.role==="assistant"){let g=L_(y.content,["output_text"]);if(!g)continue;o.push({sequence:n.sequence++,eventType:"assistant_message",content:g,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,model:n.model,timestamp:v,metadata:n.model?{model:n.model}:{}})}continue}if(m.type==="response_item"&&y.type==="function_call"){let g=y.name??"unknown";y.call_id&&(i[y.call_id]=g);let h=typeof y.arguments=="string"?$E(y.arguments):{};o.push({sequence:n.sequence++,eventType:"tool_call",content:null,toolName:g,toolInput:h&&typeof h=="object"&&!Array.isArray(h)?h:{arguments:h},toolOutput:null,tokenUsage:null,model:n.model,timestamp:v,metadata:{callId:y.call_id}});continue}if(m.type==="response_item"&&y.type==="function_call_output"){let g=y.call_id?i[y.call_id]??null:null;o.push({sequence:n.sequence++,eventType:"tool_result",content:y.output??null,toolName:g,toolInput:null,toolOutput:y.output==null?null:{output:y.output},tokenUsage:null,model:n.model,timestamp:v,metadata:{callId:y.call_id}});continue}if(m.type==="event_msg"&&y.type==="token_count"){let g=y.info,h=g?.total_token_usage?.total_tokens??0;if(h>0&&h===n.prevCumulativeTotal)continue;h>0&&(n.prevCumulativeTotal=h);let w=qE(g?.last_token_usage??g?.total_token_usage);if(!w)continue;let b=g?.model??g?.model_name??n.model;o.push({sequence:n.sequence++,eventType:"assistant_message",content:null,toolName:null,toolInput:null,toolOutput:null,tokenUsage:w,model:b??null,timestamp:v,metadata:{codexEventType:"token_count",...b?{model:b}:{},reasoningOutputTokens:g?.last_token_usage?.reasoning_output_tokens??0}})}}return{events:o,projectPath:c,gitBranch:a,sessionId:l,metadata:s}}}});function Qi(e){let t=BE[e];if(!t)throw new Error(`Unknown session tool: ${e}`);return t()}function Zi(e){let t=e.trim();if(t.startsWith("{")){let n=t.split(`
|
|
6
6
|
`)[0],r=null;try{r=JSON.parse(n)}catch{try{r=JSON.parse(t)}catch{}}if(r){if(r.type==="user"||r.type==="assistant")return"claude_code";if(Array.isArray(r.events)&&!r.requests&&!r.allComposers)return"rulemetric_mcp";if(Array.isArray(r.requests))return r.requests.some(s=>Array.isArray(s.toolCalls))||r.agentMode?"copilot_agent":"vscode_copilot";if(r.allComposers)return"cursor"}if(!r)try{let o=t.split(`
|
|
7
|
-
`).filter(s=>s.trim());if(o.length>1){let s=JSON.parse(o[0]);if(s.type==="user"||s.type==="assistant")return"claude_code"}}catch{}}return null}var
|
|
7
|
+
`).filter(s=>s.trim());if(o.length>1){let s=JSON.parse(o[0]);if(s.type==="user"||s.type==="assistant")return"claude_code"}}catch{}}return null}var BE,$_=Xe(()=>{"use strict";op();sp();ip();ap();cp();dp();BE={claude_code:u(()=>new ds,"claude_code"),cursor:u(()=>new ls,"cursor"),vscode_copilot:u(()=>new ps,"vscode_copilot"),copilot_agent:u(()=>new ms,"copilot_agent"),rulemetric_mcp:u(()=>new fs,"rulemetric_mcp"),codex:u(()=>new gs,"codex")};u(Qi,"getAdapter");u(Zi,"detectTool")});function q_(e,t){let n=t.length>0?t.map(o=>`### ${o.name} (ID: ${o.id})
|
|
8
8
|
|
|
9
9
|
${o.content}`).join(`
|
|
10
10
|
|
|
@@ -45,12 +45,12 @@ Return your response as JSON matching this schema:
|
|
|
45
45
|
"summary": "<string>"
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
Return valid JSON only.`}function
|
|
49
|
-
`)[0];return n?.trim()?JSON.parse(n):null}catch{return null}}async function
|
|
50
|
-
`).filter(v=>v.trim()),o,s="",i=0,c=0,a=0,l=0,p=0,m=[],
|
|
51
|
-
`).filter(c=>c.trim()),s="",i="";for(let c of o){let a;try{a=JSON.parse(c)}catch{continue}if(a.type==="session.model_change"){s=a.data.newModel??s;continue}if(a.type==="user.message"){i=a.data.content??"";continue}if(a.type==="assistant.message"){let{messageId:l,outputTokens:p,toolRequests:m=[]}=a.data;if(p===0||!s)continue;let
|
|
52
|
-
`)[0];return n?.trim()?JSON.parse(n):null}catch{return null}}function
|
|
53
|
-
`).filter(i=>i.trim()),o=
|
|
48
|
+
Return valid JSON only.`}function U_(e){try{let t=e.match(/\{[\s\S]*\}/);if(!t)return null;let n=JSON.parse(t[0]);return typeof n.adherenceScore!="number"||!Array.isArray(n.deviations)||!Array.isArray(n.suggestions)||typeof n.summary!="string"?null:{adherenceScore:n.adherenceScore,deviations:n.deviations,suggestions:n.suggestions,summary:n.summary,analyzedAt:new Date().toISOString()}}catch{return null}}var B_=Xe(()=>{"use strict";u(q_,"buildAnalysisPrompt");u(U_,"parseAnalysisResponse")});import{readdir as lp,stat as pp}from"fs/promises";import{basename as FE,join as Mr}from"path";import{homedir as tu}from"os";function WE(){return process.env.CLAUDE_CONFIG_DIR||Mr(tu(),".claude")}function zE(){return Mr(WE(),"projects")}function VE(){return process.platform==="darwin"?Mr(tu(),"Library","Application Support","Claude","local-agent-mode-sessions"):process.platform==="win32"?Mr(tu(),"AppData","Roaming","Claude","local-agent-mode-sessions"):Mr(tu(),".config","Claude","local-agent-mode-sessions")}async function JE(e){let t=[];async function n(r,o){if(o>8)return;let s=await lp(r).catch(()=>[]);for(let i of s){if(i==="node_modules"||i===".git")continue;let c=Mr(r,i);if((await pp(c).catch(()=>null))?.isDirectory())if(i==="projects"){let l=await lp(c).catch(()=>[]);for(let p of l){let m=Mr(c,p);(await pp(m).catch(()=>null))?.isDirectory()&&t.push(m)}}else await n(c,o+1)}}return u(n,"walk"),await n(e,0),t}var HE,F_,H_=Xe(()=>{"use strict";HE={"claude-opus-4-7":"Opus 4.7","claude-opus-4-6":"Opus 4.6","claude-opus-4-5":"Opus 4.5","claude-opus-4-1":"Opus 4.1","claude-opus-4":"Opus 4","claude-sonnet-4-6":"Sonnet 4.6","claude-sonnet-4-5":"Sonnet 4.5","claude-sonnet-4":"Sonnet 4","claude-3-7-sonnet":"Sonnet 3.7","claude-3-5-sonnet":"Sonnet 3.5","claude-haiku-4-5":"Haiku 4.5","claude-3-5-haiku":"Haiku 3.5"};u(WE,"getClaudeDir");u(zE,"getProjectsDir");u(VE,"getDesktopSessionsDir");u(JE,"findDesktopProjectDirs");F_={name:"claude",displayName:"Claude Code",modelDisplayName(e){let t=e.replace(/@.*$/,"").replace(/-\d{8}$/,"");for(let[n,r]of Object.entries(HE))if(t.startsWith(n))return r;return t},toolDisplayName(e){return e},async discoverSessions(){let e=[],t=zE();try{let r=await lp(t);for(let o of r){let s=Mr(t,o);(await pp(s).catch(()=>null))?.isDirectory()&&e.push({path:s,project:o,provider:"claude"})}}catch{}let n=await JE(VE());for(let r of n)e.push({path:r,project:FE(r),provider:"claude"});return e},createSessionParser(){return{async*parse(){}}}}});import{readdir as nu,readFile as W_,stat as GE}from"fs/promises";import{basename as KE,join as hs}from"path";import{homedir as YE}from"os";function QE(){return process.env.CODEX_HOME??hs(YE(),".codex")}function ZE(e){return e.replace(/^\//,"").replace(/\//g,"-")}async function eT(e){try{let n=(await W_(e,"utf-8")).split(`
|
|
49
|
+
`)[0];return n?.trim()?JSON.parse(n):null}catch{return null}}async function tT(e){let t=await eT(e);if(!t)return{valid:!1};let n=t.type==="session_meta"&&typeof t.payload?.originator=="string"&&t.payload.originator.toLowerCase().startsWith("codex");return{valid:n,meta:n?t:void 0}}async function nT(e){let t=hs(e,"sessions"),n=[],r;try{r=await nu(t)}catch{return n}for(let o of r){if(!/^\d{4}$/.test(o))continue;let s=hs(t,o),i=await nu(s).catch(()=>[]);for(let c of i){if(!/^\d{2}$/.test(c))continue;let a=hs(s,c),l=await nu(a).catch(()=>[]);for(let p of l){if(!/^\d{2}$/.test(p))continue;let m=hs(a,p),y=await nu(m).catch(()=>[]);for(let v of y){if(!v.startsWith("rollout-")||!v.endsWith(".jsonl"))continue;let g=hs(m,v);if(!(await GE(g).catch(()=>null))?.isFile())continue;let{valid:w,meta:b}=await tT(g);if(!w||!b)continue;let I=b.payload?.cwd??"unknown";n.push({path:g,project:ZE(I),provider:"codex"})}}}}return n}function rT(e,t){return e?.info?.model??e?.info?.model_name??t??"gpt-5"}function oT(e,t){return{async*parse(){let n;try{n=await W_(e.path,"utf-8")}catch{return}let r=n.split(`
|
|
50
|
+
`).filter(v=>v.trim()),o,s="",i=0,c=0,a=0,l=0,p=0,m=[],y="";for(let v of r){let g;try{g=JSON.parse(v)}catch{continue}if(g.type==="session_meta"){s=g.payload?.session_id??KE(e.path,".jsonl"),o=g.payload?.model;continue}if(g.type==="response_item"&&g.payload?.type==="function_call"){let h=g.payload.name??"";m.push(z_[h]??h);continue}if(g.type==="response_item"&&g.payload?.type==="message"&&g.payload?.role==="user"){let h=(g.payload.content??[]).filter(w=>w.type==="input_text").map(w=>w.text??"").filter(Boolean);h.length>0&&(y=h.join(" "));continue}if(g.type==="event_msg"&&g.payload?.type==="token_count"){let h=g.payload.info;if(!h)continue;let w=h.total_token_usage?.total_tokens??0;if(w>0&&w===i)continue;i=w;let b=h.last_token_usage,I=0,S=0,A=0,x=0;if(b)I=b.input_tokens??0,S=b.cached_input_tokens??0,A=b.output_tokens??0,x=b.reasoning_output_tokens??0;else if(w>0){let F=h.total_token_usage;if(!F)continue;I=(F.input_tokens??0)-c,S=(F.cached_input_tokens??0)-a,A=(F.output_tokens??0)-l,x=(F.reasoning_output_tokens??0)-p}if(!b){let F=h.total_token_usage;F&&(c=F.input_tokens??0,a=F.cached_input_tokens??0,l=F.output_tokens??0,p=F.reasoning_output_tokens??0)}if(I+S+A+x===0)continue;let P=Math.max(0,I-S),E=rT(g.payload,o),j=g.timestamp??"",O=`codex:${e.path}:${j}:${w}`;if(t.has(O))continue;t.add(O),yield{provider:"codex",model:E,inputTokens:P,outputTokens:A,cacheCreationInputTokens:0,cacheReadInputTokens:S,cachedInputTokens:S,reasoningTokens:x,costUSD:0,tools:m,bashCommands:[],timestamp:j,speed:"standard",deduplicationKey:O,userMessage:y,sessionId:s},m=[],y=""}}}}}var XE,z_,V_,J_=Xe(()=>{"use strict";XE={"gpt-5.3-codex":"GPT-5.3 Codex","gpt-5.4-mini":"GPT-5.4 Mini","gpt-5.4":"GPT-5.4","gpt-5":"GPT-5","gpt-4o-mini":"GPT-4o Mini","gpt-4o":"GPT-4o"},z_={exec_command:"Bash",read_file:"Read",write_file:"Edit",apply_diff:"Edit",apply_patch:"Edit",spawn_agent:"Agent",close_agent:"Agent",wait_agent:"Agent",read_dir:"Glob"};u(QE,"getCodexDir");u(ZE,"sanitizeProject");u(eT,"readFirstLine");u(tT,"isValidCodexSession");u(nT,"discoverSessionsInDir");u(rT,"resolveModel");u(oT,"createParser");V_={name:"codex",displayName:"Codex",modelDisplayName(e){for(let[t,n]of Object.entries(XE))if(e.startsWith(t))return n;return e},toolDisplayName(e){return z_[e]??e},async discoverSessions(){return nT(QE())},createSessionParser(e,t){return oT(e,t)}}});import{readdir as sT,readFile as G_,stat as iT}from"fs/promises";import{basename as K_,dirname as aT,join as mp}from"path";import{homedir as cT}from"os";function lT(){return mp(cT(),".copilot","session-state")}function pT(e){let t=e.match(/^cwd:\s*(.+)$/m);return t?.[1]&&t[1].replace(/\s*#.*$/,"").replace(/^['"]|['"]$/g,"").trim()||null}function mT(e,t){return{async*parse(){let n;try{n=await G_(e.path,"utf-8")}catch{return}let r=K_(aT(e.path)),o=n.split(`
|
|
51
|
+
`).filter(c=>c.trim()),s="",i="";for(let c of o){let a;try{a=JSON.parse(c)}catch{continue}if(a.type==="session.model_change"){s=a.data.newModel??s;continue}if(a.type==="user.message"){i=a.data.content??"";continue}if(a.type==="assistant.message"){let{messageId:l,outputTokens:p,toolRequests:m=[]}=a.data;if(p===0||!s)continue;let y=`copilot:${r}:${l}`;if(t.has(y))continue;t.add(y);let v=m.map(g=>g.name??"").filter(Boolean).map(g=>Y_[g]??g);yield{provider:"copilot",model:s,inputTokens:0,outputTokens:p,cacheCreationInputTokens:0,cacheReadInputTokens:0,cachedInputTokens:0,reasoningTokens:0,costUSD:0,tools:v,bashCommands:[],timestamp:a.timestamp??"",speed:"standard",deduplicationKey:y,userMessage:i,sessionId:r},i=""}}}}}async function fT(e){let t=[],n;try{n=await sT(e)}catch{return t}for(let r of n){let o=mp(e,r,"events.jsonl");if(!(await iT(o).catch(()=>null))?.isFile())continue;let i=r;try{let c=await G_(mp(e,r,"workspace.yaml"),"utf-8"),a=pT(c);a&&(i=K_(a))}catch{}t.push({path:o,project:i,provider:"copilot"})}return t}var uT,Y_,dT,X_,Q_=Xe(()=>{"use strict";uT={"gpt-4.1-nano":"GPT-4.1 Nano","gpt-4.1-mini":"GPT-4.1 Mini","gpt-4.1":"GPT-4.1","gpt-4o-mini":"GPT-4o Mini","gpt-4o":"GPT-4o","gpt-5-mini":"GPT-5 Mini","gpt-5":"GPT-5","claude-sonnet-4-5":"Sonnet 4.5","claude-sonnet-4":"Sonnet 4","claude-3-7-sonnet":"Sonnet 3.7","claude-3-5-sonnet":"Sonnet 3.5","o4-mini":"o4-mini",o3:"o3"},Y_={bash:"Bash",read_file:"Read",write_file:"Edit",edit_file:"Edit",create_file:"Write",delete_file:"Delete",search_files:"Grep",find_files:"Glob",list_directory:"LS",web_search:"WebSearch",fetch_webpage:"WebFetch",github_repo:"GitHub"},dT=Object.entries(uT).sort((e,t)=>t[0].length-e[0].length);u(lT,"getCopilotSessionStateDir");u(pT,"parseCwd");u(mT,"createParser");u(fT,"discoverSessionsInDir");X_={name:"copilot",displayName:"GitHub Copilot",modelDisplayName(e){for(let[t,n]of dT)if(e===t||e.startsWith(t+"-"))return n;return e},toolDisplayName(e){return Y_[e]??e},async discoverSessions(){return fT(lT())},createSessionParser(e,t){return mT(e,t)}}});import{readdir as Z_,readFile as ty,stat as ey}from"fs/promises";import{basename as ny,join as fp}from"path";import{homedir as gT}from"os";function yT(){return fp(gT(),".pi","agent","sessions")}async function wT(e){try{let n=(await ty(e,"utf-8")).split(`
|
|
52
|
+
`)[0];return n?.trim()?JSON.parse(n):null}catch{return null}}function vT(e){return e.split(/[;&|]+/).map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}async function IT(e){let t=[],n;try{n=await Z_(e)}catch{return t}for(let r of n){let o=fp(e,r);if(!(await ey(o).catch(()=>null))?.isDirectory())continue;let i;try{i=await Z_(o)}catch{continue}for(let c of i){if(!c.endsWith(".jsonl"))continue;let a=fp(o,c);if(!(await ey(a).catch(()=>null))?.isFile())continue;let p=await wT(a);if(!p||p.type!=="session")continue;let m=p.cwd??r;t.push({path:a,project:ny(m),provider:"pi"})}}return t}function bT(e,t){return{async*parse(){let n;try{n=await ty(e.path,"utf-8")}catch{return}let r=n.split(`
|
|
53
|
+
`).filter(i=>i.trim()),o=ny(e.path,".jsonl"),s="";for(let[i,c]of r.entries()){let a;try{a=JSON.parse(c)}catch{continue}if(a.type==="session"){o=a.id??o;continue}if(a.type!=="message")continue;let l=a.message;if(!l)continue;if(l.role==="user"){let x=(l.content??[]).filter(T=>T.type==="text").map(T=>T.text??"").filter(Boolean);x.length>0&&(s=x.join(" "));continue}if(l.role!=="assistant"||!l.usage)continue;let{input:p,output:m,cacheRead:y,cacheWrite:v}=l.usage;if(p===0&&m===0)continue;let g=l.model??"gpt-5",h=l.responseId??"",w=`pi:${e.path}:${h||a.id||a.timestamp||String(i)}`;if(t.has(w))continue;t.add(w);let b=(l.content??[]).filter(x=>x.type==="toolCall"&&x.name),I=b.map(x=>ry[x.name]??x.name),S=b.filter(x=>x.name==="bash").flatMap(x=>{let T=x.arguments?.command;return typeof T=="string"?vT(T):[]}),A=a.timestamp??"";yield{provider:"pi",model:g,inputTokens:p,outputTokens:m,cacheCreationInputTokens:v,cacheReadInputTokens:y,cachedInputTokens:y,reasoningTokens:0,costUSD:0,tools:I,bashCommands:S,timestamp:A,speed:"standard",deduplicationKey:w,userMessage:s,sessionId:o},s=""}}}}var hT,ry,_T,oy,sy=Xe(()=>{"use strict";hT={"gpt-5.4":"GPT-5.4","gpt-5.4-mini":"GPT-5.4 Mini","gpt-5":"GPT-5","gpt-4o":"GPT-4o","gpt-4o-mini":"GPT-4o Mini"},ry={bash:"Bash",read:"Read",edit:"Edit",write:"Write",glob:"Glob",grep:"Grep",task:"Agent",dispatch_agent:"Agent",fetch:"WebFetch",search:"WebSearch",todo:"TodoWrite",patch:"Patch"},_T=Object.entries(hT).sort((e,t)=>t[0].length-e[0].length);u(yT,"getPiSessionsDir");u(wT,"readFirstEntry");u(vT,"extractBashCommands");u(IT,"discoverSessionsInDir");u(bT,"createParser");oy={name:"pi",displayName:"Pi",modelDisplayName(e){for(let[t,n]of _T)if(e.startsWith(t))return n;return e},toolDisplayName(e){return ry[e]??e},async discoverSessions(){return IT(yT())},createSessionParser(e,t){return bT(e,t)}}});var ay={};no(ay,{cursor:()=>jT});import{existsSync as ST}from"fs";import{join as gp}from"path";import{homedir as hp}from"os";function iy(){if(ru)return!0;try{return ru=Td("better-sqlite3"),!0}catch{return!1}}function ET(){return process.platform==="darwin"?gp(hp(),"Library","Application Support","Cursor","User","globalStorage","state.vscdb"):process.platform==="win32"?gp(hp(),"AppData","Roaming","Cursor","User","globalStorage","state.vscdb"):gp(hp(),".config","Cursor","User","globalStorage","state.vscdb")}function TT(e){return!e||e==="default"?AT:e}function kT(e,t){return{async*parse(){if(!iy()||!ru)return;let n;try{n=new ru(e.path,{readonly:!0})}catch{return}try{let o=n.prepare(RT).all();for(let s of o){let i=s.input_tokens??0,c=s.output_tokens??0;if(i===0&&c===0)continue;let a=s.created_at??"",l=s.conversation_id??"unknown",p=`cursor:${l}:${a}:${i}:${c}`;if(t.has(p))continue;t.add(p);let m=TT(s.model);yield{provider:"cursor",model:s.model??"default",inputTokens:i,outputTokens:c,cacheCreationInputTokens:0,cacheReadInputTokens:0,cachedInputTokens:0,reasoningTokens:0,costUSD:0,tools:[],bashCommands:[],timestamp:a,speed:"standard",deduplicationKey:p,userMessage:s.user_text??"",sessionId:l}}}finally{n.close()}}}}var ru,AT,xT,RT,jT,cy=Xe(()=>{"use strict";ru=null;u(iy,"loadSqlite");AT="claude-sonnet-4-5",xT={"claude-4.5-opus-high-thinking":"Opus 4.5 (Thinking)","claude-4-opus":"Opus 4","claude-4-sonnet-thinking":"Sonnet 4 (Thinking)","claude-4.5-sonnet-thinking":"Sonnet 4.5 (Thinking)","claude-4.6-sonnet":"Sonnet 4.6","composer-1":"Composer 1","gpt-5":"GPT-5","gpt-4.1":"GPT-4.1",default:"Auto (Sonnet est.)"};u(ET,"getCursorDbPath");u(TT,"resolveModel");RT=`
|
|
54
54
|
SELECT
|
|
55
55
|
json_extract(value, '$.tokenCount.inputTokens') as input_tokens,
|
|
56
56
|
json_extract(value, '$.tokenCount.outputTokens') as output_tokens,
|
|
@@ -62,24 +62,24 @@ Return valid JSON only.`}function L_(e){try{let t=e.match(/\{[\s\S]*\}/);if(!t)r
|
|
|
62
62
|
WHERE key LIKE 'bubbleId:%'
|
|
63
63
|
AND json_extract(value, '$.tokenCount.inputTokens') > 0
|
|
64
64
|
ORDER BY json_extract(value, '$.createdAt') ASC
|
|
65
|
-
`;u(
|
|
65
|
+
`;u(kT,"createParser");jT={name:"cursor",displayName:"Cursor",modelDisplayName(e){return xT[e]??e},toolDisplayName(e){return e},async discoverSessions(){if(!iy())return[];let e=ET();return ST(e)?[{path:e,project:"cursor",provider:"cursor"}]:[]},createSessionParser(e,t){return kT(e,t)}}});var ly={};no(ly,{opencode:()=>qT});import{readdir as NT}from"fs/promises";import{join as _p}from"path";import{homedir as CT}from"os";function yp(){if(_s)return!0;try{return _s=Td("better-sqlite3"),!0}catch{return!1}}function uy(e){return e.replace(/^\//,"").replace(/\//g,"-")}function PT(){let e=process.env.XDG_DATA_HOME??_p(CT(),".local","share");return _p(e,"opencode")}async function OT(e){try{return(await NT(e)).filter(n=>n.startsWith("opencode")&&n.endsWith(".db")).map(n=>_p(e,n))}catch{return[]}}function DT(e){let t=e<1e12?e*1e3:e;return new Date(t).toISOString()}function MT(e){return e.split(/[;&|]+/).map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}function LT(e,t){return{async*parse(){if(!yp()||!_s)return;let n=e.path.split(":"),r=n[n.length-1],o=n.slice(0,-1).join(":"),s;try{s=new _s(o,{readonly:!0})}catch{return}try{let i=s.prepare("SELECT id, time_created, data FROM message WHERE session_id = ? ORDER BY time_created ASC").all(r),c=s.prepare("SELECT message_id, data FROM part WHERE session_id = ? ORDER BY message_id, id").all(r),a=new Map;for(let p of c)try{let m=JSON.parse(p.data),y=a.get(p.message_id)??[];y.push(m),a.set(p.message_id,y)}catch{}let l="";for(let p of i){let m;try{m=JSON.parse(p.data)}catch{continue}if(m.role==="user"){let S=(a.get(p.id)??[]).filter(A=>A.type==="text").map(()=>"").filter(Boolean);S.length>0&&(l=S.join(" "));continue}if(m.role!=="assistant")continue;let y={input:m.tokens?.input??0,output:m.tokens?.output??0,reasoning:m.tokens?.reasoning??0,cacheRead:m.tokens?.cache?.read??0,cacheWrite:m.tokens?.cache?.write??0};if(y.input===0&&y.output===0&&y.reasoning===0&&y.cacheRead===0&&y.cacheWrite===0&&(m.cost??0)===0)continue;let h=(a.get(p.id)??[]).filter(S=>S.type==="tool"),w=h.map(S=>dy[S.tool??""]??S.tool??"").filter(Boolean),b=h.filter(S=>S.tool==="bash"&&typeof S.state?.input?.command=="string").flatMap(S=>MT(S.state.input.command)),I=`opencode:${r}:${p.id}`;t.has(I)||(t.add(I),yield{provider:"opencode",model:m.modelID??"unknown",inputTokens:y.input,outputTokens:y.output,cacheCreationInputTokens:y.cacheWrite,cacheReadInputTokens:y.cacheRead,cachedInputTokens:y.cacheRead,reasoningTokens:y.reasoning,costUSD:m.cost??0,tools:w,bashCommands:b,timestamp:DT(p.time_created),speed:"standard",deduplicationKey:I,userMessage:l,sessionId:r})}}finally{s.close()}}}}async function $T(e){if(!yp()||!_s)return[];let t;try{t=new _s(e,{readonly:!0})}catch{return[]}try{return t.prepare("SELECT id, directory, title FROM session WHERE time_archived IS NULL AND parent_id IS NULL ORDER BY time_created DESC").all().map(r=>({path:`${e}:${r.id}`,project:r.directory?uy(r.directory):uy(r.title),provider:"opencode"}))}catch{return[]}finally{t.close()}}var _s,dy,qT,py=Xe(()=>{"use strict";_s=null;u(yp,"loadSqlite");dy={bash:"Bash",read:"Read",edit:"Edit",write:"Write",glob:"Glob",grep:"Grep",task:"Agent",fetch:"WebFetch",search:"WebSearch",todo:"TodoWrite",skill:"Skill",patch:"Patch"};u(uy,"sanitize");u(PT,"getDataDir");u(OT,"findDbFiles");u(DT,"parseTimestamp");u(MT,"extractBashCommands");u(LT,"createParser");u($T,"discoverFromDb");qT={name:"opencode",displayName:"OpenCode",modelDisplayName(e){return e.replace(/^[^/]+\//,"")},toolDisplayName(e){return dy[e]??e},async discoverSessions(){if(!yp())return[];let e=await OT(PT()),t=[];for(let n of e)t.push(...await $T(n));return t},createSessionParser(e,t){return LT(e,t)}}});async function yy(){if(fy)return my;fy=!0;try{let{cursor:e}=await Promise.resolve().then(()=>(cy(),ay));return my=e,e}catch{return null}}async function wy(){if(hy)return gy;hy=!0;try{let{opencode:e}=await Promise.resolve().then(()=>(py(),ly));return gy=e,e}catch{return null}}async function wp(){let[e,t]=await Promise.all([yy(),wy()]),n=[..._y];return e&&n.push(e),t&&n.push(t),n}async function vy(e){let t=await wp(),n=e&&e!=="all"?t.filter(o=>o.name===e):t,r=[];for(let o of n){let s=await o.discoverSessions();r.push(...s)}return r}async function Iy(e){return e==="cursor"?await yy()??void 0:e==="opencode"?await wy()??void 0:_y.find(t=>t.name===e)}var _y,my,fy,gy,hy,by=Xe(()=>{"use strict";H_();J_();Q_();sy();_y=[F_,V_,X_,oy],my=null,fy=!1;u(yy,"loadCursor");gy=null,hy=!1;u(wy,"loadOpenCode");u(wp,"getAllProviders");u(vy,"discoverAllSessions");u(Iy,"getProvider")});import{spawn as UT}from"node:child_process";function ou(e){return`rm-${e.trim().replace(/[^A-Za-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"session"}`}function su(e){let t=e.runId?["env",`RULEMETRIC_RUN_ID=${e.runId}`,"claude"]:["claude"];return e.resumeSessionId&&t.push("--resume",e.resumeSessionId),e.model&&t.push("--model",e.model),["new-session","-d","-s",e.sessionName,"-c",e.projectPath,"--",...t]}function ea(e,t,n={}){return n.literal===!1?["send-keys","-t",e,t]:["send-keys","-t",e,"-l","--",t]}function Sy(e){return["has-session","-t",e]}function ta(e){return`tmux attach -t ${e}`}function BT(){let e=["/opt/homebrew/bin","/usr/local/bin"],t=(process.env.PATH??"").split(":").filter(Boolean),n=e.filter(r=>!t.includes(r));return n.length===0?process.env:{...process.env,PATH:[...t,...n].join(":")}}function vp(e){return new Promise(t=>{let n=UT("tmux",e,{stdio:["ignore","ignore","pipe"],env:BT()}),r="";n.stderr.on("data",o=>{r+=o.toString()}),n.on("close",o=>t({code:o,stderr:r})),n.on("error",o=>t({code:null,stderr:o.message}))})}async function Ay(){return(await vp(["-V"])).code===0}var Ip=Xe(()=>{"use strict";u(ou,"sanitizeTmuxName");u(su,"buildTmuxLaunchArgs");u(ea,"buildTmuxSendKeysArgs");u(Sy,"buildTmuxHasSessionArgs");u(ta,"buildTmuxAttachCommand");u(BT,"tmuxSpawnEnv");u(vp,"runTmux");u(Ay,"isTmuxAvailable")});import{spawn as bp}from"node:child_process";import{randomUUID as FT}from"node:crypto";import{writeFile as xy}from"node:fs/promises";import{tmpdir as Ey}from"node:os";import{join as Ty}from"node:path";function WT(e){if(e!==void 0){if(HT.test(e))return e;console.warn(`[claude-code-launcher] dropping non-uuid runId (RULEMETRIC_RUN_ID not injected): ${JSON.stringify(e)}`)}}function zT(e){return`'${e.replace(/'/g,"'\\''")}'`}var HT,iu,Ry=Xe(()=>{"use strict";Ip();HT=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;u(WT,"validateRunId");u(zT,"shellSingleQuote");iu=class{static{u(this,"ClaudeCodeLauncher")}options;tool="claude_code";constructor(t={}){this.options=t}capabilities={headless:!0,interactive:!0,remoteSpawn:!0};async launch(t){let n=FT(),r={...t,runId:WT(t.runId)};return r.mode==="headless"?this.launchHeadless(r,n):this.launchInteractive(r,n)}async launchHeadless(t,n){let r=["-p",t.prompt??"","--output-format","json"];t.systemPrompt&&r.push("--system-prompt",t.systemPrompt),t.model&&r.push("--model",t.model);let o={...process.env};return delete o.CLAUDECODE,delete o.HTTPS_PROXY,t.runId&&(o.RULEMETRIC_RUN_ID=t.runId),new Promise(s=>{let i=bp("claude",r,{cwd:t.projectPath,env:o,stdio:["ignore","pipe","pipe"]}),c="",a="";i.stdout.on("data",p=>{c+=p.toString()}),i.stderr.on("data",p=>{a+=p.toString()});let l=t.timeout?setTimeout(()=>{i.kill("SIGTERM")},t.timeout):null;i.on("close",p=>{l&&clearTimeout(l);let m=c;try{let y=JSON.parse(c);m=y.result??y.content??c}catch{}s({sessionId:n,pid:i.pid,exitCode:p,output:m,error:p!==0?a:void 0})}),i.on("error",p=>{l&&clearTimeout(l),s({sessionId:n,error:`Failed to spawn claude: ${p.message}`})})})}async launchInteractive(t,n){return await(this.options.tmuxAvailable??Ay)().catch(()=>!1)?this.launchInteractiveTmux(t,n):this.launchInteractiveTerminal(t,n,"tmux_not_found")}async launchInteractiveTmux(t,n){let r=this.options.runTmux??vp,o=ou(`claude-${t.resumeSessionId??n}`),s=await r(su({sessionName:o,projectPath:t.projectPath,resumeSessionId:t.resumeSessionId,model:t.model,runId:t.runId}));if(s.code!==0)return this.launchInteractiveTerminal(t,n,"tmux_launch_failed",`tmux new-session exited ${s.code}: ${s.stderr.trim()||"no stderr"}`);let i=await this.openTerminalAttach(o,n);if(t.prompt){let c=await r(ea(o,t.prompt));if(c.code!==0)return{sessionId:n,liveSendAvailable:!1,fallbackReason:"tmux_launch_failed",error:`tmux send-keys exited ${c.code}: ${c.stderr.trim()||"no stderr"}`};let a=await r(ea(o,"Enter",{literal:!1}));if(a.code!==0)return{sessionId:n,liveSendAvailable:!1,fallbackReason:"tmux_launch_failed",error:`tmux send Enter exited ${a.code}: ${a.stderr.trim()||"no stderr"}`}}return{sessionId:n,pid:i.pid,liveSendAvailable:!0,...i.error?{error:i.error}:{},terminalTarget:{kind:"tmux",target:o,attachCommand:ta(o),live:!0}}}async openTerminalAttach(t,n){let r=Ty(Ey(),`rulemetric-attach-${n}.command`),o=`#!/bin/zsh
|
|
66
66
|
rm -- "$0"
|
|
67
67
|
${ta(t)}
|
|
68
|
-
`;return await
|
|
68
|
+
`;return await xy(r,o,{mode:493}),new Promise(s=>{let i=bp("open",["-a","Terminal",r],{stdio:["ignore","pipe","pipe"]}),c="";i.stderr.on("data",a=>{c+=a.toString()}),i.on("close",a=>{s(a===0?{pid:i.pid}:{pid:i.pid,error:`open attach exited ${a}: ${c.trim()||"no stderr"}`})}),i.on("error",a=>{s({error:`Failed to spawn open attach: ${a.message}`})})})}async launchInteractiveTerminal(t,n,r,o){let s=["claude"];t.resumeSessionId?s.push("--resume",t.resumeSessionId):t.prompt&&s.push("-p",JSON.stringify(t.prompt)),t.model&&s.push("--model",t.model);let i=s.join(" "),c=Ty(Ey(),`rulemetric-launch-${n}.command`),a=t.runId?`export RULEMETRIC_RUN_ID=${zT(t.runId)}
|
|
69
69
|
`:"",l=`#!/bin/zsh
|
|
70
70
|
rm -- "$0"
|
|
71
71
|
cd ${JSON.stringify(t.projectPath)} || exit
|
|
72
72
|
`+a+`${i}
|
|
73
|
-
`;return await
|
|
73
|
+
`;return await xy(c,l,{mode:493}),new Promise(p=>{let m=bp("open",["-a","Terminal",c],{stdio:["ignore","pipe","pipe"]}),y="";m.stderr.on("data",v=>{y+=v.toString()}),m.on("close",v=>{if(v===0)p({sessionId:n,pid:m.pid,liveSendAvailable:!1,fallbackReason:r,...o?{error:o}:{}});else{let g=y.trim()||"no stderr";p({sessionId:n,pid:m.pid,liveSendAvailable:!1,fallbackReason:r,error:o?`${o}; open exited ${v}: ${g}`:`open exited ${v}: ${g}`})}}),m.on("error",v=>{p({sessionId:n,liveSendAvailable:!1,fallbackReason:r,error:`Failed to spawn open: ${v.message}`})})})}}});import{spawn as ky}from"node:child_process";import{randomUUID as VT}from"node:crypto";var au,jy=Xe(()=>{"use strict";au=class{static{u(this,"CodexLauncher")}tool="codex";capabilities={headless:!0,interactive:!0,remoteSpawn:!0};async launch(t){let n=VT();return t.mode==="headless"?this.launchHeadless(t,n):this.launchInteractive(t,n)}launchHeadless(t,n){let r=["-q",t.prompt??""];return t.model&&r.push("--model",t.model),new Promise(o=>{let s=ky("codex",r,{cwd:t.projectPath,stdio:["ignore","pipe","pipe"]}),i="",c="";s.stdout.on("data",l=>{i+=l.toString()}),s.stderr.on("data",l=>{c+=l.toString()});let a=t.timeout?setTimeout(()=>{s.kill("SIGTERM")},t.timeout):null;s.on("close",l=>{a&&clearTimeout(a),o({sessionId:n,pid:s.pid,exitCode:l,output:i,error:l!==0?c:void 0})}),s.on("error",l=>{a&&clearTimeout(a),o({sessionId:n,error:`Failed to spawn codex: ${l.message}`})})})}launchInteractive(t,n){let r=["codex"];t.prompt&&r.push(JSON.stringify(t.prompt));let o=`cd ${JSON.stringify(t.projectPath)} && ${r.join(" ")}`,s=ky("osascript",["-e",`tell application "Terminal" to do script ${JSON.stringify(o)}`],{stdio:"ignore",detached:!0});return s.unref(),Promise.resolve({sessionId:n,pid:s.pid})}}});import{spawn as Ny}from"node:child_process";import{randomUUID as JT}from"node:crypto";var cu,Cy=Xe(()=>{"use strict";cu=class{static{u(this,"AiderLauncher")}tool="aider";capabilities={headless:!0,interactive:!0,remoteSpawn:!0};async launch(t){let n=JT();return t.mode==="headless"?this.launchHeadless(t,n):this.launchInteractive(t,n)}launchHeadless(t,n){let r=["--message",t.prompt??"","--yes"];return t.model&&r.push("--model",t.model),new Promise(o=>{let s=Ny("aider",r,{cwd:t.projectPath,stdio:["ignore","pipe","pipe"]}),i="",c="";s.stdout.on("data",l=>{i+=l.toString()}),s.stderr.on("data",l=>{c+=l.toString()});let a=t.timeout?setTimeout(()=>{s.kill("SIGTERM")},t.timeout):null;s.on("close",l=>{a&&clearTimeout(a),o({sessionId:n,pid:s.pid,exitCode:l,output:i,error:l!==0?c:void 0})}),s.on("error",l=>{a&&clearTimeout(a),o({sessionId:n,error:`Failed to spawn aider: ${l.message}`})})})}launchInteractive(t,n){let r=["aider"];t.model&&r.push("--model",t.model);let o=`cd ${JSON.stringify(t.projectPath)} && ${r.join(" ")}`,s=Ny("osascript",["-e",`tell application "Terminal" to do script ${JSON.stringify(o)}`],{stdio:"ignore",detached:!0});return s.unref(),Promise.resolve({sessionId:n,pid:s.pid})}}});import{spawn as GT}from"node:child_process";import{randomUUID as KT}from"node:crypto";var uu,Py=Xe(()=>{"use strict";uu=class{static{u(this,"GenericLauncher")}tool;constructor(t){this.tool=t}capabilities={headless:!1,interactive:!0,remoteSpawn:!1};async launch(t){let n=KT();if(t.mode==="headless")return{sessionId:n,error:`${this.tool} does not support headless mode`};let r=`cd ${JSON.stringify(t.projectPath)} && echo "Session ${n} \u2014 tool: ${this.tool}" && exec $SHELL`,o=GT("osascript",["-e",`tell application "Terminal" to do script ${JSON.stringify(r)}`],{stdio:"ignore",detached:!0});return o.unref(),{sessionId:n,pid:o.pid}}}});function Dy(e){let t=Oy[e];return t?t():new uu(e)}function My(){return Object.entries(Oy).map(([e,t])=>({tool:e,capabilities:t().capabilities}))}var Oy,Ly=Xe(()=>{"use strict";Ry();jy();Cy();Py();Oy={claude_code:u(()=>new iu,"claude_code"),codex:u(()=>new au,"codex"),aider:u(()=>new cu,"aider")};u(Dy,"getLauncher");u(My,"getAvailableLaunchers")});import $y from"node:path";function Sp(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^[-.]+|[-.]+$/g,"")||"worktree"}function du(e){return $y.resolve(e.basePath??$y.join(e.repoRoot,"..",".rulemetric-worktrees",Sp(e.branch)))}var qy=Xe(()=>{"use strict";u(Sp,"sanitizeBranch");u(du,"worktreePathFor")});var Uy={};no(Uy,{ClaudeCodeAdapter:()=>ds,CodexAdapter:()=>gs,CopilotAgentAdapter:()=>ms,CursorAdapter:()=>ls,RuleMetricMcpAdapter:()=>fs,SESSION_EVENT_TYPES:()=>LE,SESSION_TOOLS:()=>ME,VSCodeCopilotAdapter:()=>ps,buildAnalysisPrompt:()=>q_,buildTmuxAttachCommand:()=>ta,buildTmuxHasSessionArgs:()=>Sy,buildTmuxLaunchArgs:()=>su,buildTmuxSendKeysArgs:()=>ea,detectTool:()=>Zi,discoverAllSessions:()=>vy,freshCodexState:()=>up,getAdapter:()=>Qi,getAllProviders:()=>wp,getAvailableLaunchers:()=>My,getLauncher:()=>Dy,getProvider:()=>Iy,parseAnalysisResponse:()=>U_,sanitizeBranch:()=>Sp,sanitizeTmuxName:()=>ou,worktreePathFor:()=>du});var lu=Xe(()=>{"use strict";M_();op();sp();ip();ap();cp();dp();$_();B_();by();Ly();qy();Ip()});var tw={};no(tw,{getSupabaseAdmin:()=>vn});import{createClient as aR}from"@supabase/supabase-js";function vn(){if(gu)return gu;let e=process.env.SUPABASE_URL,t=process.env.SUPABASE_SERVICE_ROLE_KEY;if(!e||!t)throw new Error("SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY are required for admin operations");return gu=aR(e,t,{auth:{autoRefreshToken:!1,persistSession:!1}}),gu}var gu,na=Xe(()=>{"use strict";gu=null;u(vn,"getSupabaseAdmin")});var sw={};no(sw,{SNAPSHOT_DELTA_BUCKET:()=>xp,decodeDeltaBlob:()=>nw,encodeDeltaBlob:()=>Ep,getDeltaBlob:()=>ra,resolveDeltaPage:()=>oa,resolveFullRows:()=>Rp,uploadEncodedDelta:()=>Tp});import{gzipSync as cR,gunzipSync as uR}from"node:zlib";import{createHash as dR}from"node:crypto";function Ep(e){let t=JSON.stringify(e??[]),n=cR(Buffer.from(t,"utf-8")),r=dR("sha256").update(n).digest("hex");return{body:n,ref:`sha256/${r}.json.gz`,bytes:n.byteLength}}function nw(e){try{let t=uR(Buffer.from(e)).toString("utf-8"),n=JSON.parse(t);return Array.isArray(n)?n:[]}catch{return[]}}async function Tp(e){let{body:t,ref:n,bytes:r}=e,{error:o}=await vn().storage.from(xp).upload(n,t,{contentType:"application/gzip",upsert:!0});if(o)throw new Error(`uploadEncodedDelta failed for ${n}: ${o.message}`);return{ref:n,bytes:r}}async function ra(e){let{data:t,error:n}=await vn().storage.from(xp).download(e);if(n||!t)return console.warn(`[storage-blobs] delta.source=storage_miss ref=${e} err=${n?.message??"no data"}`),[];let r=Buffer.from(await t.arrayBuffer());return nw(r)}function hu(e){return typeof e.messagesDeltaRef=="string"&&e.messagesDeltaRef.length>0}async function ow(e,t,n){let r=new Array(e.length),o=0,s=u(async()=>{for(;;){let i=o++;if(i>=e.length)return;r[i]=await n(e[i])}},"worker");return await Promise.all(Array.from({length:Math.min(t,e.length)},s)),r}async function oa(e){return e.some(hu)?ow(e,rw,async t=>({sequence:t.sequence,messagesDelta:hu(t)?await ra(t.messagesDeltaRef):t.messagesDelta})):e.map(t=>({sequence:t.sequence,messagesDelta:t.messagesDelta}))}async function Rp(e){return e.some(hu)?ow(e,rw,async t=>hu(t)?{...t,messagesDelta:await ra(t.messagesDeltaRef)}:t):e}var xp,rw,_u=Xe(()=>{"use strict";na();xp="snapshot-deltas";u(Ep,"encodeDeltaBlob");u(nw,"decodeDeltaBlob");u(Tp,"uploadEncodedDelta");u(ra,"getDeltaBlob");rw=8;u(hu,"hasRef");u(ow,"mapCapped");u(oa,"resolveDeltaPage");u(Rp,"resolveFullRows")});var DI={};no(DI,{resolveRuntimeWebConfig:()=>OI,stampRuntimeConfig:()=>DO});function OI(e=process.env){let t=e.SUPABASE_URL?.trim(),n=e.SUPABASE_ANON_KEY?.trim();return!t||!n?null:{supabaseUrl:t,supabaseAnonKey:n}}function DO(e,t=process.env){let n=OI(t);if(!n)return e;let o=`<script>window.__RM_CONFIG=${JSON.stringify(n).replace(/</g,"\\u003c")}</script>`;return e.includes("</head>")?e.replace("</head>",`${o}
|
|
74
74
|
</head>`):`${o}
|
|
75
|
-
${e}`}var OI=Xe(()=>{"use strict";u(CI,"resolveRuntimeWebConfig");u(OO,"stampRuntimeConfig")});import*as yd from"node:fs";import*as wd from"node:path";import{fileURLToPath as mD}from"node:url";import{serve as fD}from"@hono/node-server";import{trace as vf,context as l0}from"@opentelemetry/api";import{NodeSDK as p0}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as m0}from"@opentelemetry/exporter-trace-otlp-http";import{BatchSpanProcessor as f0,ConsoleSpanExporter as g0,SimpleSpanProcessor as h0}from"@opentelemetry/sdk-trace-node";import{Resource as _0}from"@opentelemetry/resources";import{ATTR_SERVICE_NAME as y0,ATTR_SERVICE_VERSION as w0}from"@opentelemetry/semantic-conventions";function wf(e){if(!e)return{};let t={};for(let n of e.split(",")){let r=n.indexOf("=");if(r===-1)continue;let o=n.slice(0,r).trim(),s=n.slice(r+1).trim();o&&(t[o]=s)}return t}u(wf,"parseOtlpHeaders");var $o=null;function qo(){return process.env.TELEMETRY_ENABLED!=="false"}u(qo,"isTelemetryEnabled");function Ed(e){if(!qo()||$o!==null)return"off";let t=new _0({[y0]:e.serviceName,[w0]:e.serviceVersion??"0.1.0"}),n=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r,o;if(n){let s=wf(process.env.OTEL_EXPORTER_OTLP_HEADERS),i=new m0({url:`${n}/v1/traces`,headers:s});o=new f0(i),r="otlp"}else if(process.env.OTEL_SPAN_EXPORT==="none")o=void 0,r="silent";else{let s=new g0;o=new h0(s),r="console"}return $o=new p0({resource:t,spanProcessors:o?[o]:[]}),$o.start(),r}u(Ed,"initTelemetry");async function Td(){$o&&(await $o.shutdown(),$o=null)}u(Td,"shutdownTelemetry");function Rd(e){return vf.getTracer(e??"rulemetric")}u(Rd,"getTracer");function kd(){return vf.getSpan(l0.active())?.spanContext().traceId}u(kd,"getTraceId");import{SpanKind as v0,SpanStatusCode as If}from"@opentelemetry/api";function jd(){return async(e,t)=>{if(!qo()){await t();return}let n=Rd(),r=e.req.method,o=e.req.path;await n.startActiveSpan(`${r} ${o}`,{kind:v0.SERVER,attributes:{"http.method":r,"http.url":e.req.url,"http.route":o}},async s=>{try{await t(),s.setAttribute("http.status_code",e.res.status);let i=e.get("userId");i&&s.setAttribute("rulemetric.user_id",i),e.res.status>=400&&s.setStatus({code:If.ERROR})}catch(i){throw s.setStatus({code:If.ERROR}),s.recordException(i),i}finally{s.end()}})}}u(jd,"telemetryMiddleware");import{trace as I0,context as b0}from"@opentelemetry/api";function Nd(e){let t=I0.getSpan(b0.active());if(t)for(let[n,r]of Object.entries(e))t.setAttribute(n,r)}u(Nd,"setSpanAttributes");import*as sr from"@sentry/node";var ri=!1;function Cd(e){if(ri)return!1;let t=process.env.SENTRY_DSN;return t?(sr.init({dsn:t,serverName:e.serviceName,environment:process.env.NODE_ENV??"development",tracesSampleRate:0}),ri=!0,!0):!1}u(Cd,"initSentry");function qn(e,t){if(!ri)return;let n=e instanceof Error?e:new Error(typeof e=="string"?e:JSON.stringify(e));sr.captureException(n,t)}u(qn,"captureException");function oi(e){if(ri){if(e===null){sr.setUser(null);return}sr.setUser({id:e})}}u(oi,"setSentryUser");async function si(e){ri&&await sr.flush(e)}u(si,"flushSentry");import*as Va from"node:fs";import*as Ks from"node:path";import{fileURLToPath as DO}from"node:url";import{Hono as MO}from"hono";import{cors as LO}from"hono/cors";import{bodyLimit as $O}from"hono/body-limit";import{serveStatic as qO}from"@hono/node-server/serve-static";import{createHash as bA}from"node:crypto";import{createClient as SA}from"@supabase/supabase-js";import{eq as Jg,and as AA,isNull as xA}from"drizzle-orm";var Cc={};to(Cc,{agentJobs:()=>Ie,agentRuns:()=>W,agentRunsRelations:()=>zS,alertDispatches:()=>un,announcementDeliveries:()=>po,announcements:()=>Je,apiKeys:()=>ye,apiKeysRelations:()=>CS,benchmarks:()=>Rn,benchmarksRelations:()=>rA,cliErrorEvents:()=>yc,cliSetupEvents:()=>_c,contentBlobs:()=>cn,contextSnapshots:()=>j,contextSnapshotsRelations:()=>cA,evalComparisons:()=>Ke,evalConversations:()=>Te,evalConversationsRelations:()=>aA,evalGradeAnnotations:()=>ze,evalJobs:()=>be,evalJobsRelations:()=>iA,evalRuns:()=>_e,evalRunsRelations:()=>nA,evalTargets:()=>R,evalTargetsRelations:()=>eA,evals:()=>he,evalsRelations:()=>tA,extensionAuthCodes:()=>gn,harnessReleases:()=>Tt,insightsJobs:()=>F,instructionEvents:()=>Nt,instructionEventsRelations:()=>qS,instructionPromotions:()=>ke,instructionSuggestionEvents:()=>zt,instructionSuggestions:()=>Y,instructionUsageEvents:()=>Er,instructionUsageEventsRelations:()=>ZS,instructionVersionIdentities:()=>Bn,instructionVersions:()=>me,instructionVersionsRelations:()=>BS,instructions:()=>y,instructionsRelations:()=>$S,judgeReviewerVerdicts:()=>ae,launchJobs:()=>re,launchJobsRelations:()=>VS,limitObservations:()=>pe,memories:()=>L,memoriesRelations:()=>US,memoryExperiments:()=>Ar,modelPricing:()=>Ye,notificationPreferences:()=>Zt,notifications:()=>ft,optimizationRuns:()=>fn,optimizationRunsRelations:()=>sA,orgInvitations:()=>ne,orgInvitationsRelations:()=>DS,organizations:()=>H,organizationsRelations:()=>PS,packInstructions:()=>xe,packInstructionsRelations:()=>QS,packs:()=>Ee,packsRelations:()=>XS,pendingTreatmentExposures:()=>uc,planLimitsActive:()=>Ve,profiles:()=>T,profilesRelations:()=>NS,projectCheckouts:()=>ce,projectInstructions:()=>ot,projectInstructionsRelations:()=>HS,projects:()=>O,projectsRelations:()=>FS,providerDocsSnapshots:()=>It,scaffoldingFingerprints:()=>Tg,scaffoldingSegments:()=>kg,sessionEvents:()=>Me,sessionEventsRelations:()=>JS,sessionInstructions:()=>te,sessionInstructionsRelations:()=>GS,sessionSendJobs:()=>mc,sessionTerminalTargets:()=>We,sessions:()=>f,sessionsRelations:()=>WS,skillSubmissions:()=>Rr,teams:()=>G,teamsRelations:()=>OS,treatmentAssignments:()=>Et,treatmentAssignmentsRelations:()=>KS,treatmentExposures:()=>ee,treatmentExposuresRelations:()=>YS,triggerEvals:()=>Ct,triggerEvalsRelations:()=>oA,userOrganizations:()=>K,userOrganizationsRelations:()=>MS,userTeams:()=>ge,userTeamsRelations:()=>LS,workerConnections:()=>we});import{boolean as Af,pgTable as S0,text as Za,timestamp as Pd,uuid as xf}from"drizzle-orm/pg-core";import{pgTable as Qa,text as Uo,timestamp as ii,jsonb as bf,uuid as no,primaryKey as Sf}from"drizzle-orm/pg-core";var H=Qa("organizations",{id:no("id").primaryKey().defaultRandom(),name:Uo("name").unique().notNull(),slug:Uo("slug").unique().notNull(),metadata:bf("metadata"),createdAt:ii("created_at",{withTimezone:!0}).defaultNow(),updatedAt:ii("updated_at",{withTimezone:!0}).defaultNow()}),G=Qa("teams",{id:no("id").primaryKey().defaultRandom(),orgId:no("org_id").references(()=>H.id,{onDelete:"cascade"}),name:Uo("name").notNull(),slug:Uo("slug").notNull(),metadata:bf("metadata"),createdAt:ii("created_at",{withTimezone:!0}).defaultNow()}),K=Qa("user_organizations",{userId:no("user_id").notNull(),orgId:no("org_id").references(()=>H.id,{onDelete:"cascade"}).notNull(),role:Uo("role").notNull().default("member"),createdAt:ii("created_at",{withTimezone:!0}).defaultNow()},e=>[Sf({columns:[e.userId,e.orgId]})]),ge=Qa("user_teams",{userId:no("user_id").notNull(),teamId:no("team_id").references(()=>G.id,{onDelete:"cascade"}).notNull(),role:Uo("role").notNull().default("member"),createdAt:ii("created_at",{withTimezone:!0}).defaultNow()},e=>[Sf({columns:[e.userId,e.teamId]})]);var T=S0("profiles",{id:xf("id").primaryKey(),email:Za("email"),displayName:Za("display_name"),activeOrgId:xf("active_org_id").references(()=>H.id,{onDelete:"set null"}),isSuperadmin:Af("is_superadmin").notNull().default(!1),claudeCodePlan:Za("claude_code_plan"),planSource:Za("plan_source").notNull().default("detected"),setupCompletedAt:Pd("setup_completed_at",{withTimezone:!0}),liveSendSkipped:Af("live_send_skipped").notNull().default(!1),createdAt:Pd("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Pd("updated_at",{withTimezone:!0}).defaultNow()});import{pgTable as A0,text as Od,timestamp as ec,uuid as tc,index as Ef}from"drizzle-orm/pg-core";var ne=A0("org_invitations",{id:tc("id").primaryKey().defaultRandom(),orgId:tc("org_id").notNull().references(()=>H.id,{onDelete:"cascade"}),email:Od("email").notNull(),role:Od("role").notNull().default("member"),teamId:tc("team_id").references(()=>G.id,{onDelete:"set null"}),invitedBy:tc("invited_by").notNull().references(()=>T.id,{onDelete:"cascade"}),token:Od("token").notNull().unique(),expiresAt:ec("expires_at",{withTimezone:!0}).notNull(),acceptedAt:ec("accepted_at",{withTimezone:!0}),revokedAt:ec("revoked_at",{withTimezone:!0}),createdAt:ec("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Ef("idx_org_invitations_token").on(e.token),Ef("idx_org_invitations_org").on(e.orgId)]);import{pgTable as Dd,text as Ht,timestamp as Sr,jsonb as nc,uuid as Un,integer as rc,boolean as x0,uniqueIndex as oc,index as ai}from"drizzle-orm/pg-core";var y=Dd("instructions",{id:Un("id").primaryKey().defaultRandom(),name:Ht("name").notNull(),description:Ht("description").notNull(),type:Ht("type").notNull().default("instruction"),scope:Ht("scope").notNull(),scopeRef:Un("scope_ref"),version:Ht("version").notNull(),content:Ht("content").notNull(),frontmatter:nc("frontmatter").notNull(),slots:nc("slots"),tags:Ht("tags").array(),compatibility:Ht("compatibility").array(),createdBy:Un("created_by"),createdAt:Sr("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Sr("updated_at",{withTimezone:!0}).defaultNow(),archived:x0("archived").default(!1),archivedAt:Sr("archived_at",{withTimezone:!0}),archivedBy:Un("archived_by"),forkedFromId:Un("forked_from_id").references(()=>y.id,{onDelete:"set null"}),upstreamVersion:Ht("upstream_version"),badge:Ht("badge"),contentHash:Ht("content_hash"),contextIdentity:Ht("context_identity"),scanScore:rc("scan_score"),scanFindings:nc("scan_findings"),popularityScore:rc("popularity_score"),sourceUpdatedAt:Sr("source_updated_at",{withTimezone:!0})},e=>[oc("instructions_name_scope_ref_idx").on(e.name,e.scope,e.scopeRef),ai("idx_instructions_scope").on(e.scope,e.scopeRef),ai("idx_instructions_created_by").on(e.createdBy),ai("idx_instructions_context_identity").on(e.createdBy,e.contextIdentity),ai("idx_instructions_public_recency").on(e.scope,e.sourceUpdatedAt.desc())]),Bn=Dd("instruction_version_identities",{id:Un("id").primaryKey().defaultRandom(),instructionId:Un("instruction_id").notNull().references(()=>y.id,{onDelete:"cascade"}),contentHash:Ht("content_hash").notNull(),versionOrdinal:rc("version_ordinal").notNull(),content:Ht("content"),firstSeenAt:Sr("first_seen_at",{withTimezone:!0}).notNull().defaultNow(),lastSeenAt:Sr("last_seen_at",{withTimezone:!0}).notNull().defaultNow(),createdAt:Sr("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[oc("instruction_version_identities_hash_unique").on(e.instructionId,e.contentHash),oc("instruction_version_identities_ordinal_unique").on(e.instructionId,e.versionOrdinal),ai("idx_ivi_instruction").on(e.instructionId)]),me=Dd("instruction_versions",{id:Un("id").primaryKey().defaultRandom(),instructionId:Un("instruction_id").references(()=>y.id,{onDelete:"cascade"}),versionNumber:rc("version_number").notNull(),content:Ht("content").notNull(),frontmatter:nc("frontmatter").notNull(),changeSummary:Ht("change_summary"),createdBy:Un("created_by"),createdAt:Sr("created_at",{withTimezone:!0}).defaultNow()},e=>[oc("instruction_versions_instruction_version_idx").on(e.instructionId,e.versionNumber)]);import{pgTable as E0,text as T0,timestamp as R0,jsonb as k0,uuid as Md,index as Tf}from"drizzle-orm/pg-core";var Nt=E0("instruction_events",{id:Md("id").primaryKey().defaultRandom(),instructionId:Md("instruction_id").notNull().references(()=>y.id,{onDelete:"cascade"}),eventType:T0("event_type").notNull(),actorId:Md("actor_id").notNull(),metadata:k0("metadata"),createdAt:R0("created_at",{withTimezone:!0}).defaultNow()},e=>[Tf("idx_instruction_events_instruction").on(e.instructionId),Tf("idx_instruction_events_type").on(e.eventType)]);import{boolean as j0,jsonb as N0,pgTable as $d,primaryKey as Rf,text as ro,timestamp as ci,uniqueIndex as Ld,uuid as oo}from"drizzle-orm/pg-core";import{sql as C0}from"drizzle-orm";var O=$d("projects",{id:oo("id").primaryKey().defaultRandom(),orgId:oo("org_id").references(()=>H.id,{onDelete:"cascade"}),name:ro("name").notNull(),description:ro("description"),githubRepo:ro("github_repo"),gitRemoteUrl:ro("git_remote_url"),gitRootCommit:ro("git_root_commit"),gitRemoteAliases:ro("git_remote_aliases").array().notNull().default([]),metadata:N0("metadata"),createdBy:oo("created_by"),createdAt:ci("created_at",{withTimezone:!0}).defaultNow(),updatedAt:ci("updated_at",{withTimezone:!0}).defaultNow()},e=>[Ld("projects_org_name_idx").on(e.orgId,e.name),Ld("projects_git_remote_url_unique").on(e.gitRemoteUrl).where(C0`${e.gitRemoteUrl} IS NOT NULL`)]),ot=$d("project_instructions",{projectId:oo("project_id").references(()=>O.id,{onDelete:"cascade"}).notNull(),instructionId:oo("instruction_id").references(()=>y.id,{onDelete:"cascade"}).notNull(),addedAt:ci("added_at",{withTimezone:!0}).defaultNow(),addedBy:oo("added_by")},e=>[Rf({columns:[e.projectId,e.instructionId]})]),ce=$d("project_checkouts",{projectId:oo("project_id").references(()=>O.id,{onDelete:"cascade"}).notNull(),path:ro("path").notNull(),isWorktree:j0("is_worktree").notNull().default(!1),firstSeen:ci("first_seen",{withTimezone:!0}).notNull().defaultNow(),lastSeen:ci("last_seen",{withTimezone:!0}).notNull().defaultNow()},e=>[Rf({columns:[e.projectId,e.path]}),Ld("project_checkouts_path_unique").on(e.path)]);import{pgTable as Bd,text as an,timestamp as ui,jsonb as so,uuid as ir,integer as ic,uniqueIndex as jf,index as Fn}from"drizzle-orm/pg-core";import{pgTable as P0,text as Bo,timestamp as qd,jsonb as kf,uuid as sc,integer as O0,boolean as D0,index as Ud}from"drizzle-orm/pg-core";var W=P0("agent_runs",{id:sc("id").primaryKey().defaultRandom(),userId:sc("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),orgId:sc("org_id").references(()=>H.id,{onDelete:"set null"}),projectId:sc("project_id").references(()=>O.id,{onDelete:"set null"}),projectPath:Bo("project_path"),gitRemote:Bo("git_remote"),baseBranch:Bo("base_branch"),title:Bo("title"),prompt:Bo("prompt"),toolSpec:kf("tool_spec").notNull().default([]),autoWorktree:D0("auto_worktree").notNull().default(!0),status:Bo("status").notNull().default("pending"),sessionCount:O0("session_count").notNull().default(0),metadata:kf("metadata").notNull().default({}),createdAt:qd("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:qd("updated_at",{withTimezone:!0}).notNull().defaultNow(),completedAt:qd("completed_at",{withTimezone:!0})},e=>[Ud("idx_agent_runs_user").on(e.userId),Ud("idx_agent_runs_org_created").on(e.orgId,e.createdAt),Ud("idx_agent_runs_project").on(e.projectId)]);var f=Bd("sessions",{id:ir("id").primaryKey().defaultRandom(),userId:ir("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),externalSessionId:an("external_session_id"),projectId:ir("project_id").references(()=>O.id,{onDelete:"set null"}),orgId:ir("org_id").references(()=>H.id,{onDelete:"set null"}),tool:an("tool").notNull(),projectPath:an("project_path"),gitBranch:an("git_branch"),startedAt:ui("started_at",{withTimezone:!0}).notNull(),endedAt:ui("ended_at",{withTimezone:!0}),eventCount:ic("event_count").default(0),tokenUsage:so("token_usage"),analysis:so("analysis"),analyzedAt:ui("analyzed_at",{withTimezone:!0}),analyzedEventCount:ic("analyzed_event_count"),analyzedTurnCount:ic("analyzed_turn_count"),metadata:so("metadata").default({}),origin:an("origin").notNull().default("unknown"),runId:ir("run_id").references(()=>W.id,{onDelete:"set null"}),model:an("model"),harnessVersion:an("harness_version"),createdAt:ui("created_at",{withTimezone:!0}).defaultNow()},e=>[Fn("idx_sessions_user").on(e.userId),Fn("idx_sessions_tool").on(e.tool),Fn("idx_sessions_started_at").on(e.startedAt),Fn("idx_sessions_project").on(e.projectId),Fn("idx_sessions_org_started_at").on(e.orgId,e.startedAt),Fn("idx_sessions_run").on(e.runId),jf("idx_sessions_user_external").on(e.userId,e.externalSessionId)]),Me=Bd("session_events",{id:ir("id").primaryKey().defaultRandom(),sessionId:ir("session_id").notNull().references(()=>f.id,{onDelete:"cascade"}),sequence:ic("sequence").notNull(),eventType:an("event_type").notNull(),content:an("content"),toolName:an("tool_name"),toolInput:so("tool_input"),toolOutput:so("tool_output"),tokenUsage:so("token_usage"),model:an("model"),timestamp:ui("timestamp",{withTimezone:!0}).notNull(),metadata:so("metadata").default({})},e=>[jf("session_events_session_sequence_idx").on(e.sessionId,e.sequence),Fn("idx_session_events_session_id").on(e.sessionId),Fn("idx_session_events_event_type").on(e.eventType),Fn("idx_session_events_model").on(e.model)]),te=Bd("session_instructions",{sessionId:ir("session_id").notNull().references(()=>f.id,{onDelete:"cascade"}),instructionId:ir("instruction_id").notNull().references(()=>y.id,{onDelete:"cascade"}),linkMethod:an("link_method").notNull(),contentHash:an("content_hash")},e=>[Fn("idx_session_instructions_instruction_id").on(e.instructionId)]);import{pgTable as Nf,text as ac,timestamp as Cf,uuid as Hn,integer as Pf,index as Fo,unique as M0}from"drizzle-orm/pg-core";var Et=Nf("treatment_assignments",{id:Hn("id").primaryKey().defaultRandom(),userId:Hn("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),treatmentType:ac("treatment_type").notNull(),treatmentId:Hn("treatment_id").notNull(),treatmentVersion:Pf("treatment_version").notNull().default(1),projectId:Hn("project_id").references(()=>O.id,{onDelete:"set null"}),assignedBy:Hn("assigned_by").references(()=>T.id,{onDelete:"set null"}),method:ac("method").notNull(),assignedAt:Cf("assigned_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Fo("idx_treatment_assignments_user").on(e.userId),Fo("idx_treatment_assignments_treatment").on(e.treatmentType,e.treatmentId),Fo("idx_treatment_assignments_project").on(e.projectId)]),ee=Nf("treatment_exposures",{id:Hn("id").primaryKey().defaultRandom(),sessionId:Hn("session_id").notNull().references(()=>f.id,{onDelete:"cascade"}),userId:Hn("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),treatmentType:ac("treatment_type").notNull(),treatmentId:Hn("treatment_id").notNull(),treatmentVersion:Pf("treatment_version").notNull().default(1),assignmentId:Hn("assignment_id").references(()=>Et.id,{onDelete:"set null"}),method:ac("method").notNull(),exposedAt:Cf("exposed_at",{withTimezone:!0}).notNull().defaultNow()},e=>[M0("treatment_exposures_unique").on(e.sessionId,e.treatmentType,e.treatmentId,e.treatmentVersion),Fo("idx_treatment_exposures_treatment").on(e.treatmentType,e.treatmentId),Fo("idx_treatment_exposures_user").on(e.userId),Fo("idx_treatment_exposures_session").on(e.sessionId)]);import{pgTable as L0,text as Fd,timestamp as $0,uuid as cc,integer as q0,index as Of,uniqueIndex as U0}from"drizzle-orm/pg-core";var uc=L0("pending_treatment_exposures",{id:cc("id").primaryKey().defaultRandom(),userId:cc("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),externalSessionId:Fd("external_session_id").notNull(),treatmentType:Fd("treatment_type").notNull(),treatmentId:cc("treatment_id").notNull(),treatmentVersion:q0("treatment_version").notNull().default(1),method:Fd("method").notNull().default("injected"),projectId:cc("project_id").references(()=>O.id,{onDelete:"set null"}),createdAt:$0("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[U0("pending_treatment_exposures_unique").on(e.externalSessionId,e.treatmentType,e.treatmentId,e.treatmentVersion),Of("idx_pending_treatment_exposures_ext").on(e.externalSessionId),Of("idx_pending_treatment_exposures_user").on(e.userId)]);import{pgTable as B0,text as Ho,timestamp as Hd,uuid as di,integer as Df,index as dc}from"drizzle-orm/pg-core";var L=B0("memories",{id:di("id").primaryKey().defaultRandom(),userId:di("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),orgId:di("org_id"),projectId:di("project_id").references(()=>O.id,{onDelete:"set null"}),version:Df("version").notNull().default(1),parentId:di("parent_id").references(()=>L.id,{onDelete:"set null"}),kind:Ho("kind").notNull(),title:Ho("title").notNull(),body:Ho("body").notNull(),source:Ho("source").notNull(),status:Ho("status").notNull().default("active"),trustClass:Ho("trust_class"),trustVersion:Df("trust_version"),trustComputedAt:Hd("trust_computed_at",{withTimezone:!0}),createdAt:Hd("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:Hd("updated_at",{withTimezone:!0}).notNull().defaultNow()},e=>[dc("idx_memories_user").on(e.userId),dc("idx_memories_project").on(e.projectId),dc("idx_memories_parent").on(e.parentId),dc("idx_memories_user_status").on(e.userId,e.status)]);import{pgTable as F0,text as li,timestamp as Wd,uuid as zd,integer as Mf,jsonb as H0,index as Lf}from"drizzle-orm/pg-core";var Ar=F0("memory_experiments",{id:zd("id").primaryKey().defaultRandom(),memoryId:zd("memory_id").notNull().references(()=>L.id,{onDelete:"cascade"}),userId:zd("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),memoryVersion:Mf("memory_version").notNull().default(1),taskPrompt:li("task_prompt").notNull(),expectations:li("expectations").array().notNull().default([]),trials:Mf("trials").notNull().default(10),model:li("model"),status:li("status").notNull().default("pending"),result:H0("result").$type(),error:li("error"),createdAt:Wd("created_at",{withTimezone:!0}).notNull().defaultNow(),startedAt:Wd("started_at",{withTimezone:!0}),completedAt:Wd("completed_at",{withTimezone:!0})},e=>[Lf("idx_memory_experiments_memory").on(e.memoryId),Lf("idx_memory_experiments_user").on(e.userId)]);import{pgTable as W0,text as Wo,timestamp as Vd,uuid as Jd,jsonb as z0,uniqueIndex as V0,index as $f}from"drizzle-orm/pg-core";var We=W0("session_terminal_targets",{id:Jd("id").primaryKey().defaultRandom(),userId:Jd("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),sessionId:Jd("session_id").references(()=>f.id,{onDelete:"set null"}),externalSessionId:Wo("external_session_id"),kind:Wo("kind").notNull(),target:Wo("target").notNull(),status:Wo("status").notNull().default("active"),attachCommand:Wo("attach_command").notNull(),projectPath:Wo("project_path"),metadata:z0("metadata").notNull().default({}),lastSeenAt:Vd("last_seen_at",{withTimezone:!0}).defaultNow(),createdAt:Vd("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Vd("updated_at",{withTimezone:!0}).defaultNow()},e=>[V0("idx_session_terminal_targets_user_target").on(e.userId,e.target),$f("idx_session_terminal_targets_session").on(e.sessionId),$f("idx_session_terminal_targets_user_status").on(e.userId,e.status)]);import{boolean as J0,index as lc,jsonb as qf,pgTable as G0,text as io,timestamp as pi,uuid as pc,integer as Uf}from"drizzle-orm/pg-core";var mc=G0("session_send_jobs",{id:pc("id").primaryKey().defaultRandom(),userId:pc("user_id").notNull(),sessionId:pc("session_id").notNull().references(()=>f.id,{onDelete:"cascade"}),terminalTargetId:pc("terminal_target_id").references(()=>We.id,{onDelete:"set null"}),target:io("target").notNull(),message:io("message").notNull(),submit:J0("submit").notNull().default(!0),delivery:io("delivery").notNull().default("live"),status:io("status").notNull().default("pending"),result:qf("result"),error:io("error"),attempts:Uf("attempts").notNull().default(0),taskKind:io("task_kind"),payload:qf("payload"),claimedBy:io("claimed_by"),claimedAt:pi("claimed_at",{withTimezone:!0}),leaseExpiresAt:pi("lease_expires_at",{withTimezone:!0}),leaseRecoveries:Uf("lease_recoveries").notNull().default(0),createdAt:pi("created_at",{withTimezone:!0}).defaultNow(),updatedAt:pi("updated_at",{withTimezone:!0}).defaultNow(),completedAt:pi("completed_at",{withTimezone:!0})},e=>[lc("idx_session_send_jobs_user").on(e.userId),lc("idx_session_send_jobs_session").on(e.sessionId),lc("idx_session_send_jobs_status").on(e.status),lc("idx_session_send_jobs_pending").on(e.userId,e.status)]);import{pgTable as Ff,text as ao,timestamp as fc,jsonb as Hf,uuid as xr,integer as K0,boolean as Y0,uniqueIndex as X0,index as Bf,primaryKey as Q0}from"drizzle-orm/pg-core";var Ee=Ff("packs",{id:xr("id").primaryKey().defaultRandom(),name:ao("name").notNull(),description:ao("description").notNull(),scope:ao("scope").notNull(),scopeRef:xr("scope_ref"),version:ao("version").notNull().default("1.0.0"),tags:ao("tags").array(),badge:ao("badge"),metadata:Hf("metadata"),createdBy:xr("created_by"),createdAt:fc("created_at",{withTimezone:!0}).defaultNow(),updatedAt:fc("updated_at",{withTimezone:!0}).defaultNow(),archived:Y0("archived").default(!1),archivedAt:fc("archived_at",{withTimezone:!0}),archivedBy:xr("archived_by"),forkedFromId:xr("forked_from_id").references(()=>Ee.id,{onDelete:"set null"}),upstreamVersion:ao("upstream_version")},e=>[X0("packs_name_scope_ref_idx").on(e.name,e.scope,e.scopeRef),Bf("idx_packs_scope").on(e.scope,e.scopeRef),Bf("idx_packs_created_by").on(e.createdBy)]),xe=Ff("pack_instructions",{packId:xr("pack_id").references(()=>Ee.id,{onDelete:"cascade"}).notNull(),instructionId:xr("instruction_id").references(()=>y.id,{onDelete:"cascade"}).notNull(),position:K0("position").notNull().default(0),slotOverrides:Hf("slot_overrides"),addedAt:fc("added_at",{withTimezone:!0}).defaultNow(),addedBy:xr("added_by")},e=>[Q0({columns:[e.packId,e.instructionId]})]);import{pgTable as Z0,text as Gd,timestamp as eb,jsonb as tb,uuid as Kd,index as zo}from"drizzle-orm/pg-core";var Er=Z0("instruction_usage_events",{id:Kd("id").primaryKey().defaultRandom(),instructionId:Kd("instruction_id").references(()=>y.id,{onDelete:"set null"}),userId:Kd("user_id").notNull(),surface:Gd("surface").notNull(),action:Gd("action").notNull(),metadata:tb("metadata"),traceId:Gd("trace_id"),createdAt:eb("created_at",{withTimezone:!0}).defaultNow()},e=>[zo("idx_usage_events_instruction").on(e.instructionId),zo("idx_usage_events_user").on(e.userId),zo("idx_usage_events_surface").on(e.surface),zo("idx_usage_events_action").on(e.action),zo("idx_usage_events_created_at").on(e.createdAt),zo("idx_usage_events_user_created").on(e.userId,e.createdAt)]);import{pgTable as nb,text as gc,timestamp as Wf,jsonb as rb,uuid as zf,index as Yd}from"drizzle-orm/pg-core";var we=nb("worker_connections",{id:zf("id").primaryKey().defaultRandom(),userId:zf("user_id").notNull(),workerType:gc("worker_type").notNull().default("mcp"),clientName:gc("client_name").notNull(),clientVersion:gc("client_version"),workerVersion:gc("worker_version"),lastHeartbeat:Wf("last_heartbeat",{withTimezone:!0}).notNull().defaultNow(),connectedAt:Wf("connected_at",{withTimezone:!0}).notNull().defaultNow(),metadata:rb("metadata")},e=>[Yd("idx_worker_connections_user").on(e.userId),Yd("idx_worker_connections_heartbeat").on(e.userId,e.lastHeartbeat),Yd("idx_worker_connections_type").on(e.userId,e.workerType)]);import{pgTable as ob,text as hc,timestamp as sb,jsonb as ib,uuid as Vf,index as Jf}from"drizzle-orm/pg-core";var _c=ob("cli_setup_events",{id:Vf("id").primaryKey().defaultRandom(),userId:Vf("user_id").notNull(),deviceId:hc("device_id").notNull(),event:hc("event").notNull(),cliVersion:hc("cli_version"),os:hc("os"),props:ib("props").notNull().default({}),createdAt:sb("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Jf("idx_cli_setup_events_user").on(e.userId,e.createdAt),Jf("idx_cli_setup_events_device").on(e.deviceId,e.createdAt)]);import{pgTable as ab,text as co,integer as cb,boolean as ub,timestamp as db,jsonb as lb,uuid as pb,index as Gf}from"drizzle-orm/pg-core";var yc=ab("cli_error_events",{id:pb("id").primaryKey().defaultRandom(),deviceId:co("device_id"),event:co("event").notNull(),command:co("command"),statusCode:cb("status_code"),message:co("message"),cliVersion:co("cli_version"),os:co("os"),nodeVersion:co("node_version"),proxied:ub("proxied"),props:lb("props").notNull().default({}),createdAt:db("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Gf("idx_cli_error_events_created").on(e.createdAt),Gf("idx_cli_error_events_device").on(e.deviceId,e.createdAt)]);import{sql as mb}from"drizzle-orm";import{pgTable as uo,text as dt,timestamp as Qt,jsonb as mn,uuid as st,integer as ar,boolean as mi,index as Wt,unique as Kf}from"drizzle-orm/pg-core";var R=uo("eval_targets",{id:st("id").primaryKey().defaultRandom(),userId:st("user_id").notNull(),name:dt("name").notNull(),type:dt("type").notNull(),content:dt("content").notNull(),description:dt("description").notNull().default(""),metadata:mn("metadata").notNull().default({}),version:ar("version").notNull().default(1),parentId:st("parent_id").references(()=>R.id,{onDelete:"set null"}),createdAt:Qt("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Qt("updated_at",{withTimezone:!0}).defaultNow()},e=>[Wt("eval_targets_name_user_idx").on(e.name,e.userId),Wt("idx_eval_targets_user").on(e.userId),Wt("idx_eval_targets_type").on(e.type),Wt("idx_eval_targets_parent").on(e.parentId)]),he=uo("evals",{id:st("id").primaryKey().defaultRandom(),evalTargetId:st("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),name:dt("name").notNull(),prompt:dt("prompt").notNull(),expectedOutput:dt("expected_output").notNull().default(""),files:mn("files").notNull().default([]),expectations:mn("expectations").notNull().default([]),retiredAt:Qt("retired_at",{withTimezone:!0}),retiredReason:dt("retired_reason"),createdAt:Qt("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Qt("updated_at",{withTimezone:!0}).defaultNow(),contentUpdatedAt:Qt("content_updated_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Wt("idx_evals_target").on(e.evalTargetId),Wt("idx_evals_target_active").on(e.evalTargetId).where(mb`${e.retiredAt} IS NULL`)]),_e=uo("eval_runs",{id:st("id").primaryKey().defaultRandom(),jobId:st("job_id"),evalId:st("eval_id").notNull().references(()=>he.id,{onDelete:"cascade"}),evalTargetId:st("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),evalTargetVersion:ar("eval_target_version").notNull(),configuration:dt("configuration").notNull(),runNumber:ar("run_number").notNull().default(1),iteration:ar("iteration").notNull().default(1),status:dt("status").notNull().default("completed"),outputs:mn("outputs").notNull().default({}),timing:mn("timing").notNull().default({}),grading:mn("grading").notNull().default({}),comparison:mn("comparison"),createdAt:Qt("created_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_eval_runs_eval").on(e.evalId),Wt("idx_eval_runs_target").on(e.evalTargetId),Wt("idx_eval_runs_iteration").on(e.evalTargetId,e.iteration)]),Ke=uo("eval_comparisons",{id:st("id").primaryKey().defaultRandom(),userId:st("user_id").notNull(),targetAId:st("target_a_id").notNull().references(()=>R.id,{onDelete:"cascade"}),targetBId:st("target_b_id").notNull().references(()=>R.id,{onDelete:"cascade"}),targetAVersion:ar("target_a_version").notNull(),targetBVersion:ar("target_b_version").notNull(),isSwapped:mi("is_swapped").notNull().default(!1),winnerTargetId:st("winner_target_id").references(()=>R.id,{onDelete:"set null"}),perEval:mn("per_eval").notNull().default([]),overall:mn("overall").notNull().default({}),rawOutput:dt("raw_output"),model:dt("model"),status:dt("status").notNull().default("completed"),createdAt:Qt("created_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_eval_comparisons_target_a").on(e.targetAId),Wt("idx_eval_comparisons_target_b").on(e.targetBId),Wt("idx_eval_comparisons_user").on(e.userId)]),ze=uo("eval_grade_annotations",{id:st("id").primaryKey().defaultRandom(),userId:st("user_id").notNull(),evalRunId:st("eval_run_id").notNull().references(()=>_e.id,{onDelete:"cascade"}),evalTargetId:st("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),expectationIndex:ar("expectation_index").notNull(),expectationText:dt("expectation_text").notNull(),judgePassed:mi("judge_passed").notNull(),judgeMethod:dt("judge_method").notNull(),judgeModel:dt("judge_model"),verdict:dt("verdict").notNull(),flag:dt("flag"),note:dt("note"),createdAt:Qt("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Qt("updated_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_eval_grade_annotations_target").on(e.evalTargetId),Wt("idx_eval_grade_annotations_run").on(e.evalRunId),Kf("eval_grade_annotations_eval_run_id_expectation_index_key").on(e.evalRunId,e.expectationIndex)]),ae=uo("judge_reviewer_verdicts",{id:st("id").primaryKey().defaultRandom(),userId:st("user_id").notNull(),evalTargetId:st("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),evalRunId:st("eval_run_id").notNull().references(()=>_e.id,{onDelete:"cascade"}),expectationIndex:ar("expectation_index").notNull(),expectationText:dt("expectation_text").notNull(),judgePassed:mi("judge_passed").notNull(),humanPassed:mi("human_passed").notNull(),reviewerEngine:dt("reviewer_engine").notNull(),reviewerModel:dt("reviewer_model").notNull(),reviewerPassed:mi("reviewer_passed").notNull(),resolvedAt:Qt("resolved_at",{withTimezone:!0}),resolution:dt("resolution"),createdAt:Qt("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Qt("updated_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_jrv_target").on(e.evalTargetId),Kf("judge_reviewer_verdicts_eval_run_id_expectation_index_review_key").on(e.evalRunId,e.expectationIndex,e.reviewerModel)]),Rn=uo("benchmarks",{id:st("id").primaryKey().defaultRandom(),evalTargetId:st("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),iteration:ar("iteration").notNull().default(1),runSummary:mn("run_summary").notNull().default({}),notes:mn("notes").notNull().default([]),feedback:mn("feedback"),createdAt:Qt("created_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_benchmarks_target").on(e.evalTargetId)]);import{sql as Xd}from"drizzle-orm";import{pgTable as fb,text as cr,timestamp as gb,jsonb as wc,uuid as vc,boolean as hb,index as fi,uniqueIndex as _b}from"drizzle-orm/pg-core";var ke=fb("instruction_promotions",{id:vc("id").primaryKey().defaultRandom(),userId:vc("user_id").notNull(),evalTargetId:vc("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),instructionId:vc("instruction_id").references(()=>y.id,{onDelete:"set null"}),fromContentHash:cr("from_content_hash").notNull(),toContentHash:cr("to_content_hash").notNull(),fromContent:cr("from_content").notNull(),toContent:cr("to_content").notNull(),proposalSource:cr("proposal_source").notNull(),proposalRationale:cr("proposal_rationale").notNull().default(""),decision:cr("decision").notNull(),applied:hb("applied").notNull().default(!1),refusals:wc("refusals").notNull().default([]),rationale:cr("rationale").notNull().default(""),effectClass:cr("effect_class").notNull(),verdict:wc("verdict").notNull().default({}),gates:wc("gates").notNull().default({}),touchedSections:wc("touched_sections").notNull().default([]),createdAt:gb("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[fi("idx_instruction_promotions_budget").on(e.evalTargetId,e.createdAt.desc()).where(Xd`${e.applied}`),fi("idx_instruction_promotions_target").on(e.evalTargetId,e.createdAt.desc()),fi("idx_instruction_promotions_user").on(e.userId,e.createdAt.desc()),fi("idx_instruction_promotions_to_hash").on(e.toContentHash),_b("uq_instruction_promotions_applied").on(e.evalTargetId,e.fromContentHash,e.toContentHash).where(Xd`${e.applied}`),fi("idx_instruction_promotions_applied_hash").on(e.toContentHash,e.createdAt.desc()).where(Xd`${e.applied}`)]);import{pgTable as Xf,text as Qd,timestamp as Zd,jsonb as Qf,uuid as Vo,integer as gi,index as Ic,real as Yf}from"drizzle-orm/pg-core";var Ct=Xf("trigger_evals",{id:Vo("id").primaryKey().defaultRandom(),evalTargetId:Vo("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),userId:Vo("user_id").notNull(),queries:Qf("queries").notNull().default([]),status:Qd("status").notNull().default("pending_review"),trainIndices:gi("train_indices").array().default([]),testIndices:gi("test_indices").array().default([]),createdAt:Zd("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Zd("updated_at",{withTimezone:!0}).defaultNow()},e=>[Ic("idx_trigger_evals_target").on(e.evalTargetId),Ic("idx_trigger_evals_user").on(e.userId)]),fn=Xf("optimization_runs",{id:Vo("id").primaryKey().defaultRandom(),evalTargetId:Vo("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),userId:Vo("user_id").notNull(),type:Qd("type").notNull(),iteration:gi("iteration").notNull(),inputVersion:gi("input_version").notNull(),outputVersion:gi("output_version"),trainScore:Yf("train_score"),testScore:Yf("test_score"),analysis:Qf("analysis").notNull().default({}),status:Qd("status").notNull().default("running"),createdAt:Zd("created_at",{withTimezone:!0}).defaultNow()},e=>[Ic("idx_optimization_runs_target").on(e.evalTargetId),Ic("idx_optimization_runs_user").on(e.userId)]);import{pgTable as yb,text as Tr,timestamp as wb,jsonb as hi,uuid as el,integer as tl,real as vb,index as _i,uniqueIndex as Zf}from"drizzle-orm/pg-core";var j=yb("context_snapshots",{id:el("id").primaryKey().defaultRandom(),sessionId:el("session_id").references(()=>f.id,{onDelete:"cascade"}),userId:el("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),sequence:tl("sequence").notNull().default(0),provider:Tr("provider").notNull(),model:Tr("model").notNull(),systemPrompt:Tr("system_prompt").notNull(),injectedInstructions:hi("injected_instructions").notNull().default([]),messagesSummary:hi("messages_summary").notNull(),tools:hi("tools").notNull().default([]),systemHash:Tr("system_hash").notNull(),requestHash:Tr("request_hash").notNull().default(""),toolsHash:Tr("tools_hash"),injectedHash:Tr("injected_hash"),messagesDelta:hi("messages_delta").default([]),messagesDeltaRef:Tr("messages_delta_ref"),maxTokens:tl("max_tokens"),temperature:vb("temperature"),estimatedTokens:tl("estimated_tokens"),capturedAt:wb("captured_at",{withTimezone:!0}).notNull().defaultNow(),metadata:hi("metadata").default({})},e=>[_i("idx_context_snapshots_session").on(e.sessionId),_i("idx_context_snapshots_user").on(e.userId),_i("idx_context_snapshots_hash").on(e.systemHash),_i("idx_context_snapshots_request_hash").on(e.requestHash),Zf("idx_snapshots_session_request").on(e.sessionId,e.requestHash),Zf("idx_snapshots_session_sequence").on(e.sessionId,e.sequence),_i("idx_context_snapshots_user_session_captured").on(e.userId,e.sessionId,e.capturedAt.desc())]);import{pgTable as Ib,text as eg,timestamp as bb,jsonb as Sb,integer as Ab,index as xb}from"drizzle-orm/pg-core";var cn=Ib("content_blobs",{hash:eg("hash").primaryKey(),contentType:eg("content_type").notNull(),content:Sb("content").notNull(),sizeBytes:Ab("size_bytes").notNull().default(0),createdAt:bb("created_at",{withTimezone:!0}).defaultNow()},e=>[xb("idx_content_blobs_type").on(e.contentType)]);import{pgTable as Eb,text as bc,timestamp as yi,jsonb as Sc,uuid as nl,index as Ac,integer as tg}from"drizzle-orm/pg-core";var be=Eb("eval_jobs",{id:nl("id").primaryKey().defaultRandom(),userId:nl("user_id").notNull(),evalTargetId:nl("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),status:bc("status").notNull().default("pending"),config:Sc("config").notNull().default({}),progress:Sc("progress").notNull().default({}),result:Sc("result"),error:bc("error"),attempts:tg("attempts").notNull().default(0),taskKind:bc("task_kind"),payload:Sc("payload"),claimedBy:bc("claimed_by"),claimedAt:yi("claimed_at",{withTimezone:!0}),leaseExpiresAt:yi("lease_expires_at",{withTimezone:!0}),leaseRecoveries:tg("lease_recoveries").notNull().default(0),createdAt:yi("created_at",{withTimezone:!0}).defaultNow(),updatedAt:yi("updated_at",{withTimezone:!0}).defaultNow(),completedAt:yi("completed_at",{withTimezone:!0})},e=>[Ac("idx_eval_jobs_user").on(e.userId),Ac("idx_eval_jobs_target").on(e.evalTargetId),Ac("idx_eval_jobs_status").on(e.status),Ac("idx_eval_jobs_pending").on(e.userId,e.status)]);import{pgTable as Tb,text as wi,timestamp as vi,jsonb as ng,uuid as rg,integer as og,index as sg}from"drizzle-orm/pg-core";var Ie=Tb("agent_jobs",{id:rg("id").primaryKey().defaultRandom(),userId:rg("user_id").notNull(),taskKind:wi("task_kind").notNull(),status:wi("status").notNull().default("pending"),payload:ng("payload").notNull(),dedupeKey:wi("dedupe_key"),result:ng("result"),error:wi("error"),attempts:og("attempts").notNull().default(0),claimedBy:wi("claimed_by"),claimedAt:vi("claimed_at",{withTimezone:!0}),leaseExpiresAt:vi("lease_expires_at",{withTimezone:!0}),leaseRecoveries:og("lease_recoveries").notNull().default(0),createdAt:vi("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:vi("updated_at",{withTimezone:!0}).notNull().defaultNow(),completedAt:vi("completed_at",{withTimezone:!0})},e=>[sg("idx_agent_jobs_claim").on(e.userId,e.status,e.taskKind,e.createdAt),sg("idx_agent_jobs_dedupe").on(e.userId,e.taskKind,e.dedupeKey)]);import{pgTable as Rb,text as Ii,timestamp as bi,jsonb as xc,uuid as rl,index as Ec,integer as ig}from"drizzle-orm/pg-core";var F=Rb("insights_jobs",{id:rl("id").primaryKey().defaultRandom(),userId:rl("user_id").notNull(),status:Ii("status").notNull().default("pending"),projectPath:Ii("project_path"),projectId:rl("project_id").references(()=>O.id,{onDelete:"set null"}),config:xc("config").notNull().default({}),progress:xc("progress").notNull().default({}),result:xc("result"),error:Ii("error"),attempts:ig("attempts").notNull().default(0),taskKind:Ii("task_kind"),payload:xc("payload"),claimedBy:Ii("claimed_by"),claimedAt:bi("claimed_at",{withTimezone:!0}),leaseExpiresAt:bi("lease_expires_at",{withTimezone:!0}),leaseRecoveries:ig("lease_recoveries").notNull().default(0),createdAt:bi("created_at",{withTimezone:!0}).defaultNow(),updatedAt:bi("updated_at",{withTimezone:!0}).defaultNow(),completedAt:bi("completed_at",{withTimezone:!0})},e=>[Ec("idx_insights_jobs_user").on(e.userId),Ec("idx_insights_jobs_status").on(e.status),Ec("idx_insights_jobs_pending").on(e.userId,e.status),Ec("idx_insights_jobs_project").on(e.projectId)]);import{pgTable as kb,text as ol,timestamp as Tc,uuid as ag,index as jb,uniqueIndex as Nb}from"drizzle-orm/pg-core";var ye=kb("api_keys",{id:ag("id").primaryKey().defaultRandom(),userId:ag("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),name:ol("name").notNull(),keyHash:ol("key_hash").notNull(),keyPrefix:ol("key_prefix").notNull(),lastUsedAt:Tc("last_used_at",{withTimezone:!0}),expiresAt:Tc("expires_at",{withTimezone:!0}),revokedAt:Tc("revoked_at",{withTimezone:!0}),createdAt:Tc("created_at",{withTimezone:!0}).defaultNow()},e=>[jb("idx_api_keys_user").on(e.userId),Nb("idx_api_keys_hash").on(e.keyHash)]);import{pgTable as Cb,text as sl,timestamp as cg,uuid as Pb,index as Ob}from"drizzle-orm/pg-core";var gn=Cb("extension_auth_codes",{code:sl("code").primaryKey(),userId:Pb("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),editor:sl("editor"),email:sl("email"),expiresAt:cg("expires_at",{withTimezone:!0}).notNull(),createdAt:cg("created_at",{withTimezone:!0}).defaultNow()},e=>[Ob("idx_ext_auth_codes_expiry").on(e.expiresAt)]);import{pgTable as Db,text as Mb,timestamp as ug,jsonb as Lb,uuid as il,index as dg}from"drizzle-orm/pg-core";var Te=Db("eval_conversations",{id:il("id").primaryKey().defaultRandom(),evalTargetId:il("eval_target_id").notNull().references(()=>R.id,{onDelete:"cascade"}),userId:il("user_id").notNull(),messages:Lb("messages").notNull().default([]),status:Mb("status").notNull().default("active"),createdAt:ug("created_at",{withTimezone:!0}).defaultNow(),updatedAt:ug("updated_at",{withTimezone:!0}).defaultNow()},e=>[dg("idx_eval_conversations_target").on(e.evalTargetId),dg("idx_eval_conversations_user").on(e.userId)]);import{pgTable as $b,text as ur,timestamp as lg,jsonb as qb,uuid as al}from"drizzle-orm/pg-core";var Rr=$b("skill_submissions",{id:al("id").primaryKey().defaultRandom(),skillId:ur("skill_id").notNull(),name:ur("name").notNull(),description:ur("description").notNull(),category:ur("category").notNull(),tools:ur("tools").array().notNull(),tags:ur("tags").array().default([]),content:ur("content").notNull(),status:ur("status").notNull().default("pending"),submittedBy:al("submitted_by").notNull(),reviewedBy:al("reviewed_by"),reviewNote:ur("review_note"),metadata:qb("metadata"),createdAt:lg("created_at",{withTimezone:!0}).defaultNow(),updatedAt:lg("updated_at",{withTimezone:!0}).defaultNow()});import{pgTable as Ub,text as Si,timestamp as pg,jsonb as Bb,uuid as Fb,uniqueIndex as Hb,index as mg}from"drizzle-orm/pg-core";var Tt=Ub("harness_releases",{id:Fb("id").primaryKey().defaultRandom(),harness:Si("harness").notNull(),version:Si("version").notNull(),publishedAt:pg("published_at",{withTimezone:!0}).notNull(),title:Si("title"),body:Si("body"),categories:Bb("categories").default({}),url:Si("url"),createdAt:pg("created_at",{withTimezone:!0}).defaultNow()},e=>[Hb("idx_harness_releases_unique").on(e.harness,e.version),mg("idx_harness_releases_harness").on(e.harness),mg("idx_harness_releases_published").on(e.publishedAt)]);import{pgTable as Wb,text as Jo,timestamp as fg,jsonb as zb,uuid as gg,index as hg,uniqueIndex as Vb}from"drizzle-orm/pg-core";var ft=Wb("notifications",{id:gg("id").primaryKey().defaultRandom(),userId:gg("user_id").notNull(),type:Jo("type").notNull(),title:Jo("title").notNull(),body:Jo("body"),url:Jo("url"),sourceTable:Jo("source_table"),sourceId:Jo("source_id"),metadata:zb("metadata").notNull().default({}),readAt:fg("read_at",{withTimezone:!0}),createdAt:fg("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[hg("idx_notifications_user_created").on(e.userId,e.createdAt),hg("idx_notifications_user_unread").on(e.userId),Vb("idx_notifications_source_dedup").on(e.userId,e.sourceTable,e.sourceId)]);import{pgTable as Jb,text as Ai,timestamp as xi,jsonb as cl,uuid as ul,index as Rc,integer as _g}from"drizzle-orm/pg-core";var re=Jb("launch_jobs",{id:ul("id").primaryKey().defaultRandom(),userId:ul("user_id").notNull(),tool:Ai("tool").notNull(),status:Ai("status").notNull().default("pending"),config:cl("config").notNull().default({}),result:cl("result"),error:Ai("error"),attempts:_g("attempts").notNull().default(0),taskKind:Ai("task_kind"),payload:cl("payload"),claimedBy:Ai("claimed_by"),claimedAt:xi("claimed_at",{withTimezone:!0}),leaseExpiresAt:xi("lease_expires_at",{withTimezone:!0}),leaseRecoveries:_g("lease_recoveries").notNull().default(0),createdAt:xi("created_at",{withTimezone:!0}).defaultNow(),updatedAt:xi("updated_at",{withTimezone:!0}).defaultNow(),completedAt:xi("completed_at",{withTimezone:!0}),runId:ul("run_id").references(()=>W.id,{onDelete:"set null"})},e=>[Rc("idx_launch_jobs_user").on(e.userId),Rc("idx_launch_jobs_status").on(e.status),Rc("idx_launch_jobs_pending").on(e.userId,e.status),Rc("idx_launch_jobs_run").on(e.runId)]);import{pgTable as yg,uuid as dr,text as Ei,real as Gb,timestamp as kc,boolean as Kb,uniqueIndex as Yb,index as Ti}from"drizzle-orm/pg-core";var Y=yg("instruction_suggestions",{id:dr("id").primaryKey().defaultRandom(),userId:dr("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),instructionId:dr("instruction_id").notNull().references(()=>y.id,{onDelete:"cascade"}),projectPath:Ei("project_path").notNull(),projectId:dr("project_id").references(()=>O.id,{onDelete:"set null"}),score:Gb("score").notNull(),reason:Ei("reason").notNull(),generatedAt:kc("generated_at",{withTimezone:!0}).notNull().defaultNow(),isStale:Kb("is_stale").notNull().default(!1),dismissedAt:kc("dismissed_at",{withTimezone:!0}),acceptedAt:kc("accepted_at",{withTimezone:!0}),promotedToInstructionId:dr("promoted_to_instruction_id").references(()=>y.id,{onDelete:"set null"})},e=>[Yb("idx_instruction_suggestions_user_project_instruction").on(e.userId,e.projectPath,e.instructionId),Ti("idx_instruction_suggestions_user_project").on(e.userId,e.projectPath),Ti("idx_instruction_suggestions_user_proj_id").on(e.userId,e.projectId),Ti("idx_instruction_suggestions_generated_at").on(e.generatedAt)]),zt=yg("instruction_suggestion_events",{id:dr("id").primaryKey().defaultRandom(),suggestionId:dr("suggestion_id").notNull().references(()=>Y.id,{onDelete:"cascade"}),userId:dr("user_id").notNull().references(()=>T.id,{onDelete:"cascade"}),eventType:Ei("event_type").notNull(),tool:Ei("tool"),sessionId:dr("session_id"),projectPath:Ei("project_path").notNull(),createdAt:kc("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Ti("idx_instruction_suggestion_events_suggestion_id").on(e.suggestionId),Ti("idx_instruction_suggestion_events_user_id").on(e.userId)]);import{pgTable as Xb,text as dl,integer as Qb,numeric as Ri,timestamp as ll,index as Zb,primaryKey as eS}from"drizzle-orm/pg-core";var Ye=Xb("model_pricing",{provider:dl("provider").notNull(),modelId:dl("model_id").notNull(),inputPerM:Ri("input_per_m").notNull(),outputPerM:Ri("output_per_m").notNull(),cacheReadPerM:Ri("cache_read_per_m").notNull(),cacheWrite5mPerM:Ri("cache_write_5m_per_m").notNull(),cacheWrite1hPerM:Ri("cache_write_1h_per_m").notNull(),contextWindow:Qb("context_window"),effectiveFrom:ll("effective_from",{withTimezone:!0}).notNull(),effectiveUntil:ll("effective_until",{withTimezone:!0}),source:dl("source").notNull(),verifiedAt:ll("verified_at",{withTimezone:!0})},e=>[eS({columns:[e.provider,e.modelId,e.effectiveFrom]}),Zb("idx_model_pricing_active").on(e.provider,e.modelId,e.effectiveFrom.desc())]);import{pgTable as tS,text as lo,numeric as wg,timestamp as vg,uuid as Ig,jsonb as nS,index as bg}from"drizzle-orm/pg-core";var pe=tS("limit_observations",{id:Ig("id").primaryKey().defaultRandom(),observedAt:vg("observed_at",{withTimezone:!0}).notNull().defaultNow(),provider:lo("provider").notNull(),plan:lo("plan").notNull(),limitType:lo("limit_type").notNull(),value:wg("value").notNull(),unit:lo("unit").notNull(),comparator:lo("comparator").notNull().default("="),resetsAt:vg("resets_at",{withTimezone:!0}),sourceType:lo("source_type").notNull(),sourceUrl:lo("source_url"),sourceEvidence:nS("source_evidence"),confidence:wg("confidence").notNull(),userId:Ig("user_id")},e=>[bg("idx_limit_obs_lookup").on(e.provider,e.plan,e.limitType,e.observedAt.desc()),bg("idx_limit_obs_user").on(e.userId,e.observedAt.desc())]);import{pgTable as rS,text as jc,timestamp as oS,uuid as sS,jsonb as iS,boolean as aS,uniqueIndex as cS}from"drizzle-orm/pg-core";var It=rS("provider_docs_snapshots",{id:sS("id").primaryKey().defaultRandom(),fetchedAt:oS("fetched_at",{withTimezone:!0}).notNull().defaultNow(),provider:jc("provider").notNull(),docUrl:jc("doc_url").notNull(),contentHash:jc("content_hash").notNull(),content:jc("content").notNull(),parseSuccess:aS("parse_success").notNull(),parseErrors:iS("parse_errors")},e=>[cS("idx_docs_dedup").on(e.provider,e.docUrl,e.contentHash)]);import{pgTable as uS,text as Nc,numeric as Sg,timestamp as Ag,uuid as dS,primaryKey as lS,index as pS}from"drizzle-orm/pg-core";var Ve=uS("plan_limits_active",{provider:Nc("provider").notNull(),plan:Nc("plan").notNull(),limitType:Nc("limit_type").notNull(),value:Sg("value").notNull(),unit:Nc("unit").notNull(),effectiveFrom:Ag("effective_from",{withTimezone:!0}).notNull(),effectiveUntil:Ag("effective_until",{withTimezone:!0}),confidence:Sg("confidence").notNull(),sourceObservationIds:dS("source_observation_ids").array().notNull()},e=>[lS({columns:[e.provider,e.plan,e.limitType,e.effectiveFrom]}),pS("idx_plan_limits_lookup").on(e.provider,e.plan,e.limitType,e.effectiveFrom.desc())]);import{pgTable as mS,text as pl,timestamp as fS,uuid as xg,jsonb as gS,index as hS}from"drizzle-orm/pg-core";var un=mS("alert_dispatches",{id:xg("id").primaryKey().defaultRandom(),userId:xg("user_id").notNull(),alertKey:pl("alert_key").notNull(),severity:pl("severity").notNull(),lastDispatchedAt:fS("last_dispatched_at",{withTimezone:!0}).notNull().defaultNow(),lastState:gS("last_state").notNull(),channel:pl("channel").notNull()},e=>[hS("idx_alert_user_key").on(e.userId,e.alertKey,e.lastDispatchedAt.desc())]);import{boolean as _S,date as yS,index as ml,integer as wS,jsonb as vS,pgTable as fl,text as kn,timestamp as kr,uniqueIndex as IS,uuid as Go}from"drizzle-orm/pg-core";var Je=fl("announcements",{id:Go("id").primaryKey().defaultRandom(),version:kn("version").notNull().unique(),releaseDate:yS("release_date").notNull(),subject:kn("subject").notNull(),htmlBody:kn("html_body").notNull(),textBody:kn("text_body").notNull(),sections:vS("sections").notNull().default({}),status:kn("status").notNull().default("draft"),recipientCount:wS("recipient_count"),sentAt:kr("sent_at",{withTimezone:!0}),sentBy:Go("sent_by"),error:kn("error"),createdAt:kr("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:kr("updated_at",{withTimezone:!0}).notNull().defaultNow()},e=>[ml("idx_announcements_status").on(e.status),ml("idx_announcements_created").on(e.createdAt)]),po=fl("announcement_deliveries",{id:Go("id").primaryKey().defaultRandom(),announcementId:Go("announcement_id").notNull(),userId:Go("user_id").notNull(),email:kn("email").notNull(),status:kn("status").notNull().default("pending"),providerId:kn("provider_id"),error:kn("error"),sentAt:kr("sent_at",{withTimezone:!0}),createdAt:kr("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[IS("uniq_announcement_deliveries_announcement_user").on(e.announcementId,e.userId),ml("idx_announcement_deliveries_user").on(e.userId,e.createdAt)]),Zt=fl("notification_preferences",{userId:Go("user_id").primaryKey(),productAnnouncements:_S("product_announcements").notNull().default(!0),unsubscribeToken:kn("unsubscribe_token").notNull().unique(),unsubscribedAt:kr("unsubscribed_at",{withTimezone:!0}),createdAt:kr("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:kr("updated_at",{withTimezone:!0}).notNull().defaultNow()});import{pgTable as bS,text as gl,timestamp as Eg,uuid as hl,integer as SS,index as AS,unique as xS}from"drizzle-orm/pg-core";var Tg=bS("scaffolding_fingerprints",{id:hl("id").primaryKey().defaultRandom(),userId:hl("user_id").notNull(),harness:gl("harness").notNull(),model:gl("model").notNull(),toolsHash:gl("tools_hash").notNull(),firstSeenAt:Eg("first_seen_at",{withTimezone:!0}).notNull().defaultNow(),lastSeenAt:Eg("last_seen_at",{withTimezone:!0}).notNull().defaultNow(),snapshotCount:SS("snapshot_count").notNull().default(1),firstSessionId:hl("first_session_id")},e=>[xS("scaffolding_fingerprints_user_id_harness_model_tools_hash_key").on(e.userId,e.harness,e.model,e.toolsHash),AS("idx_scaffolding_fp_segment").on(e.userId,e.harness,e.model)]);import{pgTable as ES,text as _l,timestamp as TS,jsonb as RS,uuid as Rg,integer as kS,unique as jS}from"drizzle-orm/pg-core";var kg=ES("scaffolding_segments",{id:Rg("id").primaryKey().defaultRandom(),userId:Rg("user_id").notNull(),harness:_l("harness").notNull(),model:_l("model").notNull(),coreNames:RS("core_names").notNull(),coreHash:_l("core_hash").notNull(),activeFingerprints:kS("active_fingerprints").notNull(),computedAt:TS("computed_at",{withTimezone:!0}).notNull().defaultNow()},e=>[jS("scaffolding_segments_user_id_harness_model_key").on(e.userId,e.harness,e.model)]);import{relations as Pe}from"drizzle-orm";var NS=Pe(T,({many:e})=>({sessions:e(f),contextSnapshots:e(j),apiKeys:e(ye)})),CS=Pe(ye,({one:e})=>({profile:e(T,{fields:[ye.userId],references:[T.id]})})),PS=Pe(H,({many:e})=>({teams:e(G),userOrganizations:e(K),projects:e(O),invitations:e(ne)})),OS=Pe(G,({one:e,many:t})=>({organization:e(H,{fields:[G.orgId],references:[H.id]}),userTeams:t(ge),invitations:t(ne)})),DS=Pe(ne,({one:e})=>({organization:e(H,{fields:[ne.orgId],references:[H.id]}),team:e(G,{fields:[ne.teamId],references:[G.id]}),inviter:e(T,{fields:[ne.invitedBy],references:[T.id]})})),MS=Pe(K,({one:e})=>({organization:e(H,{fields:[K.orgId],references:[H.id]})})),LS=Pe(ge,({one:e})=>({team:e(G,{fields:[ge.teamId],references:[G.id]})})),$S=Pe(y,({one:e,many:t})=>({versions:t(me),projectInstructions:t(ot),events:t(Nt),usageEvents:t(Er),sessionInstructions:t(te),packInstructions:t(xe),forkedFrom:e(y,{fields:[y.forkedFromId],references:[y.id]})})),qS=Pe(Nt,({one:e})=>({instruction:e(y,{fields:[Nt.instructionId],references:[y.id]})})),US=Pe(L,({one:e,many:t})=>({project:e(O,{fields:[L.projectId],references:[O.id]}),parent:e(L,{fields:[L.parentId],references:[L.id]}),versions:t(L)})),BS=Pe(me,({one:e})=>({instruction:e(y,{fields:[me.instructionId],references:[y.id]})})),FS=Pe(O,({one:e,many:t})=>({organization:e(H,{fields:[O.orgId],references:[H.id]}),projectInstructions:t(ot),sessions:t(f)})),HS=Pe(ot,({one:e})=>({project:e(O,{fields:[ot.projectId],references:[O.id]}),instruction:e(y,{fields:[ot.instructionId],references:[y.id]})})),WS=Pe(f,({one:e,many:t})=>({profile:e(T,{fields:[f.userId],references:[T.id]}),project:e(O,{fields:[f.projectId],references:[O.id]}),run:e(W,{fields:[f.runId],references:[W.id]}),events:t(Me),sessionInstructions:t(te),treatmentExposures:t(ee),contextSnapshots:t(j)})),zS=Pe(W,({one:e,many:t})=>({profile:e(T,{fields:[W.userId],references:[T.id]}),organization:e(H,{fields:[W.orgId],references:[H.id]}),project:e(O,{fields:[W.projectId],references:[O.id]}),sessions:t(f),launchJobs:t(re)})),VS=Pe(re,({one:e})=>({run:e(W,{fields:[re.runId],references:[W.id]})})),JS=Pe(Me,({one:e})=>({session:e(f,{fields:[Me.sessionId],references:[f.id]})})),GS=Pe(te,({one:e})=>({session:e(f,{fields:[te.sessionId],references:[f.id]}),instruction:e(y,{fields:[te.instructionId],references:[y.id]})})),KS=Pe(Et,({one:e,many:t})=>({owner:e(T,{fields:[Et.userId],references:[T.id]}),project:e(O,{fields:[Et.projectId],references:[O.id]}),exposures:t(ee)})),YS=Pe(ee,({one:e})=>({session:e(f,{fields:[ee.sessionId],references:[f.id]}),owner:e(T,{fields:[ee.userId],references:[T.id]}),assignment:e(Et,{fields:[ee.assignmentId],references:[Et.id]})})),XS=Pe(Ee,({one:e,many:t})=>({packInstructions:t(xe),forkedFrom:e(Ee,{fields:[Ee.forkedFromId],references:[Ee.id]})})),QS=Pe(xe,({one:e})=>({pack:e(Ee,{fields:[xe.packId],references:[Ee.id]}),instruction:e(y,{fields:[xe.instructionId],references:[y.id]})})),ZS=Pe(Er,({one:e})=>({instruction:e(y,{fields:[Er.instructionId],references:[y.id]})})),eA=Pe(R,({one:e,many:t})=>({parent:e(R,{fields:[R.parentId],references:[R.id]}),evals:t(he),evalRuns:t(_e),benchmarks:t(Rn),triggerEvals:t(Ct),optimizationRuns:t(fn),evalJobs:t(be),evalConversations:t(Te)})),tA=Pe(he,({one:e,many:t})=>({evalTarget:e(R,{fields:[he.evalTargetId],references:[R.id]}),runs:t(_e)})),nA=Pe(_e,({one:e})=>({eval:e(he,{fields:[_e.evalId],references:[he.id]}),evalTarget:e(R,{fields:[_e.evalTargetId],references:[R.id]})})),rA=Pe(Rn,({one:e})=>({evalTarget:e(R,{fields:[Rn.evalTargetId],references:[R.id]})})),oA=Pe(Ct,({one:e})=>({evalTarget:e(R,{fields:[Ct.evalTargetId],references:[R.id]})})),sA=Pe(fn,({one:e})=>({evalTarget:e(R,{fields:[fn.evalTargetId],references:[R.id]})})),iA=Pe(be,({one:e})=>({evalTarget:e(R,{fields:[be.evalTargetId],references:[R.id]})})),aA=Pe(Te,({one:e})=>({evalTarget:e(R,{fields:[Te.evalTargetId],references:[R.id]})})),cA=Pe(j,({one:e})=>({session:e(f,{fields:[j.sessionId],references:[f.id]}),profile:e(T,{fields:[j.userId],references:[T.id]})}));import{drizzle as Pg}from"drizzle-orm/postgres-js";import Rl from"postgres";var mo=0,yl=0,Ko=0,wl=0,jg=0,Ng=0,vl=0;function Il(){mo++,mo>yl&&(yl=mo)}u(Il,"trackDbOpStart");function bl(){mo>0&&mo--}u(bl,"trackDbOpEnd");function Sl(){Ko++,Ko>wl&&(wl=Ko)}u(Sl,"trackHeavyDbOpStart");function Al(){Ko>0&&Ko--}u(Al,"trackHeavyDbOpEnd");function ki(){return mo}u(ki,"getDbLoad");function xl(){jg++}u(xl,"recordDbShed");function ji(){Ng++}u(ji,"recordIngestShed");function Cg(){vl++}u(Cg,"recordQueryDeadline");function El(){let e=vl;return vl=0,e}u(El,"consumeDeadlineCount");function Tl(){return{current:mo,peak:yl,heavyCurrent:Ko,heavyPeak:wl,shedCount:jg,ingestShedCount:Ng}}u(Tl,"getDbLoadStats");function Yo(){let e=Number(process.env.PG_INFLIGHT_MAX);return Number.isFinite(e)&&e>0?e:(Number(process.env.PG_POOL_MAX)||3)*4}u(Yo,"dbInflightMax");function Ni(){let e=Yo(),t=Number(process.env.PG_INGEST_INFLIGHT_MAX);if(Number.isFinite(t)&&t>0)return Math.min(t,e);let n=Number(process.env.PG_POOL_MAX)||3;return Math.min(e,Math.max(n,Math.floor(e/2)))}u(Ni,"dbIngestInflightMax");var Pi,Qo,Oi=!1,Pc,Ci,Xo,Dc,Oc;function kl(e){let t=process.env[e];if(!t)throw new Error(`Missing required env var: ${e}`);return t}u(kl,"getEnv");function Og(){if(Oi)throw new Error("getDb() called after closeDb(): the connection pool is closed for shutdown. Stop issuing queries (timers/requests) before draining the pool.");if(!Pi){let e=process.env.PG_APPLICATION_NAME||"rulemetric",t=Number(process.env.PG_POOL_MAX)||3,n=Number(process.env.PG_CONNECT_TIMEOUT_S)||10,r=Number(process.env.PG_STATEMENT_TIMEOUT_MS)||0,o=Number(process.env.PG_IDLE_TIMEOUT)||5,s=Number(process.env.PG_KEEP_ALIVE_S)||60;Qo=Rl(kl("DATABASE_URL"),{prepare:!1,max:t,connect_timeout:n,idle_timeout:o,keep_alive:s,max_lifetime:300,connection:{application_name:e,...r>0?{statement_timeout:r}:{}}}),Pi=Pg(Qo,{schema:Cc})}return Pi}u(Og,"getDb");function Dg(){if(Oi)throw new Error("getHeavyDb() called after closeDb(): the connection pool is closed for shutdown. Stop issuing queries (timers/requests) before draining the pool.");if(!Oc){let e=(process.env.PG_APPLICATION_NAME||"rulemetric")+":heavy",t=Number(process.env.PG_HEAVY_POOL_MAX)||2;Dc=Rl(kl("DATABASE_URL"),{prepare:!1,max:t,connect_timeout:Number(process.env.PG_CONNECT_TIMEOUT_S)||10,idle_timeout:Number(process.env.PG_IDLE_TIMEOUT)||5,keep_alive:Number(process.env.PG_KEEP_ALIVE_S)||60,max_lifetime:300,connection:{application_name:e}}),Oc=Pg(Dc,{schema:Cc})}return Oc}u(Dg,"getHeavyDb");async function Di(){if(Pc)return Pc;Oi=!0;let e=Qo,t=Xo,n=Dc;return Qo=void 0,Pi=void 0,Xo=void 0,Dc=void 0,Oc=void 0,Pc=Promise.allSettled([e?e.end({timeout:5}):Promise.resolve(),t?t.end({timeout:5}):Promise.resolve(),n?n.end({timeout:5}):Promise.resolve()]).then(()=>{}),Pc}u(Di,"closeDb");function jl(){if(Oi)return Promise.resolve();if(Ci)return Ci;let e=Qo;return Qo=void 0,Pi=void 0,Ci=(async()=>{e&&await e.end({timeout:5}).catch(()=>{})})().finally(()=>{Ci=void 0}),Ci}u(jl,"recyclePool");async function Nl(e){let t=Date.now();if(Oi)return{ok:!1,ms:0,err:new Error("pool closed for shutdown")};let n=Xo;try{return n||(n=Rl(kl("DATABASE_URL"),{prepare:!1,max:1,connect_timeout:Number(process.env.PG_CONNECT_TIMEOUT_S)||10,idle_timeout:20,max_lifetime:300,connection:{application_name:(process.env.PG_APPLICATION_NAME||"rulemetric")+":probe",statement_timeout:Math.max(2e3,e-2e3)}}),Xo=n),await Promise.race([n`SELECT 1`,new Promise((r,o)=>setTimeout(()=>o(new Error("db probe timeout")),e))]),{ok:!0,ms:Date.now()-t}}catch(r){return Xo===n&&(Xo=void 0),n?.end({timeout:1}).catch(()=>{}),{ok:!1,ms:Date.now()-t,err:r}}}u(Nl,"probeDbReachable");var uA="called after closeDb()";function Cl(e){let t=e?.message;return typeof t=="string"&&t.includes(uA)}u(Cl,"isPoolClosedError");var dA=new Set(["CONNECT_TIMEOUT","ETIMEDOUT","ENOTFOUND","ECONNREFUSED","EAI_AGAIN"]);function Lc(e){let t=e,n=t?.code??t?.cause?.code??t?.errno;return n!==void 0&&dA.has(n)}u(Lc,"isRetryableConnectError");var lA=new Set(["CONNECTION_CLOSED","ECONNRESET","EPIPE"]);function Mg(e){let t=e,n=t?.code??t?.cause?.code??t?.errno;return n!==void 0&&lA.has(n)}u(Mg,"isRetryableResetError");async function Lg(e,t={}){let n=t.attempts??3,r=t.baseMs??100,o;for(let s=0;s<n;s++)try{return await e()}catch(i){o=i;let c=Lc(i)||t.retryResets===!0&&Mg(i);if(s===n-1||!c)throw i;await new Promise(a=>setTimeout(a,r*2**s))}throw o}u(Lg,"withDbRetry");var Mc=class extends Error{static{u(this,"QueryDeadlineError")}code="QUERY_DEADLINE";constructor(t){super(`Query exceeded the client-side deadline of ${t}ms \u2014 the DB pool is likely saturated (acquire-wait) or holding a dead socket; failing fast to avoid pinning the caller. See client.ts.`),this.name="QueryDeadlineError"}};function Pl(e){return e?.code==="QUERY_DEADLINE"}u(Pl,"isQueryDeadlineError");function $g(){let e=Number(process.env.PG_QUERY_DEADLINE_MS);return Number.isFinite(e)&&e>=0?e:2e4}u($g,"queryDeadlineMs");function pA(e,t){let n,r=new Promise((o,s)=>{n=setTimeout(()=>{Cg(),s(new Mc(t))},t);let i=n;typeof i.unref=="function"&&i.unref()});return Promise.race([e,r]).finally(()=>clearTimeout(n))}u(pA,"raceWithDeadline");var qg=new Set(["select","selectDistinct","selectDistinctOn","insert","update","delete","execute","with","$count","refreshMaterializedView"]),Ug=new Set(["select","selectDistinct","selectDistinctOn","$count"]);function Ol(e,t=!1,n=0,r=!1){return e===null||typeof e!="object"&&typeof e!="function"?e:new Proxy(e,{get(o,s,i){if(s==="then"){let a=Reflect.get(o,s,i);return typeof a!="function"?a:(l,p)=>{let m=r?Sl:Il,_=r?Al:bl;m();let v=Lg(()=>new Promise((h,w)=>a.call(o,h,w)),{retryResets:t});return(n>0?pA(v,n):v).finally(_).then(l,p)}}let c=Reflect.get(o,s,i);return typeof c=="function"?(...a)=>Ol(c.apply(o,a),t,n,r):c}})}u(Ol,"wrapBuilder");function Bg(e,t=!1){let n=t?Sl:Il,r=t?Al:bl;n();try{return Promise.resolve(e()).finally(r)}catch(o){throw r(),o}}u(Bg,"gaugeTransaction");var d=new Proxy({},{get(e,t){let n=Og(),r=n[t];if(typeof t=="string"&&qg.has(t)&&typeof r=="function"){let o=Ug.has(t),s=$g();return(...i)=>Ol(r.apply(n,i),o,s)}return t==="transaction"&&typeof r=="function"?(...o)=>Bg(()=>r.apply(n,o)):r}}),lt=new Proxy({},{get(e,t){let n=Dg(),r=n[t];if(typeof t=="string"&&qg.has(t)&&typeof r=="function"){let o=Ug.has(t);return(...s)=>Ol(r.apply(n,s),o,0,!0)}return t==="transaction"&&typeof r=="function"?(...o)=>Bg(()=>r.apply(n,o),!0):r}});async function en(e){let[t]=await d.insert(ft).values({userId:e.userId,type:e.type,title:e.title,body:e.body??null,url:e.url??null,sourceTable:e.sourceTable??null,sourceId:e.sourceId??null,metadata:e.metadata??{}}).onConflictDoNothing({target:[ft.userId,ft.sourceTable,ft.sourceId]}).returning();return t??null}u(en,"notifyUser");import{createHmac as mA,createPublicKey as fA,timingSafeEqual as gA,verify as hA}from"node:crypto";var _A=6e4,Li=null,Hg=0,Mi=null,yA=null;async function wA(){let e=process.env.SUPABASE_URL;if(!e)throw new Error("SUPABASE_URL not set");let t=await fetch(`${e}/auth/v1/.well-known/jwks.json`,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw new Error(`JWKS fetch failed: ${t.status}`);return await t.json()}u(wA,"defaultJwksFetcher");async function Dl(){return Mi||(Mi=(async()=>{try{let e=await(yA??wA)(),t=new Map;for(let n of e.keys)if(n.kid)try{t.set(n.kid,fA({key:n,format:"jwk"}))}catch{}Li=t,Hg=Date.now()}finally{Mi=null}})(),Mi)}u(Dl,"refreshJwks");function Fg(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf-8"))}catch{return null}}u(Fg,"decodeB64Json");function vA(e){if(typeof e.exp=="number"&&e.exp*1e3<Date.now()||typeof e.sub!="string"||e.sub.length===0)return null;let t=e.aud;return t==="authenticated"||Array.isArray(t)&&t.includes("authenticated")?{userId:e.sub}:null}u(vA,"checkPayload");function IA(e,t,n,r){let o=mA("sha256",r).update(`${e}.${t}`).digest(),s;try{s=Buffer.from(n,"base64url")}catch{return!1}return s.length!==o.length?!1:gA(s,o)}u(IA,"verifyHs256");async function Wg(e){let t=e.split(".");if(t.length!==3)return{ok:!1,reason:"invalid"};let[n,r,o]=t,s=Fg(n);if(!s)return{ok:!1,reason:"invalid"};if(s.alg==="HS256"){let a=process.env.SUPABASE_JWT_SECRET;if(!a)return{ok:!1,reason:"unavailable"};if(!IA(n,r,o,a))return{ok:!1,reason:"invalid"}}else if(s.alg==="ES256"){if(typeof s.kid!="string")return{ok:!1,reason:"invalid"};if(Li===null)try{await Dl()}catch{return{ok:!1,reason:"unavailable"}}let a=Li?.get(s.kid);if(!a&&Date.now()-Hg>=_A){try{await Dl()}catch{return{ok:!1,reason:"unavailable"}}a=Li?.get(s.kid)}if(!a)return{ok:!1,reason:"invalid"};let l;try{l=Buffer.from(o,"base64url")}catch{return{ok:!1,reason:"invalid"}}if(!hA("sha256",Buffer.from(`${n}.${r}`),{key:a,dsaEncoding:"ieee-p1363"},l))return{ok:!1,reason:"invalid"}}else return{ok:!1,reason:"invalid"};let i=Fg(r);if(!i)return{ok:!1,reason:"invalid"};let c=vA(i);return c?{ok:!0,userId:c.userId,payload:i}:{ok:!1,reason:"invalid"}}u(Wg,"verifySupabaseJwt");async function zg(e=3){for(let t=0;t<e;t++)try{return await Dl(),Li!==null}catch{await new Promise(n=>setTimeout(n,500*2**t))}return!1}u(zg,"primeJwks");function EA(e){return bA("sha256").update(e).digest("hex")}u(EA,"hashApiKey");var Vg=new Map,TA=300*1e3;function RA(e){let t=Date.now(),n=Vg.get(e)??0;t-n<TA||(Vg.set(e,t),d.update(ye).set({lastUsedAt:new Date}).where(Jg(ye.id,e)).then(()=>{}).catch(()=>{}))}u(RA,"updateLastUsed");var kA=60*1e3,jA=5e3,Zo=new Map;async function Gg(e,t){let n=e.req.header("Authorization");if(!n?.startsWith("Bearer "))return e.json({error:"Missing authorization header"},401);let r=n.slice(7);if(r.startsWith("rm_")){let o=EA(r),s,i=Zo.get(o);if(i&&Date.now()-i.cachedAt<kA)s=i;else{i&&Zo.delete(o);let[c]=await d.select({id:ye.id,userId:ye.userId,expiresAt:ye.expiresAt}).from(ye).where(AA(Jg(ye.keyHash,o),xA(ye.revokedAt)));if(!c)return e.json({error:"Invalid API key"},401);s={id:c.id,userId:c.userId,expiresAt:c.expiresAt,cachedAt:Date.now()},Zo.size>=jA&&Zo.clear(),Zo.set(o,s)}if(s.expiresAt&&new Date(s.expiresAt)<new Date)return Zo.delete(o),e.json({error:"API key expired"},401);e.set("userId",s.userId),oi(s.userId),RA(s.id),await t();return}try{let o=SA(process.env.SUPABASE_URL,process.env.SUPABASE_ANON_KEY,{global:{headers:{Authorization:`Bearer ${r}`}}}),s=await Wg(r);if(s.ok){e.set("userId",s.userId),e.set("supabase",o),oi(s.userId),await t();return}if(s.reason==="invalid")return console.log(`[auth] local JWT verify FAIL ${e.req.method} ${e.req.path}`),e.json({error:"Invalid token"},401);let i=Date.now(),{data:{user:c},error:a}=await o.auth.getUser();if(console.log(`[auth] getUser ${e.req.method} ${e.req.path} ms=${Date.now()-i} ${a?`err=${a.message}`:`userId=${c?.id??"?"}`}`),a||!c)return e.json({error:"Invalid token"},401);e.set("user",c),e.set("userId",c.id),e.set("supabase",o),oi(c.id),await t()}catch{return e.json({error:"Authentication failed"},401)}}u(Gg,"authMiddleware");import{HTTPException as NA}from"hono/http-exception";import{ZodError as CA}from"zod";function Ze(e){return e.replace(/[%_\\]/g,"\\$&")}u(Ze,"escapeLike");function es(e){let t=e;return t?.code??t?.cause?.code??t?.errno}u(es,"transientCode");var PA=new Set(["ECONNRESET","EPIPE","ECONNABORTED"]);function Kg(e,t){return e instanceof CA?t.json({error:"Validation error",details:e.flatten().fieldErrors},400):e instanceof NA?e.getResponse():Cl(e)?t.json({error:"Server draining, retry shortly"},503):Pl(e)?(process.env.LOG_LEVEL==="debug"&&console.debug("[req] query deadline exceeded \u2014 DB pool saturated; shed 503"),t.json({error:"Database busy, retry shortly"},503,{"Retry-After":"2"})):e.message==="aborted"||PA.has(es(e)??"")?(process.env.LOG_LEVEL==="debug"&&console.debug(`[req] client/transient disconnect code=${es(e)??"aborted"}`),t.body(null,503)):(console.error("Unhandled error:",e),t.json({error:"Internal server error"},500))}u(Kg,"errorHandler");function $i(e,t){let n=new Map;return setInterval(()=>{let r=Date.now();for(let[o,s]of n)r>s.resetAt&&n.delete(o)},6e4).unref(),async(r,o)=>{let i=`${r.req.header("x-forwarded-for")?.split(",")[0]?.trim()??r.req.header("x-real-ip")??"unknown"}:${r.req.path}`,c=Date.now(),a=n.get(i);if((!a||c>a.resetAt)&&(a={count:0,resetAt:c+e},n.set(i,a)),a.count++,r.res.headers.set("X-RateLimit-Limit",String(t)),r.res.headers.set("X-RateLimit-Remaining",String(Math.max(0,t-a.count))),r.res.headers.set("X-RateLimit-Reset",String(Math.ceil(a.resetAt/1e3))),a.count>t)return r.json({error:"Too many requests, please try again later"},429);await o()}}u($i,"rateLimit");var $c=!0,Ml="",Yg=0;function Ll(e,t="",n=-1){if(e===$c){!e&&t&&(Ml=t);return}$c=e,Ml=e?"":t,Yg=n,console.log(`[db-readiness] -> ${e?"READY":"NOT READY"}${t?` (${t})`:""}`)}u(Ll,"setDbReady");function qi(){return $c}u(qi,"isDbReady");function qc(){return{ready:$c,reason:Ml,changedAt:Yg}}u(qc,"dbReadiness");async function Xg(e,t){return qi()?t():(e.header("Retry-After","5"),e.json({error:"Service temporarily unavailable: the database is recovering. Retry shortly.",reason:qc().reason||void 0},503))}u(Xg,"dbShed");var OA=5e3,Qg=0;async function Zg(e,t){let n=ki(),r=Yo();if(n>r){xl();let o=Date.now();return o-Qg>=OA&&(Qg=o,console.warn(`[db_load_shed] shedding: inFlight=${n} > max=${r} path=${e.req.path}`)),e.header("Retry-After","1"),e.json({error:"Service busy: the database is under transient load. Retry shortly.",inFlight:n},503)}return t()}u(Zg,"dbLoadShed");var DA=5e3,eh=0;async function Ui(e,t){if(e.req.method!=="POST")return t();let n=ki(),r=Ni();if(n>=r){ji();let o=Date.now();return o-eh>=DA&&(eh=o,console.warn(`[ingest_load_shed] shedding write: inFlight=${n} >= ingestMax=${r} path=${e.req.path}`)),e.header("Retry-After","2"),e.json({error:"Ingest busy: the database is under transient write load. Retry shortly.",inFlight:n},429)}return t()}u(Ui,"ingestLoadShed");var th=u(async(e,t)=>{await t(),e.res.headers.set("X-Content-Type-Options","nosniff"),e.res.headers.set("X-Frame-Options","DENY"),e.res.headers.set("X-XSS-Protection","0"),e.res.headers.set("Referrer-Policy","strict-origin-when-cross-origin"),e.res.headers.set("Permissions-Policy","camera=(), microphone=(), geolocation=()")},"securityHeaders");function nh(){return async(e,t)=>{let n=Date.now();try{await t()}finally{let r=Date.now()-n,o=Number(process.env.SLOW_REQUEST_LOG_MS)||2e3,s=Number(process.env.SLOW_REQUEST_MAX_MS)||12e4;if(r>s||r<o&&e.res.status<500)return;let i=new URL(e.req.url).pathname,c=e.get("userId");console.warn(`[http] slow_or_error method=${e.req.method} path=${i} status=${e.res.status} ms=${r}${c?` user=${c}`:""}`)}}}u(nh,"slowRequestLog");import{Hono as LA}from"hono";import{z as jr}from"zod";import{createClient as rh}from"@supabase/supabase-js";import{createClient as MA}from"@supabase/supabase-js";async function Uc(e){let t=process.env.SUPABASE_URL,n=process.env.SUPABASE_ANON_KEY;if(!t||!n)return{ok:!1,status:500,error:"Server authentication not configured"};let r=MA(t,n,{auth:{persistSession:!1,autoRefreshToken:!1}}),o=`${e.slice(0,6)}\u2026${e.slice(-4)}`,s=Date.now();console.log(`[auth] refreshSession start refresh_token=${o}`);let{data:i,error:c}=await r.auth.refreshSession({refresh_token:e});return c||!i.session?(console.log(`[auth] refreshSession FAIL refresh_token=${o} ms=${Date.now()-s} err=${c?.message??"no-session"}`),{ok:!1,status:401,error:c?.message??"refresh failed"}):(console.log(`[auth] refreshSession OK refresh_token=${o} ms=${Date.now()-s} userId=${i.user?.id??"?"}`),{ok:!0,session:{accessToken:i.session.access_token,refreshToken:i.session.refresh_token,expiresAt:i.session.expires_at?new Date(i.session.expires_at*1e3).toISOString():null,email:i.user?.email??null}})}u(Uc,"refreshSupabaseSession");var ts=new LA,$A=jr.object({email:jr.string().email(),password:jr.string().min(1)}),qA=jr.object({refreshToken:jr.string().min(1)});ts.post("/auth/login",async e=>{let t=await e.req.json(),n=$A.parse(t),r=process.env.SUPABASE_URL,o=process.env.SUPABASE_ANON_KEY;if(!r||!o)return e.json({error:"Server authentication not configured"},500);let s=rh(r,o),i=Date.now();console.log(`[auth] signInWithPassword start email=${n.email} ua="${e.req.header("user-agent")??""}"`);let{data:c,error:a}=await s.auth.signInWithPassword({email:n.email,password:n.password});return a||!c.session?(console.log(`[auth] signInWithPassword FAIL email=${n.email} ms=${Date.now()-i} err=${a?.message??"no-session"}`),e.json({error:"Invalid email or password"},401)):(console.log(`[auth] signInWithPassword OK email=${n.email} ms=${Date.now()-i} userId=${c.user?.id??"?"}`),e.json({accessToken:c.session.access_token,refreshToken:c.session.refresh_token,expiresAt:c.session.expires_at?new Date(c.session.expires_at*1e3).toISOString():null,email:c.user?.email??n.email}))});var UA=jr.object({email:jr.string().email(),password:jr.string().min(8,"Password must be at least 8 characters")});ts.post("/auth/signup",async e=>{let t=await e.req.json(),n=UA.parse(t),r=process.env.SUPABASE_URL,o=process.env.SUPABASE_ANON_KEY;if(!r||!o)return e.json({error:"Server authentication not configured"},500);let s=rh(r,o),i=process.env.WEB_URL??"http://localhost:5174",{data:c,error:a}=await s.auth.signUp({email:n.email,password:n.password,options:{emailRedirectTo:`${i}/auth/confirm`}});if(a){let l=/already registered|already exists|user already/i.test(a.message);return e.json({error:a.message},l?409:400)}return c.user&&(c.user.identities?.length??0)===0&&!c.session?e.json({error:"An account with this email already exists. Run `rulemetric auth login`."},409):c.session?e.json({confirmationRequired:!1,accessToken:c.session.access_token,refreshToken:c.session.refresh_token,expiresAt:c.session.expires_at?new Date(c.session.expires_at*1e3).toISOString():null,email:c.user?.email??n.email}):e.json({confirmationRequired:!0,email:c.user?.email??n.email})});ts.post("/auth/refresh",async e=>{let t=await e.req.json().catch(()=>null),n=qA.safeParse(t);if(!n.success)return e.json({error:"refreshToken is required"},400);let r=await Uc(n.data.refreshToken);return r.ok?e.json(r.session):e.json({error:r.error},r.status)});import{readFileSync as BA}from"node:fs";import{dirname as FA,resolve as $l}from"node:path";import{fileURLToPath as HA}from"node:url";import{Hono as WA}from"hono";var zA="https://registry.npmjs.org/-/package/@rulemetric%2Fcli/dist-tags",VA=3600*1e3,JA=3e3,Bi=null;function GA(){if(process.env.RULEMETRIC_BUNDLED_CLI_VERSION)return process.env.RULEMETRIC_BUNDLED_CLI_VERSION;let e=FA(HA(import.meta.url)),t=[$l(e,"../../../cli/package.json"),$l(e,"../../../../apps/cli/package.json"),$l(process.cwd(),"apps/cli/package.json")];for(let n of t)try{let r=JSON.parse(BA(n,"utf-8"));if(r.version)return r.version}catch{}return"0.0.0"}u(GA,"readBundledCliVersion");async function KA(){try{let e=await fetch(zA,{headers:{accept:"application/json"},signal:AbortSignal.timeout(JA)});if(!e.ok)return null;let t=await e.json();return typeof t.latest=="string"&&t.latest?t.latest:null}catch{return null}}u(KA,"fetchLatestFromNpm");async function YA(){let e=Date.now();if(Bi&&e-Bi.at<VA)return Bi.version;let n=await KA()??Bi?.version??GA();return Bi={version:n,at:e},n}u(YA,"getLatestCliVersion");var Bc=new WA;Bc.get("/cli/latest-version",async e=>e.json({latest:await YA()}));import{Hono as ux}from"hono";import{sql as XA}from"drizzle-orm";var QA=12e3,ZA=3e4,oh=4,ex=Number(process.env.PG_RECYCLE_DEADLINE_THRESHOLD)||3,tx="pipeline:api_db_pool_wedged",nx="pipeline:api_db_pool_recycled",ns=0;async function ql(){return Nl(QA)}u(ql,"probeDb");function rx(e){let t=[],n=[],r=e;for(let o=0;r&&o<8;o++){let s=r;typeof s.code=="string"&&t.push(s.code),typeof s.message=="string"&&n.push(s.message),r=s.cause}return{codes:t,message:n.join(" ").toLowerCase()}}u(rx,"flattenCauseChain");function ox(e){let{codes:t,message:n}=rx(e);return n.includes("max client")||n.includes("emaxconn")||n.includes("max_client_conn")||t.includes("XX000")&&n.includes("client")}u(ox,"isPoolSaturation");function sx(e){return ox(e)?"Supavisor tenant saturated (client cap reached)":Lc(e)?"transient connect failure":"DB unreachable / probe timed out"}u(sx,"classifyProbeFailure");async function ix(e=ql,t={}){let n=t.consumeDeadlines??El,r=t.recycle??jl,o=t.onRecycle??cx,s=await e();if(s.ok){let c=!qi();ns>0&&console.log(`[db-wedge] DB reachable again after ${ns} failed probe(s)`),ns=0,Ll(!0,"",Date.now()),c&&ax();let a=n();a>=ex&&(console.error(`[db-wedge] recycling the MAIN pool: ${a} client-side query-deadline(s) while a fresh dedicated probe is healthy \u2014 the pool is holding black-holed sockets a restart is not needed to clear.`),Promise.resolve().then(()=>r()).catch(l=>console.error("[db-wedge] pool recycle failed:",l instanceof Error?l.message:l)),o(a));return}ns+=1;let i=sx(s.err);console.error(`[db-wedge] dedicated DB probe failed (${ns}/${oh}) \u2014 ${i}`),ns>=oh&&qi()&&(Ll(!1,`DB unreachable from a dedicated connection \u2014 ${i}`,Date.now()),console.error("[db-wedge] marking API NOT READY (shedding DB traffic). NOT restarting: a process restart cannot free a shared Supavisor pooler. Readiness restores automatically on the next OK probe."))}u(ix,"watchdogTick");async function sh(e,t){try{await d.execute(XA`
|
|
75
|
+
${e}`}var MI=Xe(()=>{"use strict";u(OI,"resolveRuntimeWebConfig");u(DO,"stampRuntimeConfig")});import*as vd from"node:fs";import*as Id from"node:path";import{fileURLToPath as fD}from"node:url";import{serve as gD}from"@hono/node-server";import{trace as bf,context as m0}from"@opentelemetry/api";import{NodeSDK as f0}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as g0}from"@opentelemetry/exporter-trace-otlp-http";import{BatchSpanProcessor as h0,ConsoleSpanExporter as _0,SimpleSpanProcessor as y0}from"@opentelemetry/sdk-trace-node";import{Resource as w0}from"@opentelemetry/resources";import{ATTR_SERVICE_NAME as v0,ATTR_SERVICE_VERSION as I0}from"@opentelemetry/semantic-conventions";function If(e){if(!e)return{};let t={};for(let n of e.split(",")){let r=n.indexOf("=");if(r===-1)continue;let o=n.slice(0,r).trim(),s=n.slice(r+1).trim();o&&(t[o]=s)}return t}u(If,"parseOtlpHeaders");var Bo=null;function Fo(){return process.env.TELEMETRY_ENABLED!=="false"}u(Fo,"isTelemetryEnabled");function Rd(e){if(!Fo()||Bo!==null)return"off";let t=new w0({[v0]:e.serviceName,[I0]:e.serviceVersion??"0.1.0"}),n=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r,o;if(n){let s=If(process.env.OTEL_EXPORTER_OTLP_HEADERS),i=new g0({url:`${n}/v1/traces`,headers:s});o=new h0(i),r="otlp"}else if(process.env.OTEL_SPAN_EXPORT==="none")o=void 0,r="silent";else{let s=new _0;o=new y0(s),r="console"}return Bo=new f0({resource:t,spanProcessors:o?[o]:[]}),Bo.start(),r}u(Rd,"initTelemetry");async function kd(){Bo&&(await Bo.shutdown(),Bo=null)}u(kd,"shutdownTelemetry");function jd(e){return bf.getTracer(e??"rulemetric")}u(jd,"getTracer");function Nd(){return bf.getSpan(m0.active())?.spanContext().traceId}u(Nd,"getTraceId");import{SpanKind as b0,SpanStatusCode as Sf}from"@opentelemetry/api";function Cd(){return async(e,t)=>{if(!Fo()){await t();return}let n=jd(),r=e.req.method,o=e.req.path;await n.startActiveSpan(`${r} ${o}`,{kind:b0.SERVER,attributes:{"http.method":r,"http.url":e.req.url,"http.route":o}},async s=>{try{await t(),s.setAttribute("http.status_code",e.res.status);let i=e.get("userId");i&&s.setAttribute("rulemetric.user_id",i),e.res.status>=400&&s.setStatus({code:Sf.ERROR})}catch(i){throw s.setStatus({code:Sf.ERROR}),s.recordException(i),i}finally{s.end()}})}}u(Cd,"telemetryMiddleware");import{trace as S0,context as A0}from"@opentelemetry/api";function Pd(e){let t=S0.getSpan(A0.active());if(t)for(let[n,r]of Object.entries(e))t.setAttribute(n,r)}u(Pd,"setSpanAttributes");import*as sr from"@sentry/node";var oi=!1;function Od(e){if(oi)return!1;let t=process.env.SENTRY_DSN;return t?(sr.init({dsn:t,serverName:e.serviceName,environment:process.env.NODE_ENV??"development",tracesSampleRate:0}),oi=!0,!0):!1}u(Od,"initSentry");function Un(e,t){if(!oi)return;let n=e instanceof Error?e:new Error(typeof e=="string"?e:JSON.stringify(e));sr.captureException(n,t)}u(Un,"captureException");function si(e){if(oi){if(e===null){sr.setUser(null);return}sr.setUser({id:e})}}u(si,"setSentryUser");async function ii(e){oi&&await sr.flush(e)}u(ii,"flushSentry");import*as Va from"node:fs";import*as Ys from"node:path";import{fileURLToPath as MO}from"node:url";import{Hono as LO}from"hono";import{cors as $O}from"hono/cors";import{bodyLimit as qO}from"hono/body-limit";import{serveStatic as UO}from"@hono/node-server/serve-static";import{createHash as AA}from"node:crypto";import{createClient as xA}from"@supabase/supabase-js";import{eq as Kg,and as EA,isNull as TA}from"drizzle-orm";var Pc={};no(Pc,{SUGGESTION_KINDS:()=>jc,agentJobs:()=>be,agentRuns:()=>J,agentRunsRelations:()=>JS,alertDispatches:()=>un,announcementDeliveries:()=>mo,announcements:()=>Je,apiKeys:()=>we,apiKeysRelations:()=>OS,benchmarks:()=>kn,benchmarksRelations:()=>sA,cliErrorEvents:()=>yc,cliSetupEvents:()=>_c,contentBlobs:()=>cn,contextSnapshots:()=>C,contextSnapshotsRelations:()=>dA,evalComparisons:()=>Ke,evalConversations:()=>ke,evalConversationsRelations:()=>uA,evalGradeAnnotations:()=>ze,evalJobs:()=>Se,evalJobsRelations:()=>cA,evalRuns:()=>ye,evalRunsRelations:()=>oA,evalTargets:()=>k,evalTargetsRelations:()=>nA,evals:()=>_e,evalsRelations:()=>rA,extensionAuthCodes:()=>_n,harnessReleases:()=>Rt,insightsJobs:()=>W,instructionEvents:()=>Nt,instructionEventsRelations:()=>BS,instructionPromotions:()=>Ne,instructionSuggestionEvents:()=>zt,instructionSuggestions:()=>q,instructionUsageEvents:()=>Rr,instructionUsageEventsRelations:()=>tA,instructionVersionIdentities:()=>Fn,instructionVersions:()=>fe,instructionVersionsRelations:()=>HS,instructions:()=>_,instructionsRelations:()=>US,judgeReviewerVerdicts:()=>ce,launchJobs:()=>oe,launchJobsRelations:()=>GS,limitObservations:()=>pe,memories:()=>$,memoriesRelations:()=>FS,memoryExperiments:()=>Er,modelPricing:()=>Ye,notificationPreferences:()=>en,notifications:()=>ht,optimizationRuns:()=>hn,optimizationRunsRelations:()=>aA,orgInvitations:()=>re,orgInvitationsRelations:()=>LS,organizations:()=>V,organizationsRelations:()=>DS,packInstructions:()=>Ee,packInstructionsRelations:()=>eA,packs:()=>Re,packsRelations:()=>ZS,pendingTreatmentExposures:()=>uc,planLimitsActive:()=>Ve,profiles:()=>R,profilesRelations:()=>PS,projectCheckouts:()=>ue,projectInstructions:()=>at,projectInstructionsRelations:()=>zS,projects:()=>D,projectsRelations:()=>WS,providerDocsSnapshots:()=>bt,scaffoldingFingerprints:()=>kg,scaffoldingSegments:()=>Ng,sessionEvents:()=>Le,sessionEventsRelations:()=>KS,sessionInstructions:()=>ne,sessionInstructionsRelations:()=>YS,sessionSendJobs:()=>mc,sessionTerminalTargets:()=>We,sessions:()=>f,sessionsRelations:()=>VS,skillSubmissions:()=>jr,teams:()=>K,teamsRelations:()=>MS,treatmentAssignments:()=>Tt,treatmentAssignmentsRelations:()=>XS,treatmentExposures:()=>X,treatmentExposuresRelations:()=>QS,triggerEvals:()=>Ct,triggerEvalsRelations:()=>iA,userOrganizations:()=>Y,userOrganizationsRelations:()=>$S,userTeams:()=>he,userTeamsRelations:()=>qS,workerConnections:()=>ve});import{boolean as Ef,pgTable as x0,text as Za,timestamp as Dd,uuid as Tf}from"drizzle-orm/pg-core";import{pgTable as Qa,text as Ho,timestamp as ai,jsonb as Af,uuid as ro,primaryKey as xf}from"drizzle-orm/pg-core";var V=Qa("organizations",{id:ro("id").primaryKey().defaultRandom(),name:Ho("name").unique().notNull(),slug:Ho("slug").unique().notNull(),metadata:Af("metadata"),createdAt:ai("created_at",{withTimezone:!0}).defaultNow(),updatedAt:ai("updated_at",{withTimezone:!0}).defaultNow()}),K=Qa("teams",{id:ro("id").primaryKey().defaultRandom(),orgId:ro("org_id").references(()=>V.id,{onDelete:"cascade"}),name:Ho("name").notNull(),slug:Ho("slug").notNull(),metadata:Af("metadata"),createdAt:ai("created_at",{withTimezone:!0}).defaultNow()}),Y=Qa("user_organizations",{userId:ro("user_id").notNull(),orgId:ro("org_id").references(()=>V.id,{onDelete:"cascade"}).notNull(),role:Ho("role").notNull().default("member"),createdAt:ai("created_at",{withTimezone:!0}).defaultNow()},e=>[xf({columns:[e.userId,e.orgId]})]),he=Qa("user_teams",{userId:ro("user_id").notNull(),teamId:ro("team_id").references(()=>K.id,{onDelete:"cascade"}).notNull(),role:Ho("role").notNull().default("member"),createdAt:ai("created_at",{withTimezone:!0}).defaultNow()},e=>[xf({columns:[e.userId,e.teamId]})]);var R=x0("profiles",{id:Tf("id").primaryKey(),email:Za("email"),displayName:Za("display_name"),activeOrgId:Tf("active_org_id").references(()=>V.id,{onDelete:"set null"}),isSuperadmin:Ef("is_superadmin").notNull().default(!1),claudeCodePlan:Za("claude_code_plan"),planSource:Za("plan_source").notNull().default("detected"),setupCompletedAt:Dd("setup_completed_at",{withTimezone:!0}),liveSendSkipped:Ef("live_send_skipped").notNull().default(!1),createdAt:Dd("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Dd("updated_at",{withTimezone:!0}).defaultNow()});import{pgTable as E0,text as Md,timestamp as ec,uuid as tc,index as Rf}from"drizzle-orm/pg-core";var re=E0("org_invitations",{id:tc("id").primaryKey().defaultRandom(),orgId:tc("org_id").notNull().references(()=>V.id,{onDelete:"cascade"}),email:Md("email").notNull(),role:Md("role").notNull().default("member"),teamId:tc("team_id").references(()=>K.id,{onDelete:"set null"}),invitedBy:tc("invited_by").notNull().references(()=>R.id,{onDelete:"cascade"}),token:Md("token").notNull().unique(),expiresAt:ec("expires_at",{withTimezone:!0}).notNull(),acceptedAt:ec("accepted_at",{withTimezone:!0}),revokedAt:ec("revoked_at",{withTimezone:!0}),createdAt:ec("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Rf("idx_org_invitations_token").on(e.token),Rf("idx_org_invitations_org").on(e.orgId)]);import{pgTable as Ld,text as Ht,timestamp as xr,jsonb as nc,uuid as Bn,integer as rc,boolean as T0,uniqueIndex as oc,index as ci}from"drizzle-orm/pg-core";var _=Ld("instructions",{id:Bn("id").primaryKey().defaultRandom(),name:Ht("name").notNull(),description:Ht("description").notNull(),type:Ht("type").notNull().default("instruction"),scope:Ht("scope").notNull(),scopeRef:Bn("scope_ref"),version:Ht("version").notNull(),content:Ht("content").notNull(),frontmatter:nc("frontmatter").notNull(),slots:nc("slots"),tags:Ht("tags").array(),compatibility:Ht("compatibility").array(),createdBy:Bn("created_by"),createdAt:xr("created_at",{withTimezone:!0}).defaultNow(),updatedAt:xr("updated_at",{withTimezone:!0}).defaultNow(),archived:T0("archived").default(!1),archivedAt:xr("archived_at",{withTimezone:!0}),archivedBy:Bn("archived_by"),forkedFromId:Bn("forked_from_id").references(()=>_.id,{onDelete:"set null"}),upstreamVersion:Ht("upstream_version"),badge:Ht("badge"),contentHash:Ht("content_hash"),contextIdentity:Ht("context_identity"),scanScore:rc("scan_score"),scanFindings:nc("scan_findings"),popularityScore:rc("popularity_score"),sourceUpdatedAt:xr("source_updated_at",{withTimezone:!0})},e=>[oc("instructions_name_scope_ref_idx").on(e.name,e.scope,e.scopeRef),ci("idx_instructions_scope").on(e.scope,e.scopeRef),ci("idx_instructions_created_by").on(e.createdBy),ci("idx_instructions_context_identity").on(e.createdBy,e.contextIdentity),ci("idx_instructions_public_recency").on(e.scope,e.sourceUpdatedAt.desc())]),Fn=Ld("instruction_version_identities",{id:Bn("id").primaryKey().defaultRandom(),instructionId:Bn("instruction_id").notNull().references(()=>_.id,{onDelete:"cascade"}),contentHash:Ht("content_hash").notNull(),versionOrdinal:rc("version_ordinal").notNull(),content:Ht("content"),firstSeenAt:xr("first_seen_at",{withTimezone:!0}).notNull().defaultNow(),lastSeenAt:xr("last_seen_at",{withTimezone:!0}).notNull().defaultNow(),createdAt:xr("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[oc("instruction_version_identities_hash_unique").on(e.instructionId,e.contentHash),oc("instruction_version_identities_ordinal_unique").on(e.instructionId,e.versionOrdinal),ci("idx_ivi_instruction").on(e.instructionId)]),fe=Ld("instruction_versions",{id:Bn("id").primaryKey().defaultRandom(),instructionId:Bn("instruction_id").references(()=>_.id,{onDelete:"cascade"}),versionNumber:rc("version_number").notNull(),content:Ht("content").notNull(),frontmatter:nc("frontmatter").notNull(),changeSummary:Ht("change_summary"),createdBy:Bn("created_by"),createdAt:xr("created_at",{withTimezone:!0}).defaultNow()},e=>[oc("instruction_versions_instruction_version_idx").on(e.instructionId,e.versionNumber)]);import{pgTable as R0,text as k0,timestamp as j0,jsonb as N0,uuid as $d,index as kf}from"drizzle-orm/pg-core";var Nt=R0("instruction_events",{id:$d("id").primaryKey().defaultRandom(),instructionId:$d("instruction_id").notNull().references(()=>_.id,{onDelete:"cascade"}),eventType:k0("event_type").notNull(),actorId:$d("actor_id").notNull(),metadata:N0("metadata"),createdAt:j0("created_at",{withTimezone:!0}).defaultNow()},e=>[kf("idx_instruction_events_instruction").on(e.instructionId),kf("idx_instruction_events_type").on(e.eventType)]);import{boolean as C0,jsonb as P0,pgTable as Ud,primaryKey as jf,text as oo,timestamp as ui,uniqueIndex as qd,uuid as so}from"drizzle-orm/pg-core";import{sql as O0}from"drizzle-orm";var D=Ud("projects",{id:so("id").primaryKey().defaultRandom(),orgId:so("org_id").references(()=>V.id,{onDelete:"cascade"}),name:oo("name").notNull(),description:oo("description"),githubRepo:oo("github_repo"),gitRemoteUrl:oo("git_remote_url"),gitRootCommit:oo("git_root_commit"),gitRemoteAliases:oo("git_remote_aliases").array().notNull().default([]),metadata:P0("metadata"),createdBy:so("created_by"),createdAt:ui("created_at",{withTimezone:!0}).defaultNow(),updatedAt:ui("updated_at",{withTimezone:!0}).defaultNow()},e=>[qd("projects_org_name_idx").on(e.orgId,e.name),qd("projects_git_remote_url_unique").on(e.gitRemoteUrl).where(O0`${e.gitRemoteUrl} IS NOT NULL`)]),at=Ud("project_instructions",{projectId:so("project_id").references(()=>D.id,{onDelete:"cascade"}).notNull(),instructionId:so("instruction_id").references(()=>_.id,{onDelete:"cascade"}).notNull(),addedAt:ui("added_at",{withTimezone:!0}).defaultNow(),addedBy:so("added_by")},e=>[jf({columns:[e.projectId,e.instructionId]})]),ue=Ud("project_checkouts",{projectId:so("project_id").references(()=>D.id,{onDelete:"cascade"}).notNull(),path:oo("path").notNull(),isWorktree:C0("is_worktree").notNull().default(!1),firstSeen:ui("first_seen",{withTimezone:!0}).notNull().defaultNow(),lastSeen:ui("last_seen",{withTimezone:!0}).notNull().defaultNow()},e=>[jf({columns:[e.projectId,e.path]}),qd("project_checkouts_path_unique").on(e.path)]);import{pgTable as Hd,text as an,timestamp as di,jsonb as io,uuid as ir,integer as ic,uniqueIndex as Cf,index as Hn}from"drizzle-orm/pg-core";import{pgTable as D0,text as Wo,timestamp as Bd,jsonb as Nf,uuid as sc,integer as M0,boolean as L0,index as Fd}from"drizzle-orm/pg-core";var J=D0("agent_runs",{id:sc("id").primaryKey().defaultRandom(),userId:sc("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),orgId:sc("org_id").references(()=>V.id,{onDelete:"set null"}),projectId:sc("project_id").references(()=>D.id,{onDelete:"set null"}),projectPath:Wo("project_path"),gitRemote:Wo("git_remote"),baseBranch:Wo("base_branch"),title:Wo("title"),prompt:Wo("prompt"),toolSpec:Nf("tool_spec").notNull().default([]),autoWorktree:L0("auto_worktree").notNull().default(!0),status:Wo("status").notNull().default("pending"),sessionCount:M0("session_count").notNull().default(0),metadata:Nf("metadata").notNull().default({}),createdAt:Bd("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:Bd("updated_at",{withTimezone:!0}).notNull().defaultNow(),completedAt:Bd("completed_at",{withTimezone:!0})},e=>[Fd("idx_agent_runs_user").on(e.userId),Fd("idx_agent_runs_org_created").on(e.orgId,e.createdAt),Fd("idx_agent_runs_project").on(e.projectId)]);var f=Hd("sessions",{id:ir("id").primaryKey().defaultRandom(),userId:ir("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),externalSessionId:an("external_session_id"),projectId:ir("project_id").references(()=>D.id,{onDelete:"set null"}),orgId:ir("org_id").references(()=>V.id,{onDelete:"set null"}),tool:an("tool").notNull(),projectPath:an("project_path"),gitBranch:an("git_branch"),startedAt:di("started_at",{withTimezone:!0}).notNull(),endedAt:di("ended_at",{withTimezone:!0}),eventCount:ic("event_count").default(0),tokenUsage:io("token_usage"),analysis:io("analysis"),analyzedAt:di("analyzed_at",{withTimezone:!0}),analyzedEventCount:ic("analyzed_event_count"),analyzedTurnCount:ic("analyzed_turn_count"),metadata:io("metadata").default({}),origin:an("origin").notNull().default("unknown"),runId:ir("run_id").references(()=>J.id,{onDelete:"set null"}),model:an("model"),harnessVersion:an("harness_version"),createdAt:di("created_at",{withTimezone:!0}).defaultNow()},e=>[Hn("idx_sessions_user").on(e.userId),Hn("idx_sessions_tool").on(e.tool),Hn("idx_sessions_started_at").on(e.startedAt),Hn("idx_sessions_project").on(e.projectId),Hn("idx_sessions_org_started_at").on(e.orgId,e.startedAt),Hn("idx_sessions_run").on(e.runId),Cf("idx_sessions_user_external").on(e.userId,e.externalSessionId)]),Le=Hd("session_events",{id:ir("id").primaryKey().defaultRandom(),sessionId:ir("session_id").notNull().references(()=>f.id,{onDelete:"cascade"}),sequence:ic("sequence").notNull(),eventType:an("event_type").notNull(),content:an("content"),toolName:an("tool_name"),toolInput:io("tool_input"),toolOutput:io("tool_output"),tokenUsage:io("token_usage"),model:an("model"),timestamp:di("timestamp",{withTimezone:!0}).notNull(),metadata:io("metadata").default({})},e=>[Cf("session_events_session_sequence_idx").on(e.sessionId,e.sequence),Hn("idx_session_events_session_id").on(e.sessionId),Hn("idx_session_events_event_type").on(e.eventType),Hn("idx_session_events_model").on(e.model)]),ne=Hd("session_instructions",{sessionId:ir("session_id").notNull().references(()=>f.id,{onDelete:"cascade"}),instructionId:ir("instruction_id").notNull().references(()=>_.id,{onDelete:"cascade"}),linkMethod:an("link_method").notNull(),contentHash:an("content_hash")},e=>[Hn("idx_session_instructions_instruction_id").on(e.instructionId)]);import{pgTable as Pf,text as ac,timestamp as Of,uuid as Wn,integer as Df,index as zo,unique as $0}from"drizzle-orm/pg-core";var Tt=Pf("treatment_assignments",{id:Wn("id").primaryKey().defaultRandom(),userId:Wn("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),treatmentType:ac("treatment_type").notNull(),treatmentId:Wn("treatment_id").notNull(),treatmentVersion:Df("treatment_version").notNull().default(1),projectId:Wn("project_id").references(()=>D.id,{onDelete:"set null"}),assignedBy:Wn("assigned_by").references(()=>R.id,{onDelete:"set null"}),method:ac("method").notNull(),assignedAt:Of("assigned_at",{withTimezone:!0}).notNull().defaultNow()},e=>[zo("idx_treatment_assignments_user").on(e.userId),zo("idx_treatment_assignments_treatment").on(e.treatmentType,e.treatmentId),zo("idx_treatment_assignments_project").on(e.projectId)]),X=Pf("treatment_exposures",{id:Wn("id").primaryKey().defaultRandom(),sessionId:Wn("session_id").notNull().references(()=>f.id,{onDelete:"cascade"}),userId:Wn("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),treatmentType:ac("treatment_type").notNull(),treatmentId:Wn("treatment_id").notNull(),treatmentVersion:Df("treatment_version").notNull().default(1),assignmentId:Wn("assignment_id").references(()=>Tt.id,{onDelete:"set null"}),method:ac("method").notNull(),exposedAt:Of("exposed_at",{withTimezone:!0}).notNull().defaultNow()},e=>[$0("treatment_exposures_unique").on(e.sessionId,e.treatmentType,e.treatmentId,e.treatmentVersion),zo("idx_treatment_exposures_treatment").on(e.treatmentType,e.treatmentId),zo("idx_treatment_exposures_user").on(e.userId),zo("idx_treatment_exposures_session").on(e.sessionId)]);import{pgTable as q0,text as Wd,timestamp as U0,uuid as cc,integer as B0,index as Mf,uniqueIndex as F0}from"drizzle-orm/pg-core";var uc=q0("pending_treatment_exposures",{id:cc("id").primaryKey().defaultRandom(),userId:cc("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),externalSessionId:Wd("external_session_id").notNull(),treatmentType:Wd("treatment_type").notNull(),treatmentId:cc("treatment_id").notNull(),treatmentVersion:B0("treatment_version").notNull().default(1),method:Wd("method").notNull().default("injected"),projectId:cc("project_id").references(()=>D.id,{onDelete:"set null"}),createdAt:U0("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[F0("pending_treatment_exposures_unique").on(e.externalSessionId,e.treatmentType,e.treatmentId,e.treatmentVersion),Mf("idx_pending_treatment_exposures_ext").on(e.externalSessionId),Mf("idx_pending_treatment_exposures_user").on(e.userId)]);import{pgTable as H0,text as Vo,timestamp as zd,uuid as li,integer as Lf,index as dc}from"drizzle-orm/pg-core";var $=H0("memories",{id:li("id").primaryKey().defaultRandom(),userId:li("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),orgId:li("org_id"),projectId:li("project_id").references(()=>D.id,{onDelete:"set null"}),version:Lf("version").notNull().default(1),parentId:li("parent_id").references(()=>$.id,{onDelete:"set null"}),kind:Vo("kind").notNull(),title:Vo("title").notNull(),body:Vo("body").notNull(),source:Vo("source").notNull(),status:Vo("status").notNull().default("active"),trustClass:Vo("trust_class"),trustVersion:Lf("trust_version"),trustComputedAt:zd("trust_computed_at",{withTimezone:!0}),createdAt:zd("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:zd("updated_at",{withTimezone:!0}).notNull().defaultNow()},e=>[dc("idx_memories_user").on(e.userId),dc("idx_memories_project").on(e.projectId),dc("idx_memories_parent").on(e.parentId),dc("idx_memories_user_status").on(e.userId,e.status)]);import{pgTable as W0,text as pi,timestamp as Vd,uuid as Jd,integer as $f,jsonb as z0,index as qf}from"drizzle-orm/pg-core";var Er=W0("memory_experiments",{id:Jd("id").primaryKey().defaultRandom(),memoryId:Jd("memory_id").notNull().references(()=>$.id,{onDelete:"cascade"}),userId:Jd("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),memoryVersion:$f("memory_version").notNull().default(1),taskPrompt:pi("task_prompt").notNull(),expectations:pi("expectations").array().notNull().default([]),trials:$f("trials").notNull().default(10),model:pi("model"),status:pi("status").notNull().default("pending"),result:z0("result").$type(),error:pi("error"),createdAt:Vd("created_at",{withTimezone:!0}).notNull().defaultNow(),startedAt:Vd("started_at",{withTimezone:!0}),completedAt:Vd("completed_at",{withTimezone:!0})},e=>[qf("idx_memory_experiments_memory").on(e.memoryId),qf("idx_memory_experiments_user").on(e.userId)]);import{pgTable as V0,text as Jo,timestamp as Gd,uuid as Kd,jsonb as J0,uniqueIndex as G0,index as Uf}from"drizzle-orm/pg-core";var We=V0("session_terminal_targets",{id:Kd("id").primaryKey().defaultRandom(),userId:Kd("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),sessionId:Kd("session_id").references(()=>f.id,{onDelete:"set null"}),externalSessionId:Jo("external_session_id"),kind:Jo("kind").notNull(),target:Jo("target").notNull(),status:Jo("status").notNull().default("active"),attachCommand:Jo("attach_command").notNull(),projectPath:Jo("project_path"),metadata:J0("metadata").notNull().default({}),lastSeenAt:Gd("last_seen_at",{withTimezone:!0}).defaultNow(),createdAt:Gd("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Gd("updated_at",{withTimezone:!0}).defaultNow()},e=>[G0("idx_session_terminal_targets_user_target").on(e.userId,e.target),Uf("idx_session_terminal_targets_session").on(e.sessionId),Uf("idx_session_terminal_targets_user_status").on(e.userId,e.status)]);import{boolean as K0,index as lc,jsonb as Bf,pgTable as Y0,text as ao,timestamp as mi,uuid as pc,integer as Ff}from"drizzle-orm/pg-core";var mc=Y0("session_send_jobs",{id:pc("id").primaryKey().defaultRandom(),userId:pc("user_id").notNull(),sessionId:pc("session_id").notNull().references(()=>f.id,{onDelete:"cascade"}),terminalTargetId:pc("terminal_target_id").references(()=>We.id,{onDelete:"set null"}),target:ao("target").notNull(),message:ao("message").notNull(),submit:K0("submit").notNull().default(!0),delivery:ao("delivery").notNull().default("live"),status:ao("status").notNull().default("pending"),result:Bf("result"),error:ao("error"),attempts:Ff("attempts").notNull().default(0),taskKind:ao("task_kind"),payload:Bf("payload"),claimedBy:ao("claimed_by"),claimedAt:mi("claimed_at",{withTimezone:!0}),leaseExpiresAt:mi("lease_expires_at",{withTimezone:!0}),leaseRecoveries:Ff("lease_recoveries").notNull().default(0),createdAt:mi("created_at",{withTimezone:!0}).defaultNow(),updatedAt:mi("updated_at",{withTimezone:!0}).defaultNow(),completedAt:mi("completed_at",{withTimezone:!0})},e=>[lc("idx_session_send_jobs_user").on(e.userId),lc("idx_session_send_jobs_session").on(e.sessionId),lc("idx_session_send_jobs_status").on(e.status),lc("idx_session_send_jobs_pending").on(e.userId,e.status)]);import{pgTable as Wf,text as co,timestamp as fc,jsonb as zf,uuid as Tr,integer as X0,boolean as Q0,uniqueIndex as Z0,index as Hf,primaryKey as eb}from"drizzle-orm/pg-core";var Re=Wf("packs",{id:Tr("id").primaryKey().defaultRandom(),name:co("name").notNull(),description:co("description").notNull(),scope:co("scope").notNull(),scopeRef:Tr("scope_ref"),version:co("version").notNull().default("1.0.0"),tags:co("tags").array(),badge:co("badge"),metadata:zf("metadata"),createdBy:Tr("created_by"),createdAt:fc("created_at",{withTimezone:!0}).defaultNow(),updatedAt:fc("updated_at",{withTimezone:!0}).defaultNow(),archived:Q0("archived").default(!1),archivedAt:fc("archived_at",{withTimezone:!0}),archivedBy:Tr("archived_by"),forkedFromId:Tr("forked_from_id").references(()=>Re.id,{onDelete:"set null"}),upstreamVersion:co("upstream_version")},e=>[Z0("packs_name_scope_ref_idx").on(e.name,e.scope,e.scopeRef),Hf("idx_packs_scope").on(e.scope,e.scopeRef),Hf("idx_packs_created_by").on(e.createdBy)]),Ee=Wf("pack_instructions",{packId:Tr("pack_id").references(()=>Re.id,{onDelete:"cascade"}).notNull(),instructionId:Tr("instruction_id").references(()=>_.id,{onDelete:"cascade"}).notNull(),position:X0("position").notNull().default(0),slotOverrides:zf("slot_overrides"),addedAt:fc("added_at",{withTimezone:!0}).defaultNow(),addedBy:Tr("added_by")},e=>[eb({columns:[e.packId,e.instructionId]})]);import{pgTable as tb,text as Yd,timestamp as nb,jsonb as rb,uuid as Xd,index as Go}from"drizzle-orm/pg-core";var Rr=tb("instruction_usage_events",{id:Xd("id").primaryKey().defaultRandom(),instructionId:Xd("instruction_id").references(()=>_.id,{onDelete:"set null"}),userId:Xd("user_id").notNull(),surface:Yd("surface").notNull(),action:Yd("action").notNull(),metadata:rb("metadata"),traceId:Yd("trace_id"),createdAt:nb("created_at",{withTimezone:!0}).defaultNow()},e=>[Go("idx_usage_events_instruction").on(e.instructionId),Go("idx_usage_events_user").on(e.userId),Go("idx_usage_events_surface").on(e.surface),Go("idx_usage_events_action").on(e.action),Go("idx_usage_events_created_at").on(e.createdAt),Go("idx_usage_events_user_created").on(e.userId,e.createdAt)]);import{pgTable as ob,text as gc,timestamp as Vf,jsonb as sb,uuid as Jf,index as Qd}from"drizzle-orm/pg-core";var ve=ob("worker_connections",{id:Jf("id").primaryKey().defaultRandom(),userId:Jf("user_id").notNull(),workerType:gc("worker_type").notNull().default("mcp"),clientName:gc("client_name").notNull(),clientVersion:gc("client_version"),workerVersion:gc("worker_version"),lastHeartbeat:Vf("last_heartbeat",{withTimezone:!0}).notNull().defaultNow(),connectedAt:Vf("connected_at",{withTimezone:!0}).notNull().defaultNow(),metadata:sb("metadata")},e=>[Qd("idx_worker_connections_user").on(e.userId),Qd("idx_worker_connections_heartbeat").on(e.userId,e.lastHeartbeat),Qd("idx_worker_connections_type").on(e.userId,e.workerType)]);import{pgTable as ib,text as hc,timestamp as ab,jsonb as cb,uuid as Gf,index as Kf}from"drizzle-orm/pg-core";var _c=ib("cli_setup_events",{id:Gf("id").primaryKey().defaultRandom(),userId:Gf("user_id").notNull(),deviceId:hc("device_id").notNull(),event:hc("event").notNull(),cliVersion:hc("cli_version"),os:hc("os"),props:cb("props").notNull().default({}),createdAt:ab("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Kf("idx_cli_setup_events_user").on(e.userId,e.createdAt),Kf("idx_cli_setup_events_device").on(e.deviceId,e.createdAt)]);import{pgTable as ub,text as uo,integer as db,boolean as lb,timestamp as pb,jsonb as mb,uuid as fb,index as Yf}from"drizzle-orm/pg-core";var yc=ub("cli_error_events",{id:fb("id").primaryKey().defaultRandom(),deviceId:uo("device_id"),event:uo("event").notNull(),command:uo("command"),statusCode:db("status_code"),message:uo("message"),cliVersion:uo("cli_version"),os:uo("os"),nodeVersion:uo("node_version"),proxied:lb("proxied"),props:mb("props").notNull().default({}),createdAt:pb("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Yf("idx_cli_error_events_created").on(e.createdAt),Yf("idx_cli_error_events_device").on(e.deviceId,e.createdAt)]);import{sql as gb}from"drizzle-orm";import{pgTable as lo,text as mt,timestamp as Zt,jsonb as gn,uuid as ct,integer as ar,boolean as fi,index as Wt,unique as Xf}from"drizzle-orm/pg-core";var k=lo("eval_targets",{id:ct("id").primaryKey().defaultRandom(),userId:ct("user_id").notNull(),name:mt("name").notNull(),type:mt("type").notNull(),content:mt("content").notNull(),description:mt("description").notNull().default(""),metadata:gn("metadata").notNull().default({}),version:ar("version").notNull().default(1),parentId:ct("parent_id").references(()=>k.id,{onDelete:"set null"}),createdAt:Zt("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Zt("updated_at",{withTimezone:!0}).defaultNow()},e=>[Wt("eval_targets_name_user_idx").on(e.name,e.userId),Wt("idx_eval_targets_user").on(e.userId),Wt("idx_eval_targets_type").on(e.type),Wt("idx_eval_targets_parent").on(e.parentId)]),_e=lo("evals",{id:ct("id").primaryKey().defaultRandom(),evalTargetId:ct("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),name:mt("name").notNull(),prompt:mt("prompt").notNull(),expectedOutput:mt("expected_output").notNull().default(""),files:gn("files").notNull().default([]),expectations:gn("expectations").notNull().default([]),retiredAt:Zt("retired_at",{withTimezone:!0}),retiredReason:mt("retired_reason"),createdAt:Zt("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Zt("updated_at",{withTimezone:!0}).defaultNow(),contentUpdatedAt:Zt("content_updated_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Wt("idx_evals_target").on(e.evalTargetId),Wt("idx_evals_target_active").on(e.evalTargetId).where(gb`${e.retiredAt} IS NULL`)]),ye=lo("eval_runs",{id:ct("id").primaryKey().defaultRandom(),jobId:ct("job_id"),evalId:ct("eval_id").notNull().references(()=>_e.id,{onDelete:"cascade"}),evalTargetId:ct("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),evalTargetVersion:ar("eval_target_version").notNull(),configuration:mt("configuration").notNull(),runNumber:ar("run_number").notNull().default(1),iteration:ar("iteration").notNull().default(1),status:mt("status").notNull().default("completed"),outputs:gn("outputs").notNull().default({}),timing:gn("timing").notNull().default({}),grading:gn("grading").notNull().default({}),comparison:gn("comparison"),createdAt:Zt("created_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_eval_runs_eval").on(e.evalId),Wt("idx_eval_runs_target").on(e.evalTargetId),Wt("idx_eval_runs_iteration").on(e.evalTargetId,e.iteration)]),Ke=lo("eval_comparisons",{id:ct("id").primaryKey().defaultRandom(),userId:ct("user_id").notNull(),targetAId:ct("target_a_id").notNull().references(()=>k.id,{onDelete:"cascade"}),targetBId:ct("target_b_id").notNull().references(()=>k.id,{onDelete:"cascade"}),targetAVersion:ar("target_a_version").notNull(),targetBVersion:ar("target_b_version").notNull(),isSwapped:fi("is_swapped").notNull().default(!1),winnerTargetId:ct("winner_target_id").references(()=>k.id,{onDelete:"set null"}),perEval:gn("per_eval").notNull().default([]),overall:gn("overall").notNull().default({}),rawOutput:mt("raw_output"),model:mt("model"),status:mt("status").notNull().default("completed"),createdAt:Zt("created_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_eval_comparisons_target_a").on(e.targetAId),Wt("idx_eval_comparisons_target_b").on(e.targetBId),Wt("idx_eval_comparisons_user").on(e.userId)]),ze=lo("eval_grade_annotations",{id:ct("id").primaryKey().defaultRandom(),userId:ct("user_id").notNull(),evalRunId:ct("eval_run_id").notNull().references(()=>ye.id,{onDelete:"cascade"}),evalTargetId:ct("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),expectationIndex:ar("expectation_index").notNull(),expectationText:mt("expectation_text").notNull(),judgePassed:fi("judge_passed").notNull(),judgeMethod:mt("judge_method").notNull(),judgeModel:mt("judge_model"),verdict:mt("verdict").notNull(),flag:mt("flag"),note:mt("note"),createdAt:Zt("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Zt("updated_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_eval_grade_annotations_target").on(e.evalTargetId),Wt("idx_eval_grade_annotations_run").on(e.evalRunId),Xf("eval_grade_annotations_eval_run_id_expectation_index_key").on(e.evalRunId,e.expectationIndex)]),ce=lo("judge_reviewer_verdicts",{id:ct("id").primaryKey().defaultRandom(),userId:ct("user_id").notNull(),evalTargetId:ct("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),evalRunId:ct("eval_run_id").notNull().references(()=>ye.id,{onDelete:"cascade"}),expectationIndex:ar("expectation_index").notNull(),expectationText:mt("expectation_text").notNull(),judgePassed:fi("judge_passed").notNull(),humanPassed:fi("human_passed").notNull(),reviewerEngine:mt("reviewer_engine").notNull(),reviewerModel:mt("reviewer_model").notNull(),reviewerPassed:fi("reviewer_passed").notNull(),resolvedAt:Zt("resolved_at",{withTimezone:!0}),resolution:mt("resolution"),createdAt:Zt("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Zt("updated_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_jrv_target").on(e.evalTargetId),Xf("judge_reviewer_verdicts_eval_run_id_expectation_index_review_key").on(e.evalRunId,e.expectationIndex,e.reviewerModel)]),kn=lo("benchmarks",{id:ct("id").primaryKey().defaultRandom(),evalTargetId:ct("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),iteration:ar("iteration").notNull().default(1),runSummary:gn("run_summary").notNull().default({}),notes:gn("notes").notNull().default([]),feedback:gn("feedback"),createdAt:Zt("created_at",{withTimezone:!0}).defaultNow()},e=>[Wt("idx_benchmarks_target").on(e.evalTargetId)]);import{sql as Zd}from"drizzle-orm";import{pgTable as hb,text as cr,timestamp as _b,jsonb as wc,uuid as vc,boolean as yb,index as gi,uniqueIndex as wb}from"drizzle-orm/pg-core";var Ne=hb("instruction_promotions",{id:vc("id").primaryKey().defaultRandom(),userId:vc("user_id").notNull(),evalTargetId:vc("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),instructionId:vc("instruction_id").references(()=>_.id,{onDelete:"set null"}),fromContentHash:cr("from_content_hash").notNull(),toContentHash:cr("to_content_hash").notNull(),fromContent:cr("from_content").notNull(),toContent:cr("to_content").notNull(),proposalSource:cr("proposal_source").notNull(),proposalRationale:cr("proposal_rationale").notNull().default(""),decision:cr("decision").notNull(),applied:yb("applied").notNull().default(!1),refusals:wc("refusals").notNull().default([]),rationale:cr("rationale").notNull().default(""),effectClass:cr("effect_class").notNull(),verdict:wc("verdict").notNull().default({}),gates:wc("gates").notNull().default({}),touchedSections:wc("touched_sections").notNull().default([]),createdAt:_b("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[gi("idx_instruction_promotions_budget").on(e.evalTargetId,e.createdAt.desc()).where(Zd`${e.applied}`),gi("idx_instruction_promotions_target").on(e.evalTargetId,e.createdAt.desc()),gi("idx_instruction_promotions_user").on(e.userId,e.createdAt.desc()),gi("idx_instruction_promotions_to_hash").on(e.toContentHash),wb("uq_instruction_promotions_applied").on(e.evalTargetId,e.fromContentHash,e.toContentHash).where(Zd`${e.applied}`),gi("idx_instruction_promotions_applied_hash").on(e.toContentHash,e.createdAt.desc()).where(Zd`${e.applied}`)]);import{pgTable as Zf,text as el,timestamp as tl,jsonb as eg,uuid as Ko,integer as hi,index as Ic,real as Qf}from"drizzle-orm/pg-core";var Ct=Zf("trigger_evals",{id:Ko("id").primaryKey().defaultRandom(),evalTargetId:Ko("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),userId:Ko("user_id").notNull(),queries:eg("queries").notNull().default([]),status:el("status").notNull().default("pending_review"),trainIndices:hi("train_indices").array().default([]),testIndices:hi("test_indices").array().default([]),createdAt:tl("created_at",{withTimezone:!0}).defaultNow(),updatedAt:tl("updated_at",{withTimezone:!0}).defaultNow()},e=>[Ic("idx_trigger_evals_target").on(e.evalTargetId),Ic("idx_trigger_evals_user").on(e.userId)]),hn=Zf("optimization_runs",{id:Ko("id").primaryKey().defaultRandom(),evalTargetId:Ko("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),userId:Ko("user_id").notNull(),type:el("type").notNull(),iteration:hi("iteration").notNull(),inputVersion:hi("input_version").notNull(),outputVersion:hi("output_version"),trainScore:Qf("train_score"),testScore:Qf("test_score"),analysis:eg("analysis").notNull().default({}),status:el("status").notNull().default("running"),createdAt:tl("created_at",{withTimezone:!0}).defaultNow()},e=>[Ic("idx_optimization_runs_target").on(e.evalTargetId),Ic("idx_optimization_runs_user").on(e.userId)]);import{pgTable as vb,text as kr,timestamp as Ib,jsonb as _i,uuid as nl,integer as rl,real as bb,index as yi,uniqueIndex as tg}from"drizzle-orm/pg-core";var C=vb("context_snapshots",{id:nl("id").primaryKey().defaultRandom(),sessionId:nl("session_id").references(()=>f.id,{onDelete:"cascade"}),userId:nl("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),sequence:rl("sequence").notNull().default(0),provider:kr("provider").notNull(),model:kr("model").notNull(),systemPrompt:kr("system_prompt").notNull(),injectedInstructions:_i("injected_instructions").notNull().default([]),messagesSummary:_i("messages_summary").notNull(),tools:_i("tools").notNull().default([]),systemHash:kr("system_hash").notNull(),requestHash:kr("request_hash").notNull().default(""),toolsHash:kr("tools_hash"),injectedHash:kr("injected_hash"),messagesDelta:_i("messages_delta").default([]),messagesDeltaRef:kr("messages_delta_ref"),maxTokens:rl("max_tokens"),temperature:bb("temperature"),estimatedTokens:rl("estimated_tokens"),capturedAt:Ib("captured_at",{withTimezone:!0}).notNull().defaultNow(),metadata:_i("metadata").default({})},e=>[yi("idx_context_snapshots_session").on(e.sessionId),yi("idx_context_snapshots_user").on(e.userId),yi("idx_context_snapshots_hash").on(e.systemHash),yi("idx_context_snapshots_request_hash").on(e.requestHash),tg("idx_snapshots_session_request").on(e.sessionId,e.requestHash),tg("idx_snapshots_session_sequence").on(e.sessionId,e.sequence),yi("idx_context_snapshots_user_session_captured").on(e.userId,e.sessionId,e.capturedAt.desc())]);import{pgTable as Sb,text as ng,timestamp as Ab,jsonb as xb,integer as Eb,index as Tb}from"drizzle-orm/pg-core";var cn=Sb("content_blobs",{hash:ng("hash").primaryKey(),contentType:ng("content_type").notNull(),content:xb("content").notNull(),sizeBytes:Eb("size_bytes").notNull().default(0),createdAt:Ab("created_at",{withTimezone:!0}).defaultNow()},e=>[Tb("idx_content_blobs_type").on(e.contentType)]);import{pgTable as Rb,text as bc,timestamp as wi,jsonb as Sc,uuid as ol,index as Ac,integer as rg}from"drizzle-orm/pg-core";var Se=Rb("eval_jobs",{id:ol("id").primaryKey().defaultRandom(),userId:ol("user_id").notNull(),evalTargetId:ol("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),status:bc("status").notNull().default("pending"),config:Sc("config").notNull().default({}),progress:Sc("progress").notNull().default({}),result:Sc("result"),error:bc("error"),attempts:rg("attempts").notNull().default(0),taskKind:bc("task_kind"),payload:Sc("payload"),claimedBy:bc("claimed_by"),claimedAt:wi("claimed_at",{withTimezone:!0}),leaseExpiresAt:wi("lease_expires_at",{withTimezone:!0}),leaseRecoveries:rg("lease_recoveries").notNull().default(0),createdAt:wi("created_at",{withTimezone:!0}).defaultNow(),updatedAt:wi("updated_at",{withTimezone:!0}).defaultNow(),completedAt:wi("completed_at",{withTimezone:!0})},e=>[Ac("idx_eval_jobs_user").on(e.userId),Ac("idx_eval_jobs_target").on(e.evalTargetId),Ac("idx_eval_jobs_status").on(e.status),Ac("idx_eval_jobs_pending").on(e.userId,e.status)]);import{pgTable as kb,text as vi,timestamp as Ii,jsonb as og,uuid as sg,integer as ig,index as ag}from"drizzle-orm/pg-core";var be=kb("agent_jobs",{id:sg("id").primaryKey().defaultRandom(),userId:sg("user_id").notNull(),taskKind:vi("task_kind").notNull(),status:vi("status").notNull().default("pending"),payload:og("payload").notNull(),dedupeKey:vi("dedupe_key"),result:og("result"),error:vi("error"),attempts:ig("attempts").notNull().default(0),claimedBy:vi("claimed_by"),claimedAt:Ii("claimed_at",{withTimezone:!0}),leaseExpiresAt:Ii("lease_expires_at",{withTimezone:!0}),leaseRecoveries:ig("lease_recoveries").notNull().default(0),createdAt:Ii("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:Ii("updated_at",{withTimezone:!0}).notNull().defaultNow(),completedAt:Ii("completed_at",{withTimezone:!0})},e=>[ag("idx_agent_jobs_claim").on(e.userId,e.status,e.taskKind,e.createdAt),ag("idx_agent_jobs_dedupe").on(e.userId,e.taskKind,e.dedupeKey)]);import{pgTable as jb,text as bi,timestamp as Si,jsonb as xc,uuid as sl,index as Ec,integer as cg}from"drizzle-orm/pg-core";var W=jb("insights_jobs",{id:sl("id").primaryKey().defaultRandom(),userId:sl("user_id").notNull(),status:bi("status").notNull().default("pending"),projectPath:bi("project_path"),projectId:sl("project_id").references(()=>D.id,{onDelete:"set null"}),config:xc("config").notNull().default({}),progress:xc("progress").notNull().default({}),result:xc("result"),error:bi("error"),attempts:cg("attempts").notNull().default(0),taskKind:bi("task_kind"),payload:xc("payload"),claimedBy:bi("claimed_by"),claimedAt:Si("claimed_at",{withTimezone:!0}),leaseExpiresAt:Si("lease_expires_at",{withTimezone:!0}),leaseRecoveries:cg("lease_recoveries").notNull().default(0),createdAt:Si("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Si("updated_at",{withTimezone:!0}).defaultNow(),completedAt:Si("completed_at",{withTimezone:!0})},e=>[Ec("idx_insights_jobs_user").on(e.userId),Ec("idx_insights_jobs_status").on(e.status),Ec("idx_insights_jobs_pending").on(e.userId,e.status),Ec("idx_insights_jobs_project").on(e.projectId)]);import{pgTable as Nb,text as il,timestamp as Tc,uuid as ug,index as Cb,uniqueIndex as Pb}from"drizzle-orm/pg-core";var we=Nb("api_keys",{id:ug("id").primaryKey().defaultRandom(),userId:ug("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),name:il("name").notNull(),keyHash:il("key_hash").notNull(),keyPrefix:il("key_prefix").notNull(),lastUsedAt:Tc("last_used_at",{withTimezone:!0}),expiresAt:Tc("expires_at",{withTimezone:!0}),revokedAt:Tc("revoked_at",{withTimezone:!0}),createdAt:Tc("created_at",{withTimezone:!0}).defaultNow()},e=>[Cb("idx_api_keys_user").on(e.userId),Pb("idx_api_keys_hash").on(e.keyHash)]);import{pgTable as Ob,text as al,timestamp as dg,uuid as Db,index as Mb}from"drizzle-orm/pg-core";var _n=Ob("extension_auth_codes",{code:al("code").primaryKey(),userId:Db("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),editor:al("editor"),email:al("email"),expiresAt:dg("expires_at",{withTimezone:!0}).notNull(),createdAt:dg("created_at",{withTimezone:!0}).defaultNow()},e=>[Mb("idx_ext_auth_codes_expiry").on(e.expiresAt)]);import{pgTable as Lb,text as $b,timestamp as lg,jsonb as qb,uuid as cl,index as pg}from"drizzle-orm/pg-core";var ke=Lb("eval_conversations",{id:cl("id").primaryKey().defaultRandom(),evalTargetId:cl("eval_target_id").notNull().references(()=>k.id,{onDelete:"cascade"}),userId:cl("user_id").notNull(),messages:qb("messages").notNull().default([]),status:$b("status").notNull().default("active"),createdAt:lg("created_at",{withTimezone:!0}).defaultNow(),updatedAt:lg("updated_at",{withTimezone:!0}).defaultNow()},e=>[pg("idx_eval_conversations_target").on(e.evalTargetId),pg("idx_eval_conversations_user").on(e.userId)]);import{pgTable as Ub,text as ur,timestamp as mg,jsonb as Bb,uuid as ul}from"drizzle-orm/pg-core";var jr=Ub("skill_submissions",{id:ul("id").primaryKey().defaultRandom(),skillId:ur("skill_id").notNull(),name:ur("name").notNull(),description:ur("description").notNull(),category:ur("category").notNull(),tools:ur("tools").array().notNull(),tags:ur("tags").array().default([]),content:ur("content").notNull(),status:ur("status").notNull().default("pending"),submittedBy:ul("submitted_by").notNull(),reviewedBy:ul("reviewed_by"),reviewNote:ur("review_note"),metadata:Bb("metadata"),createdAt:mg("created_at",{withTimezone:!0}).defaultNow(),updatedAt:mg("updated_at",{withTimezone:!0}).defaultNow()});import{pgTable as Fb,text as Ai,timestamp as fg,jsonb as Hb,uuid as Wb,uniqueIndex as zb,index as gg}from"drizzle-orm/pg-core";var Rt=Fb("harness_releases",{id:Wb("id").primaryKey().defaultRandom(),harness:Ai("harness").notNull(),version:Ai("version").notNull(),publishedAt:fg("published_at",{withTimezone:!0}).notNull(),title:Ai("title"),body:Ai("body"),categories:Hb("categories").default({}),url:Ai("url"),createdAt:fg("created_at",{withTimezone:!0}).defaultNow()},e=>[zb("idx_harness_releases_unique").on(e.harness,e.version),gg("idx_harness_releases_harness").on(e.harness),gg("idx_harness_releases_published").on(e.publishedAt)]);import{pgTable as Vb,text as Yo,timestamp as hg,jsonb as Jb,uuid as _g,index as yg,uniqueIndex as Gb}from"drizzle-orm/pg-core";var ht=Vb("notifications",{id:_g("id").primaryKey().defaultRandom(),userId:_g("user_id").notNull(),type:Yo("type").notNull(),title:Yo("title").notNull(),body:Yo("body"),url:Yo("url"),sourceTable:Yo("source_table"),sourceId:Yo("source_id"),metadata:Jb("metadata").notNull().default({}),readAt:hg("read_at",{withTimezone:!0}),createdAt:hg("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[yg("idx_notifications_user_created").on(e.userId,e.createdAt),yg("idx_notifications_user_unread").on(e.userId),Gb("idx_notifications_source_dedup").on(e.userId,e.sourceTable,e.sourceId)]);import{pgTable as Kb,text as xi,timestamp as Ei,jsonb as dl,uuid as ll,index as Rc,integer as wg}from"drizzle-orm/pg-core";var oe=Kb("launch_jobs",{id:ll("id").primaryKey().defaultRandom(),userId:ll("user_id").notNull(),tool:xi("tool").notNull(),status:xi("status").notNull().default("pending"),config:dl("config").notNull().default({}),result:dl("result"),error:xi("error"),attempts:wg("attempts").notNull().default(0),taskKind:xi("task_kind"),payload:dl("payload"),claimedBy:xi("claimed_by"),claimedAt:Ei("claimed_at",{withTimezone:!0}),leaseExpiresAt:Ei("lease_expires_at",{withTimezone:!0}),leaseRecoveries:wg("lease_recoveries").notNull().default(0),createdAt:Ei("created_at",{withTimezone:!0}).defaultNow(),updatedAt:Ei("updated_at",{withTimezone:!0}).defaultNow(),completedAt:Ei("completed_at",{withTimezone:!0}),runId:ll("run_id").references(()=>J.id,{onDelete:"set null"})},e=>[Rc("idx_launch_jobs_user").on(e.userId),Rc("idx_launch_jobs_status").on(e.status),Rc("idx_launch_jobs_pending").on(e.userId,e.status),Rc("idx_launch_jobs_run").on(e.runId)]);import{pgTable as vg,uuid as dr,text as Xo,real as Yb,timestamp as kc,boolean as Xb,uniqueIndex as Qb,index as Ti}from"drizzle-orm/pg-core";var jc=["add","remove","trim"],q=vg("instruction_suggestions",{id:dr("id").primaryKey().defaultRandom(),userId:dr("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),instructionId:dr("instruction_id").notNull().references(()=>_.id,{onDelete:"cascade"}),projectPath:Xo("project_path").notNull(),projectId:dr("project_id").references(()=>D.id,{onDelete:"set null"}),score:Yb("score").notNull(),reason:Xo("reason").notNull(),kind:Xo("kind").$type().notNull().default("add"),generatedAt:kc("generated_at",{withTimezone:!0}).notNull().defaultNow(),isStale:Xb("is_stale").notNull().default(!1),dismissedAt:kc("dismissed_at",{withTimezone:!0}),acceptedAt:kc("accepted_at",{withTimezone:!0}),promotedToInstructionId:dr("promoted_to_instruction_id").references(()=>_.id,{onDelete:"set null"})},e=>[Qb("idx_instruction_suggestions_user_project_instruction_kind").on(e.userId,e.projectPath,e.instructionId,e.kind),Ti("idx_instruction_suggestions_user_project").on(e.userId,e.projectPath),Ti("idx_instruction_suggestions_user_proj_id").on(e.userId,e.projectId),Ti("idx_instruction_suggestions_generated_at").on(e.generatedAt)]),zt=vg("instruction_suggestion_events",{id:dr("id").primaryKey().defaultRandom(),suggestionId:dr("suggestion_id").notNull().references(()=>q.id,{onDelete:"cascade"}),userId:dr("user_id").notNull().references(()=>R.id,{onDelete:"cascade"}),eventType:Xo("event_type").notNull(),tool:Xo("tool"),sessionId:dr("session_id"),projectPath:Xo("project_path").notNull(),createdAt:kc("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[Ti("idx_instruction_suggestion_events_suggestion_id").on(e.suggestionId),Ti("idx_instruction_suggestion_events_user_id").on(e.userId)]);import{pgTable as Zb,text as pl,integer as eS,numeric as Ri,timestamp as ml,index as tS,primaryKey as nS}from"drizzle-orm/pg-core";var Ye=Zb("model_pricing",{provider:pl("provider").notNull(),modelId:pl("model_id").notNull(),inputPerM:Ri("input_per_m").notNull(),outputPerM:Ri("output_per_m").notNull(),cacheReadPerM:Ri("cache_read_per_m").notNull(),cacheWrite5mPerM:Ri("cache_write_5m_per_m").notNull(),cacheWrite1hPerM:Ri("cache_write_1h_per_m").notNull(),contextWindow:eS("context_window"),effectiveFrom:ml("effective_from",{withTimezone:!0}).notNull(),effectiveUntil:ml("effective_until",{withTimezone:!0}),source:pl("source").notNull(),verifiedAt:ml("verified_at",{withTimezone:!0})},e=>[nS({columns:[e.provider,e.modelId,e.effectiveFrom]}),tS("idx_model_pricing_active").on(e.provider,e.modelId,e.effectiveFrom.desc())]);import{pgTable as rS,text as po,numeric as Ig,timestamp as bg,uuid as Sg,jsonb as oS,index as Ag}from"drizzle-orm/pg-core";var pe=rS("limit_observations",{id:Sg("id").primaryKey().defaultRandom(),observedAt:bg("observed_at",{withTimezone:!0}).notNull().defaultNow(),provider:po("provider").notNull(),plan:po("plan").notNull(),limitType:po("limit_type").notNull(),value:Ig("value").notNull(),unit:po("unit").notNull(),comparator:po("comparator").notNull().default("="),resetsAt:bg("resets_at",{withTimezone:!0}),sourceType:po("source_type").notNull(),sourceUrl:po("source_url"),sourceEvidence:oS("source_evidence"),confidence:Ig("confidence").notNull(),userId:Sg("user_id")},e=>[Ag("idx_limit_obs_lookup").on(e.provider,e.plan,e.limitType,e.observedAt.desc()),Ag("idx_limit_obs_user").on(e.userId,e.observedAt.desc())]);import{pgTable as sS,text as Nc,timestamp as iS,uuid as aS,jsonb as cS,boolean as uS,uniqueIndex as dS}from"drizzle-orm/pg-core";var bt=sS("provider_docs_snapshots",{id:aS("id").primaryKey().defaultRandom(),fetchedAt:iS("fetched_at",{withTimezone:!0}).notNull().defaultNow(),provider:Nc("provider").notNull(),docUrl:Nc("doc_url").notNull(),contentHash:Nc("content_hash").notNull(),content:Nc("content").notNull(),parseSuccess:uS("parse_success").notNull(),parseErrors:cS("parse_errors")},e=>[dS("idx_docs_dedup").on(e.provider,e.docUrl,e.contentHash)]);import{pgTable as lS,text as Cc,numeric as xg,timestamp as Eg,uuid as pS,primaryKey as mS,index as fS}from"drizzle-orm/pg-core";var Ve=lS("plan_limits_active",{provider:Cc("provider").notNull(),plan:Cc("plan").notNull(),limitType:Cc("limit_type").notNull(),value:xg("value").notNull(),unit:Cc("unit").notNull(),effectiveFrom:Eg("effective_from",{withTimezone:!0}).notNull(),effectiveUntil:Eg("effective_until",{withTimezone:!0}),confidence:xg("confidence").notNull(),sourceObservationIds:pS("source_observation_ids").array().notNull()},e=>[mS({columns:[e.provider,e.plan,e.limitType,e.effectiveFrom]}),fS("idx_plan_limits_lookup").on(e.provider,e.plan,e.limitType,e.effectiveFrom.desc())]);import{pgTable as gS,text as fl,timestamp as hS,uuid as Tg,jsonb as _S,index as yS}from"drizzle-orm/pg-core";var un=gS("alert_dispatches",{id:Tg("id").primaryKey().defaultRandom(),userId:Tg("user_id").notNull(),alertKey:fl("alert_key").notNull(),severity:fl("severity").notNull(),lastDispatchedAt:hS("last_dispatched_at",{withTimezone:!0}).notNull().defaultNow(),lastState:_S("last_state").notNull(),channel:fl("channel").notNull()},e=>[yS("idx_alert_user_key").on(e.userId,e.alertKey,e.lastDispatchedAt.desc())]);import{boolean as wS,date as vS,index as gl,integer as IS,jsonb as bS,pgTable as hl,text as jn,timestamp as Nr,uniqueIndex as SS,uuid as Qo}from"drizzle-orm/pg-core";var Je=hl("announcements",{id:Qo("id").primaryKey().defaultRandom(),version:jn("version").notNull().unique(),releaseDate:vS("release_date").notNull(),subject:jn("subject").notNull(),htmlBody:jn("html_body").notNull(),textBody:jn("text_body").notNull(),sections:bS("sections").notNull().default({}),status:jn("status").notNull().default("draft"),recipientCount:IS("recipient_count"),sentAt:Nr("sent_at",{withTimezone:!0}),sentBy:Qo("sent_by"),error:jn("error"),createdAt:Nr("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:Nr("updated_at",{withTimezone:!0}).notNull().defaultNow()},e=>[gl("idx_announcements_status").on(e.status),gl("idx_announcements_created").on(e.createdAt)]),mo=hl("announcement_deliveries",{id:Qo("id").primaryKey().defaultRandom(),announcementId:Qo("announcement_id").notNull(),userId:Qo("user_id").notNull(),email:jn("email").notNull(),status:jn("status").notNull().default("pending"),providerId:jn("provider_id"),error:jn("error"),sentAt:Nr("sent_at",{withTimezone:!0}),createdAt:Nr("created_at",{withTimezone:!0}).notNull().defaultNow()},e=>[SS("uniq_announcement_deliveries_announcement_user").on(e.announcementId,e.userId),gl("idx_announcement_deliveries_user").on(e.userId,e.createdAt)]),en=hl("notification_preferences",{userId:Qo("user_id").primaryKey(),productAnnouncements:wS("product_announcements").notNull().default(!0),unsubscribeToken:jn("unsubscribe_token").notNull().unique(),unsubscribedAt:Nr("unsubscribed_at",{withTimezone:!0}),createdAt:Nr("created_at",{withTimezone:!0}).notNull().defaultNow(),updatedAt:Nr("updated_at",{withTimezone:!0}).notNull().defaultNow()});import{pgTable as AS,text as _l,timestamp as Rg,uuid as yl,integer as xS,index as ES,unique as TS}from"drizzle-orm/pg-core";var kg=AS("scaffolding_fingerprints",{id:yl("id").primaryKey().defaultRandom(),userId:yl("user_id").notNull(),harness:_l("harness").notNull(),model:_l("model").notNull(),toolsHash:_l("tools_hash").notNull(),firstSeenAt:Rg("first_seen_at",{withTimezone:!0}).notNull().defaultNow(),lastSeenAt:Rg("last_seen_at",{withTimezone:!0}).notNull().defaultNow(),snapshotCount:xS("snapshot_count").notNull().default(1),firstSessionId:yl("first_session_id")},e=>[TS("scaffolding_fingerprints_user_id_harness_model_tools_hash_key").on(e.userId,e.harness,e.model,e.toolsHash),ES("idx_scaffolding_fp_segment").on(e.userId,e.harness,e.model)]);import{pgTable as RS,text as wl,timestamp as kS,jsonb as jS,uuid as jg,integer as NS,unique as CS}from"drizzle-orm/pg-core";var Ng=RS("scaffolding_segments",{id:jg("id").primaryKey().defaultRandom(),userId:jg("user_id").notNull(),harness:wl("harness").notNull(),model:wl("model").notNull(),coreNames:jS("core_names").notNull(),coreHash:wl("core_hash").notNull(),activeFingerprints:NS("active_fingerprints").notNull(),computedAt:kS("computed_at",{withTimezone:!0}).notNull().defaultNow()},e=>[CS("scaffolding_segments_user_id_harness_model_key").on(e.userId,e.harness,e.model)]);import{relations as Oe}from"drizzle-orm";var PS=Oe(R,({many:e})=>({sessions:e(f),contextSnapshots:e(C),apiKeys:e(we)})),OS=Oe(we,({one:e})=>({profile:e(R,{fields:[we.userId],references:[R.id]})})),DS=Oe(V,({many:e})=>({teams:e(K),userOrganizations:e(Y),projects:e(D),invitations:e(re)})),MS=Oe(K,({one:e,many:t})=>({organization:e(V,{fields:[K.orgId],references:[V.id]}),userTeams:t(he),invitations:t(re)})),LS=Oe(re,({one:e})=>({organization:e(V,{fields:[re.orgId],references:[V.id]}),team:e(K,{fields:[re.teamId],references:[K.id]}),inviter:e(R,{fields:[re.invitedBy],references:[R.id]})})),$S=Oe(Y,({one:e})=>({organization:e(V,{fields:[Y.orgId],references:[V.id]})})),qS=Oe(he,({one:e})=>({team:e(K,{fields:[he.teamId],references:[K.id]})})),US=Oe(_,({one:e,many:t})=>({versions:t(fe),projectInstructions:t(at),events:t(Nt),usageEvents:t(Rr),sessionInstructions:t(ne),packInstructions:t(Ee),forkedFrom:e(_,{fields:[_.forkedFromId],references:[_.id]})})),BS=Oe(Nt,({one:e})=>({instruction:e(_,{fields:[Nt.instructionId],references:[_.id]})})),FS=Oe($,({one:e,many:t})=>({project:e(D,{fields:[$.projectId],references:[D.id]}),parent:e($,{fields:[$.parentId],references:[$.id]}),versions:t($)})),HS=Oe(fe,({one:e})=>({instruction:e(_,{fields:[fe.instructionId],references:[_.id]})})),WS=Oe(D,({one:e,many:t})=>({organization:e(V,{fields:[D.orgId],references:[V.id]}),projectInstructions:t(at),sessions:t(f)})),zS=Oe(at,({one:e})=>({project:e(D,{fields:[at.projectId],references:[D.id]}),instruction:e(_,{fields:[at.instructionId],references:[_.id]})})),VS=Oe(f,({one:e,many:t})=>({profile:e(R,{fields:[f.userId],references:[R.id]}),project:e(D,{fields:[f.projectId],references:[D.id]}),run:e(J,{fields:[f.runId],references:[J.id]}),events:t(Le),sessionInstructions:t(ne),treatmentExposures:t(X),contextSnapshots:t(C)})),JS=Oe(J,({one:e,many:t})=>({profile:e(R,{fields:[J.userId],references:[R.id]}),organization:e(V,{fields:[J.orgId],references:[V.id]}),project:e(D,{fields:[J.projectId],references:[D.id]}),sessions:t(f),launchJobs:t(oe)})),GS=Oe(oe,({one:e})=>({run:e(J,{fields:[oe.runId],references:[J.id]})})),KS=Oe(Le,({one:e})=>({session:e(f,{fields:[Le.sessionId],references:[f.id]})})),YS=Oe(ne,({one:e})=>({session:e(f,{fields:[ne.sessionId],references:[f.id]}),instruction:e(_,{fields:[ne.instructionId],references:[_.id]})})),XS=Oe(Tt,({one:e,many:t})=>({owner:e(R,{fields:[Tt.userId],references:[R.id]}),project:e(D,{fields:[Tt.projectId],references:[D.id]}),exposures:t(X)})),QS=Oe(X,({one:e})=>({session:e(f,{fields:[X.sessionId],references:[f.id]}),owner:e(R,{fields:[X.userId],references:[R.id]}),assignment:e(Tt,{fields:[X.assignmentId],references:[Tt.id]})})),ZS=Oe(Re,({one:e,many:t})=>({packInstructions:t(Ee),forkedFrom:e(Re,{fields:[Re.forkedFromId],references:[Re.id]})})),eA=Oe(Ee,({one:e})=>({pack:e(Re,{fields:[Ee.packId],references:[Re.id]}),instruction:e(_,{fields:[Ee.instructionId],references:[_.id]})})),tA=Oe(Rr,({one:e})=>({instruction:e(_,{fields:[Rr.instructionId],references:[_.id]})})),nA=Oe(k,({one:e,many:t})=>({parent:e(k,{fields:[k.parentId],references:[k.id]}),evals:t(_e),evalRuns:t(ye),benchmarks:t(kn),triggerEvals:t(Ct),optimizationRuns:t(hn),evalJobs:t(Se),evalConversations:t(ke)})),rA=Oe(_e,({one:e,many:t})=>({evalTarget:e(k,{fields:[_e.evalTargetId],references:[k.id]}),runs:t(ye)})),oA=Oe(ye,({one:e})=>({eval:e(_e,{fields:[ye.evalId],references:[_e.id]}),evalTarget:e(k,{fields:[ye.evalTargetId],references:[k.id]})})),sA=Oe(kn,({one:e})=>({evalTarget:e(k,{fields:[kn.evalTargetId],references:[k.id]})})),iA=Oe(Ct,({one:e})=>({evalTarget:e(k,{fields:[Ct.evalTargetId],references:[k.id]})})),aA=Oe(hn,({one:e})=>({evalTarget:e(k,{fields:[hn.evalTargetId],references:[k.id]})})),cA=Oe(Se,({one:e})=>({evalTarget:e(k,{fields:[Se.evalTargetId],references:[k.id]})})),uA=Oe(ke,({one:e})=>({evalTarget:e(k,{fields:[ke.evalTargetId],references:[k.id]})})),dA=Oe(C,({one:e})=>({session:e(f,{fields:[C.sessionId],references:[f.id]}),profile:e(R,{fields:[C.userId],references:[R.id]})}));import{drizzle as Dg}from"drizzle-orm/postgres-js";import jl from"postgres";var fo=0,vl=0,Zo=0,Il=0,Cg=0,Pg=0,bl=0;function Sl(){fo++,fo>vl&&(vl=fo)}u(Sl,"trackDbOpStart");function Al(){fo>0&&fo--}u(Al,"trackDbOpEnd");function xl(){Zo++,Zo>Il&&(Il=Zo)}u(xl,"trackHeavyDbOpStart");function El(){Zo>0&&Zo--}u(El,"trackHeavyDbOpEnd");function ki(){return fo}u(ki,"getDbLoad");function Tl(){Cg++}u(Tl,"recordDbShed");function ji(){Pg++}u(ji,"recordIngestShed");function Og(){bl++}u(Og,"recordQueryDeadline");function Rl(){let e=bl;return bl=0,e}u(Rl,"consumeDeadlineCount");function kl(){return{current:fo,peak:vl,heavyCurrent:Zo,heavyPeak:Il,shedCount:Cg,ingestShedCount:Pg}}u(kl,"getDbLoadStats");function es(){let e=Number(process.env.PG_INFLIGHT_MAX);return Number.isFinite(e)&&e>0?e:(Number(process.env.PG_POOL_MAX)||3)*4}u(es,"dbInflightMax");function Ni(){let e=es(),t=Number(process.env.PG_INGEST_INFLIGHT_MAX);if(Number.isFinite(t)&&t>0)return Math.min(t,e);let n=Number(process.env.PG_POOL_MAX)||3;return Math.min(e,Math.max(n,Math.floor(e/2)))}u(Ni,"dbIngestInflightMax");var Pi,ns,Oi=!1,Oc,Ci,ts,Mc,Dc;function Nl(e){let t=process.env[e];if(!t)throw new Error(`Missing required env var: ${e}`);return t}u(Nl,"getEnv");function Mg(){if(Oi)throw new Error("getDb() called after closeDb(): the connection pool is closed for shutdown. Stop issuing queries (timers/requests) before draining the pool.");if(!Pi){let e=process.env.PG_APPLICATION_NAME||"rulemetric",t=Number(process.env.PG_POOL_MAX)||3,n=Number(process.env.PG_CONNECT_TIMEOUT_S)||10,r=Number(process.env.PG_STATEMENT_TIMEOUT_MS)||0,o=Number(process.env.PG_IDLE_TIMEOUT)||5,s=Number(process.env.PG_KEEP_ALIVE_S)||60;ns=jl(Nl("DATABASE_URL"),{prepare:!1,max:t,connect_timeout:n,idle_timeout:o,keep_alive:s,max_lifetime:300,connection:{application_name:e,...r>0?{statement_timeout:r}:{}}}),Pi=Dg(ns,{schema:Pc})}return Pi}u(Mg,"getDb");function Lg(){if(Oi)throw new Error("getHeavyDb() called after closeDb(): the connection pool is closed for shutdown. Stop issuing queries (timers/requests) before draining the pool.");if(!Dc){let e=(process.env.PG_APPLICATION_NAME||"rulemetric")+":heavy",t=Number(process.env.PG_HEAVY_POOL_MAX)||2;Mc=jl(Nl("DATABASE_URL"),{prepare:!1,max:t,connect_timeout:Number(process.env.PG_CONNECT_TIMEOUT_S)||10,idle_timeout:Number(process.env.PG_IDLE_TIMEOUT)||5,keep_alive:Number(process.env.PG_KEEP_ALIVE_S)||60,max_lifetime:300,connection:{application_name:e}}),Dc=Dg(Mc,{schema:Pc})}return Dc}u(Lg,"getHeavyDb");async function Di(){if(Oc)return Oc;Oi=!0;let e=ns,t=ts,n=Mc;return ns=void 0,Pi=void 0,ts=void 0,Mc=void 0,Dc=void 0,Oc=Promise.allSettled([e?e.end({timeout:5}):Promise.resolve(),t?t.end({timeout:5}):Promise.resolve(),n?n.end({timeout:5}):Promise.resolve()]).then(()=>{}),Oc}u(Di,"closeDb");function Cl(){if(Oi)return Promise.resolve();if(Ci)return Ci;let e=ns;return ns=void 0,Pi=void 0,Ci=(async()=>{e&&await e.end({timeout:5}).catch(()=>{})})().finally(()=>{Ci=void 0}),Ci}u(Cl,"recyclePool");async function Pl(e){let t=Date.now();if(Oi)return{ok:!1,ms:0,err:new Error("pool closed for shutdown")};let n=ts;try{return n||(n=jl(Nl("DATABASE_URL"),{prepare:!1,max:1,connect_timeout:Number(process.env.PG_CONNECT_TIMEOUT_S)||10,idle_timeout:20,max_lifetime:300,connection:{application_name:(process.env.PG_APPLICATION_NAME||"rulemetric")+":probe",statement_timeout:Math.max(2e3,e-2e3)}}),ts=n),await Promise.race([n`SELECT 1`,new Promise((r,o)=>setTimeout(()=>o(new Error("db probe timeout")),e))]),{ok:!0,ms:Date.now()-t}}catch(r){return ts===n&&(ts=void 0),n?.end({timeout:1}).catch(()=>{}),{ok:!1,ms:Date.now()-t,err:r}}}u(Pl,"probeDbReachable");var lA="called after closeDb()";function Ol(e){let t=e?.message;return typeof t=="string"&&t.includes(lA)}u(Ol,"isPoolClosedError");var pA=new Set(["CONNECT_TIMEOUT","ETIMEDOUT","ENOTFOUND","ECONNREFUSED","EAI_AGAIN"]);function $c(e){let t=e,n=t?.code??t?.cause?.code??t?.errno;return n!==void 0&&pA.has(n)}u($c,"isRetryableConnectError");var mA=new Set(["CONNECTION_CLOSED","ECONNRESET","EPIPE"]);function $g(e){let t=e,n=t?.code??t?.cause?.code??t?.errno;return n!==void 0&&mA.has(n)}u($g,"isRetryableResetError");async function qg(e,t={}){let n=t.attempts??3,r=t.baseMs??100,o;for(let s=0;s<n;s++)try{return await e()}catch(i){o=i;let c=$c(i)||t.retryResets===!0&&$g(i);if(s===n-1||!c)throw i;await new Promise(a=>setTimeout(a,r*2**s))}throw o}u(qg,"withDbRetry");var Lc=class extends Error{static{u(this,"QueryDeadlineError")}code="QUERY_DEADLINE";constructor(t){super(`Query exceeded the client-side deadline of ${t}ms \u2014 the DB pool is likely saturated (acquire-wait) or holding a dead socket; failing fast to avoid pinning the caller. See client.ts.`),this.name="QueryDeadlineError"}};function Dl(e){return e?.code==="QUERY_DEADLINE"}u(Dl,"isQueryDeadlineError");function Ug(){let e=Number(process.env.PG_QUERY_DEADLINE_MS);return Number.isFinite(e)&&e>=0?e:2e4}u(Ug,"queryDeadlineMs");function fA(e,t){let n,r=new Promise((o,s)=>{n=setTimeout(()=>{Og(),s(new Lc(t))},t);let i=n;typeof i.unref=="function"&&i.unref()});return Promise.race([e,r]).finally(()=>clearTimeout(n))}u(fA,"raceWithDeadline");var Bg=new Set(["select","selectDistinct","selectDistinctOn","insert","update","delete","execute","with","$count","refreshMaterializedView"]),Fg=new Set(["select","selectDistinct","selectDistinctOn","$count"]);function Ml(e,t=!1,n=0,r=!1){return e===null||typeof e!="object"&&typeof e!="function"?e:new Proxy(e,{get(o,s,i){if(s==="then"){let a=Reflect.get(o,s,i);return typeof a!="function"?a:(l,p)=>{let m=r?xl:Sl,y=r?El:Al;m();let v=qg(()=>new Promise((h,w)=>a.call(o,h,w)),{retryResets:t});return(n>0?fA(v,n):v).finally(y).then(l,p)}}let c=Reflect.get(o,s,i);return typeof c=="function"?(...a)=>Ml(c.apply(o,a),t,n,r):c}})}u(Ml,"wrapBuilder");function Hg(e,t=!1){let n=t?xl:Sl,r=t?El:Al;n();try{return Promise.resolve(e()).finally(r)}catch(o){throw r(),o}}u(Hg,"gaugeTransaction");var d=new Proxy({},{get(e,t){let n=Mg(),r=n[t];if(typeof t=="string"&&Bg.has(t)&&typeof r=="function"){let o=Fg.has(t),s=Ug();return(...i)=>Ml(r.apply(n,i),o,s)}return t==="transaction"&&typeof r=="function"?(...o)=>Hg(()=>r.apply(n,o)):r}}),ft=new Proxy({},{get(e,t){let n=Lg(),r=n[t];if(typeof t=="string"&&Bg.has(t)&&typeof r=="function"){let o=Fg.has(t);return(...s)=>Ml(r.apply(n,s),o,0,!0)}return t==="transaction"&&typeof r=="function"?(...o)=>Hg(()=>r.apply(n,o),!0):r}});async function tn(e){let[t]=await d.insert(ht).values({userId:e.userId,type:e.type,title:e.title,body:e.body??null,url:e.url??null,sourceTable:e.sourceTable??null,sourceId:e.sourceId??null,metadata:e.metadata??{}}).onConflictDoNothing({target:[ht.userId,ht.sourceTable,ht.sourceId]}).returning();return t??null}u(tn,"notifyUser");import{createHmac as gA,createPublicKey as hA,timingSafeEqual as _A,verify as yA}from"node:crypto";var wA=6e4,Li=null,zg=0,Mi=null,vA=null;async function IA(){let e=process.env.SUPABASE_URL;if(!e)throw new Error("SUPABASE_URL not set");let t=await fetch(`${e}/auth/v1/.well-known/jwks.json`,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw new Error(`JWKS fetch failed: ${t.status}`);return await t.json()}u(IA,"defaultJwksFetcher");async function Ll(){return Mi||(Mi=(async()=>{try{let e=await(vA??IA)(),t=new Map;for(let n of e.keys)if(n.kid)try{t.set(n.kid,hA({key:n,format:"jwk"}))}catch{}Li=t,zg=Date.now()}finally{Mi=null}})(),Mi)}u(Ll,"refreshJwks");function Wg(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf-8"))}catch{return null}}u(Wg,"decodeB64Json");function bA(e){if(typeof e.exp=="number"&&e.exp*1e3<Date.now()||typeof e.sub!="string"||e.sub.length===0)return null;let t=e.aud;return t==="authenticated"||Array.isArray(t)&&t.includes("authenticated")?{userId:e.sub}:null}u(bA,"checkPayload");function SA(e,t,n,r){let o=gA("sha256",r).update(`${e}.${t}`).digest(),s;try{s=Buffer.from(n,"base64url")}catch{return!1}return s.length!==o.length?!1:_A(s,o)}u(SA,"verifyHs256");async function Vg(e){let t=e.split(".");if(t.length!==3)return{ok:!1,reason:"invalid"};let[n,r,o]=t,s=Wg(n);if(!s)return{ok:!1,reason:"invalid"};if(s.alg==="HS256"){let a=process.env.SUPABASE_JWT_SECRET;if(!a)return{ok:!1,reason:"unavailable"};if(!SA(n,r,o,a))return{ok:!1,reason:"invalid"}}else if(s.alg==="ES256"){if(typeof s.kid!="string")return{ok:!1,reason:"invalid"};if(Li===null)try{await Ll()}catch{return{ok:!1,reason:"unavailable"}}let a=Li?.get(s.kid);if(!a&&Date.now()-zg>=wA){try{await Ll()}catch{return{ok:!1,reason:"unavailable"}}a=Li?.get(s.kid)}if(!a)return{ok:!1,reason:"invalid"};let l;try{l=Buffer.from(o,"base64url")}catch{return{ok:!1,reason:"invalid"}}if(!yA("sha256",Buffer.from(`${n}.${r}`),{key:a,dsaEncoding:"ieee-p1363"},l))return{ok:!1,reason:"invalid"}}else return{ok:!1,reason:"invalid"};let i=Wg(r);if(!i)return{ok:!1,reason:"invalid"};let c=bA(i);return c?{ok:!0,userId:c.userId,payload:i}:{ok:!1,reason:"invalid"}}u(Vg,"verifySupabaseJwt");async function Jg(e=3){for(let t=0;t<e;t++)try{return await Ll(),Li!==null}catch{await new Promise(n=>setTimeout(n,500*2**t))}return!1}u(Jg,"primeJwks");function RA(e){return AA("sha256").update(e).digest("hex")}u(RA,"hashApiKey");var Gg=new Map,kA=300*1e3;function jA(e){let t=Date.now(),n=Gg.get(e)??0;t-n<kA||(Gg.set(e,t),d.update(we).set({lastUsedAt:new Date}).where(Kg(we.id,e)).then(()=>{}).catch(()=>{}))}u(jA,"updateLastUsed");var NA=60*1e3,CA=5e3,rs=new Map;async function Yg(e,t){let n=e.req.header("Authorization");if(!n?.startsWith("Bearer "))return e.json({error:"Missing authorization header"},401);let r=n.slice(7);if(r.startsWith("rm_")){let o=RA(r),s,i=rs.get(o);if(i&&Date.now()-i.cachedAt<NA)s=i;else{i&&rs.delete(o);let[c]=await d.select({id:we.id,userId:we.userId,expiresAt:we.expiresAt}).from(we).where(EA(Kg(we.keyHash,o),TA(we.revokedAt)));if(!c)return e.json({error:"Invalid API key"},401);s={id:c.id,userId:c.userId,expiresAt:c.expiresAt,cachedAt:Date.now()},rs.size>=CA&&rs.clear(),rs.set(o,s)}if(s.expiresAt&&new Date(s.expiresAt)<new Date)return rs.delete(o),e.json({error:"API key expired"},401);e.set("userId",s.userId),si(s.userId),jA(s.id),await t();return}try{let o=xA(process.env.SUPABASE_URL,process.env.SUPABASE_ANON_KEY,{global:{headers:{Authorization:`Bearer ${r}`}}}),s=await Vg(r);if(s.ok){e.set("userId",s.userId),e.set("supabase",o),si(s.userId),await t();return}if(s.reason==="invalid")return console.log(`[auth] local JWT verify FAIL ${e.req.method} ${e.req.path}`),e.json({error:"Invalid token"},401);let i=Date.now(),{data:{user:c},error:a}=await o.auth.getUser();if(console.log(`[auth] getUser ${e.req.method} ${e.req.path} ms=${Date.now()-i} ${a?`err=${a.message}`:`userId=${c?.id??"?"}`}`),a||!c)return e.json({error:"Invalid token"},401);e.set("user",c),e.set("userId",c.id),e.set("supabase",o),si(c.id),await t()}catch{return e.json({error:"Authentication failed"},401)}}u(Yg,"authMiddleware");import{HTTPException as PA}from"hono/http-exception";import{ZodError as OA}from"zod";function et(e){return e.replace(/[%_\\]/g,"\\$&")}u(et,"escapeLike");function os(e){let t=e;return t?.code??t?.cause?.code??t?.errno}u(os,"transientCode");var DA=new Set(["ECONNRESET","EPIPE","ECONNABORTED"]);function Xg(e,t){return e instanceof OA?t.json({error:"Validation error",details:e.flatten().fieldErrors},400):e instanceof PA?e.getResponse():Ol(e)?t.json({error:"Server draining, retry shortly"},503):Dl(e)?(process.env.LOG_LEVEL==="debug"&&console.debug("[req] query deadline exceeded \u2014 DB pool saturated; shed 503"),t.json({error:"Database busy, retry shortly"},503,{"Retry-After":"2"})):e.message==="aborted"||DA.has(os(e)??"")?(process.env.LOG_LEVEL==="debug"&&console.debug(`[req] client/transient disconnect code=${os(e)??"aborted"}`),t.body(null,503)):(console.error("Unhandled error:",e),t.json({error:"Internal server error"},500))}u(Xg,"errorHandler");function $i(e,t){let n=new Map;return setInterval(()=>{let r=Date.now();for(let[o,s]of n)r>s.resetAt&&n.delete(o)},6e4).unref(),async(r,o)=>{let i=`${r.req.header("x-forwarded-for")?.split(",")[0]?.trim()??r.req.header("x-real-ip")??"unknown"}:${r.req.path}`,c=Date.now(),a=n.get(i);if((!a||c>a.resetAt)&&(a={count:0,resetAt:c+e},n.set(i,a)),a.count++,r.res.headers.set("X-RateLimit-Limit",String(t)),r.res.headers.set("X-RateLimit-Remaining",String(Math.max(0,t-a.count))),r.res.headers.set("X-RateLimit-Reset",String(Math.ceil(a.resetAt/1e3))),a.count>t)return r.json({error:"Too many requests, please try again later"},429);await o()}}u($i,"rateLimit");var qc=!0,$l="",Qg=0;function ql(e,t="",n=-1){if(e===qc){!e&&t&&($l=t);return}qc=e,$l=e?"":t,Qg=n,console.log(`[db-readiness] -> ${e?"READY":"NOT READY"}${t?` (${t})`:""}`)}u(ql,"setDbReady");function qi(){return qc}u(qi,"isDbReady");function Uc(){return{ready:qc,reason:$l,changedAt:Qg}}u(Uc,"dbReadiness");async function Zg(e,t){return qi()?t():(e.header("Retry-After","5"),e.json({error:"Service temporarily unavailable: the database is recovering. Retry shortly.",reason:Uc().reason||void 0},503))}u(Zg,"dbShed");var MA=5e3,eh=0;async function th(e,t){let n=ki(),r=es();if(n>r){Tl();let o=Date.now();return o-eh>=MA&&(eh=o,console.warn(`[db_load_shed] shedding: inFlight=${n} > max=${r} path=${e.req.path}`)),e.header("Retry-After","1"),e.json({error:"Service busy: the database is under transient load. Retry shortly.",inFlight:n},503)}return t()}u(th,"dbLoadShed");var LA=5e3,nh=0;async function Ui(e,t){if(e.req.method!=="POST")return t();let n=ki(),r=Ni();if(n>=r){ji();let o=Date.now();return o-nh>=LA&&(nh=o,console.warn(`[ingest_load_shed] shedding write: inFlight=${n} >= ingestMax=${r} path=${e.req.path}`)),e.header("Retry-After","2"),e.json({error:"Ingest busy: the database is under transient write load. Retry shortly.",inFlight:n},429)}return t()}u(Ui,"ingestLoadShed");var rh=u(async(e,t)=>{await t(),e.res.headers.set("X-Content-Type-Options","nosniff"),e.res.headers.set("X-Frame-Options","DENY"),e.res.headers.set("X-XSS-Protection","0"),e.res.headers.set("Referrer-Policy","strict-origin-when-cross-origin"),e.res.headers.set("Permissions-Policy","camera=(), microphone=(), geolocation=()")},"securityHeaders");function oh(){return async(e,t)=>{let n=Date.now();try{await t()}finally{let r=Date.now()-n,o=Number(process.env.SLOW_REQUEST_LOG_MS)||2e3,s=Number(process.env.SLOW_REQUEST_MAX_MS)||12e4;if(r>s||r<o&&e.res.status<500)return;let i=new URL(e.req.url).pathname,c=e.get("userId");console.warn(`[http] slow_or_error method=${e.req.method} path=${i} status=${e.res.status} ms=${r}${c?` user=${c}`:""}`)}}}u(oh,"slowRequestLog");import{Hono as qA}from"hono";import{z as Cr}from"zod";import{createClient as sh}from"@supabase/supabase-js";import{createClient as $A}from"@supabase/supabase-js";async function Bc(e){let t=process.env.SUPABASE_URL,n=process.env.SUPABASE_ANON_KEY;if(!t||!n)return{ok:!1,status:500,error:"Server authentication not configured"};let r=$A(t,n,{auth:{persistSession:!1,autoRefreshToken:!1}}),o=`${e.slice(0,6)}\u2026${e.slice(-4)}`,s=Date.now();console.log(`[auth] refreshSession start refresh_token=${o}`);let{data:i,error:c}=await r.auth.refreshSession({refresh_token:e});return c||!i.session?(console.log(`[auth] refreshSession FAIL refresh_token=${o} ms=${Date.now()-s} err=${c?.message??"no-session"}`),{ok:!1,status:401,error:c?.message??"refresh failed"}):(console.log(`[auth] refreshSession OK refresh_token=${o} ms=${Date.now()-s} userId=${i.user?.id??"?"}`),{ok:!0,session:{accessToken:i.session.access_token,refreshToken:i.session.refresh_token,expiresAt:i.session.expires_at?new Date(i.session.expires_at*1e3).toISOString():null,email:i.user?.email??null}})}u(Bc,"refreshSupabaseSession");var ss=new qA,UA=Cr.object({email:Cr.string().email(),password:Cr.string().min(1)}),BA=Cr.object({refreshToken:Cr.string().min(1)});ss.post("/auth/login",async e=>{let t=await e.req.json(),n=UA.parse(t),r=process.env.SUPABASE_URL,o=process.env.SUPABASE_ANON_KEY;if(!r||!o)return e.json({error:"Server authentication not configured"},500);let s=sh(r,o),i=Date.now();console.log(`[auth] signInWithPassword start email=${n.email} ua="${e.req.header("user-agent")??""}"`);let{data:c,error:a}=await s.auth.signInWithPassword({email:n.email,password:n.password});return a||!c.session?(console.log(`[auth] signInWithPassword FAIL email=${n.email} ms=${Date.now()-i} err=${a?.message??"no-session"}`),e.json({error:"Invalid email or password"},401)):(console.log(`[auth] signInWithPassword OK email=${n.email} ms=${Date.now()-i} userId=${c.user?.id??"?"}`),e.json({accessToken:c.session.access_token,refreshToken:c.session.refresh_token,expiresAt:c.session.expires_at?new Date(c.session.expires_at*1e3).toISOString():null,email:c.user?.email??n.email}))});var FA=Cr.object({email:Cr.string().email(),password:Cr.string().min(8,"Password must be at least 8 characters")});ss.post("/auth/signup",async e=>{let t=await e.req.json(),n=FA.parse(t),r=process.env.SUPABASE_URL,o=process.env.SUPABASE_ANON_KEY;if(!r||!o)return e.json({error:"Server authentication not configured"},500);let s=sh(r,o),i=process.env.WEB_URL??"http://localhost:5174",{data:c,error:a}=await s.auth.signUp({email:n.email,password:n.password,options:{emailRedirectTo:`${i}/auth/confirm`}});if(a){let l=/already registered|already exists|user already/i.test(a.message);return e.json({error:a.message},l?409:400)}return c.user&&(c.user.identities?.length??0)===0&&!c.session?e.json({error:"An account with this email already exists. Run `rulemetric auth login`."},409):c.session?e.json({confirmationRequired:!1,accessToken:c.session.access_token,refreshToken:c.session.refresh_token,expiresAt:c.session.expires_at?new Date(c.session.expires_at*1e3).toISOString():null,email:c.user?.email??n.email}):e.json({confirmationRequired:!0,email:c.user?.email??n.email})});ss.post("/auth/refresh",async e=>{let t=await e.req.json().catch(()=>null),n=BA.safeParse(t);if(!n.success)return e.json({error:"refreshToken is required"},400);let r=await Bc(n.data.refreshToken);return r.ok?e.json(r.session):e.json({error:r.error},r.status)});import{readFileSync as HA}from"node:fs";import{dirname as WA,resolve as Ul}from"node:path";import{fileURLToPath as zA}from"node:url";import{Hono as VA}from"hono";var JA="https://registry.npmjs.org/-/package/@rulemetric%2Fcli/dist-tags",GA=3600*1e3,KA=3e3,Bi=null;function YA(){if(process.env.RULEMETRIC_BUNDLED_CLI_VERSION)return process.env.RULEMETRIC_BUNDLED_CLI_VERSION;let e=WA(zA(import.meta.url)),t=[Ul(e,"../../../cli/package.json"),Ul(e,"../../../../apps/cli/package.json"),Ul(process.cwd(),"apps/cli/package.json")];for(let n of t)try{let r=JSON.parse(HA(n,"utf-8"));if(r.version)return r.version}catch{}return"0.0.0"}u(YA,"readBundledCliVersion");async function XA(){try{let e=await fetch(JA,{headers:{accept:"application/json"},signal:AbortSignal.timeout(KA)});if(!e.ok)return null;let t=await e.json();return typeof t.latest=="string"&&t.latest?t.latest:null}catch{return null}}u(XA,"fetchLatestFromNpm");async function QA(){let e=Date.now();if(Bi&&e-Bi.at<GA)return Bi.version;let n=await XA()??Bi?.version??YA();return Bi={version:n,at:e},n}u(QA,"getLatestCliVersion");var Fc=new VA;Fc.get("/cli/latest-version",async e=>e.json({latest:await QA()}));import{Hono as lx}from"hono";import{sql as ZA}from"drizzle-orm";var ex=12e3,tx=3e4,ih=4,nx=Number(process.env.PG_RECYCLE_DEADLINE_THRESHOLD)||3,rx="pipeline:api_db_pool_wedged",ox="pipeline:api_db_pool_recycled",is=0;async function Bl(){return Pl(ex)}u(Bl,"probeDb");function sx(e){let t=[],n=[],r=e;for(let o=0;r&&o<8;o++){let s=r;typeof s.code=="string"&&t.push(s.code),typeof s.message=="string"&&n.push(s.message),r=s.cause}return{codes:t,message:n.join(" ").toLowerCase()}}u(sx,"flattenCauseChain");function ix(e){let{codes:t,message:n}=sx(e);return n.includes("max client")||n.includes("emaxconn")||n.includes("max_client_conn")||t.includes("XX000")&&n.includes("client")}u(ix,"isPoolSaturation");function ax(e){return ix(e)?"Supavisor tenant saturated (client cap reached)":$c(e)?"transient connect failure":"DB unreachable / probe timed out"}u(ax,"classifyProbeFailure");async function cx(e=Bl,t={}){let n=t.consumeDeadlines??Rl,r=t.recycle??Cl,o=t.onRecycle??dx,s=await e();if(s.ok){let c=!qi();is>0&&console.log(`[db-wedge] DB reachable again after ${is} failed probe(s)`),is=0,ql(!0,"",Date.now()),c&&ux();let a=n();a>=nx&&(console.error(`[db-wedge] recycling the MAIN pool: ${a} client-side query-deadline(s) while a fresh dedicated probe is healthy \u2014 the pool is holding black-holed sockets a restart is not needed to clear.`),Promise.resolve().then(()=>r()).catch(l=>console.error("[db-wedge] pool recycle failed:",l instanceof Error?l.message:l)),o(a));return}is+=1;let i=ax(s.err);console.error(`[db-wedge] dedicated DB probe failed (${is}/${ih}) \u2014 ${i}`),is>=ih&&qi()&&(ql(!1,`DB unreachable from a dedicated connection \u2014 ${i}`,Date.now()),console.error("[db-wedge] marking API NOT READY (shedding DB traffic). NOT restarting: a process restart cannot free a shared Supavisor pooler. Readiness restores automatically on the next OK probe."))}u(cx,"watchdogTick");async function ah(e,t){try{await d.execute(ZA`
|
|
76
76
|
INSERT INTO alert_dispatches (user_id, alert_key, severity, channel, last_state)
|
|
77
77
|
SELECT DISTINCT user_id, ${e}, 'soft', 'in_app',
|
|
78
78
|
jsonb_build_object('message', ${t})
|
|
79
79
|
FROM sessions
|
|
80
80
|
WHERE created_at > now() - interval '7 days' AND user_id IS NOT NULL
|
|
81
|
-
`)}catch(n){console.error(`[db-wedge] failed to record ${e} alert:`,n instanceof Error?n.message:n)}}u(
|
|
82
|
-
`)){let o=r.match(/->([\d.]+|\[[^\]]+\]):(?:6543|5432)\b/);o&&n.push({remote:o[1].replace(/^\[|\]$/g,"")})}return n}catch{return[]}}u(
|
|
81
|
+
`)}catch(n){console.error(`[db-wedge] failed to record ${e} alert:`,n instanceof Error?n.message:n)}}u(ah,"dispatchSoftAlert");async function ux(){await ah(rx,'The API database pool was briefly unreachable and shed traffic; it has recovered. Sessions and other pages may have shown 503s during that window. If this recurs, run "bash scripts/debug-loop.sh".')}u(ux,"reportRecovery");async function dx(e){try{Un(new Error(`[db-wedge] auto-recycled the main DB pool after ${e} client-side query-deadline(s) with a healthy probe \u2014 black-holed pooler sockets, no restart needed.`),{tags:{source:"db-wedge",action:"pool_recycle"},extra:{deadlines:e}})}catch{}await ah(ox,'The API database pool held stale connections after a network interruption and was automatically recycled \u2014 no restart needed. A few requests may have shown 503s briefly. If this recurs often, run "bash scripts/debug-loop.sh".')}u(dx,"reportPoolRecycle");function ch(){let e=setInterval(()=>{cx().catch(()=>{})},tx);return{stop:u(()=>clearInterval(e),"stop")}}u(ch,"startDbWedgeWatchdog");var as=new lx;as.get("/health",e=>e.json({status:"ok"}));as.get("/ready",e=>{let t=Uc();return e.json({ready:t.ready,reason:t.reason||void 0},t.ready?200:503)});as.get("/health/deep",async e=>{let t=await Bl();return e.json({status:t.ok?"ok":"degraded",db:t.ok?"ok":"wedged",dbProbeMs:t.ms},t.ok?200:503)});import{Hono as px}from"hono";import{sql as mx}from"drizzle-orm";import{execFileSync as fx}from"node:child_process";import*as uh from"node:fs";var Hc=new px,gx=["/usr/sbin/lsof","/usr/bin/lsof","/bin/lsof"].find(e=>uh.existsSync(e))??"lsof";function hx(e=process.pid){try{let t=fx(gx,["-a","-p",String(e),"-i","TCP","-P","-n"],{encoding:"utf8",timeout:3e3}),n=[];for(let r of t.split(`
|
|
82
|
+
`)){let o=r.match(/->([\d.]+|\[[^\]]+\]):(?:6543|5432)\b/);o&&n.push({remote:o[1].replace(/^\[|\]$/g,"")})}return n}catch{return[]}}u(hx,"snapshotPoolerSockets");Hc.get("/diag/pg-health",async e=>{let t=await d.execute(mx`
|
|
83
83
|
SELECT
|
|
84
84
|
application_name,
|
|
85
85
|
client_addr::text AS client_addr,
|
|
@@ -91,97 +91,97 @@ ${e}`}var OI=Xe(()=>{"use strict";u(CI,"resolveRuntimeWebConfig");u(OO,"stampRun
|
|
|
91
91
|
WHERE datname = current_database()
|
|
92
92
|
GROUP BY application_name, client_addr, state
|
|
93
93
|
ORDER BY conns DESC
|
|
94
|
-
`),n=t.reduce((s,i)=>s+i.conns,0),r=
|
|
94
|
+
`),n=t.reduce((s,i)=>s+i.conns,0),r=hx(),o={};for(let s of r)o[s.remote]=(o[s.remote]??0)+1;return e.json({sampled_at:new Date().toISOString(),self:{process:process.env.PG_APPLICATION_NAME??"rulemetric",pid:process.pid,pool_max:Number(process.env.PG_POOL_MAX)||3,pooler_sockets:r.length,pooler_sockets_by_node:o,...(()=>{let s=kl();return{inflight_current:s.current,inflight_peak:s.peak,inflight_shed_count:s.shedCount,inflight_max:es(),ingest_inflight_max:Ni(),ingest_shed_count:s.ingestShedCount}})()},total_backends:n,breakdown:t})});import{Hono as sE}from"hono";import{z as tt}from"zod";import{eq as Ce,and as lr,sql as Vi,ilike as ep,or as tp,desc as E_,inArray as x_}from"drizzle-orm";import{z as Vt}from"zod";var dh=["org","team","project","personal"],Fl=Vt.object({name:Vt.string().min(1),description:Vt.string().min(1),type:Vt.literal("instruction").default("instruction"),scope:Vt.enum(dh),version:Vt.string().min(1),tags:Vt.array(Vt.string()).optional(),compatibility:Vt.array(Vt.string()).optional(),slots:Vt.record(Vt.string(),Vt.string()).optional(),metadata:Vt.record(Vt.string(),Vt.unknown()).optional()});import{z as yn}from"zod";var lh=yn.object({name:yn.string().min(1),description:yn.string().min(1),type:yn.literal("prompt"),version:yn.string().min(1),tags:yn.array(yn.string()).optional(),variables:yn.array(yn.string()).optional(),metadata:yn.record(yn.string(),yn.unknown()).optional()});function Fi(e){return e<=3?"light":e<=8?"standard":"heavy"}u(Fi,"computePackTier");var Wc={claude_md:"claude_md",memory:"memory",skill_loaded:"skill"};function Hl(e,t){let n=Wc[e];return n?`${n}::${t}`:null}u(Hl,"deriveContextIdentity");function Wl(e){if(!e||typeof e!="object")return e;let t=e,n=t.project_areas;if(n!==void 0&&!Array.isArray(n)){let r=n&&typeof n=="object"?n.areas:void 0;t.project_areas=Array.isArray(r)?r:void 0}return e}u(Wl,"normalizeRecommendations");import _x from"gray-matter";import{z as ph}from"zod";var cU=ph.object({type:ph.enum(["instruction","prompt"])});function cs(e){let{data:t,content:n}=_x(e),r=Fl.parse(t),o=r.slots??null;return{frontmatter:r,content:n.trim(),slots:o}}u(cs,"parseInstruction");var zc=["agents-md","claude-md","cursorrules","copilot","windsurf","cline","roo","aider","gemini","continue","junie","jetbrains","codex","soul-md","amazon-q","goose","kilocode","augment","tabnine","opencode","warp","trae","vscode-copilot","qodo","genkit","amp"];var Hi=class{static{u(this,"ConverterRegistry")}converters=new Map;reverseConverters=new Map;register(t,n,r){this.converters.set(t,{converter:n,metadata:r})}registerReverse(t,n){this.reverseConverters.set(t,n)}get(t){return this.converters.get(t)?.converter}getReverse(t){return this.reverseConverters.get(t)}getMetadata(t){return this.converters.get(t)?.metadata}listFormats(){return[...this.converters.keys()]}listAll(){return[...this.converters.values()]}listReverseFormats(){return[...this.reverseConverters.keys()]}};function mh(e,t){let n=[];for(let[r,o]of Object.entries(t)){let s=e[r];if(!s)continue;let i=s.trim();switch(o.placement){case"prefix":case"suffix":n.push(i);break;case"section":o.header?n.push(`${o.header}
|
|
95
95
|
|
|
96
96
|
${i}`):n.push(i);break}}return n.join(`
|
|
97
97
|
|
|
98
|
-
`)}u(
|
|
98
|
+
`)}u(mh,"assembleSlots");function ie(e,t,n,r){if(!t||Object.keys(t).length===0)return e;let o=mh(t,n);return r?.appendContent&&e.trim()?`${o}
|
|
99
99
|
|
|
100
|
-
${e.trim()}`:o}u(ie,"buildOutput");function
|
|
100
|
+
${e.trim()}`:o}u(ie,"buildOutput");function zl(e){let{filename:t,content:n}=e;if(t){let r=t.toLowerCase();if(r==="agents.md")return{format:"agents-md",confidence:.95};if(r==="claude.md")return{format:"claude-md",confidence:.95};if(r===".cursorrules"||r.endsWith(".mdc"))return{format:"cursorrules",confidence:.95};if(r==="copilot-instructions.md"||r.includes("copilot-instructions"))return{format:"copilot",confidence:.95};if(r===".windsurfrules")return{format:"windsurf",confidence:.95};if(r===".clinerules")return{format:"cline",confidence:.9};if(r===".goosehints")return{format:"goose",confidence:.9};if(r==="gemini.md")return{format:"gemini",confidence:.9};if(r==="soul.md")return{format:"soul-md",confidence:.95};if(r==="conventions.md")return{format:"aider",confidence:.7}}if(n){if(n.includes("alwaysApply:")&&n.includes("---"))return{format:"cursorrules",confidence:.8};if(n.includes("## File Access")&&n.includes("## Code Rules"))return{format:"claude-md",confidence:.6};if(n.includes("## Identity")&&n.includes("## File Handling"))return{format:"agents-md",confidence:.6};if(n.includes("## Persona")&&n.includes("## Rules"))return{format:"soul-md",confidence:.6}}return null}u(zl,"detectFormat");var yx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Handling",placement:"section"},code_generation_rules:{header:"## Code Generation",placement:"section"},review_checklist:{header:"## Review Process",placement:"section"}},fh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,yx);return o&&n.push(o),{output:n.join(`
|
|
101
101
|
|
|
102
|
-
`),format:"agents-md",outputPath:"AGENTS.md",warnings:[]}}},
|
|
102
|
+
`),format:"agents-md",outputPath:"AGENTS.md",warnings:[]}}},gh={id:"agents-md",name:"AGENTS.md",description:"Universal cross-tool standard (Linux Foundation). Used by Codex, Amp, Gemini CLI, Aider, Zed.",tier:1,outputPath:"AGENTS.md",toolUrl:"https://agents.md/",scoringMetadata:{expectedSections:["## Identity","## File Handling","## Code Generation","## Review Process"],idealLengthRange:{min:500,max:8e3},supportedFeatures:["markdown-sections","code-blocks","lists","hierarchy"]}};function Vl(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}u(Vl,"escapeYamlString");function zn(e){return e.replace(/[\r\n]+/g," ").trim()}u(zn,"sanitizeHeading");var wx={system_identity:{header:"",placement:"prefix"},file_access_rules:{header:"## File Access",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Checklist",placement:"section"}},hh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${zn(e.frontmatter.name)}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,wx);return o&&n.push(o),{output:n.join(`
|
|
103
103
|
|
|
104
|
-
`),format:"claude-md",outputPath:"CLAUDE.md",warnings:[]}}},
|
|
105
|
-
`),o=[];({includeTitle:!0,includeDescription:!1,includeMetadata:!1,...t}).includeTitle&&o.push(`# ${
|
|
104
|
+
`),format:"claude-md",outputPath:"CLAUDE.md",warnings:[]}}},_h={id:"claude-md",name:"Claude Code (CLAUDE.md)",description:"Claude Code configuration with hierarchical sections and @import support.",tier:1,outputPath:"CLAUDE.md",toolUrl:"https://docs.anthropic.com/en/docs/claude-code",scoringMetadata:{expectedSections:["## File Access","## Code Rules","## Checklist"],idealLengthRange:{min:300,max:5e3},supportedFeatures:["markdown-sections","code-blocks","import-syntax","hierarchy"]}};var vx={system_identity:{header:"",placement:"prefix"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},yh={convert(e,t){let n=[],r=["---",`description: "${Vl(e.frontmatter.description)}"`,"alwaysApply: true","---"].join(`
|
|
105
|
+
`),o=[];({includeTitle:!0,includeDescription:!1,includeMetadata:!1,...t}).includeTitle&&o.push(`# ${zn(e.frontmatter.name)}`);let i=ie(e.content,e.slots,vx);i&&o.push(i);let c=`${r}
|
|
106
106
|
|
|
107
107
|
${o.join(`
|
|
108
108
|
|
|
109
109
|
`)}`,a=c.split(`
|
|
110
|
-
`).length;return a>50&&n.push(`Output is ${a} lines. Cursor recommends 25-50 lines for .mdc files.`),{output:c,format:"cursorrules",outputPath:".cursor/rules/rulemetric.mdc",warnings:n}}},
|
|
110
|
+
`).length;return a>50&&n.push(`Output is ${a} lines. Cursor recommends 25-50 lines for .mdc files.`),{output:c,format:"cursorrules",outputPath:".cursor/rules/rulemetric.mdc",warnings:n}}},wh={id:"cursorrules",name:"Cursor Rules (.mdc)",description:"Cursor IDE rules in MDC format with YAML frontmatter. Supports globs and alwaysApply.",tier:1,outputPath:".cursor/rules/rulemetric.mdc",toolUrl:"https://docs.cursor.com/context/rules-for-ai",scoringMetadata:{expectedSections:["## File Rules","## Rules","## Review"],idealLengthRange:{min:200,max:3e3},supportedFeatures:["mdc-frontmatter","globs","markdown-sections","code-blocks"]}};var Ix={system_identity:{header:"",placement:"prefix"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Coding Rules",placement:"section"},review_checklist:{header:"## Review Steps",placement:"section"}},vh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Ix);return o&&n.push(o),{output:n.join(`
|
|
111
111
|
|
|
112
|
-
`),format:"copilot",outputPath:".github/copilot-instructions.md",warnings:[]}}},
|
|
112
|
+
`),format:"copilot",outputPath:".github/copilot-instructions.md",warnings:[]}}},Ih={id:"copilot",name:"GitHub Copilot Instructions",description:"GitHub Copilot custom instructions in .github/copilot-instructions.md.",tier:1,outputPath:".github/copilot-instructions.md",toolUrl:"https://docs.github.com/en/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot",scoringMetadata:{expectedSections:["## File Rules","## Coding Rules","## Review Steps"],idealLengthRange:{min:300,max:4e3},supportedFeatures:["markdown-sections","natural-language","code-blocks"]}};var bx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},bh={convert(e,t){let n=[],r=[],o={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};o.includeTitle&&r.push(`# ${e.frontmatter.name}`),o.includeDescription&&r.push(e.frontmatter.description);let s=ie(e.content,e.slots,bx);s&&r.push(s);let i=r.join(`
|
|
113
113
|
|
|
114
|
-
`);return i.length>12e3&&n.push(`Output is ${i.length} characters. Windsurf recommends under 12000 characters.`),{output:i,format:"windsurf",outputPath:".windsurfrules",warnings:n}}},
|
|
114
|
+
`);return i.length>12e3&&n.push(`Output is ${i.length} characters. Windsurf recommends under 12000 characters.`),{output:i,format:"windsurf",outputPath:".windsurfrules",warnings:n}}},Sh={id:"windsurf",name:"Windsurf Rules (.windsurfrules)",description:"Windsurf IDE rules file with markdown sections. Warns if output exceeds 12000 characters.",tier:2,outputPath:".windsurfrules",toolUrl:"https://docs.windsurf.com/windsurf/cascade#memories-and-rules",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:12e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Sx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Handling",placement:"section"},code_generation_rules:{header:"## Code Standards",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Ah={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Sx);return o&&n.push(o),{output:n.join(`
|
|
115
115
|
|
|
116
|
-
`),format:"cline",outputPath:".clinerules",warnings:[]}}},
|
|
116
|
+
`),format:"cline",outputPath:".clinerules",warnings:[]}}},xh={id:"cline",name:"Cline Rules (.clinerules)",description:"Cline AI assistant rules file with markdown sections for project-level instructions.",tier:2,outputPath:".clinerules",toolUrl:"https://docs.cline.bot/improving-your-workflow/custom-instructions",scoringMetadata:{expectedSections:["## Identity","## File Handling","## Code Standards","## Review"],idealLengthRange:{min:200,max:8e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Ax={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Eh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Ax);return o&&n.push(o),{output:n.join(`
|
|
117
117
|
|
|
118
|
-
`),format:"roo",outputPath:".roo/rules/rulemetric.md",warnings:[]}}},
|
|
118
|
+
`),format:"roo",outputPath:".roo/rules/rulemetric.md",warnings:[]}}},Th={id:"roo",name:"Roo Code Rules (.roo/rules)",description:"Roo Code rules in markdown format stored in .roo/rules/ directory.",tier:2,outputPath:".roo/rules/rulemetric.md",toolUrl:"https://docs.roocode.com/features/custom-rules",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:8e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var xx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Conventions",placement:"section"},code_generation_rules:{header:"## Code Conventions",placement:"section"},review_checklist:{header:"## Review Conventions",placement:"section"}},Rh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,xx);return o&&n.push(o),{output:n.join(`
|
|
119
119
|
|
|
120
|
-
`),format:"aider",outputPath:"CONVENTIONS.md",warnings:[]}}},
|
|
120
|
+
`),format:"aider",outputPath:"CONVENTIONS.md",warnings:[]}}},kh={id:"aider",name:"Aider Conventions (CONVENTIONS.md)",description:"Aider coding conventions file in markdown format, loaded automatically from CONVENTIONS.md.",tier:2,outputPath:"CONVENTIONS.md",toolUrl:"https://aider.chat/docs/usage/conventions.html",scoringMetadata:{expectedSections:["## Identity","## File Conventions","## Code Conventions","## Review Conventions"],idealLengthRange:{min:200,max:8e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Ex={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Handling",placement:"section"},code_generation_rules:{header:"## Code Generation",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},jh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Ex);return o&&n.push(o),{output:n.join(`
|
|
121
121
|
|
|
122
|
-
`),format:"gemini",outputPath:"GEMINI.md",warnings:[]}}},
|
|
122
|
+
`),format:"gemini",outputPath:"GEMINI.md",warnings:[]}}},Nh={id:"gemini",name:"Gemini Instructions (GEMINI.md)",description:"Gemini CLI and Google AI Studio instructions in markdown format.",tier:2,outputPath:"GEMINI.md",toolUrl:"https://googlegemini.wiki/gemini-cli/customization/",scoringMetadata:{expectedSections:["## Identity","## File Handling","## Code Generation","## Review"],idealLengthRange:{min:200,max:8e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Tx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Ch={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Tx);return o&&n.push(o),{output:n.join(`
|
|
123
123
|
|
|
124
|
-
`),format:"continue",outputPath:".continuerules",warnings:[]}}},
|
|
124
|
+
`),format:"continue",outputPath:".continuerules",warnings:[]}}},Ph={id:"continue",name:"Continue Rules (.continuerules)",description:"Continue IDE extension rules file with markdown-based project instructions.",tier:2,outputPath:".continuerules",toolUrl:"https://docs.continue.dev/customize/deep-dives/rules",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Rx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Guidelines",placement:"section"},code_generation_rules:{header:"## Code Guidelines",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Oh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Rx);return o&&n.push(o),{output:n.join(`
|
|
125
125
|
|
|
126
|
-
`),format:"junie",outputPath:".junie/guidelines.md",warnings:[]}}},
|
|
126
|
+
`),format:"junie",outputPath:".junie/guidelines.md",warnings:[]}}},Dh={id:"junie",name:"Junie Guidelines (.junie/guidelines.md)",description:"JetBrains Junie AI agent guidelines in markdown format.",tier:2,outputPath:".junie/guidelines.md",toolUrl:"https://www.jetbrains.com/help/junie/guidelines.html",scoringMetadata:{expectedSections:["## Identity","## File Guidelines","## Code Guidelines","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var kx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Mh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,kx);return o&&n.push(o),{output:n.join(`
|
|
127
127
|
|
|
128
|
-
`),format:"jetbrains",outputPath:".aiassistant/rules/rulemetric.md",warnings:[]}}},
|
|
128
|
+
`),format:"jetbrains",outputPath:".aiassistant/rules/rulemetric.md",warnings:[]}}},Lh={id:"jetbrains",name:"JetBrains AI Assistant Rules",description:"JetBrains AI Assistant project-level rules in .aiassistant/rules/ directory.",tier:2,outputPath:".aiassistant/rules/rulemetric.md",toolUrl:"https://www.jetbrains.com/help/idea/ai-prompts.html",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var jx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Handling",placement:"section"},code_generation_rules:{header:"## Code Generation",placement:"section"},review_checklist:{header:"## Review Process",placement:"section"}},$h={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,jx);return o&&n.push(o),{output:n.join(`
|
|
129
129
|
|
|
130
|
-
`),format:"codex",outputPath:"AGENTS.md",warnings:[]}}},
|
|
130
|
+
`),format:"codex",outputPath:"AGENTS.md",warnings:[]}}},qh={id:"codex",name:"OpenAI Codex (AGENTS.md)",description:"OpenAI Codex CLI instructions using the AGENTS.md standard format.",tier:2,outputPath:"AGENTS.md",toolUrl:"https://github.com/openai/codex",scoringMetadata:{expectedSections:["## Identity","## File Handling","## Code Generation","## Review Process"],idealLengthRange:{min:200,max:8e3},supportedFeatures:["markdown-sections","code-blocks","lists","hierarchy"]}};var Nx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Uh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Nx);return o&&n.push(o),{output:n.join(`
|
|
131
131
|
|
|
132
|
-
`),format:"amazon-q",outputPath:".amazonq/rules/rulemetric.md",warnings:[]}}},
|
|
132
|
+
`),format:"amazon-q",outputPath:".amazonq/rules/rulemetric.md",warnings:[]}}},Bh={id:"amazon-q",name:"Amazon Q Developer (experimental)",description:"Amazon Q Developer rules format (experimental). Community-reported path.",tier:3,outputPath:".amazonq/rules/rulemetric.md",toolUrl:"https://aws.amazon.com/q/developer/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Cx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Fh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Cx);return o&&n.push(o),{output:n.join(`
|
|
133
133
|
|
|
134
|
-
`),format:"goose",outputPath:".goosehints",warnings:[]}}},
|
|
134
|
+
`),format:"goose",outputPath:".goosehints",warnings:[]}}},Hh={id:"goose",name:"Goose Hints (experimental)",description:"Block Goose hints file format (experimental). Community-reported path.",tier:3,outputPath:".goosehints",toolUrl:"https://block.github.io/goose/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Px={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Wh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Px);return o&&n.push(o),{output:n.join(`
|
|
135
135
|
|
|
136
|
-
`),format:"kilocode",outputPath:".kilocode/rules/rulemetric.md",warnings:[]}}},
|
|
136
|
+
`),format:"kilocode",outputPath:".kilocode/rules/rulemetric.md",warnings:[]}}},zh={id:"kilocode",name:"Kilocode Rules (experimental)",description:"Kilocode rules file format (experimental). Community-reported path.",tier:3,outputPath:".kilocode/rules/rulemetric.md",toolUrl:"https://kilocode.ai/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Ox={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Vh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Ox);return o&&n.push(o),{output:n.join(`
|
|
137
137
|
|
|
138
|
-
`),format:"augment",outputPath:".augment-guidelines/rulemetric.md",warnings:[]}}},
|
|
138
|
+
`),format:"augment",outputPath:".augment-guidelines/rulemetric.md",warnings:[]}}},Jh={id:"augment",name:"Augment Code Guidelines (experimental)",description:"Augment Code guidelines file format (experimental). Community-reported path.",tier:3,outputPath:".augment-guidelines/rulemetric.md",toolUrl:"https://www.augmentcode.com/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Dx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Gh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Dx);return o&&n.push(o),{output:n.join(`
|
|
139
139
|
|
|
140
|
-
`),format:"tabnine",outputPath:".tabnine/instructions.md",warnings:[]}}},
|
|
140
|
+
`),format:"tabnine",outputPath:".tabnine/instructions.md",warnings:[]}}},Kh={id:"tabnine",name:"Tabnine Instructions (experimental)",description:"Tabnine instructions file format (experimental). Community-reported path.",tier:3,outputPath:".tabnine/instructions.md",toolUrl:"https://www.tabnine.com/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Mx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Yh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Mx);return o&&n.push(o),{output:n.join(`
|
|
141
141
|
|
|
142
|
-
`),format:"opencode",outputPath:"AGENTS.md",warnings:[]}}},
|
|
142
|
+
`),format:"opencode",outputPath:"AGENTS.md",warnings:[]}}},Xh={id:"opencode",name:"OpenCode (experimental)",description:"OpenCode AGENTS.md format (experimental). Uses AGENTS.md standard.",tier:3,outputPath:"AGENTS.md",toolUrl:"https://opencode.ai/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Lx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},Qh={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Lx);return o&&n.push(o),{output:n.join(`
|
|
143
143
|
|
|
144
|
-
`),format:"warp",outputPath:".warp/rules/rulemetric.md",warnings:[]}}},
|
|
144
|
+
`),format:"warp",outputPath:".warp/rules/rulemetric.md",warnings:[]}}},Zh={id:"warp",name:"Warp Rules (experimental)",description:"Warp terminal rules file format (experimental). Community-reported path.",tier:3,outputPath:".warp/rules/rulemetric.md",toolUrl:"https://www.warp.dev/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var $x={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},e_={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,$x);return o&&n.push(o),{output:n.join(`
|
|
145
145
|
|
|
146
|
-
`),format:"trae",outputPath:".trae/rules/rulemetric.md",warnings:[]}}},
|
|
146
|
+
`),format:"trae",outputPath:".trae/rules/rulemetric.md",warnings:[]}}},t_={id:"trae",name:"Trae Rules (experimental)",description:"Trae rules file format (experimental). Community-reported path.",tier:3,outputPath:".trae/rules/rulemetric.md",toolUrl:"https://www.trae.ai/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var qx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},n_={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,qx);return o&&n.push(o),{output:n.join(`
|
|
147
147
|
|
|
148
|
-
`),format:"vscode-copilot",outputPath:".vscode/copilot-instructions.md",warnings:[]}}},
|
|
148
|
+
`),format:"vscode-copilot",outputPath:".vscode/copilot-instructions.md",warnings:[]}}},r_={id:"vscode-copilot",name:"VS Code Copilot Instructions (experimental)",description:"VS Code Copilot instructions file format (experimental). Community-reported path.",tier:3,outputPath:".vscode/copilot-instructions.md",toolUrl:"https://code.visualstudio.com/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Ux={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},o_={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Ux);return o&&n.push(o),{output:n.join(`
|
|
149
149
|
|
|
150
|
-
`),format:"qodo",outputPath:".qodo/guidelines.md",warnings:[]}}},
|
|
150
|
+
`),format:"qodo",outputPath:".qodo/guidelines.md",warnings:[]}}},s_={id:"qodo",name:"Qodo Guidelines (experimental)",description:"Qodo guidelines file format (experimental). Community-reported path.",tier:3,outputPath:".qodo/guidelines.md",toolUrl:"https://www.qodo.ai/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Bx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},i_={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Bx);return o&&n.push(o),{output:n.join(`
|
|
151
151
|
|
|
152
|
-
`),format:"genkit",outputPath:".genkit/rulemetric.md",warnings:[]}}},
|
|
152
|
+
`),format:"genkit",outputPath:".genkit/rulemetric.md",warnings:[]}}},a_={id:"genkit",name:"Firebase Genkit (experimental)",description:"Firebase Genkit rules file format (experimental). Community-reported path.",tier:3,outputPath:".genkit/rulemetric.md",toolUrl:"https://firebase.google.com/docs/genkit",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Fx={system_identity:{header:"## Identity",placement:"section"},file_access_rules:{header:"## File Rules",placement:"section"},code_generation_rules:{header:"## Code Rules",placement:"section"},review_checklist:{header:"## Review",placement:"section"}},c_={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Fx);return o&&n.push(o),{output:n.join(`
|
|
153
153
|
|
|
154
|
-
`),format:"amp",outputPath:"AGENTS.md",warnings:[]}}},
|
|
154
|
+
`),format:"amp",outputPath:"AGENTS.md",warnings:[]}}},u_={id:"amp",name:"Amp Rules (experimental)",description:"Amp AGENTS.md format (experimental). Uses AGENTS.md standard.",tier:3,outputPath:"AGENTS.md",toolUrl:"https://amp.dev/",scoringMetadata:{expectedSections:["## Identity","## File Rules","## Code Rules","## Review"],idealLengthRange:{min:200,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists"]}};var Hx={system_identity:{header:"## Persona",placement:"section"},file_access_rules:{header:"## Knowledge",placement:"section"},code_generation_rules:{header:"## Rules",placement:"section"},review_checklist:{header:"## Workflow",placement:"section"}},d_={convert(e,t){let n=[],r={includeTitle:!0,includeDescription:!0,includeMetadata:!1,...t};r.includeTitle&&n.push(`# ${e.frontmatter.name}`),r.includeDescription&&n.push(e.frontmatter.description);let o=ie(e.content,e.slots,Hx);return o&&n.push(o),{output:n.join(`
|
|
155
155
|
|
|
156
|
-
`),format:"soul-md",outputPath:"SOUL.md",warnings:[]}}},
|
|
157
|
-
`),r=t?.replace(/\.md$/i,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/\.md$/i,"")??"Untitled")){r=l.slice(2).trim();continue}let m=
|
|
156
|
+
`),format:"soul-md",outputPath:"SOUL.md",warnings:[]}}},l_={id:"soul-md",name:"SOUL.md",description:"OpenClaw agent personality format. Defines persona, rules, constraints, and knowledge for AI agents.",tier:2,outputPath:"SOUL.md",toolUrl:"https://openclaw.org/",scoringMetadata:{expectedSections:["## Persona","## Rules","## Knowledge","## Workflow"],idealLengthRange:{min:300,max:6e3},supportedFeatures:["markdown-sections","code-blocks","lists","hierarchy"]}};var Wx={"## identity":"system_identity","## file handling":"file_access_rules","## code generation":"code_generation_rules","## review process":"review_checklist"},p_={parse(e,t){let n=e.split(`
|
|
157
|
+
`),r=t?.replace(/\.md$/i,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/\.md$/i,"")??"Untitled")){r=l.slice(2).trim();continue}let m=Wx[p];if(m!==void 0){i&&(o[i]=c.join(`
|
|
158
158
|
`).trim()),i=m,c=[];continue}i?c.push(l):s.push(l)}i&&(o[i]=c.join(`
|
|
159
159
|
`).trim());let a=Object.keys(o).length>0;return{frontmatter:{name:r,description:`Imported from ${t??"AGENTS.md"}`,type:"instruction",scope:"personal",version:"1.0.0",tags:["imported"],compatibility:["agents-md"],...a?{slots:o}:{}},content:s.join(`
|
|
160
|
-
`).trim(),slots:a?o:null}}};var
|
|
161
|
-
`),r=t?.replace(/\.md$/i,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/\.md$/i,"")??"Untitled")){r=l.slice(2).trim();continue}let m=
|
|
160
|
+
`).trim(),slots:a?o:null}}};var zx={"## file access":"file_access_rules","## code rules":"code_generation_rules","## checklist":"review_checklist"},m_={parse(e,t){let n=e.split(`
|
|
161
|
+
`),r=t?.replace(/\.md$/i,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/\.md$/i,"")??"Untitled")){r=l.slice(2).trim();continue}let m=zx[p];if(m!==void 0){i&&(o[i]=c.join(`
|
|
162
162
|
`).trim()),i=m,c=[];continue}i?c.push(l):s.push(l)}i&&(o[i]=c.join(`
|
|
163
163
|
`).trim());let a=Object.keys(o).length>0;return{frontmatter:{name:r,description:`Imported from ${t??"CLAUDE.md"}`,type:"instruction",scope:"personal",version:"1.0.0",tags:["imported"],compatibility:["claude-code"],...a?{slots:o}:{}},content:s.join(`
|
|
164
|
-
`).trim(),slots:a?o:null}}};var
|
|
165
|
-
`),s=t?.replace(/\.(mdc|cursorrules)$/i,"").replace(/^\./,"")??"Untitled",i={},c=[],a=null,l=[];for(let m of o){let
|
|
164
|
+
`).trim(),slots:a?o:null}}};var Vx={"## file rules":"file_access_rules","## rules":"code_generation_rules","## review":"review_checklist"},f_={parse(e,t){let n=e,r=e.match(/^---\n[\s\S]*?\n---\n?/);r&&(n=e.slice(r[0].length));let o=n.split(`
|
|
165
|
+
`),s=t?.replace(/\.(mdc|cursorrules)$/i,"").replace(/^\./,"")??"Untitled",i={},c=[],a=null,l=[];for(let m of o){let y=m.toLowerCase().trim();if(m.startsWith("# ")&&s===(t?.replace(/\.(mdc|cursorrules)$/i,"").replace(/^\./,"")??"Untitled")){s=m.slice(2).trim();continue}let v=Vx[y];if(v!==void 0){a&&(i[a]=l.join(`
|
|
166
166
|
`).trim()),a=v,l=[];continue}a?l.push(m):c.push(m)}a&&(i[a]=l.join(`
|
|
167
167
|
`).trim());let p=Object.keys(i).length>0;return{frontmatter:{name:s,description:`Imported from ${t??".cursorrules"}`,type:"instruction",scope:"personal",version:"1.0.0",tags:["imported"],compatibility:["cursor"],...p?{slots:i}:{}},content:c.join(`
|
|
168
|
-
`).trim(),slots:p?i:null}}};var
|
|
169
|
-
`),r=t?.replace(/\.md$/i,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/\.md$/i,"")??"Untitled")){r=l.slice(2).trim();continue}let m=
|
|
168
|
+
`).trim(),slots:p?i:null}}};var Jx={"## file rules":"file_access_rules","## coding rules":"code_generation_rules","## review steps":"review_checklist"},g_={parse(e,t){let n=e.split(`
|
|
169
|
+
`),r=t?.replace(/\.md$/i,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/\.md$/i,"")??"Untitled")){r=l.slice(2).trim();continue}let m=Jx[p];if(m!==void 0){i&&(o[i]=c.join(`
|
|
170
170
|
`).trim()),i=m,c=[];continue}i?c.push(l):s.push(l)}i&&(o[i]=c.join(`
|
|
171
171
|
`).trim());let a=Object.keys(o).length>0;return{frontmatter:{name:r,description:`Imported from ${t??"copilot-instructions.md"}`,type:"instruction",scope:"personal",version:"1.0.0",tags:["imported"],compatibility:["github-copilot"],...a?{slots:o}:{}},content:s.join(`
|
|
172
|
-
`).trim(),slots:a?o:null}}};var
|
|
173
|
-
`),r=t?.replace(/^\./,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/^\./,"")??"Untitled")){r=l.slice(2).trim();continue}let m=
|
|
172
|
+
`).trim(),slots:a?o:null}}};var Gx={"## identity":"system_identity","## file rules":"file_access_rules","## code rules":"code_generation_rules","## review":"review_checklist"},h_={parse(e,t){let n=e.split(`
|
|
173
|
+
`),r=t?.replace(/^\./,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/^\./,"")??"Untitled")){r=l.slice(2).trim();continue}let m=Gx[p];if(m!==void 0){i&&(o[i]=c.join(`
|
|
174
174
|
`).trim()),i=m,c=[];continue}i?c.push(l):s.push(l)}i&&(o[i]=c.join(`
|
|
175
175
|
`).trim());let a=Object.keys(o).length>0;return{frontmatter:{name:r,description:`Imported from ${t??".windsurfrules"}`,type:"instruction",scope:"personal",version:"1.0.0",tags:["imported"],compatibility:["windsurf"],...a?{slots:o}:{}},content:s.join(`
|
|
176
|
-
`).trim(),slots:a?o:null}}};var
|
|
177
|
-
`),r=t?.replace(/\.md$/i,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/\.md$/i,"")??"Untitled")){r=l.slice(2).trim();continue}let m=
|
|
176
|
+
`).trim(),slots:a?o:null}}};var Kx={"## persona":"system_identity","## identity":"system_identity","## rules":"code_generation_rules","## constraints":"code_generation_rules","## workflow":"review_checklist","## knowledge":"file_access_rules"},__={parse(e,t){let n=e.split(`
|
|
177
|
+
`),r=t?.replace(/\.md$/i,"")??"Untitled",o={},s=[],i=null,c=[];for(let l of n){let p=l.toLowerCase().trim();if(l.startsWith("# ")&&r===(t?.replace(/\.md$/i,"")??"Untitled")){r=l.slice(2).trim();continue}let m=Kx[p];if(m!==void 0){i&&(o[i]=c.join(`
|
|
178
178
|
`).trim()),i=m,c=[];continue}i?c.push(l):s.push(l)}i&&(o[i]=c.join(`
|
|
179
179
|
`).trim());let a=Object.keys(o).length>0;return{frontmatter:{name:r,description:`Imported from ${t??"SOUL.md"}`,type:"instruction",scope:"personal",version:"1.0.0",tags:["imported"],compatibility:["soul-md"],...a?{slots:o}:{}},content:s.join(`
|
|
180
|
-
`).trim(),slots:a?o:null}}};function
|
|
180
|
+
`).trim(),slots:a?o:null}}};function us(){let e=new Hi;return e.register("agents-md",fh,gh),e.register("claude-md",hh,_h),e.register("cursorrules",yh,wh),e.register("copilot",vh,Ih),e.register("windsurf",bh,Sh),e.register("cline",Ah,xh),e.register("roo",Eh,Th),e.register("aider",Rh,kh),e.register("gemini",jh,Nh),e.register("continue",Ch,Ph),e.register("junie",Oh,Dh),e.register("jetbrains",Mh,Lh),e.register("codex",$h,qh),e.register("soul-md",d_,l_),e.register("amazon-q",Uh,Bh),e.register("goose",Fh,Hh),e.register("kilocode",Wh,zh),e.register("augment",Vh,Jh),e.register("tabnine",Gh,Kh),e.register("opencode",Yh,Xh),e.register("warp",Qh,Zh),e.register("trae",e_,t_),e.register("vscode-copilot",n_,r_),e.register("qodo",o_,s_),e.register("genkit",i_,a_),e.register("amp",c_,u_),e.registerReverse("agents-md",p_),e.registerReverse("claude-md",m_),e.registerReverse("cursorrules",f_),e.registerReverse("copilot",g_),e.registerReverse("windsurf",h_),e.registerReverse("soul-md",__),e}u(us,"defaultRegistry");function y_(e,t){let{expectedSections:n}=t;if(n.length===0)return{name:"completeness",score:100,details:"No expected sections defined."};let r=e.toLowerCase(),o=n.filter(a=>r.includes(a.toLowerCase())),s=Math.round(o.length/n.length*100),i=n.filter(a=>!r.includes(a.toLowerCase())),c=`${o.length}/${n.length} expected sections found.`;return i.length>0&&(c+=` Missing: ${i.join(", ")}`),{name:"completeness",score:s,details:c}}u(y_,"scoreCompleteness");function w_(e){let t=50,r=["always","never","must","use","avoid","ensure","require","do not"].filter(l=>e.toLowerCase().includes(l)).length;t+=Math.min(r*5,25);let o=(e.match(/```/g)||[]).length/2;t+=Math.min(o*5,15);let s=(e.match(/\*\.\w+|\.\w+\.\*/g)||[]).length;t+=Math.min(s*3,10);let c=["write good code","be careful","try to","when possible","if appropriate"].filter(l=>e.toLowerCase().includes(l)).length;t-=c*10,t=Math.max(0,Math.min(100,t));let a=t>=70?"Good specificity with concrete rules and examples.":t>=40?"Moderate specificity. Consider adding more concrete rules, code examples, or file patterns.":"Low specificity. Add imperative rules (always/never), code examples, and file patterns.";return{name:"specificity",score:t,details:a}}u(w_,"scoreSpecificity");function v_(e){let t=100,n=[];/^#{1,6} /m.test(e)||(t-=20,n.push("No markdown headings found.")),(e.match(/```/g)||[]).length%2!==0&&(t-=30,n.push("Unmatched code fence found."));let s=(e.match(/^- /gm)||[]).length,i=(e.match(/^\* /gm)||[]).length;s>0&&i>0&&(t-=10,n.push("Inconsistent list markers (mixing - and *).")),e.trim().length===0&&(t=0,n.push("Output is empty.")),t=Math.max(0,t);let c=n.length>0?n.join(" "):"Well-formatted markdown.";return{name:"formatting",score:t,details:c}}u(v_,"scoreFormatting");function I_(e,t){let{min:n,max:r}=t.idealLengthRange,o=e.length;if(o>=n&&o<=r)return{name:"length",score:100,details:`${o} chars is within ideal range (${n}-${r}).`};let s;if(o<n)s=Math.max(0,Math.round(o/n*100));else{let c=o-r,a=r*.5;s=Math.max(0,Math.round((1-c/a)*100))}let i=o<n?`${o} chars is below ideal minimum (${n}). Add more content.`:`${o} chars exceeds ideal maximum (${r}). Consider trimming.`;return{name:"length",score:s,details:i}}u(I_,"scoreLength");function b_(e,t){let{supportedFeatures:n}=t,r=100,o=[];!n.includes("mdc-frontmatter")&&/^---\n/m.test(e)&&(r-=20,o.push("Contains YAML frontmatter but format may not support it.")),!n.includes("import-syntax")&&/@import\b/.test(e)&&(r-=15,o.push("Contains @import syntax but format does not support it.")),!n.includes("code-blocks")&&/```/.test(e)&&(r-=10,o.push("Contains code blocks but format may not render them.")),r=Math.max(0,r);let s=o.length>0?o.join(" "):"Output uses only supported features.";return{name:"compatibility",score:r,details:s}}u(b_,"scoreCompatibility");function Jl(e,t){let n=[{...y_(e,t),weight:.3},{...w_(e),weight:.25},{...v_(e),weight:.15},{...I_(e,t),weight:.15},{...b_(e,t),weight:.15}],r=Math.round(n.reduce((s,i)=>s+i.score*i.weight,0)),o=[];for(let s of n)s.score<50?o.push({dimension:s.name,message:s.details,severity:s.score<30?"error":"warning"}):s.score<70&&o.push({dimension:s.name,message:s.details,severity:"info"});return{overall:r,dimensions:n,suggestions:o}}u(Jl,"scoreOutput");function Gl(e,t,n){let r=e.split(`
|
|
181
181
|
`),o=t.split(`
|
|
182
182
|
`),s=n.split(`
|
|
183
|
-
`),i=
|
|
184
|
-
`),hasConflicts:a.length>0,conflicts:a}}u(
|
|
183
|
+
`),i=S_(r,o),c=S_(r,s),a=[],l=[],p=0;for(;p<r.length||i.has(p)||c.has(p);){let m=i.get(p),y=c.get(p);if(m&&y)Xx(m.newLines,y.newLines)?l.push(...m.newLines):(a.push({localLines:y.newLines,upstreamLines:m.newLines,startLine:p}),l.push("<<<<<<< local"),l.push(...y.newLines),l.push("======="),l.push(...m.newLines),l.push(">>>>>>> upstream")),i.delete(p),c.delete(p),p=Math.max(m.endBase,y.endBase);else if(m)l.push(...m.newLines),i.delete(p),p=m.endBase;else if(y)l.push(...y.newLines),c.delete(p),p=y.endBase;else if(p<r.length)l.push(r[p]),p++;else break}return{merged:l.join(`
|
|
184
|
+
`),hasConflicts:a.length>0,conflicts:a}}u(Gl,"threeWayMerge");function S_(e,t){let n=new Map,r=Yx(e,t),o=0,s=0,i=0;for(;o<e.length||s<t.length;)if(i<r.length&&o<e.length&&s<t.length&&e[o]===r[i]&&t[s]===r[i])o++,s++,i++;else{let c=o,a=[];for(;o<e.length&&(i>=r.length||e[o]!==r[i]);)o++;for(;s<t.length&&(i>=r.length||t[s]!==r[i]);)a.push(t[s]),s++;n.set(c,{newLines:a,endBase:o})}return n}u(S_,"diffLines");function Yx(e,t){let n=e.length,r=t.length,o=Array.from({length:n+1},()=>Array(r+1).fill(0));for(let a=1;a<=n;a++)for(let l=1;l<=r;l++)o[a][l]=e[a-1]===t[l-1]?o[a-1][l-1]+1:Math.max(o[a-1][l],o[a][l-1]);let s=[],i=n,c=r;for(;i>0&&c>0;)e[i-1]===t[c-1]?(s.unshift(e[i-1]),i--,c--):o[i-1][c]>o[i][c-1]?i--:c--;return s}u(Yx,"computeLCS");function Xx(e,t){return e.length===t.length&&e.every((n,r)=>n===t[r])}u(Xx,"arraysEqual");var Vc=class{static{u(this,"AnthropicProvider")}name="anthropic";apiKey;constructor(t){this.apiKey=t}async complete(t,n){let r=n?.model??"claude-sonnet-4-5-20250929",o=n?.maxTokens??2048,s=n?.temperature??.3,i=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json","x-api-key":this.apiKey,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:r,max_tokens:o,temperature:s,messages:[{role:"user",content:t}]})});if(!i.ok){let a=await i.text();throw new Error(`Anthropic API error (${i.status}): ${a}`)}let c=await i.json();return{text:c.content.filter(a=>a.type==="text").map(a=>a.text).join(""),usage:{inputTokens:c.usage.input_tokens,outputTokens:c.usage.output_tokens}}}};var Jc=class{static{u(this,"OpenAIProvider")}name="openai";apiKey;constructor(t){this.apiKey=t}async complete(t,n){let r=n?.model??"gpt-4o",o=n?.maxTokens??2048,s=n?.temperature??.3,i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify({model:r,max_tokens:o,temperature:s,messages:[{role:"user",content:t}]})});if(!i.ok){let a=await i.text();throw new Error(`OpenAI API error (${i.status}): ${a}`)}let c=await i.json();return{text:c.choices[0]?.message.content??"",usage:{inputTokens:c.usage.prompt_tokens,outputTokens:c.usage.completion_tokens}}}};var Qx={anthropic:u(e=>new Vc(e),"anthropic"),openai:u(e=>new Jc(e),"openai")};function Wi(e,t){let n=Qx[e];if(!n)throw new Error(`Unknown LLM provider: ${e}`);return n(t)}u(Wi,"createLLMProvider");function zi(e,t){let n=t.map(r=>`- ID: ${r.id}
|
|
185
185
|
Name: ${r.name}
|
|
186
186
|
Description: ${r.description}
|
|
187
187
|
Tags: ${r.tags.join(", ")}
|
|
@@ -214,12 +214,12 @@ Return your response as JSON in this exact format:
|
|
|
214
214
|
]
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
Only include instructions with a relevance score >= 0.5. Order by score descending. Return valid JSON only, no markdown fences.`}u(zi,"buildRecommendationPrompt");function
|
|
217
|
+
Only include instructions with a relevance score >= 0.5. Order by score descending. Return valid JSON only, no markdown fences.`}u(zi,"buildRecommendationPrompt");function Kl(e){try{let t=e.match(/\{[\s\S]*\}/);if(!t)return[];let n=JSON.parse(t[0]);return!n.recommendations||!Array.isArray(n.recommendations)?[]:n.recommendations.filter(r=>typeof r.instructionId=="string"&&typeof r.score=="number"&&typeof r.reason=="string")}catch{return[]}}u(Kl,"parseRecommendationResponse");var A_=32e3,Zx={name:"x".repeat(64),description:"x".repeat(256),languages:["TypeScript","Python","Go"],topics:["x".repeat(32)],dependencies:["x".repeat(32)]};function Yl(e,t={}){if(e.length===0)return[];let n=t.charBudget??A_,r=zi(Zx,[]).length,o=[],s=[],i=0;for(let c of e){let a=eE(c);s.length>0&&r+i+a>n&&(o.push(s),s=[],i=0),s.push(c),i+=a}return s.length>0&&o.push(s),o}u(Yl,"batchCandidatesForPrompt");function eE(e){return`- ID: ${e.id}
|
|
218
218
|
Name: ${e.name}
|
|
219
219
|
Description: ${e.description}
|
|
220
220
|
Tags: ${e.tags.join(", ")}
|
|
221
|
-
Preview: ${e.contentPreview}`.length+2}u(
|
|
222
|
-
`);for(let i of nE){let c=o.match(i.pattern);c&&r.push({pattern:i.description,severity:i.severity,category:i.category,match:c[0].slice(0,100)})}let s=100;for(let i of r)s-=tE[i.severity]??5;return{score:Math.max(0,Math.min(100,s)),findings:r}}u(Xl,"scanContent");var _n=new rE,oE=et.object({name:et.string().min(1).max(255),description:et.string().min(1),scope:et.enum(["org","team","project","personal"]),scopeRef:et.string().uuid().optional(),version:et.string().default("1.0.0"),content:et.string().min(1),tags:et.array(et.string()).optional(),compatibility:et.array(et.string()).optional()}),sE=et.object({name:et.string().min(1).max(255).optional(),description:et.string().min(1).optional(),version:et.string().optional(),content:et.string().min(1).optional(),tags:et.array(et.string()).optional(),compatibility:et.array(et.string()).optional(),changeSummary:et.string().optional()});_n.get("/instructions",async e=>{let t=e.get("userId"),n=e.req.query("search"),r=e.req.query("scope"),o=e.req.query("tags"),s=e.req.query("type"),i=parseInt(e.req.query("limit")??"100",10),c=parseInt(e.req.query("offset")??"0",10),a=[$e(y.archived,!1),$e(y.createdBy,t)];if(r&&a.push($e(y.scope,r)),s&&a.push($e(y.type,s)),n){let g=Ze(n);a.push(Zl(Ql(y.name,`%${g}%`),Ql(y.description,`%${g}%`),Ql(y.content,`%${g}%`)))}let l=await d.select().from(y).where(Nr(...a)).orderBy(A_(y.updatedAt)).limit(i).offset(c);if(o){let g=o.split(",").map(h=>h.trim().toLowerCase());l=l.filter(h=>g.some(w=>h.tags?.some(I=>I.toLowerCase().includes(w))))}let p=l.map(g=>g.id),m=p.length>0?await d.select({instructionId:ot.instructionId,projectName:O.name,projectId:O.id}).from(ot).innerJoin(O,$e(O.id,ot.projectId)).where(Vi`${ot.instructionId} IN (${Vi.join(p.map(g=>Vi`${g}`),Vi`, `)})`):[],_=new Map;for(let g of m){let h=_.get(g.instructionId)??[];h.push({projectId:g.projectId,projectName:g.projectName}),_.set(g.instructionId,h)}let v=l.map(g=>({...g,projects:_.get(g.id)??[]}));return Rt({userId:t,surface:"api",action:"list"}),e.json(v)});_n.get("/instructions/by-hash/:hash",async e=>{let t=e.get("userId"),n=e.req.param("hash"),[r]=await d.select({id:y.id,name:y.name,contextIdentity:y.contextIdentity,version:y.version,type:y.type}).from(y).where(Nr($e(y.contentHash,n),$e(y.createdBy,t),$e(y.archived,!1))).limit(1);return r?e.json({instruction:r}):e.json({instruction:null})});_n.post("/instructions/by-hashes",async e=>{let t=e.get("userId"),n=await e.req.json(),r=et.array(et.string()).max(200).parse(n.hashes??[]),o=et.array(et.string()).max(200).parse(n.identities??[]);if(r.length===0&&o.length===0)return e.json({instructions:{}});let s=[$e(y.createdBy,t),$e(y.archived,!1)],i=[];r.length>0&&i.push(S_(y.contentHash,r)),o.length>0&&i.push(S_(y.contextIdentity,o));let c=await d.select({id:y.id,name:y.name,contextIdentity:y.contextIdentity,version:y.version,type:y.type,contentHash:y.contentHash}).from(y).where(Nr(...s,i.length===1?i[0]:Zl(...i))),a={};for(let l of c)l.contentHash&&(a[l.contentHash]=l),l.contextIdentity&&(a[l.contextIdentity]=l);return e.json({instructions:a})});_n.get("/instructions/:id/sessions",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await d.select({sessionId:te.sessionId,linkMethod:te.linkMethod,tool:f.tool,projectPath:f.projectPath,startedAt:f.startedAt,endedAt:f.endedAt,analysis:f.analysis}).from(te).innerJoin(f,$e(f.id,te.sessionId)).where(Nr($e(te.instructionId,n),$e(f.userId,t))).orderBy(A_(f.startedAt)).limit(50);return e.json({sessions:r})});_n.get("/instructions/:id",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select().from(y).where(Nr($e(y.id,t),$e(y.archived,!1),Zl($e(y.createdBy,n),$e(y.scope,"public"))));return r?(Rt({instructionId:t,userId:n,surface:"api",action:"view"}),e.json(r)):e.json({error:"Instruction not found"},404)});var iE=/<\/?(?:system-reminder|system|available-deferred-tools|tool-result)>/i;function x_(e){return iE.test(e)?"Content contains forbidden system tags":null}u(x_,"validateNoForbiddenTags");_n.post("/instructions",async e=>{let t=e.get("userId"),n=await e.req.json(),r=oE.parse(n),o=x_(r.content);if(o)return e.json({error:o},422);r.name=Wn(r.name),r.description=Wn(r.description);let s={},i=null;try{let p=os(r.content);s=p.frontmatter,i=p.slots}catch{s={name:r.name,description:r.description,type:"instruction",scope:r.scope,version:r.version}}let c=r.scope==="personal"?t:r.scopeRef??null,a=Xl(r.content,r.name,r.description),[l]=await d.insert(y).values({name:r.name,description:r.description,type:"instruction",scope:r.scope,scopeRef:c,version:r.version,content:r.content,frontmatter:s,slots:i,tags:r.tags??[],compatibility:r.compatibility??[],createdBy:t,scanScore:a.score,scanFindings:a.findings.length>0?a.findings:null}).returning();return await d.insert(me).values({instructionId:l.id,versionNumber:1,content:r.content,frontmatter:s,changeSummary:"Initial version",createdBy:t}),Rt({instructionId:l.id,userId:t,surface:"api",action:"create"}),e.json(l,201)});_n.put("/instructions/:id",async e=>{let t=e.req.param("id"),n=e.get("userId"),r=await e.req.json(),o=sE.parse(r);if(o.content){let m=x_(o.content);if(m)return e.json({error:m},422)}o.name&&(o.name=Wn(o.name)),o.description&&(o.description=Wn(o.description));let[s]=await d.select().from(y).where(Nr($e(y.id,t),$e(y.createdBy,n),$e(y.archived,!1)));if(!s)return e.json({error:"Instruction not found"},404);let i=s.frontmatter,c=s.slots;if(o.content)try{let m=os(o.content);i=m.frontmatter,c=m.slots}catch{}let a={};if(o.content||o.name||o.description){let m=Xl(o.content??s.content,o.name??s.name,o.description??s.description);a.scanScore=m.score,a.scanFindings=m.findings.length>0?m.findings:null}let l,p=4;for(let m=0;m<=p;m++)try{l=await d.transaction(async _=>{await _.select({id:y.id}).from(y).where($e(y.id,t)).for("update");let[{maxVersion:v}]=await _.select({maxVersion:Vi`COALESCE(MAX(${me.versionNumber}), 0)`}).from(me).where($e(me.instructionId,t)),g=v+1,[h]=await _.update(y).set({...o.name&&{name:o.name},...o.description&&{description:o.description},...o.version&&{version:o.version},...o.content&&{content:o.content},...o.tags&&{tags:o.tags},...o.compatibility&&{compatibility:o.compatibility},frontmatter:i,slots:c,...a,updatedAt:new Date}).where($e(y.id,t)).returning();return await _.insert(me).values({instructionId:t,versionNumber:g,content:o.content??s.content,frontmatter:i,changeSummary:o.changeSummary??null,createdBy:n}),h});break}catch(_){if(_.cause?.code==="23505"&&m<p)continue;throw _}return l?(Rt({instructionId:t,userId:n,surface:"api",action:"update"}),e.json(l)):e.json({error:"Instruction update failed"},500)});_n.delete("/instructions/:id",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select().from(y).where(Nr($e(y.id,t),$e(y.createdBy,n),$e(y.archived,!1)));if(!r)return e.json({error:"Instruction not found"},404);let[o]=await d.update(y).set({archived:!0,archivedAt:new Date,archivedBy:n}).where($e(y.id,t)).returning();return Rt({instructionId:t,userId:n,surface:"api",action:"delete"}),e.json(o)});_n.get("/instructions/:id/versions",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select({id:y.id}).from(y).where(Nr($e(y.id,t),$e(y.createdBy,n)));if(!r)return e.json({error:"Instruction not found"},404);let o=await d.select().from(me).where($e(me.instructionId,t)).orderBy(me.versionNumber);return e.json(o)});import{Hono as aE}from"hono";import{z as ep}from"zod";import{eq as E_,and as cE}from"drizzle-orm";var Jc=new aE,uE=ep.object({format:ep.enum(Wc),score:ep.enum(["true","false"]).optional().default("false")});Jc.post("/instructions/:id/convert",async e=>{let t=e.req.param("id"),n=uE.parse(e.req.query()),r=n.format,o=n.score==="true",[s]=await d.select().from(y).where(cE(E_(y.id,t),E_(y.archived,!1)));if(!s)return e.json({error:"Instruction not found"},404);let i;try{i=os(s.content)}catch{i={frontmatter:{name:s.name,description:s.description??"",type:"instruction",scope:s.scope,version:s.version??"1.0.0",tags:s.tags??[],compatibility:s.compatibility??[]},content:s.content,slots:s.slots}}let c=ss(),a=c.get(r);if(!a)return e.json({error:`Unsupported format: ${r}`},400);let l=a.convert(i),p=e.get("userId");if(Rt({instructionId:t,userId:p,surface:"api",action:"convert",metadata:{format:r}}),o){let m=c.getMetadata(r);if(m){let _=zl(l.output,m.scoringMetadata);return e.json({...l,score:_})}}return e.json(l)});import{Hono as dE}from"hono";var Gc=new dE;Gc.get("/converters",async e=>{let n=ss().listAll().map(r=>({id:r.metadata.id,name:r.metadata.name,description:r.metadata.description,tier:r.metadata.tier,outputPath:r.metadata.outputPath,toolUrl:r.metadata.toolUrl}));return e.json(n)});import{Hono as lE}from"hono";import{z as lr}from"zod";var Kc=new lE,pE=lr.object({content:lr.string().min(1),sourceFormat:lr.enum(Wc).optional(),filename:lr.string().optional(),name:lr.string().optional(),scope:lr.enum(["org","team","project","personal"]).default("personal"),scopeRef:lr.string().uuid().optional(),tags:lr.array(lr.string()).optional()});Kc.post("/instructions/import",async e=>{let t=e.get("userId"),n=await e.req.json(),r=pE.parse(n),o=r.sourceFormat??null;if(!o){let m=Hl({filename:r.filename,content:r.content});m&&(o=m.format)}if(!o)return e.json({error:"Could not detect format. Provide sourceFormat explicitly."},400);let s=ss(),i=s.getReverse(o);if(!i)return e.json({error:`No import parser for format: ${o}`,supportedFormats:s.listReverseFormats()},400);let c=i.parse(r.content,r.filename),a=r.name??c.frontmatter.name,l=r.scope==="personal"?t:r.scopeRef??null,[p]=await d.insert(y).values({name:a,description:c.frontmatter.description,type:"instruction",scope:r.scope,scopeRef:l,version:"1.0.0",content:c.content,frontmatter:c.frontmatter,slots:c.slots,tags:r.tags??c.frontmatter.tags??[],compatibility:c.frontmatter.compatibility??[],createdBy:t}).returning();return await d.insert(me).values({instructionId:p.id,versionNumber:1,content:c.content,frontmatter:c.frontmatter,changeSummary:`Imported from ${o}`,createdBy:t}),Rt({instructionId:p.id,userId:t,surface:"api",action:"import",metadata:{sourceFormat:o}}),e.json({instruction:p,sourceFormat:o,parseWarnings:[]},201)});import{Hono as mE}from"hono";import{eq as Cr,and as tp}from"drizzle-orm";var Ji=new mE;Ji.post("/instructions/:id/fork",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(y).where(tp(Cr(y.id,n),Cr(y.archived,!1)));if(!r)return e.json({error:"Instruction not found"},404);if(r.createdBy===t)return e.json({error:"Cannot fork your own instruction"},400);if(r.scope==="org"&&r.scopeRef){let[s]=await d.select({id:y.id}).from(y).where(tp(Cr(y.createdBy,t),Cr(y.scope,"org"),Cr(y.scopeRef,r.scopeRef))).limit(1);if(!s)return e.json({error:"Instruction not found"},404)}else if(r.scope!=="org")return e.json({error:"Instruction not found"},404);let[o]=await d.insert(y).values({name:`${r.name} (fork)`,description:r.description,type:r.type,scope:"personal",scopeRef:t,version:"1.0.0",content:r.content,frontmatter:r.frontmatter,slots:r.slots,tags:r.tags,compatibility:r.compatibility,createdBy:t,forkedFromId:r.id,upstreamVersion:r.version}).returning();return await d.insert(me).values({instructionId:o.id,versionNumber:1,content:o.content,frontmatter:o.frontmatter,changeSummary:`Forked from ${r.name}`,createdBy:t}),await d.insert(Nt).values({instructionId:o.id,eventType:"fork",actorId:t,metadata:{sourceId:r.id,sourceName:r.name,sourceVersion:r.version}}),Rt({instructionId:o.id,userId:t,surface:"api",action:"fork"}),e.json(o,201)});Ji.get("/instructions/:id/events",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select({id:y.id}).from(y).where(tp(Cr(y.id,t),Cr(y.createdBy,n)));if(!r)return e.json({error:"Instruction not found"},404);let o=await d.select().from(Nt).where(Cr(Nt.instructionId,t)).orderBy(Nt.createdAt);return e.json(o)});import{Hono as fE}from"hono";import{eq as jn,and as T_,sql as gE}from"drizzle-orm";var Gi=new fE;Gi.get("/instructions/:id/upstream",async e=>{let t=e.req.param("id"),[n]=await d.select().from(y).where(T_(jn(y.id,t),jn(y.archived,!1)));if(!n)return e.json({error:"Instruction not found"},404);if(!n.forkedFromId)return e.json({error:"This instruction is not a fork"},400);let[r]=await d.select().from(y).where(jn(y.id,n.forkedFromId));return r?e.json({hasUpdate:r.version!==n.upstreamVersion,currentVersion:n.upstreamVersion,upstreamVersion:r.version,parentId:r.id,parentName:r.name}):e.json({hasUpdate:!1,currentVersion:n.upstreamVersion,upstreamVersion:null,parentId:n.forkedFromId})});Gi.post("/instructions/:id/pull-upstream",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(y).where(T_(jn(y.id,n),jn(y.createdBy,t),jn(y.archived,!1)));if(!r)return e.json({error:"Instruction not found"},404);if(!r.forkedFromId)return e.json({error:"This instruction is not a fork"},400);let[o]=await d.select().from(y).where(jn(y.id,r.forkedFromId));if(!o)return e.json({error:"Parent instruction no longer exists"},404);let[s]=await d.select().from(me).where(jn(me.instructionId,o.id)).orderBy(me.versionNumber).limit(1),i=s?.content??o.content,c=Vl(i,o.content,r.content);if(c.hasConflicts)return e.json({hasConflicts:!0,merged:c.merged,conflicts:c.conflicts});let a,l=4;for(let p=0;p<=l;p++)try{a=await d.transaction(async m=>{await m.select({id:y.id}).from(y).where(jn(y.id,n)).for("update");let[_]=await m.select({maxVersion:gE`COALESCE(MAX(${me.versionNumber}), 0)`}).from(me).where(jn(me.instructionId,n)),v=(_?.maxVersion??0)+1,[g]=await m.update(y).set({content:c.merged,upstreamVersion:o.version,updatedAt:new Date}).where(jn(y.id,n)).returning();return await m.insert(me).values({instructionId:n,versionNumber:v,content:c.merged,frontmatter:r.frontmatter,changeSummary:`Pulled upstream changes from ${o.name} (${o.version})`,createdBy:t}),await m.insert(Nt).values({instructionId:n,eventType:"pull_upstream",actorId:t,metadata:{parentId:o.id,parentVersion:o.version,previousUpstreamVersion:r.upstreamVersion}}),g});break}catch(m){if(m.cause?.code==="23505"&&p<l)continue;throw m}return a?(Rt({instructionId:n,userId:t,surface:"api",action:"pull_upstream"}),e.json({hasConflicts:!1,instruction:a})):e.json({error:"Pull-upstream failed after version conflict"},500)});import{Hono as hE}from"hono";import{z as Pr}from"zod";import{eq as Pt,and as fo,sql as _E}from"drizzle-orm";var yE=Pr.object({scope:Pr.enum(["team","org"]),scopeRef:Pr.string().uuid()}),Ki=new hE;Ki.post("/instructions/:id/promote",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=yE.parse(await e.req.json()),[o]=await d.select().from(y).where(fo(Pt(y.id,n),Pt(y.createdBy,t),Pt(y.archived,!1)));if(!o)return e.json({error:"Instruction not found"},404);if(o.scope==="org")return e.json({error:"Instruction is already org-scoped"},400);if(r.scope==="team"){let[a]=await d.select().from(ge).where(fo(Pt(ge.userId,t),Pt(ge.teamId,r.scopeRef)));if(!a)return e.json({error:"You are not a member of this team"},403)}else if(r.scope==="org"){let[a]=await d.select().from(K).where(fo(Pt(K.userId,t),Pt(K.orgId,r.scopeRef)));if(!a||a.role!=="admin"&&a.role!=="owner")return e.json({error:"You must be an org admin to promote to org scope"},403)}let s=o.scope,i=o.scopeRef,[c]=await d.update(y).set({scope:r.scope,scopeRef:r.scopeRef,updatedAt:new Date}).where(Pt(y.id,n)).returning();return await d.insert(Nt).values({instructionId:n,eventType:"promote",actorId:t,metadata:{fromScope:s,fromScopeRef:i,toScope:r.scope,toScopeRef:r.scopeRef}}),Rt({instructionId:n,userId:t,surface:"api",action:"promote"}),e.json(c)});var wE=Pr.object({targetScope:Pr.enum(["personal","team","org"]),targetScopeRef:Pr.string().uuid().optional(),name:Pr.string().optional(),seedEvalTarget:Pr.boolean().optional()});async function vE(e){let[t]=await d.select({id:R.id}).from(R).where(_E`${R.metadata}->>'instructionId' = ${e}`).limit(1);return t??null}u(vE,"findExistingEvalTarget");Ki.post("/instructions/:id/promote-from-public",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=wE.parse(await e.req.json()),[o]=await d.select().from(y).where(fo(Pt(y.id,n),Pt(y.scope,"public")));if(!o)return e.json({error:"Public instruction not found"},404);if(r.targetScope==="team"){if(!r.targetScopeRef)return e.json({error:"targetScopeRef is required for team scope"},400);let[m]=await d.select().from(ge).where(fo(Pt(ge.userId,t),Pt(ge.teamId,r.targetScopeRef)));if(!m)return e.json({error:"You are not a member of this team"},403)}else if(r.targetScope==="org"){if(!r.targetScopeRef)return e.json({error:"targetScopeRef is required for org scope"},400);let[m]=await d.select().from(K).where(fo(Pt(K.userId,t),Pt(K.orgId,r.targetScopeRef)));if(!m||m.role!=="admin"&&m.role!=="owner")return e.json({error:"You must be an org admin to promote into an org"},403)}let s=r.targetScope==="personal"?t:r.targetScopeRef,i=r.name??o.name,c=r.seedEvalTarget??(r.targetScope==="org"||r.targetScope==="team"),[a]=await d.select().from(y).where(fo(Pt(y.scope,r.targetScope),Pt(y.scopeRef,s),Pt(y.forkedFromId,n),Pt(y.archived,!1)));if(a){let m=null;return c&&(m=(await vE(a.id))?.id??null),e.json({instructionId:a.id,alreadyExisted:!0,evalTargetId:m})}let[l]=await d.insert(y).values({name:i,description:o.description,type:o.type,scope:r.targetScope,scopeRef:s,version:o.version,content:o.content,frontmatter:o.frontmatter,slots:o.slots,tags:o.tags,compatibility:o.compatibility,createdBy:t,forkedFromId:o.id,upstreamVersion:o.upstreamVersion??o.version,contentHash:o.contentHash,contextIdentity:o.contextIdentity}).returning();if(!l)return e.json({error:"Failed to clone instruction"},500);await d.insert(me).values({instructionId:l.id,versionNumber:1,content:o.content,frontmatter:o.frontmatter,changeSummary:`Promoted from public skill ${o.name}`,createdBy:t}),await d.insert(Nt).values({instructionId:l.id,eventType:"promote_from_public",actorId:t,metadata:{sourceInstructionId:o.id,sourceName:o.name,targetScope:r.targetScope,targetScopeRef:s}}),Rt({instructionId:l.id,userId:t,surface:"api",action:"promote_from_public"});let p=null;if(c){let[m]=await d.insert(R).values({userId:t,name:`${i} \u2014 baseline eval`,type:"instruction",content:o.content,description:`Auto-seeded from public skill \`${o.name}\` on promote.`,metadata:{instructionId:l.id,publicSourceId:o.id,publicContentHash:o.contentHash??null,publicVersion:o.version??null}}).returning({id:R.id});p=m?.id??null}return e.json({instructionId:l.id,alreadyExisted:!1,evalTargetId:p})});import{Hono as IE}from"hono";import{z as R_}from"zod";import{eq as dn,and as Yi,or as k_,inArray as j_,sql as Yc,desc as bE}from"drizzle-orm";var Xi=new IE,SE=R_.object({badge:R_.enum(["recommended","required"]).nullable()});Xi.get("/catalog",async e=>{let t=e.get("userId"),n=e.req.query("badge"),r=e.req.query("scope"),o=e.req.query("search"),s=parseInt(e.req.query("contentPreview")??"0",10),i=Number.isFinite(s)?Math.min(Math.max(s,0),400):0,c=parseInt(e.req.query("limit")??"50",10),a=parseInt(e.req.query("offset")??"0",10),l=Math.min(Math.max(c,1),200),p=Math.max(a,0),m=await d.select({orgId:K.orgId}).from(K).where(dn(K.userId,t)),_=await d.select({teamId:ge.teamId}).from(ge).where(dn(ge.userId,t)),v=m.map(x=>x.orgId).filter(x=>x!==null),g=_.map(x=>x.teamId).filter(x=>x!==null),h=[dn(y.archived,!1)],w=[dn(y.scope,"public")];if(v.length>0&&w.push(Yi(dn(y.scope,"org"),j_(y.scopeRef,v))),g.length>0&&w.push(Yi(dn(y.scope,"team"),j_(y.scopeRef,g))),h.push(k_(...w)),n&&h.push(dn(y.badge,n)),r&&h.push(dn(y.scope,r)),o){let x=Ze(o);h.push(k_(Yc`${y.name} ILIKE ${`%${x}%`}`,Yc`${y.description} ILIKE ${`%${x}%`}`))}let I=[bE(Yc`COALESCE(${y.sourceUpdatedAt}, ${y.updatedAt})`)],b={id:y.id,name:y.name,description:y.description,type:y.type,scope:y.scope,scopeRef:y.scopeRef,version:y.version,tags:y.tags,badge:y.badge,popularityScore:y.popularityScore,updatedAt:y.updatedAt,createdAt:y.createdAt,sourceUpdatedAt:y.sourceUpdatedAt},A=await(i>0?lt:d).select(i>0?{...b,contentPreview:Yc`left(${y.content}, ${i})`}:b).from(y).where(Yi(...h)).orderBy(...I).limit(l).offset(p);return Rt({userId:t,surface:"api",action:"search",metadata:o?{query:o}:void 0}),e.header("Cache-Control","private, max-age=30"),e.json(A)});Xi.post("/instructions/:id/badge",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=SE.parse(await e.req.json()),[o]=await d.select().from(y).where(Yi(dn(y.id,n),dn(y.archived,!1)));if(!o)return e.json({error:"Instruction not found"},404);if(o.scope!=="org"&&o.scope!=="team")return e.json({error:"Badges can only be set on org or team-scoped instructions"},400);let s=o.scopeRef;if(!s)return e.json({error:"Instruction has no scope reference"},400);let[i]=await d.select().from(K).where(Yi(dn(K.userId,t),dn(K.orgId,s)));if(!i||i.role!=="admin"&&i.role!=="owner")return e.json({error:"Only admins of the owning organization can set badges"},403);let[c]=await d.update(y).set({badge:r.badge,updatedAt:new Date}).where(dn(y.id,n)).returning(),a=r.badge?"badge_set":"badge_removed";return await d.insert(Nt).values({instructionId:n,eventType:a,actorId:t,metadata:{badge:r.badge}}),e.json(c)});import{Hono as AE}from"hono";import{eq as Or,and as Xc,or as xE,inArray as N_}from"drizzle-orm";var Qc=new AE;Qc.post("/projects/:id/recommendations",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(O).where(Xc(Or(O.id,n),Or(O.createdBy,t)));if(!r)return e.json({error:"Project not found"},404);let o=await d.select({orgId:K.orgId}).from(K).where(Or(K.userId,t)),s=await d.select({teamId:ge.teamId}).from(ge).where(Or(ge.userId,t)),i=o.map(h=>h.orgId).filter(h=>h!==null),c=s.map(h=>h.teamId).filter(h=>h!==null),a=[Or(y.scope,"public")];i.length>0&&a.push(Xc(Or(y.scope,"org"),N_(y.scopeRef,i))),c.length>0&&a.push(Xc(Or(y.scope,"team"),N_(y.scopeRef,c)));let l=await d.select().from(y).where(Xc(Or(y.archived,!1),xE(...a))).limit(50);if(l.length===0)return e.json({recommendations:[],error:null});let p={name:r.name,description:r.description,languages:[],topics:[],dependencies:[]};if(r.githubRepo)try{let h=r.githubRepo.replace("https://github.com/",""),[w,I]=await Promise.all([fetch(`https://api.github.com/repos/${h}`,{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"RuleMetric"}}),fetch(`https://api.github.com/repos/${h}/languages`,{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"RuleMetric"}})]);if(w.ok){let b=await w.json();p.topics=b.topics??[]}if(I.ok){let b=await I.json();p.languages=Object.keys(b)}}catch{}let m=l.map(h=>({id:h.id,name:h.name,description:h.description??"",tags:h.tags??[],contentPreview:(h.content??"").slice(0,400)})),_=process.env.LLM_PROVIDER,v=process.env.LLM_API_KEY;if(!_||!v)return e.json({recommendations:[],error:"LLM not configured"});let g=await Kl(p,m,{llmProvider:_,llmApiKey:v});return e.json(g)});import{Hono as EE}from"hono";import{z as tn}from"zod";import{eq as yt,and as is,or as TE,sql as bt,asc as RE,desc as np}from"drizzle-orm";var zn=new EE;zn.get("/instruction-suggestions/pending-count",async e=>{let t=e.get("userId"),n=await d.select({projectPath:Y.projectPath,count:bt`count(*)::int`}).from(Y).where(is(yt(Y.userId,t),bt`${Y.acceptedAt} IS NULL`,bt`(${Y.dismissedAt} IS NULL OR ${Y.dismissedAt} < now() - interval '30 days')`)).groupBy(Y.projectPath).orderBy(np(bt`count(*)`)),r=n.reduce((o,s)=>o+s.count,0);return e.json({total:r,byProject:n.slice(0,5)})});zn.get("/instruction-suggestions/stats",async e=>{let t=e.get("userId"),[n]=await d.select({total:bt`count(*)::int`,accepted:bt`count(*) filter (where ${Y.acceptedAt} is not null)::int`,dismissed:bt`count(*) filter (where ${Y.acceptedAt} is null and ${Y.dismissedAt} is not null)::int`,pending:bt`count(*) filter (where ${Y.acceptedAt} is null and ${Y.dismissedAt} is null)::int`,stale:bt`count(*) filter (where ${Y.isStale})::int`,promoted:bt`count(*) filter (where ${Y.promotedToInstructionId} is not null)::int`}).from(Y).where(yt(Y.userId,t)),r=await d.select({eventType:zt.eventType,count:bt`count(*)::int`}).from(zt).where(yt(zt.userId,t)).groupBy(zt.eventType),o={surfaced:0,surfaced_with_content:0,accepted:0,dismissed:0,promoted:0,proxy_injected:0};for(let a of r)o[a.eventType]=a.count;let[s]=await d.select({distinctUsersWithSuggestions:bt`count(distinct ${Y.userId})::int`}).from(Y),i=o.surfaced+o.surfaced_with_content,c=o.accepted+o.dismissed;return e.json({suggestions:n,events:o,funnel:{surfaced:i,acted:c,adoptionRate:i>0?c/i:0},denominator:{distinctUsersWithSuggestions:s?.distinctUsersWithSuggestions??0,scope:"global"}})});var C_=2e3,kE=.7;function jE(e){return e.length<=C_?e:e.slice(0,C_)+"... [truncated]"}u(jE,"truncateContent");zn.get("/instruction-suggestions",async e=>{let t=e.get("userId"),n=e.req.query("projectId"),r=e.req.query("projectPath"),o=Number(e.req.query("limit")??"5"),s=Math.min(Math.max(o,1),10),i=e.req.query("includeContent")==="true";if(!n&&!r)return e.json({error:"projectId or projectPath is required"},400);let c=n?yt(Y.projectId,n):yt(Y.projectPath,r),l=(await d.select({id:Y.id,instructionId:Y.instructionId,score:Y.score,reason:Y.reason,generatedAt:Y.generatedAt,isStale:Y.isStale,name:y.name,description:y.description,tags:y.tags,instructionScope:y.scope,_rawContent:y.content}).from(Y).innerJoin(y,yt(Y.instructionId,y.id)).where(is(yt(Y.userId,t),c,bt`${Y.acceptedAt} IS NULL`,bt`(${Y.dismissedAt} IS NULL OR ${Y.dismissedAt} < now() - interval '30 days')`)).orderBy(RE(Y.isStale),np(Y.score)).limit(s)).map(_=>{let{_rawContent:v,...g}=_,h=i&&_.score>=kE&&typeof v=="string"?jE(v):null;return{...g,content:h}}),p=await d.select({eventType:zt.eventType,count:bt`count(*)::int`}).from(zt).innerJoin(Y,yt(zt.suggestionId,Y.id)).where(is(yt(zt.userId,t),c)).groupBy(zt.eventType),m={};for(let _ of p)m[_.eventType]=_.count;return e.json({suggestions:l,stats:m})});zn.get("/instruction-suggestions/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:Y.id,instructionId:Y.instructionId,projectPath:Y.projectPath,score:Y.score,reason:Y.reason,generatedAt:Y.generatedAt,isStale:Y.isStale,dismissedAt:Y.dismissedAt,acceptedAt:Y.acceptedAt,name:y.name,description:y.description,tags:y.tags,instructionScope:y.scope}).from(Y).innerJoin(y,yt(Y.instructionId,y.id)).where(is(yt(Y.id,n),yt(Y.userId,t)));return r?e.json(r):e.json({error:"Suggestion not found"},404)});var NE=tn.object({projectPath:tn.string().min(1),projectId:tn.string().uuid().optional(),suggestions:tn.array(tn.object({instructionId:tn.string().uuid(),score:tn.number().min(0).max(1),reason:tn.string()})).max(50)});async function CE(e){try{let[t]=await d.select({projectId:ce.projectId}).from(ce).where(yt(ce.path,e)).orderBy(np(ce.lastSeen)).limit(1);return t?.projectId??null}catch{return null}}u(CE,"resolveProjectId");zn.post("/instruction-suggestions/batch-upsert",async e=>{let t=e.get("userId"),n=NE.parse(await e.req.json());if(n.suggestions.length===0)return e.json({inserted:0});let r=n.projectId??await CE(n.projectPath),o=n.suggestions.map(s=>({userId:t,instructionId:s.instructionId,projectPath:n.projectPath,projectId:r,score:s.score,reason:s.reason,generatedAt:new Date,isStale:!1}));return await d.insert(Y).values(o).onConflictDoUpdate({target:[Y.userId,Y.projectPath,Y.instructionId],set:{score:bt`excluded.score`,reason:bt`excluded.reason`,generatedAt:bt`excluded.generated_at`,isStale:bt`false`,dismissedAt:bt`CASE WHEN ${Y.dismissedAt} IS NOT NULL AND ${Y.dismissedAt} >= now() - interval '30 days' THEN ${Y.dismissedAt} ELSE NULL END`}}),e.json({inserted:o.length})});zn.post("/instruction-suggestions/mark-stale",async e=>{let t=e.get("userId");return await d.update(Y).set({isStale:!0}).where(yt(Y.userId,t)),e.json({ok:!0})});var PE=tn.object({eventType:tn.enum(["surfaced","surfaced_with_content","accepted","dismissed","promoted","proxy_injected"]),tool:tn.string().optional(),sessionId:tn.string().uuid().optional(),projectPath:tn.string().min(1),instructionId:tn.string().uuid().optional()});zn.post("/instruction-suggestions/:id/events",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=PE.parse(await e.req.json()),[o]=await d.select().from(Y).where(is(yt(Y.id,n),yt(Y.userId,t)));if(!o)return e.json({error:"Suggestion not found"},404);let s=r.eventType==="accepted"||r.eventType==="promoted",i=o.instructionId;if(s&&r.instructionId){let[c]=await d.select({id:y.id}).from(y).where(is(yt(y.id,r.instructionId),TE(yt(y.createdBy,t),yt(y.scope,"public")))).limit(1);if(!c)return e.json({error:"instructionId not found",code:"INVALID_INSTRUCTION"},400);i=c.id}return await d.insert(zt).values({suggestionId:n,userId:t,eventType:r.eventType,tool:r.tool??null,sessionId:r.sessionId??null,projectPath:r.projectPath}),s?await d.update(Y).set({acceptedAt:new Date,promotedToInstructionId:i}).where(yt(Y.id,n)):r.eventType==="dismissed"&&await d.update(Y).set({dismissedAt:new Date}).where(yt(Y.id,n)),e.json({ok:!0})});import{createHash as fR}from"node:crypto";import{Hono as gR}from"hono";import{z as Z}from"zod";import{eq as M,and as qe,asc as Np,desc as wo,sql as U,or as wu,ilike as yu,inArray as ia,gte as jp,ne as hR}from"drizzle-orm";uu();import{randomUUID as go}from"node:crypto";import{eq as gt,and as gs,gt as GT,sql as $y}from"drizzle-orm";var KT=6e4;async function ho(e){try{let t=new Date(Date.now()-KT),[n]=await d.select({exists:$y`1`}).from(we).where(gs(gt(we.userId,e),gt(we.workerType,"cli-worker"),GT(we.lastHeartbeat,t))).limit(1);return n!==void 0}catch(t){return console.warn("[enqueueJob] hasLiveWorker check failed; skipping warning:",t instanceof Error?t.message:t),!0}}u(ho,"hasLiveWorker");async function kt(e){let t=!await ho(e.userId),n=go(),r={...e.payload,mirrorId:n};switch(e.taskName){case"process_eval":case"process_conversation":{await d.insert(be).values({...e.mirror,id:n,status:"pending",taskKind:e.taskName,payload:r});break}case"process_insights":{await d.insert(F).values({...e.mirror,id:n,status:"pending",taskKind:e.taskName,payload:r});break}case"process_launch":{await d.insert(re).values({...e.mirror,id:n,status:"pending",taskKind:e.taskName,payload:r,...e.runId?{runId:e.runId}:{}});break}case"process_send_message":{await d.insert(mc).values({...e.mirror,id:n,status:"pending",taskKind:e.taskName,payload:r});break}}return{id:n,noLiveWorker:t}}u(kt,"enqueueJob");async function qy(e){let t=!await ho(e.userId),n=`announcement:${e.announcementId}`,[r]=await d.select({id:Ie.id}).from(Ie).where(gs(gt(Ie.userId,e.userId),gt(Ie.taskKind,"process_announcement"),gt(Ie.dedupeKey,n),gt(Ie.status,"pending"))).limit(1);if(r)return{jobId:r.id,noLiveWorker:t};let o=go();return await d.insert(Ie).values({id:o,userId:e.userId,taskKind:"process_announcement",payload:{announcementId:e.announcementId,mirrorId:o},dedupeKey:n}),{jobId:o,noLiveWorker:t}}u(qy,"enqueueAnnouncementJob");async function du(e){let t=`goal-${e.sessionId}-${e.milestone}`,[n]=await d.select({id:Ie.id}).from(Ie).where(gs(gt(Ie.userId,e.userId),gt(Ie.taskKind,"process_session_goal"),gt(Ie.dedupeKey,t),gt(Ie.status,"pending"))).limit(1);if(n)return;let r=go();await d.insert(Ie).values({id:r,userId:e.userId,taskKind:"process_session_goal",payload:{sessionId:e.sessionId,milestone:e.milestone,mirrorId:r},dedupeKey:t})}u(du,"enqueueSessionGoalJob");async function Uy(e){let t=`distill-${e.sessionId}`,[n]=await d.select({id:Ie.id}).from(Ie).where(gs(gt(Ie.userId,e.userId),gt(Ie.taskKind,"distill_memories"),gt(Ie.dedupeKey,t),gt(Ie.status,"pending"))).limit(1);if(n)return;let r=go();await d.insert(Ie).values({id:r,userId:e.userId,taskKind:"distill_memories",payload:{sessionId:e.sessionId,mirrorId:r},dedupeKey:t})}u(Uy,"enqueueDistillMemoriesJob");async function By(e){let t=!await ho(e.userId),n=`run-cleanup:${e.runId}`,[r]=await d.select({id:Ie.id}).from(Ie).where(gs(gt(Ie.userId,e.userId),gt(Ie.taskKind,"process_run_cleanup"),gt(Ie.dedupeKey,n),gt(Ie.status,"pending"))).limit(1);if(r)return{jobId:r.id,noLiveWorker:t};let o=go();return await d.insert(Ie).values({id:o,userId:e.userId,taskKind:"process_run_cleanup",payload:{runId:e.runId,mirrorId:o},dedupeKey:n}),{jobId:o,noLiveWorker:t}}u(By,"enqueueRunCleanupJob");async function Fy(e){let t=`judge-review:${e.evalTargetId}`,n=go();await d.execute($y`
|
|
221
|
+
Preview: ${e.contentPreview}`.length+2}u(eE,"renderedSize");async function Xl(e,t,n){if(t.length===0)return{recommendations:[],error:null};let r;try{r=Wi(n.llmProvider,n.llmApiKey)}catch(c){return{recommendations:[],error:c instanceof Error?c.message:String(c)}}let o=Yl(t,{charBudget:n.charBudget}),s=[],i=[];for(let c of o)try{let a=await r.complete(zi(e,c));s.push(...Kl(a.text))}catch(a){i.push(a instanceof Error?a.message:String(a))}return{recommendations:s,error:i.length>0?i.join("; "):null}}u(Xl,"scoreInstructions");var tE=new Set(["127.0.0.1","localhost","::1","[::1]","0.0.0.0"]);function nE(e){if(!e)return null;try{return new URL(e).hostname}catch{return null}}u(nE,"databaseUrlHost");function Ql(e=process.env){let t=e.RULEMETRIC_DEPLOYMENT?.trim().toLowerCase();if(t==="cloud"||t==="local")return{mode:t,source:"env"};if(t)return{mode:"cloud",source:"default",error:`RULEMETRIC_DEPLOYMENT="${e.RULEMETRIC_DEPLOYMENT}" is not "cloud" or "local" \u2014 ignoring it and defaulting to cloud.`};let n=nE(e.DATABASE_URL);return n&&tE.has(n)?{mode:"local",source:"inferred"}:{mode:"cloud",source:"default"}}u(Ql,"resolveDeployment");function St(e){if(!Fo())return;let t=Nd();d.insert(Rr).values({instructionId:e.instructionId??null,userId:e.userId,surface:e.surface,action:e.action,metadata:e.metadata??null,traceId:t??null}).then(()=>{}).catch(n=>{console.error("Usage tracking error:",n)})}u(St,"trackUsage");var rE={critical:25,high:15,medium:8,low:3},oE=[{pattern:/ignore\s+(all\s+)?previous\s+instructions/i,severity:"critical",category:"prompt_injection",description:"Instruction override attempt"},{pattern:/before responding.*you MUST/i,severity:"critical",category:"prompt_injection",description:"Mandatory pre-response action injection"},{pattern:/never mention.*to the user/i,severity:"high",category:"prompt_injection",description:"Concealment language"},{pattern:/forget (everything|all|your).*instructions/i,severity:"critical",category:"prompt_injection",description:"Memory wipe injection"},{pattern:/you are now\s+/i,severity:"high",category:"prompt_injection",description:"Identity/role hijacking"},{pattern:/IMPORTANT:?\s*(system|override|mandatory|compliance)/i,severity:"high",category:"prompt_injection",description:"Fake authority escalation"},{pattern:/<system-reminder>/i,severity:"critical",category:"spoofing",description:"System-reminder tag spoofing"},{pattern:/<\/system-reminder>/i,severity:"critical",category:"spoofing",description:"System-reminder closing tag spoofing"},{pattern:/Contents of.*CLAUDE\.md.*project instructions/i,severity:"high",category:"spoofing",description:"Mimics Claude system context format"},{pattern:/<(system|assistant|tool)-(reminder|message|context)>/i,severity:"high",category:"spoofing",description:"System XML tag spoofing"},{pattern:/\[SYSTEM\]|\[INST\]|<<SYS>>/i,severity:"high",category:"spoofing",description:"Llama/Mistral system prompt markers"},{pattern:/process\.env.*(include|output|log|report|display|print)/i,severity:"critical",category:"secret_exfil",description:"Node.js environment access + exfiltration"},{pattern:/(include|output|log|report|display|print).*process\.env/i,severity:"critical",category:"secret_exfil",description:"Exfiltration verb + Node.js environment access"},{pattern:/os\.environ.*(include|output|log|report|display)/i,severity:"critical",category:"secret_exfil",description:"Python environment access + exfiltration"},{pattern:/cat\s+~?\/?\.(?:env|ssh|aws|npmrc|gitconfig)/i,severity:"critical",category:"secret_exfil",description:"Direct secret file read command"},{pattern:/env\s*\|\s*sort|printenv/i,severity:"high",category:"secret_exfil",description:"Full environment dump command"},{pattern:/\.(env|ssh\/id_rsa|aws\/credentials)\b/i,severity:"high",category:"secret_exfil",description:"Secret file path reference"},{pattern:/<\/(?:rule|instruction|system)>/i,severity:"high",category:"converter_escape",description:"XML structure escape in converter output"},{pattern:/<script|<iframe|javascript:/i,severity:"high",category:"fork_poison",description:"XSS payload"}];function Zl(e,t,n){let r=[],o=[e,t??"",n??""].join(`
|
|
222
|
+
`);for(let i of oE){let c=o.match(i.pattern);c&&r.push({pattern:i.description,severity:i.severity,category:i.category,match:c[0].slice(0,100)})}let s=100;for(let i of r)s-=rE[i.severity]??5;return{score:Math.max(0,Math.min(100,s)),findings:r}}u(Zl,"scanContent");var dn=new sE,iE=tt.object({name:tt.string().min(1).max(255),description:tt.string().min(1),scope:tt.enum(["org","team","project","personal"]),scopeRef:tt.string().uuid().optional(),version:tt.string().default("1.0.0"),content:tt.string().min(1),tags:tt.array(tt.string()).optional(),compatibility:tt.array(tt.string()).optional()}),aE=tt.object({name:tt.string().min(1).max(255).optional(),description:tt.string().min(1).optional(),version:tt.string().optional(),content:tt.string().min(1).optional(),tags:tt.array(tt.string()).optional(),compatibility:tt.array(tt.string()).optional(),changeSummary:tt.string().optional()});dn.get("/instructions",async e=>{let t=e.get("userId"),n=e.req.query("search"),r=e.req.query("scope"),o=e.req.query("tags"),s=e.req.query("type"),i=parseInt(e.req.query("limit")??"100",10),c=parseInt(e.req.query("offset")??"0",10),a=[Ce(_.archived,!1),Ce(_.createdBy,t)];if(r&&a.push(Ce(_.scope,r)),s&&a.push(Ce(_.type,s)),n){let g=et(n);a.push(tp(ep(_.name,`%${g}%`),ep(_.description,`%${g}%`),ep(_.content,`%${g}%`)))}let l=await d.select().from(_).where(lr(...a)).orderBy(E_(_.updatedAt)).limit(i).offset(c);if(o){let g=o.split(",").map(h=>h.trim().toLowerCase());l=l.filter(h=>g.some(w=>h.tags?.some(b=>b.toLowerCase().includes(w))))}let p=l.map(g=>g.id),m=p.length>0?await d.select({instructionId:at.instructionId,projectName:D.name,projectId:D.id}).from(at).innerJoin(D,Ce(D.id,at.projectId)).where(Vi`${at.instructionId} IN (${Vi.join(p.map(g=>Vi`${g}`),Vi`, `)})`):[],y=new Map;for(let g of m){let h=y.get(g.instructionId)??[];h.push({projectId:g.projectId,projectName:g.projectName}),y.set(g.instructionId,h)}let v=l.map(g=>({...g,projects:y.get(g.id)??[]}));return St({userId:t,surface:"api",action:"list"}),e.json(v)});dn.get("/instructions/by-hash/:hash",async e=>{let t=e.get("userId"),n=e.req.param("hash"),[r]=await d.select({id:_.id,name:_.name,contextIdentity:_.contextIdentity,version:_.version,type:_.type}).from(_).where(lr(Ce(_.contentHash,n),Ce(_.createdBy,t),Ce(_.archived,!1))).limit(1);return r?e.json({instruction:r}):e.json({instruction:null})});dn.post("/instructions/by-hashes",async e=>{let t=e.get("userId"),n=await e.req.json(),r=tt.array(tt.string()).max(200).parse(n.hashes??[]),o=tt.array(tt.string()).max(200).parse(n.identities??[]);if(r.length===0&&o.length===0)return e.json({instructions:{}});let s=[Ce(_.createdBy,t),Ce(_.archived,!1)],i=[];r.length>0&&i.push(x_(_.contentHash,r)),o.length>0&&i.push(x_(_.contextIdentity,o));let c=await d.select({id:_.id,name:_.name,contextIdentity:_.contextIdentity,version:_.version,type:_.type,contentHash:_.contentHash}).from(_).where(lr(...s,i.length===1?i[0]:tp(...i))),a={};for(let l of c)l.contentHash&&(a[l.contentHash]=l),l.contextIdentity&&(a[l.contextIdentity]=l);return e.json({instructions:a})});dn.get("/instructions/:id/sessions",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await d.select({sessionId:ne.sessionId,linkMethod:ne.linkMethod,tool:f.tool,projectPath:f.projectPath,startedAt:f.startedAt,endedAt:f.endedAt,analysis:f.analysis}).from(ne).innerJoin(f,Ce(f.id,ne.sessionId)).where(lr(Ce(ne.instructionId,n),Ce(f.userId,t))).orderBy(E_(f.startedAt)).limit(50);return e.json({sessions:r})});dn.get("/instructions/:id",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select().from(_).where(lr(Ce(_.id,t),Ce(_.archived,!1),tp(Ce(_.createdBy,n),Ce(_.scope,"public"))));return r?(St({instructionId:t,userId:n,surface:"api",action:"view"}),e.json(r)):e.json({error:"Instruction not found"},404)});var cE=/<\/?(?:system-reminder|system|available-deferred-tools|tool-result)>/i;function T_(e){return cE.test(e)?"Content contains forbidden system tags":null}u(T_,"validateNoForbiddenTags");dn.post("/instructions",async e=>{let t=e.get("userId"),n=await e.req.json(),r=iE.parse(n),o=T_(r.content);if(o)return e.json({error:o},422);r.name=zn(r.name),r.description=zn(r.description);let s={},i=null;try{let p=cs(r.content);s=p.frontmatter,i=p.slots}catch{s={name:r.name,description:r.description,type:"instruction",scope:r.scope,version:r.version}}let c=r.scope==="personal"?t:r.scopeRef??null,a=Zl(r.content,r.name,r.description),[l]=await d.insert(_).values({name:r.name,description:r.description,type:"instruction",scope:r.scope,scopeRef:c,version:r.version,content:r.content,frontmatter:s,slots:i,tags:r.tags??[],compatibility:r.compatibility??[],createdBy:t,scanScore:a.score,scanFindings:a.findings.length>0?a.findings:null}).returning();return await d.insert(fe).values({instructionId:l.id,versionNumber:1,content:r.content,frontmatter:s,changeSummary:"Initial version",createdBy:t}),St({instructionId:l.id,userId:t,surface:"api",action:"create"}),e.json(l,201)});dn.put("/instructions/:id",async e=>{let t=e.req.param("id"),n=e.get("userId"),r=await e.req.json(),o=aE.parse(r);if(o.content){let m=T_(o.content);if(m)return e.json({error:m},422)}o.name&&(o.name=zn(o.name)),o.description&&(o.description=zn(o.description));let[s]=await d.select().from(_).where(lr(Ce(_.id,t),Ce(_.createdBy,n),Ce(_.archived,!1)));if(!s)return e.json({error:"Instruction not found"},404);let i=s.frontmatter,c=s.slots;if(o.content)try{let m=cs(o.content);i=m.frontmatter,c=m.slots}catch{}let a={};if(o.content||o.name||o.description){let m=Zl(o.content??s.content,o.name??s.name,o.description??s.description);a.scanScore=m.score,a.scanFindings=m.findings.length>0?m.findings:null}let l,p=4;for(let m=0;m<=p;m++)try{l=await d.transaction(async y=>{await y.select({id:_.id}).from(_).where(Ce(_.id,t)).for("update");let[{maxVersion:v}]=await y.select({maxVersion:Vi`COALESCE(MAX(${fe.versionNumber}), 0)`}).from(fe).where(Ce(fe.instructionId,t)),g=v+1,[h]=await y.update(_).set({...o.name&&{name:o.name},...o.description&&{description:o.description},...o.version&&{version:o.version},...o.content&&{content:o.content},...o.tags&&{tags:o.tags},...o.compatibility&&{compatibility:o.compatibility},frontmatter:i,slots:c,...a,updatedAt:new Date}).where(Ce(_.id,t)).returning();return await y.insert(fe).values({instructionId:t,versionNumber:g,content:o.content??s.content,frontmatter:i,changeSummary:o.changeSummary??null,createdBy:n}),h});break}catch(y){if(y.cause?.code==="23505"&&m<p)continue;throw y}return l?(St({instructionId:t,userId:n,surface:"api",action:"update"}),e.json(l)):e.json({error:"Instruction update failed"},500)});dn.delete("/instructions/:id",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select().from(_).where(lr(Ce(_.id,t),Ce(_.createdBy,n),Ce(_.archived,!1)));if(!r)return e.json({error:"Instruction not found"},404);let[o]=await d.update(_).set({archived:!0,archivedAt:new Date,archivedBy:n}).where(Ce(_.id,t)).returning();return St({instructionId:t,userId:n,surface:"api",action:"delete"}),e.json(o)});dn.post("/instructions/:id/restore",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select().from(_).where(lr(Ce(_.id,t),Ce(_.createdBy,n),Ce(_.archived,!0)));if(!r)return e.json({error:"Archived instruction not found"},404);let[o]=await d.update(_).set({archived:!1,archivedAt:null,archivedBy:null}).where(Ce(_.id,t)).returning();return St({instructionId:t,userId:n,surface:"api",action:"update"}),e.json(o)});dn.get("/instructions/:id/versions",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select({id:_.id}).from(_).where(lr(Ce(_.id,t),Ce(_.createdBy,n)));if(!r)return e.json({error:"Instruction not found"},404);let o=await d.select().from(fe).where(Ce(fe.instructionId,t)).orderBy(fe.versionNumber);return e.json(o)});import{Hono as uE}from"hono";import{z as np}from"zod";import{eq as R_,and as dE}from"drizzle-orm";var Gc=new uE,lE=np.object({format:np.enum(zc),score:np.enum(["true","false"]).optional().default("false")});Gc.post("/instructions/:id/convert",async e=>{let t=e.req.param("id"),n=lE.parse(e.req.query()),r=n.format,o=n.score==="true",[s]=await d.select().from(_).where(dE(R_(_.id,t),R_(_.archived,!1)));if(!s)return e.json({error:"Instruction not found"},404);let i;try{i=cs(s.content)}catch{i={frontmatter:{name:s.name,description:s.description??"",type:"instruction",scope:s.scope,version:s.version??"1.0.0",tags:s.tags??[],compatibility:s.compatibility??[]},content:s.content,slots:s.slots}}let c=us(),a=c.get(r);if(!a)return e.json({error:`Unsupported format: ${r}`},400);let l=a.convert(i),p=e.get("userId");if(St({instructionId:t,userId:p,surface:"api",action:"convert",metadata:{format:r}}),o){let m=c.getMetadata(r);if(m){let y=Jl(l.output,m.scoringMetadata);return e.json({...l,score:y})}}return e.json(l)});import{Hono as pE}from"hono";var Kc=new pE;Kc.get("/converters",async e=>{let n=us().listAll().map(r=>({id:r.metadata.id,name:r.metadata.name,description:r.metadata.description,tier:r.metadata.tier,outputPath:r.metadata.outputPath,toolUrl:r.metadata.toolUrl}));return e.json(n)});import{Hono as mE}from"hono";import{z as pr}from"zod";var Yc=new mE,fE=pr.object({content:pr.string().min(1),sourceFormat:pr.enum(zc).optional(),filename:pr.string().optional(),name:pr.string().optional(),scope:pr.enum(["org","team","project","personal"]).default("personal"),scopeRef:pr.string().uuid().optional(),tags:pr.array(pr.string()).optional()});Yc.post("/instructions/import",async e=>{let t=e.get("userId"),n=await e.req.json(),r=fE.parse(n),o=r.sourceFormat??null;if(!o){let m=zl({filename:r.filename,content:r.content});m&&(o=m.format)}if(!o)return e.json({error:"Could not detect format. Provide sourceFormat explicitly."},400);let s=us(),i=s.getReverse(o);if(!i)return e.json({error:`No import parser for format: ${o}`,supportedFormats:s.listReverseFormats()},400);let c=i.parse(r.content,r.filename),a=r.name??c.frontmatter.name,l=r.scope==="personal"?t:r.scopeRef??null,[p]=await d.insert(_).values({name:a,description:c.frontmatter.description,type:"instruction",scope:r.scope,scopeRef:l,version:"1.0.0",content:c.content,frontmatter:c.frontmatter,slots:c.slots,tags:r.tags??c.frontmatter.tags??[],compatibility:c.frontmatter.compatibility??[],createdBy:t}).returning();return await d.insert(fe).values({instructionId:p.id,versionNumber:1,content:c.content,frontmatter:c.frontmatter,changeSummary:`Imported from ${o}`,createdBy:t}),St({instructionId:p.id,userId:t,surface:"api",action:"import",metadata:{sourceFormat:o}}),e.json({instruction:p,sourceFormat:o,parseWarnings:[]},201)});import{Hono as gE}from"hono";import{eq as Pr,and as rp}from"drizzle-orm";var Ji=new gE;Ji.post("/instructions/:id/fork",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(_).where(rp(Pr(_.id,n),Pr(_.archived,!1)));if(!r)return e.json({error:"Instruction not found"},404);if(r.createdBy===t)return e.json({error:"Cannot fork your own instruction"},400);if(r.scope==="org"&&r.scopeRef){let[s]=await d.select({id:_.id}).from(_).where(rp(Pr(_.createdBy,t),Pr(_.scope,"org"),Pr(_.scopeRef,r.scopeRef))).limit(1);if(!s)return e.json({error:"Instruction not found"},404)}else if(r.scope!=="org")return e.json({error:"Instruction not found"},404);let[o]=await d.insert(_).values({name:`${r.name} (fork)`,description:r.description,type:r.type,scope:"personal",scopeRef:t,version:"1.0.0",content:r.content,frontmatter:r.frontmatter,slots:r.slots,tags:r.tags,compatibility:r.compatibility,createdBy:t,forkedFromId:r.id,upstreamVersion:r.version}).returning();return await d.insert(fe).values({instructionId:o.id,versionNumber:1,content:o.content,frontmatter:o.frontmatter,changeSummary:`Forked from ${r.name}`,createdBy:t}),await d.insert(Nt).values({instructionId:o.id,eventType:"fork",actorId:t,metadata:{sourceId:r.id,sourceName:r.name,sourceVersion:r.version}}),St({instructionId:o.id,userId:t,surface:"api",action:"fork"}),e.json(o,201)});Ji.get("/instructions/:id/events",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select({id:_.id}).from(_).where(rp(Pr(_.id,t),Pr(_.createdBy,n)));if(!r)return e.json({error:"Instruction not found"},404);let o=await d.select().from(Nt).where(Pr(Nt.instructionId,t)).orderBy(Nt.createdAt);return e.json(o)});import{Hono as hE}from"hono";import{eq as Nn,and as k_,sql as _E}from"drizzle-orm";var Gi=new hE;Gi.get("/instructions/:id/upstream",async e=>{let t=e.req.param("id"),[n]=await d.select().from(_).where(k_(Nn(_.id,t),Nn(_.archived,!1)));if(!n)return e.json({error:"Instruction not found"},404);if(!n.forkedFromId)return e.json({error:"This instruction is not a fork"},400);let[r]=await d.select().from(_).where(Nn(_.id,n.forkedFromId));return r?e.json({hasUpdate:r.version!==n.upstreamVersion,currentVersion:n.upstreamVersion,upstreamVersion:r.version,parentId:r.id,parentName:r.name}):e.json({hasUpdate:!1,currentVersion:n.upstreamVersion,upstreamVersion:null,parentId:n.forkedFromId})});Gi.post("/instructions/:id/pull-upstream",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(_).where(k_(Nn(_.id,n),Nn(_.createdBy,t),Nn(_.archived,!1)));if(!r)return e.json({error:"Instruction not found"},404);if(!r.forkedFromId)return e.json({error:"This instruction is not a fork"},400);let[o]=await d.select().from(_).where(Nn(_.id,r.forkedFromId));if(!o)return e.json({error:"Parent instruction no longer exists"},404);let[s]=await d.select().from(fe).where(Nn(fe.instructionId,o.id)).orderBy(fe.versionNumber).limit(1),i=s?.content??o.content,c=Gl(i,o.content,r.content);if(c.hasConflicts)return e.json({hasConflicts:!0,merged:c.merged,conflicts:c.conflicts});let a,l=4;for(let p=0;p<=l;p++)try{a=await d.transaction(async m=>{await m.select({id:_.id}).from(_).where(Nn(_.id,n)).for("update");let[y]=await m.select({maxVersion:_E`COALESCE(MAX(${fe.versionNumber}), 0)`}).from(fe).where(Nn(fe.instructionId,n)),v=(y?.maxVersion??0)+1,[g]=await m.update(_).set({content:c.merged,upstreamVersion:o.version,updatedAt:new Date}).where(Nn(_.id,n)).returning();return await m.insert(fe).values({instructionId:n,versionNumber:v,content:c.merged,frontmatter:r.frontmatter,changeSummary:`Pulled upstream changes from ${o.name} (${o.version})`,createdBy:t}),await m.insert(Nt).values({instructionId:n,eventType:"pull_upstream",actorId:t,metadata:{parentId:o.id,parentVersion:o.version,previousUpstreamVersion:r.upstreamVersion}}),g});break}catch(m){if(m.cause?.code==="23505"&&p<l)continue;throw m}return a?(St({instructionId:n,userId:t,surface:"api",action:"pull_upstream"}),e.json({hasConflicts:!1,instruction:a})):e.json({error:"Pull-upstream failed after version conflict"},500)});import{Hono as yE}from"hono";import{z as Or}from"zod";import{eq as Pt,and as go,sql as wE}from"drizzle-orm";var vE=Or.object({scope:Or.enum(["team","org"]),scopeRef:Or.string().uuid()}),Ki=new yE;Ki.post("/instructions/:id/promote",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=vE.parse(await e.req.json()),[o]=await d.select().from(_).where(go(Pt(_.id,n),Pt(_.createdBy,t),Pt(_.archived,!1)));if(!o)return e.json({error:"Instruction not found"},404);if(o.scope==="org")return e.json({error:"Instruction is already org-scoped"},400);if(r.scope==="team"){let[a]=await d.select().from(he).where(go(Pt(he.userId,t),Pt(he.teamId,r.scopeRef)));if(!a)return e.json({error:"You are not a member of this team"},403)}else if(r.scope==="org"){let[a]=await d.select().from(Y).where(go(Pt(Y.userId,t),Pt(Y.orgId,r.scopeRef)));if(!a||a.role!=="admin"&&a.role!=="owner")return e.json({error:"You must be an org admin to promote to org scope"},403)}let s=o.scope,i=o.scopeRef,[c]=await d.update(_).set({scope:r.scope,scopeRef:r.scopeRef,updatedAt:new Date}).where(Pt(_.id,n)).returning();return await d.insert(Nt).values({instructionId:n,eventType:"promote",actorId:t,metadata:{fromScope:s,fromScopeRef:i,toScope:r.scope,toScopeRef:r.scopeRef}}),St({instructionId:n,userId:t,surface:"api",action:"promote"}),e.json(c)});var IE=Or.object({targetScope:Or.enum(["personal","team","org"]),targetScopeRef:Or.string().uuid().optional(),name:Or.string().optional(),seedEvalTarget:Or.boolean().optional()});async function bE(e){let[t]=await d.select({id:k.id}).from(k).where(wE`${k.metadata}->>'instructionId' = ${e}`).limit(1);return t??null}u(bE,"findExistingEvalTarget");Ki.post("/instructions/:id/promote-from-public",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=IE.parse(await e.req.json()),[o]=await d.select().from(_).where(go(Pt(_.id,n),Pt(_.scope,"public")));if(!o)return e.json({error:"Public instruction not found"},404);if(r.targetScope==="team"){if(!r.targetScopeRef)return e.json({error:"targetScopeRef is required for team scope"},400);let[m]=await d.select().from(he).where(go(Pt(he.userId,t),Pt(he.teamId,r.targetScopeRef)));if(!m)return e.json({error:"You are not a member of this team"},403)}else if(r.targetScope==="org"){if(!r.targetScopeRef)return e.json({error:"targetScopeRef is required for org scope"},400);let[m]=await d.select().from(Y).where(go(Pt(Y.userId,t),Pt(Y.orgId,r.targetScopeRef)));if(!m||m.role!=="admin"&&m.role!=="owner")return e.json({error:"You must be an org admin to promote into an org"},403)}let s=r.targetScope==="personal"?t:r.targetScopeRef,i=r.name??o.name,c=r.seedEvalTarget??(r.targetScope==="org"||r.targetScope==="team"),[a]=await d.select().from(_).where(go(Pt(_.scope,r.targetScope),Pt(_.scopeRef,s),Pt(_.forkedFromId,n),Pt(_.archived,!1)));if(a){let m=null;return c&&(m=(await bE(a.id))?.id??null),e.json({instructionId:a.id,alreadyExisted:!0,evalTargetId:m})}let[l]=await d.insert(_).values({name:i,description:o.description,type:o.type,scope:r.targetScope,scopeRef:s,version:o.version,content:o.content,frontmatter:o.frontmatter,slots:o.slots,tags:o.tags,compatibility:o.compatibility,createdBy:t,forkedFromId:o.id,upstreamVersion:o.upstreamVersion??o.version,contentHash:o.contentHash,contextIdentity:o.contextIdentity}).returning();if(!l)return e.json({error:"Failed to clone instruction"},500);await d.insert(fe).values({instructionId:l.id,versionNumber:1,content:o.content,frontmatter:o.frontmatter,changeSummary:`Promoted from public skill ${o.name}`,createdBy:t}),await d.insert(Nt).values({instructionId:l.id,eventType:"promote_from_public",actorId:t,metadata:{sourceInstructionId:o.id,sourceName:o.name,targetScope:r.targetScope,targetScopeRef:s}}),St({instructionId:l.id,userId:t,surface:"api",action:"promote_from_public"});let p=null;if(c){let[m]=await d.insert(k).values({userId:t,name:`${i} \u2014 baseline eval`,type:"instruction",content:o.content,description:`Auto-seeded from public skill \`${o.name}\` on promote.`,metadata:{instructionId:l.id,publicSourceId:o.id,publicContentHash:o.contentHash??null,publicVersion:o.version??null}}).returning({id:k.id});p=m?.id??null}return e.json({instructionId:l.id,alreadyExisted:!1,evalTargetId:p})});import{Hono as SE}from"hono";import{z as j_}from"zod";import{eq as ln,and as Yi,or as N_,inArray as C_,sql as Xc,desc as AE}from"drizzle-orm";var Xi=new SE,xE=j_.object({badge:j_.enum(["recommended","required"]).nullable()});Xi.get("/catalog",async e=>{let t=e.get("userId"),n=e.req.query("badge"),r=e.req.query("scope"),o=e.req.query("search"),s=parseInt(e.req.query("contentPreview")??"0",10),i=Number.isFinite(s)?Math.min(Math.max(s,0),400):0,c=parseInt(e.req.query("limit")??"50",10),a=parseInt(e.req.query("offset")??"0",10),l=Math.min(Math.max(c,1),200),p=Math.max(a,0),m=await d.select({orgId:Y.orgId}).from(Y).where(ln(Y.userId,t)),y=await d.select({teamId:he.teamId}).from(he).where(ln(he.userId,t)),v=m.map(x=>x.orgId).filter(x=>x!==null),g=y.map(x=>x.teamId).filter(x=>x!==null),h=[ln(_.archived,!1)],w=[ln(_.scope,"public")];if(v.length>0&&w.push(Yi(ln(_.scope,"org"),C_(_.scopeRef,v))),g.length>0&&w.push(Yi(ln(_.scope,"team"),C_(_.scopeRef,g))),h.push(N_(...w)),n&&h.push(ln(_.badge,n)),r&&h.push(ln(_.scope,r)),o){let x=et(o);h.push(N_(Xc`${_.name} ILIKE ${`%${x}%`}`,Xc`${_.description} ILIKE ${`%${x}%`}`))}let b=[AE(Xc`COALESCE(${_.sourceUpdatedAt}, ${_.updatedAt})`)],I={id:_.id,name:_.name,description:_.description,type:_.type,scope:_.scope,scopeRef:_.scopeRef,version:_.version,tags:_.tags,badge:_.badge,popularityScore:_.popularityScore,updatedAt:_.updatedAt,createdAt:_.createdAt,sourceUpdatedAt:_.sourceUpdatedAt},A=await(i>0?ft:d).select(i>0?{...I,contentPreview:Xc`left(${_.content}, ${i})`}:I).from(_).where(Yi(...h)).orderBy(...b).limit(l).offset(p);return St({userId:t,surface:"api",action:"search",metadata:o?{query:o}:void 0}),e.header("Cache-Control","private, max-age=30"),e.json(A)});Xi.post("/instructions/:id/badge",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=xE.parse(await e.req.json()),[o]=await d.select().from(_).where(Yi(ln(_.id,n),ln(_.archived,!1)));if(!o)return e.json({error:"Instruction not found"},404);if(o.scope!=="org"&&o.scope!=="team")return e.json({error:"Badges can only be set on org or team-scoped instructions"},400);let s=o.scopeRef;if(!s)return e.json({error:"Instruction has no scope reference"},400);let[i]=await d.select().from(Y).where(Yi(ln(Y.userId,t),ln(Y.orgId,s)));if(!i||i.role!=="admin"&&i.role!=="owner")return e.json({error:"Only admins of the owning organization can set badges"},403);let[c]=await d.update(_).set({badge:r.badge,updatedAt:new Date}).where(ln(_.id,n)).returning(),a=r.badge?"badge_set":"badge_removed";return await d.insert(Nt).values({instructionId:n,eventType:a,actorId:t,metadata:{badge:r.badge}}),e.json(c)});import{Hono as EE}from"hono";import{eq as Dr,and as Qc,or as TE,inArray as P_}from"drizzle-orm";var Zc=new EE;Zc.post("/projects/:id/recommendations",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(D).where(Qc(Dr(D.id,n),Dr(D.createdBy,t)));if(!r)return e.json({error:"Project not found"},404);let o=await d.select({orgId:Y.orgId}).from(Y).where(Dr(Y.userId,t)),s=await d.select({teamId:he.teamId}).from(he).where(Dr(he.userId,t)),i=o.map(h=>h.orgId).filter(h=>h!==null),c=s.map(h=>h.teamId).filter(h=>h!==null),a=[Dr(_.scope,"public")];i.length>0&&a.push(Qc(Dr(_.scope,"org"),P_(_.scopeRef,i))),c.length>0&&a.push(Qc(Dr(_.scope,"team"),P_(_.scopeRef,c)));let l=await d.select().from(_).where(Qc(Dr(_.archived,!1),TE(...a))).limit(50);if(l.length===0)return e.json({recommendations:[],error:null});let p={name:r.name,description:r.description,languages:[],topics:[],dependencies:[]};if(r.githubRepo)try{let h=r.githubRepo.replace("https://github.com/",""),[w,b]=await Promise.all([fetch(`https://api.github.com/repos/${h}`,{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"RuleMetric"}}),fetch(`https://api.github.com/repos/${h}/languages`,{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"RuleMetric"}})]);if(w.ok){let I=await w.json();p.topics=I.topics??[]}if(b.ok){let I=await b.json();p.languages=Object.keys(I)}}catch{}let m=l.map(h=>({id:h.id,name:h.name,description:h.description??"",tags:h.tags??[],contentPreview:(h.content??"").slice(0,400)})),y=process.env.LLM_PROVIDER,v=process.env.LLM_API_KEY;if(!y||!v)return e.json({recommendations:[],error:"LLM not configured"});let g=await Xl(p,m,{llmProvider:y,llmApiKey:v});return e.json(g)});import{Hono as RE}from"hono";import{z as Yt}from"zod";import{eq as nt,and as ho,or as kE,sql as Qe,asc as O_,desc as eu}from"drizzle-orm";var Vn=new RE;Vn.get("/instruction-suggestions/pending-count",async e=>{let t=e.get("userId"),n=await d.select({projectPath:q.projectPath,count:Qe`count(*)::int`}).from(q).where(ho(nt(q.userId,t),Qe`${q.acceptedAt} IS NULL`,Qe`(${q.dismissedAt} IS NULL OR ${q.dismissedAt} < now() - interval '30 days')`)).groupBy(q.projectPath).orderBy(eu(Qe`count(*)`)),r=n.reduce((o,s)=>o+s.count,0);return e.json({total:r,byProject:n.slice(0,5)})});Vn.get("/instruction-suggestions/stats",async e=>{let t=e.get("userId"),[n]=await d.select({total:Qe`count(*)::int`,accepted:Qe`count(*) filter (where ${q.acceptedAt} is not null)::int`,dismissed:Qe`count(*) filter (where ${q.acceptedAt} is null and ${q.dismissedAt} is not null)::int`,pending:Qe`count(*) filter (where ${q.acceptedAt} is null and ${q.dismissedAt} is null)::int`,stale:Qe`count(*) filter (where ${q.isStale})::int`,promoted:Qe`count(*) filter (where ${q.promotedToInstructionId} is not null)::int`}).from(q).where(nt(q.userId,t)),r=await d.select({eventType:zt.eventType,count:Qe`count(*)::int`}).from(zt).where(nt(zt.userId,t)).groupBy(zt.eventType),o={surfaced:0,surfaced_with_content:0,accepted:0,dismissed:0,promoted:0,proxy_injected:0};for(let a of r)o[a.eventType]=a.count;let[s]=await d.select({distinctUsersWithSuggestions:Qe`count(distinct ${q.userId})::int`}).from(q),i=o.surfaced+o.surfaced_with_content,c=o.accepted+o.dismissed;return e.json({suggestions:n,events:o,funnel:{surfaced:i,acted:c,adoptionRate:i>0?c/i:0},denominator:{distinctUsersWithSuggestions:s?.distinctUsersWithSuggestions??0,scope:"global"}})});var D_=2e3,jE=.7,NE=4;function CE(e){return e.length<=D_?e:e.slice(0,D_)+"... [truncated]"}u(CE,"truncateContent");Vn.get("/instruction-suggestions",async e=>{let t=e.get("userId"),n=e.req.query("projectId"),r=e.req.query("projectPath"),o=Number(e.req.query("limit")??"5"),s=Math.min(Math.max(o,1),10),i=e.req.query("includeContent")==="true",c=e.req.query("groupByKind")==="true";if(!n&&!r)return e.json({error:"projectId or projectPath is required"},400);let a=n?nt(q.projectId,n):nt(q.projectPath,r),l=await d.select({id:q.id,instructionId:q.instructionId,score:q.score,reason:q.reason,generatedAt:q.generatedAt,isStale:q.isStale,kind:q.kind,name:_.name,description:_.description,tags:_.tags,instructionScope:_.scope,estimatedTokens:Qe`(length(${_.content}) / 4)::int`,_rawContent:_.content}).from(q).innerJoin(_,nt(q.instructionId,_.id)).where(ho(nt(q.userId,t),a,nt(_.archived,!1),Qe`${q.acceptedAt} IS NULL`,Qe`(${q.dismissedAt} IS NULL OR ${q.dismissedAt} < now() - interval '30 days')`)).orderBy(O_(q.isStale),eu(q.score)).limit(s),p=[];if(c){let g=new Set(l.map(w=>w.id));p=(await d.select({id:q.id,instructionId:q.instructionId,score:q.score,reason:q.reason,generatedAt:q.generatedAt,isStale:q.isStale,kind:q.kind,name:_.name,description:_.description,tags:_.tags,instructionScope:_.scope,estimatedTokens:Qe`(length(${_.content}) / 4)::int`,_rawContent:_.content}).from(q).innerJoin(_,nt(q.instructionId,_.id)).where(ho(nt(q.userId,t),a,Qe`${q.kind} <> 'add'`,nt(_.archived,!1),Qe`${q.acceptedAt} IS NULL`,Qe`(${q.dismissedAt} IS NULL OR ${q.dismissedAt} < now() - interval '30 days')`)).orderBy(O_(q.isStale),eu(q.score)).limit(NE)).filter(w=>!g.has(w.id))}let m=[...l,...p].map(g=>{let{_rawContent:h,...w}=g,b=i&&g.kind==="add"&&g.score>=jE&&typeof h=="string"?CE(h):null;return{...w,content:b}}),y=await d.select({eventType:zt.eventType,count:Qe`count(*)::int`}).from(zt).innerJoin(q,nt(zt.suggestionId,q.id)).where(ho(nt(zt.userId,t),a)).groupBy(zt.eventType),v={};for(let g of y)v[g.eventType]=g.count;return e.json({suggestions:m,stats:v})});Vn.get("/instruction-suggestions/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:q.id,instructionId:q.instructionId,projectPath:q.projectPath,score:q.score,reason:q.reason,generatedAt:q.generatedAt,isStale:q.isStale,kind:q.kind,estimatedTokens:Qe`(length(${_.content}) / 4)::int`,dismissedAt:q.dismissedAt,acceptedAt:q.acceptedAt,name:_.name,description:_.description,tags:_.tags,instructionScope:_.scope}).from(q).innerJoin(_,nt(q.instructionId,_.id)).where(ho(nt(q.id,n),nt(q.userId,t)));return r?e.json(r):e.json({error:"Suggestion not found"},404)});var PE=Yt.object({projectPath:Yt.string().min(1),projectId:Yt.string().uuid().optional(),suggestions:Yt.array(Yt.object({instructionId:Yt.string().uuid(),score:Yt.number().min(0).max(1),reason:Yt.string(),kind:Yt.enum(jc).optional()})).max(50)});async function OE(e){try{let[t]=await d.select({projectId:ue.projectId}).from(ue).where(nt(ue.path,e)).orderBy(eu(ue.lastSeen)).limit(1);return t?.projectId??null}catch{return null}}u(OE,"resolveProjectId");Vn.post("/instruction-suggestions/batch-upsert",async e=>{let t=e.get("userId"),n=PE.parse(await e.req.json());if(n.suggestions.length===0)return e.json({inserted:0});let r=n.projectId??await OE(n.projectPath),o=n.suggestions.map(s=>({userId:t,instructionId:s.instructionId,projectPath:n.projectPath,projectId:r,score:s.score,reason:s.reason,kind:s.kind??"add",generatedAt:new Date,isStale:!1}));return await d.insert(q).values(o).onConflictDoUpdate({target:[q.userId,q.projectPath,q.instructionId,q.kind],set:{score:Qe`excluded.score`,reason:Qe`excluded.reason`,generatedAt:Qe`excluded.generated_at`,isStale:Qe`false`,dismissedAt:Qe`CASE WHEN ${q.dismissedAt} IS NOT NULL AND ${q.dismissedAt} >= now() - interval '30 days' THEN ${q.dismissedAt} ELSE NULL END`}}),e.json({inserted:o.length})});Vn.post("/instruction-suggestions/mark-stale",async e=>{let t=e.get("userId");return await d.update(q).set({isStale:!0}).where(nt(q.userId,t)),e.json({ok:!0})});var DE=Yt.object({eventType:Yt.enum(["surfaced","surfaced_with_content","accepted","dismissed","promoted","proxy_injected"]),tool:Yt.string().optional(),sessionId:Yt.string().uuid().optional(),projectPath:Yt.string().min(1),instructionId:Yt.string().uuid().optional()});Vn.post("/instruction-suggestions/:id/events",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=DE.parse(await e.req.json()),[o]=await d.select().from(q).where(ho(nt(q.id,n),nt(q.userId,t)));if(!o)return e.json({error:"Suggestion not found"},404);let s=r.eventType==="accepted"||r.eventType==="promoted",i=o.instructionId;if(s&&r.instructionId){let[c]=await d.select({id:_.id}).from(_).where(ho(nt(_.id,r.instructionId),kE(nt(_.createdBy,t),nt(_.scope,"public")))).limit(1);if(!c)return e.json({error:"instructionId not found",code:"INVALID_INSTRUCTION"},400);i=c.id}return await d.insert(zt).values({suggestionId:n,userId:t,eventType:r.eventType,tool:r.tool??null,sessionId:r.sessionId??null,projectPath:r.projectPath}),s?await d.update(q).set({acceptedAt:new Date,promotedToInstructionId:i}).where(nt(q.id,n)):r.eventType==="dismissed"&&await d.update(q).set({dismissedAt:new Date}).where(nt(q.id,n)),e.json({ok:!0})});import{createHash as hR}from"node:crypto";import{Hono as _R}from"hono";import{z as te}from"zod";import{eq as L,and as qe,asc as Cp,desc as Io,sql as H,or as Iu,ilike as vu,inArray as ia,gte as Np,ne as yR}from"drizzle-orm";lu();import{randomUUID as _o}from"node:crypto";import{eq as _t,and as ys,gt as YT,sql as By}from"drizzle-orm";var XT=6e4;async function yo(e){try{let t=new Date(Date.now()-XT),[n]=await d.select({exists:By`1`}).from(ve).where(ys(_t(ve.userId,e),_t(ve.workerType,"cli-worker"),YT(ve.lastHeartbeat,t))).limit(1);return n!==void 0}catch(t){return console.warn("[enqueueJob] hasLiveWorker check failed; skipping warning:",t instanceof Error?t.message:t),!0}}u(yo,"hasLiveWorker");async function kt(e){let t=!await yo(e.userId),n=_o(),r={...e.payload,mirrorId:n};switch(e.taskName){case"process_eval":case"process_conversation":{await d.insert(Se).values({...e.mirror,id:n,status:"pending",taskKind:e.taskName,payload:r});break}case"process_insights":{await d.insert(W).values({...e.mirror,id:n,status:"pending",taskKind:e.taskName,payload:r});break}case"process_launch":{await d.insert(oe).values({...e.mirror,id:n,status:"pending",taskKind:e.taskName,payload:r,...e.runId?{runId:e.runId}:{}});break}case"process_send_message":{await d.insert(mc).values({...e.mirror,id:n,status:"pending",taskKind:e.taskName,payload:r});break}}return{id:n,noLiveWorker:t}}u(kt,"enqueueJob");async function Fy(e){let t=!await yo(e.userId),n=`announcement:${e.announcementId}`,[r]=await d.select({id:be.id}).from(be).where(ys(_t(be.userId,e.userId),_t(be.taskKind,"process_announcement"),_t(be.dedupeKey,n),_t(be.status,"pending"))).limit(1);if(r)return{jobId:r.id,noLiveWorker:t};let o=_o();return await d.insert(be).values({id:o,userId:e.userId,taskKind:"process_announcement",payload:{announcementId:e.announcementId,mirrorId:o},dedupeKey:n}),{jobId:o,noLiveWorker:t}}u(Fy,"enqueueAnnouncementJob");async function pu(e){let t=`goal-${e.sessionId}-${e.milestone}`,[n]=await d.select({id:be.id}).from(be).where(ys(_t(be.userId,e.userId),_t(be.taskKind,"process_session_goal"),_t(be.dedupeKey,t),_t(be.status,"pending"))).limit(1);if(n)return;let r=_o();await d.insert(be).values({id:r,userId:e.userId,taskKind:"process_session_goal",payload:{sessionId:e.sessionId,milestone:e.milestone,mirrorId:r},dedupeKey:t})}u(pu,"enqueueSessionGoalJob");async function Hy(e){let t=`distill-${e.sessionId}`,[n]=await d.select({id:be.id}).from(be).where(ys(_t(be.userId,e.userId),_t(be.taskKind,"distill_memories"),_t(be.dedupeKey,t),_t(be.status,"pending"))).limit(1);if(n)return;let r=_o();await d.insert(be).values({id:r,userId:e.userId,taskKind:"distill_memories",payload:{sessionId:e.sessionId,mirrorId:r},dedupeKey:t})}u(Hy,"enqueueDistillMemoriesJob");async function Wy(e){let t=!await yo(e.userId),n=`run-cleanup:${e.runId}`,[r]=await d.select({id:be.id}).from(be).where(ys(_t(be.userId,e.userId),_t(be.taskKind,"process_run_cleanup"),_t(be.dedupeKey,n),_t(be.status,"pending"))).limit(1);if(r)return{jobId:r.id,noLiveWorker:t};let o=_o();return await d.insert(be).values({id:o,userId:e.userId,taskKind:"process_run_cleanup",payload:{runId:e.runId,mirrorId:o},dedupeKey:n}),{jobId:o,noLiveWorker:t}}u(Wy,"enqueueRunCleanupJob");async function zy(e){let t=`judge-review:${e.evalTargetId}`,n=_o();await d.execute(By`
|
|
223
223
|
INSERT INTO agent_jobs (id, user_id, task_kind, payload, dedupe_key)
|
|
224
224
|
SELECT ${n}, ${e.userId}, 'process_judge_review',
|
|
225
225
|
${JSON.stringify({evalTargetId:e.evalTargetId,mirrorId:n})}::jsonb,
|
|
@@ -231,13 +231,13 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
231
231
|
AND dedupe_key = ${t}
|
|
232
232
|
AND status = 'pending'
|
|
233
233
|
)
|
|
234
|
-
`)}u(
|
|
234
|
+
`)}u(zy,"enqueueJudgeReviewJob");async function Vy(e){let t=!await yo(e.userId),n=`memory-ab:${e.experimentId}`,[r]=await d.select({id:be.id}).from(be).where(ys(_t(be.userId,e.userId),_t(be.taskKind,"memory_ab"),_t(be.dedupeKey,n),_t(be.status,"pending"))).limit(1);if(r)return{jobId:r.id,noLiveWorker:t};let o=_o();return await d.insert(be).values({id:o,userId:e.userId,taskKind:"memory_ab",payload:{experimentId:e.experimentId,mirrorId:o},dedupeKey:n}),{jobId:o,noLiveWorker:t}}u(Vy,"enqueueMemoryAbJob");import{sql as wn}from"drizzle-orm";function mu(){return process.env.EVENT_BATCHING!=="0"}u(mu,"eventBatchingEnabled");function Gy(){let e=Number(process.env.EVENT_BATCH_LINGER_MS);return Number.isFinite(e)&&e>=0?e:50}u(Gy,"eventBatchLingerMs");function Ky(){let e=Number(process.env.EVENT_BATCH_BUFFER_MAX);return Number.isFinite(e)&&e>0?Math.floor(e):5e3}u(Ky,"eventBatchBufferMax");function Yy(){let e=Number(process.env.EVENT_BATCH_FLUSH_SIZE);return Number.isFinite(e)&&e>0?Math.floor(e):QT}u(Yy,"eventBatchFlushSize");function Xy(){let e=Number(process.env.PG_POOL_MAX)||3;return Math.max(1,e-1)}u(Xy,"defaultDrainConcurrency");var QT=500;function ZT(e){let t=e.lingerMs??Gy(),n=e.maxBuffered??Ky(),r=Math.max(1,e.flushSize??Yy()),o=Math.max(1,e.concurrency??Xy()),s=new Map,i=0,c=new Set,a=0,l=!1,p=null,m=[];function y(){let A=m;m=[];for(let x of A)x()}u(y,"notifyProgress");function v(){for(;a<o;){let A=null,x=null;for(let[T,P]of s)if(!(c.has(T)||P.length===0)){x=P.splice(0,r),P.length===0&&s.delete(T),A=T;break}if(A==null||x==null)return;i-=x.length,c.add(A),a++,g(A,x)}}u(v,"tick");async function g(A,x){try{await e.drainSession(A,x)}catch(T){console.warn(`[event-batcher] drain failed for session ${A}; dropping ${x.length} event(s):`,T instanceof Error?T.message:T)}finally{a--,c.delete(A),y(),v()}}u(g,"runDrain");function h(){p!=null||l||(p=setTimeout(()=>{p=null,v()},t),p.unref?.())}u(h,"scheduleLinger");function w(A){if(l||i>=n)return!1;let x=s.get(A.sessionId);return x?x.push(A):s.set(A.sessionId,[A]),i++,i>=r?v():h(),!0}u(w,"push");function b(A){return new Promise(x=>{let T=!1,P=u(()=>{T||(T=!0,clearTimeout(E),x())},"finish"),E=setTimeout(P,A);E.unref?.(),m.push(P)})}u(b,"waitForProgress");async function I(A){let x=A!=null?Date.now()+A:Number.POSITIVE_INFINITY;for(;;){if(v(),i===0&&a===0)return;let T=x-Date.now();if(T<=0)return;await b(Math.min(T,50))}}u(I,"flush");function S(){l=!0,p!=null&&(clearTimeout(p),p=null)}return u(S,"stop"),{push:w,flush:I,stop:S,size:u(()=>i,"size"),inFlight:u(()=>a,"inFlight")}}u(ZT,"createEventBatcher");var Jy=5,eR=[5,20,50];function tR(e){let t=e.cause;return e instanceof Error&&(t?.code==="23505"||e.message.includes("unique")||e.message.includes("duplicate"))}u(tR,"isDuplicateKeyError");function nR(e){let t=Date.parse(e);return Number.isNaN(t)?(console.warn(`[event-batcher] invalid event timestamp ${JSON.stringify(e)}; using drain wall-clock`),new Date().toISOString()):new Date(t).toISOString()}u(nR,"toEventTimestamp");async function rR(e,t){if(t.length===0)return;let n=null,r=!1;for(let o=0;o<=Jy;o++)try{let s=t.map((c,a)=>{let l=c.input,p={...l.metadata??{}};l.durationMs!=null&&(p.durationMs=l.durationMs),l.success!=null&&(p.success=l.success);let m=l.toolInput==null?null:JSON.stringify(l.toolInput),y=l.toolOutput==null?null:JSON.stringify(l.toolOutput),v=l.tokenUsage==null?null:JSON.stringify(l.tokenUsage),g=!r&&l.sequence!=null?wn`${l.sequence}::int`:wn`NULL::int`;return wn`(${a+1}::int, ${g}, ${l.eventType}::text, ${l.content??null}::text, ${l.toolName??null}::text, ${m==null?wn`NULL::jsonb`:wn`${m}::jsonb`}, ${y==null?wn`NULL::jsonb`:wn`${y}::jsonb`}, ${v==null?wn`NULL::jsonb`:wn`${v}::jsonb`}, ${l.model??null}::text, ${nR(l.timestamp)}::timestamptz, ${JSON.stringify(p)}::jsonb)`});n=(await d.execute(wn`
|
|
235
235
|
WITH base AS (
|
|
236
236
|
SELECT COALESCE(MAX(sequence), 0) AS seq
|
|
237
237
|
FROM session_events WHERE session_id = ${e}
|
|
238
238
|
),
|
|
239
239
|
vals (rn, explicit_seq, event_type, content, tool_name, tool_input, tool_output, token_usage, model, ts, metadata) AS (
|
|
240
|
-
VALUES ${
|
|
240
|
+
VALUES ${wn.join(s,wn`, `)}
|
|
241
241
|
),
|
|
242
242
|
ins AS (
|
|
243
243
|
INSERT INTO session_events (id, session_id, sequence, event_type, content, tool_name, tool_input, tool_output, token_usage, model, timestamp, metadata)
|
|
@@ -258,8 +258,8 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
258
258
|
)
|
|
259
259
|
SELECT (SELECT COUNT(*)::int FROM ins) AS inserted,
|
|
260
260
|
(SELECT event_count FROM upd) AS new_count
|
|
261
|
-
`))[0]?.new_count??null;break}catch(s){if(
|
|
262
|
-
`)}u(_o,"findPgMessage");function Xy(e){if(!e||typeof e!="string")return null;let t=e.trim();if(!t)return null;if(!t.includes("://")&&!/^([\w.-]+@)?[\w.-]+:[^/]/.test(t)&&/^[\w.-]+(\.[\w.-]+)+\//.test(t)){let c=t.replace(/\.git$/i,"").replace(/\/+$/,""),a=c.indexOf("/"),l=c.slice(0,a).toLowerCase(),p=c.slice(a+1);return p?`${l}/${p}`:null}let n=t,r=/^([\w.-]+@)?([\w.-]+):([^/].*)$/.exec(t);if(r&&!t.includes("://")){let[,,c,a]=r;n=`ssh://${c}/${a}`}let o;try{o=new URL(n)}catch{return null}let s=o.hostname.toLowerCase();if(!s)return null;let i=o.pathname.replace(/^\/+|\/+$/g,"");return!i||(i=i.replace(/\.git$/i,""),!i)?null:`${s}/${i}`}u(Xy,"canonicalizeRemote");var nR=Number(process.env.PG_MESSAGE_RECONSTRUCT_BUDGET_BYTES)||16e6,rR=Number(process.env.PG_MESSAGE_RECONSTRUCT_PAGE_SIZE)||200;function oR(e){try{let t=JSON.stringify(e);return typeof t=="string"?t.length:0}catch{return 0}}u(oR,"estimateBytes");async function pu(e){let t=e.budgetBytes??nR,n=e.pageSize??rR,r=[],o=0,s=0,i=-1;for(;;){let c=await e.fetchPage(i,n);if(s++,c.length===0)break;for(let a of c){if(Array.isArray(a.messagesDelta))for(let l of a.messagesDelta){let p=oR(l);if(o+p>t)return{messages:r,truncated:!0,bytes:o,pages:s};r.push(l),o+=p}i=a.sequence}if(c.length<n)break}return{messages:r,truncated:!1,bytes:o,pages:s}}u(pu,"reconstructMessagesBounded");gu();import{inArray as uR}from"drizzle-orm";async function ow(e){let t=[...new Set(e.filter(r=>typeof r=="string"&&r.length>0))];if(t.length===0)return new Map;let n=await d.select({hash:cn.hash,content:cn.content}).from(cn).where(uR(cn.hash,t));return new Map(n.map(r=>[r.hash,r.content]))}u(ow,"fetchBlobMap");async function hu(e,t){return e?(await ow([e])).get(e)??t:t}u(hu,"resolveBlob");async function sw(e){if(e.length===0)return e;let t=await ow(e.flatMap(n=>[n.systemHash,n.toolsHash,n.injectedHash]));return t.size===0?e:e.map(n=>({...n,systemPrompt:t.get(n.systemHash)??n.systemPrompt,tools:rw(n.toolsHash!=null?t.get(n.toolsHash):void 0,n.tools),injectedInstructions:rw(n.injectedHash!=null?t.get(n.injectedHash):void 0,n.injectedInstructions)}))}u(sw,"resolveSnapshotBlobs");function rw(e,t){return Array.isArray(e)?e:t}u(rw,"preferArray");var dR=["x-anthropic-billing-header:","You are Claude Code, Anthropic","You are a Claude agent, built on Anthropic's Claude Agent SDK"];function iw(e){if(!e)return!1;let t=e.slice(0,400);return dR.some(n=>t.includes(n))}u(iw,"looksLikeHarnessSystemPrompt");function aw(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}u(aw,"escapeRegExp");function cw(e,t){let n=(e??"").trim();if(!n)return null;if(!n.includes("Contents of "))return n;if(t){let o=n.match(new RegExp(`Contents of [^\\n]*${aw(t)}[^\\n]*\\n([\\s\\S]*?)(?=\\nContents of |$)`,"i"))?.[1]?.trim();if(o)return o;let s=t.split("/").pop();if(s&&s!==t){let c=n.match(new RegExp(`Contents of [^\\n]*${aw(s)}[^\\n]*\\n([\\s\\S]*?)(?=\\nContents of |$)`,"i"))?.[1]?.trim();if(c)return c}}return null}u(cw,"extractInstructionSection");function _u(){let e=new Map;return{run(t,n){let r=e.get(t);if(r)return r;let o=Promise.resolve().then(n).finally(()=>{e.delete(t)});return o.catch(()=>{}),e.set(t,o),o},get size(){return e.size}}}u(_u,"makeSingleFlight");import{createHash as lR}from"node:crypto";function uw(e){if(!e||typeof e!="object")return null;let t=e,n=t._importContentHash,r=t._importContentLen,o=t._importEventCount;return typeof n!="string"||n.length===0||typeof r!="number"||!Number.isInteger(r)||r<0||typeof o!="number"||!Number.isInteger(o)||o<0?null:{contentHash:n,contentLen:r,eventCount:o}}u(uw,"readImportMarker");function dw(e,t){return e.length<=t.contentLen?!1:lR("sha256").update(e.slice(0,t.contentLen)).digest("hex")===t.contentHash}u(dw,"isStrictContentExtension");var lw=new Set(["claude_code","codex"]);var pR=new Set(["","unknown","<synthetic>"]);function yo(e){if(typeof e!="string")return null;let t=e.trim();return pR.has(t)?null:t}u(yo,"resolveModelId");var mR=["claudeCodeVersion","codexCliVersion"];function sa(e){if(typeof e!="object"||e===null)return null;let t=e;for(let n of mR){let r=yo(t[n]);if(r!==null)return r}return null}u(sa,"resolveHarnessVersion");var St=new gR;async function vu(e,t){let n=u((r,o)=>{let s={"org_attribution.source":r};if(o)for(let[i,c]of Object.entries(o))s[`org_attribution.${i}`]=c;Nd(s)},"tag");if(t)try{let[r]=await d.select({orgId:K.orgId}).from(K).where(qe(M(K.userId,e),M(K.orgId,t))).limit(1);if(r)return n("claim"),t;console.warn(`[sessions] User ${e} attempted to attribute session to org ${t} but is not a member; falling back to profile.active_org_id.`),n("profile_fallback",{claim_rejected:"not_member"})}catch(r){console.warn(`[sessions] Membership lookup failed for user=${e} org=${t}; falling back to profile.active_org_id:`,r instanceof Error?r.message:r),n("profile_fallback",{claim_rejected:"lookup_error"})}else n("profile_fallback",{claim_rejected:"no_claim"});try{let[r]=await d.select({activeOrgId:T.activeOrgId}).from(T).where(M(T.id,e)).limit(1);return r?.activeOrgId?r.activeOrgId:(n("unresolved"),null)}catch(r){return console.warn(`[sessions] active_org_id lookup failed for user=${e}; orgId silenced to null:`,r instanceof Error?r.message:r),n("unresolved",{profile_lookup_error:!0}),null}}u(vu,"resolveCallerOrgId");async function _R(e,t){if(!t)return null;try{let[n]=await d.select({id:W.id}).from(W).where(qe(M(W.id,t),M(W.userId,e))).limit(1);return n?n.id:(console.warn(`[sessions] User ${e} attempted to attribute session to run ${t} but does not own it; run_id left null.`),null)}catch(n){return console.warn(`[sessions] run ownership lookup failed for user=${e} run=${t}; run_id silenced to null:`,n instanceof Error?n.message:n),null}}u(_R,"resolveCallerRunId");var mw=Z.object({content:Z.string().min(1),tool:Z.string().optional(),orgId:Z.string().uuid().nullable().optional()});function yR(e){for(let t of[e.metadata?.sessionId,e.metadata?.codexSessionId])if(typeof t=="string"&&t.length>0)return t;return null}u(yR,"importedExternalSessionId");var wR=Z.object({tool:Z.string(),externalSessionId:Z.string().optional(),clientName:Z.string().optional(),mcpServerVersion:Z.string().optional(),projectPath:Z.string().optional(),gitBranch:Z.string().optional(),startedAt:Z.string().optional(),metadata:Z.record(Z.unknown()).optional(),orgId:Z.string().uuid().nullable().optional(),runId:Z.string().uuid().nullable().optional()}),vR=Z.object({sequence:Z.number().int().optional(),eventType:Z.string(),content:Z.string().nullable().optional(),toolName:Z.string().nullable().optional(),toolInput:Z.union([Z.record(Z.unknown()),Z.array(Z.unknown())]).nullable().optional(),toolOutput:Z.union([Z.record(Z.unknown()),Z.array(Z.unknown())]).nullable().optional(),durationMs:Z.number().optional(),success:Z.boolean().optional(),metadata:Z.record(Z.unknown()).optional(),timestamp:Z.string(),instructionIds:Z.array(Z.string().uuid()).optional(),model:Z.string().nullable().optional(),tokenUsage:Z.record(Z.unknown()).nullable().optional()});St.post("/sessions",async e=>{let t=e.get("userId"),n=await e.req.json(),r=wR.parse(n);if(r.projectPath){let h=await d.select({projectPath:f.projectPath}).from(f).where(qe(M(f.userId,t),U`${f.projectPath} IS NOT NULL`)).groupBy(f.projectPath);for(let w of h)if(w.projectPath&&r.projectPath!==w.projectPath&&r.projectPath.startsWith(w.projectPath+"/")){r.projectPath=w.projectPath;break}}let o=await vu(t,r.orgId??null),s=await _R(t,r.runId??null);if(r.externalSessionId){let[h]=await d.select().from(f).where(qe(M(f.userId,t),M(f.externalSessionId,r.externalSessionId))).limit(1);if(h){let w={};return!h.orgId&&o&&(w.orgId=o,h.orgId=o),!h.runId&&s&&(w.runId=s,h.runId=s),Object.keys(w).length>0&&await d.update(f).set(w).where(M(f.id,h.id)),e.json(h,200)}}if(r.tool&&r.projectPath){let h=new Date(Date.now()-3e4),w=[M(f.userId,t),M(f.tool,r.tool),M(f.projectPath,r.projectPath),jp(f.startedAt,h)],[I]=await d.select().from(f).where(qe(...w)).orderBy(wo(f.startedAt)).limit(1);if(I){let b={};return!I.externalSessionId&&r.externalSessionId&&(b.externalSessionId=r.externalSessionId,I.externalSessionId=r.externalSessionId),!I.orgId&&o&&(b.orgId=o,I.orgId=o),!I.runId&&s&&(b.runId=s,I.runId=s),Object.keys(b).length>0&&await d.update(f).set(b).where(M(f.id,I.id)),e.json(I,200)}}let i=[],c=null,a=Xy(r.metadata?.gitRemote??null),l=typeof r.metadata?.gitRootCommit=="string"&&r.metadata.gitRootCommit?r.metadata.gitRootCommit:null,p=typeof r.metadata?.launchProjectPath=="string"&&r.metadata.launchProjectPath?r.metadata.launchProjectPath:null;try{if(p){let[h]=await d.select({projectId:ce.projectId}).from(ce).where(M(ce.path,p)).orderBy(wo(ce.lastSeen)).limit(1);h&&(i=[{id:h.projectId}],c="launchPath")}if(i.length===0&&a){let[h]=await d.select({id:O.id}).from(O).where(wu(M(O.gitRemoteUrl,a),U`${a} = ANY(${O.gitRemoteAliases})`)).limit(1);h&&(i=[h],c="remote")}if(i.length===0&&l){let[h]=await d.select({id:O.id,gitRemoteUrl:O.gitRemoteUrl,gitRemoteAliases:O.gitRemoteAliases}).from(O).where(M(O.gitRootCommit,l)).limit(1);h&&(i=[{id:h.id}],c="rootCommit",a&&h.gitRemoteUrl&&h.gitRemoteUrl!==a&&!(h.gitRemoteAliases??[]).includes(a)&&await d.update(O).set({gitRemoteUrl:a,gitRemoteAliases:U`array_append(${O.gitRemoteAliases}, ${h.gitRemoteUrl})`}).where(M(O.id,h.id)))}if(i.length===0&&a){let h=a.split("/").filter(Boolean).pop()??a,[w]=await d.insert(O).values({name:h,gitRemoteUrl:a,gitRootCommit:l,createdBy:t}).onConflictDoUpdate({target:O.gitRemoteUrl,targetWhere:U`${O.gitRemoteUrl} IS NOT NULL`,set:{gitRemoteUrl:a}}).returning({id:O.id});w&&(i=[{id:w.id}],c="remote")}}catch(h){console.warn("[sessions] Project match failed (non-fatal):",h)}let m=e.req.header("X-RuleMetric-Internal")==="true"||e.req.header("x-rulemetric-internal")==="true",_;m?_="internal_worker":r.clientName==="mcp"?_="mcp":r.externalSessionId?_="hook":_="proxy";let v;try{[v]=await d.insert(f).values({userId:t,externalSessionId:r.externalSessionId??null,projectId:i[0]?.id??null,orgId:o,runId:s,tool:r.tool,projectPath:r.projectPath??null,gitBranch:r.gitBranch??null,startedAt:r.startedAt?new Date(r.startedAt):new Date,origin:_,harnessVersion:sa(r.metadata)??void 0,metadata:{...r.metadata,clientName:r.clientName,mcpServerVersion:r.mcpServerVersion}}).returning()}catch(h){if(h.cause?.code==="23505"&&r.externalSessionId){let[I]=await d.select().from(f).where(qe(M(f.userId,t),M(f.externalSessionId,r.externalSessionId))).limit(1);if(I){let b={};return!I.orgId&&o&&(b.orgId=o,I.orgId=o),!I.runId&&s&&(b.runId=s,I.runId=s),Object.keys(b).length>0&&await d.update(f).set(b).where(M(f.id,I.id)),e.json(I,200)}}throw h}if(!v)return e.json({error:"Failed to create session"},500);let g=!!r.projectPath&&/^\/(Users|home)\/[^/]+\/?$/.test(r.projectPath);if(i.length>0&&r.projectPath&&!g){let h=r.metadata?.isWorktree===!0;try{await d.insert(ce).values({projectId:i[0].id,path:r.projectPath,isWorktree:h}).onConflictDoUpdate({target:[ce.projectId,ce.path],set:{lastSeen:new Date,isWorktree:h}})}catch(w){console.warn("[sessions] project_checkouts upsert failed (non-fatal):",w)}}try{if(i.length>0){let h=r.projectPath?r.projectPath.replace(/\/$/,"")+"/":null,w=h?U`${y.name} LIKE ${h+"%"}`:U`FALSE`,I=await d.select({instructionId:ot.instructionId}).from(ot).innerJoin(y,M(y.id,ot.instructionId)).where(qe(U`${ot.projectId} IN (${U.join(i.map(b=>U`${b.id}`),U`, `)})`,wu(hR(y.type,"context_file"),w)));for(let{instructionId:b}of I)await d.insert(te).values({sessionId:v.id,instructionId:b,linkMethod:"project_match"}).onConflictDoNothing()}}catch{}return e.json(v,201)});St.post("/sessions/:id/events",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=vR.parse(r),[s]=await d.select({id:f.id,eventCount:f.eventCount,userId:f.userId}).from(f).where(qe(M(f.id,n),M(f.userId,t)));if(!s)return e.json({error:"Session not found"},404);let i=s.eventCount??0;if(lu())return Sp().push({sessionId:n,userId:s.userId,input:o})?e.json({buffered:!0,count:1,durable:!1},202):(ji(),e.header("Retry-After","2"),e.json({error:"Ingest busy: the event buffer is full. Retry shortly."},503));let c={...o.metadata??{}};o.durationMs!=null&&(c.durationMs=o.durationMs),o.success!=null&&(c.success=o.success);let a=o.toolInput==null?null:JSON.stringify(o.toolInput),l=o.toolOutput==null?null:JSON.stringify(o.toolOutput),p=JSON.stringify(c),m=o.tokenUsage==null?null:JSON.stringify(o.tokenUsage),_=o.sequence,v=5;for(let g=0;g<=v;g++)try{let h=_!=null?U`${_}::int`:U`COALESCE((SELECT MAX(sequence) FROM session_events WHERE session_id = ${n}), 0) + 1`;_=(await d.execute(U`
|
|
261
|
+
`))[0]?.new_count??null;break}catch(s){if(tR(s)&&o<Jy){r=!0;continue}throw s}for(let o of t)if(!(!o.input.instructionIds||o.input.instructionIds.length===0))for(let s of o.input.instructionIds)try{await d.insert(ne).values({sessionId:e,instructionId:s,linkMethod:"auto_capture"}).onConflictDoNothing()}catch(i){console.warn("[event-batcher] failed to auto-link instructionId:",i instanceof Error?i.message:i)}if(n!=null)try{let o=n-t.length,s=eR.filter(i=>o<i&&n>=i);for(let i of s)await pu({sessionId:e,milestone:i,userId:t[0].userId})}catch(o){console.warn("[event-batcher] failed to enqueue process_session_goal:",o instanceof Error?o.message:o)}}u(rR,"drainSessionEvents");var Lr=null;function Ap(){return Lr==null&&(Lr=ZT({drainSession:rR})),Lr}u(Ap,"getEventBatcher");function Qy(){Ap(),console.log(`[event-batcher] batched event ingest ON (lingerMs=${Gy()} flushSize=${Yy()} bufferMax=${Ky()} drainConcurrency=${Xy()}; EVENT_BATCHING=0 to disable)`)}u(Qy,"initEventBatcher");async function Zy(e=5e3){if(Lr==null)return;Lr.stop(),await Lr.flush(e);let t=Lr.size()+Lr.inFlight();t>0&&console.warn(`[event-batcher] shutdown flush deadline (${e}ms) hit; dropping ~${t} buffered event(s)`)}u(Zy,"shutdownEventBatcher");function nn(e){let t=e;for(;t&&typeof t=="object";){let n=t.code;if(typeof n=="string")return n;t=t.cause}}u(nn,"findPgCode");function wo(e){let t=[],n=e;for(;n&&typeof n=="object";){let r=n.message;typeof r=="string"&&t.push(r),n=n.cause}return t.join(`
|
|
262
|
+
`)}u(wo,"findPgMessage");function ew(e){if(!e||typeof e!="string")return null;let t=e.trim();if(!t)return null;if(!t.includes("://")&&!/^([\w.-]+@)?[\w.-]+:[^/]/.test(t)&&/^[\w.-]+(\.[\w.-]+)+\//.test(t)){let c=t.replace(/\.git$/i,"").replace(/\/+$/,""),a=c.indexOf("/"),l=c.slice(0,a).toLowerCase(),p=c.slice(a+1);return p?`${l}/${p}`:null}let n=t,r=/^([\w.-]+@)?([\w.-]+):([^/].*)$/.exec(t);if(r&&!t.includes("://")){let[,,c,a]=r;n=`ssh://${c}/${a}`}let o;try{o=new URL(n)}catch{return null}let s=o.hostname.toLowerCase();if(!s)return null;let i=o.pathname.replace(/^\/+|\/+$/g,"");return!i||(i=i.replace(/\.git$/i,""),!i)?null:`${s}/${i}`}u(ew,"canonicalizeRemote");var oR=Number(process.env.PG_MESSAGE_RECONSTRUCT_BUDGET_BYTES)||16e6,sR=Number(process.env.PG_MESSAGE_RECONSTRUCT_PAGE_SIZE)||200;function iR(e){try{let t=JSON.stringify(e);return typeof t=="string"?t.length:0}catch{return 0}}u(iR,"estimateBytes");async function fu(e){let t=e.budgetBytes??oR,n=e.pageSize??sR,r=[],o=0,s=0,i=-1;for(;;){let c=await e.fetchPage(i,n);if(s++,c.length===0)break;for(let a of c){if(Array.isArray(a.messagesDelta))for(let l of a.messagesDelta){let p=iR(l);if(o+p>t)return{messages:r,truncated:!0,bytes:o,pages:s};r.push(l),o+=p}i=a.sequence}if(c.length<n)break}return{messages:r,truncated:!1,bytes:o,pages:s}}u(fu,"reconstructMessagesBounded");_u();import{inArray as lR}from"drizzle-orm";async function aw(e){let t=[...new Set(e.filter(r=>typeof r=="string"&&r.length>0))];if(t.length===0)return new Map;let n=await d.select({hash:cn.hash,content:cn.content}).from(cn).where(lR(cn.hash,t));return new Map(n.map(r=>[r.hash,r.content]))}u(aw,"fetchBlobMap");async function yu(e,t){return e?(await aw([e])).get(e)??t:t}u(yu,"resolveBlob");async function cw(e){if(e.length===0)return e;let t=await aw(e.flatMap(n=>[n.systemHash,n.toolsHash,n.injectedHash]));return t.size===0?e:e.map(n=>({...n,systemPrompt:t.get(n.systemHash)??n.systemPrompt,tools:iw(n.toolsHash!=null?t.get(n.toolsHash):void 0,n.tools),injectedInstructions:iw(n.injectedHash!=null?t.get(n.injectedHash):void 0,n.injectedInstructions)}))}u(cw,"resolveSnapshotBlobs");function iw(e,t){return Array.isArray(e)?e:t}u(iw,"preferArray");var pR=["x-anthropic-billing-header:","You are Claude Code, Anthropic","You are a Claude agent, built on Anthropic's Claude Agent SDK"];function uw(e){if(!e)return!1;let t=e.slice(0,400);return pR.some(n=>t.includes(n))}u(uw,"looksLikeHarnessSystemPrompt");function dw(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}u(dw,"escapeRegExp");function lw(e,t){let n=(e??"").trim();if(!n)return null;if(!n.includes("Contents of "))return n;if(t){let o=n.match(new RegExp(`Contents of [^\\n]*${dw(t)}[^\\n]*\\n([\\s\\S]*?)(?=\\nContents of |$)`,"i"))?.[1]?.trim();if(o)return o;let s=t.split("/").pop();if(s&&s!==t){let c=n.match(new RegExp(`Contents of [^\\n]*${dw(s)}[^\\n]*\\n([\\s\\S]*?)(?=\\nContents of |$)`,"i"))?.[1]?.trim();if(c)return c}}return null}u(lw,"extractInstructionSection");function wu(){let e=new Map;return{run(t,n){let r=e.get(t);if(r)return r;let o=Promise.resolve().then(n).finally(()=>{e.delete(t)});return o.catch(()=>{}),e.set(t,o),o},get size(){return e.size}}}u(wu,"makeSingleFlight");import{createHash as mR}from"node:crypto";function pw(e){if(!e||typeof e!="object")return null;let t=e,n=t._importContentHash,r=t._importContentLen,o=t._importEventCount;return typeof n!="string"||n.length===0||typeof r!="number"||!Number.isInteger(r)||r<0||typeof o!="number"||!Number.isInteger(o)||o<0?null:{contentHash:n,contentLen:r,eventCount:o}}u(pw,"readImportMarker");function mw(e,t){return e.length<=t.contentLen?!1:mR("sha256").update(e.slice(0,t.contentLen)).digest("hex")===t.contentHash}u(mw,"isStrictContentExtension");var fw=new Set(["claude_code","codex"]);var fR=new Set(["","unknown","<synthetic>"]);function vo(e){if(typeof e!="string")return null;let t=e.trim();return fR.has(t)?null:t}u(vo,"resolveModelId");var gR=["claudeCodeVersion","codexCliVersion"];function sa(e){if(typeof e!="object"||e===null)return null;let t=e;for(let n of gR){let r=vo(t[n]);if(r!==null)return r}return null}u(sa,"resolveHarnessVersion");var At=new _R;async function bu(e,t){let n=u((r,o)=>{let s={"org_attribution.source":r};if(o)for(let[i,c]of Object.entries(o))s[`org_attribution.${i}`]=c;Pd(s)},"tag");if(t)try{let[r]=await d.select({orgId:Y.orgId}).from(Y).where(qe(L(Y.userId,e),L(Y.orgId,t))).limit(1);if(r)return n("claim"),t;console.warn(`[sessions] User ${e} attempted to attribute session to org ${t} but is not a member; falling back to profile.active_org_id.`),n("profile_fallback",{claim_rejected:"not_member"})}catch(r){console.warn(`[sessions] Membership lookup failed for user=${e} org=${t}; falling back to profile.active_org_id:`,r instanceof Error?r.message:r),n("profile_fallback",{claim_rejected:"lookup_error"})}else n("profile_fallback",{claim_rejected:"no_claim"});try{let[r]=await d.select({activeOrgId:R.activeOrgId}).from(R).where(L(R.id,e)).limit(1);return r?.activeOrgId?r.activeOrgId:(n("unresolved"),null)}catch(r){return console.warn(`[sessions] active_org_id lookup failed for user=${e}; orgId silenced to null:`,r instanceof Error?r.message:r),n("unresolved",{profile_lookup_error:!0}),null}}u(bu,"resolveCallerOrgId");async function wR(e,t){if(!t)return null;try{let[n]=await d.select({id:J.id}).from(J).where(qe(L(J.id,t),L(J.userId,e))).limit(1);return n?n.id:(console.warn(`[sessions] User ${e} attempted to attribute session to run ${t} but does not own it; run_id left null.`),null)}catch(n){return console.warn(`[sessions] run ownership lookup failed for user=${e} run=${t}; run_id silenced to null:`,n instanceof Error?n.message:n),null}}u(wR,"resolveCallerRunId");var hw=te.object({content:te.string().min(1),tool:te.string().optional(),orgId:te.string().uuid().nullable().optional()});function vR(e){for(let t of[e.metadata?.sessionId,e.metadata?.codexSessionId])if(typeof t=="string"&&t.length>0)return t;return null}u(vR,"importedExternalSessionId");var IR=te.object({tool:te.string(),externalSessionId:te.string().optional(),clientName:te.string().optional(),mcpServerVersion:te.string().optional(),projectPath:te.string().optional(),gitBranch:te.string().optional(),startedAt:te.string().optional(),metadata:te.record(te.unknown()).optional(),orgId:te.string().uuid().nullable().optional(),runId:te.string().uuid().nullable().optional()}),bR=te.object({sequence:te.number().int().optional(),eventType:te.string(),content:te.string().nullable().optional(),toolName:te.string().nullable().optional(),toolInput:te.union([te.record(te.unknown()),te.array(te.unknown())]).nullable().optional(),toolOutput:te.union([te.record(te.unknown()),te.array(te.unknown())]).nullable().optional(),durationMs:te.number().optional(),success:te.boolean().optional(),metadata:te.record(te.unknown()).optional(),timestamp:te.string(),instructionIds:te.array(te.string().uuid()).optional(),model:te.string().nullable().optional(),tokenUsage:te.record(te.unknown()).nullable().optional()});At.post("/sessions",async e=>{let t=e.get("userId"),n=await e.req.json(),r=IR.parse(n);if(r.projectPath){let h=await d.select({projectPath:f.projectPath}).from(f).where(qe(L(f.userId,t),H`${f.projectPath} IS NOT NULL`)).groupBy(f.projectPath);for(let w of h)if(w.projectPath&&r.projectPath!==w.projectPath&&r.projectPath.startsWith(w.projectPath+"/")){r.projectPath=w.projectPath;break}}let o=await bu(t,r.orgId??null),s=await wR(t,r.runId??null);if(r.externalSessionId){let[h]=await d.select().from(f).where(qe(L(f.userId,t),L(f.externalSessionId,r.externalSessionId))).limit(1);if(h){let w={};return!h.orgId&&o&&(w.orgId=o,h.orgId=o),!h.runId&&s&&(w.runId=s,h.runId=s),Object.keys(w).length>0&&await d.update(f).set(w).where(L(f.id,h.id)),e.json(h,200)}}if(r.tool&&r.projectPath){let h=new Date(Date.now()-3e4),w=[L(f.userId,t),L(f.tool,r.tool),L(f.projectPath,r.projectPath),Np(f.startedAt,h)],[b]=await d.select().from(f).where(qe(...w)).orderBy(Io(f.startedAt)).limit(1);if(b){let I={};return!b.externalSessionId&&r.externalSessionId&&(I.externalSessionId=r.externalSessionId,b.externalSessionId=r.externalSessionId),!b.orgId&&o&&(I.orgId=o,b.orgId=o),!b.runId&&s&&(I.runId=s,b.runId=s),Object.keys(I).length>0&&await d.update(f).set(I).where(L(f.id,b.id)),e.json(b,200)}}let i=[],c=null,a=ew(r.metadata?.gitRemote??null),l=typeof r.metadata?.gitRootCommit=="string"&&r.metadata.gitRootCommit?r.metadata.gitRootCommit:null,p=typeof r.metadata?.launchProjectPath=="string"&&r.metadata.launchProjectPath?r.metadata.launchProjectPath:null;try{if(p){let[h]=await d.select({projectId:ue.projectId}).from(ue).where(L(ue.path,p)).orderBy(Io(ue.lastSeen)).limit(1);h&&(i=[{id:h.projectId}],c="launchPath")}if(i.length===0&&a){let[h]=await d.select({id:D.id}).from(D).where(Iu(L(D.gitRemoteUrl,a),H`${a} = ANY(${D.gitRemoteAliases})`)).limit(1);h&&(i=[h],c="remote")}if(i.length===0&&l){let[h]=await d.select({id:D.id,gitRemoteUrl:D.gitRemoteUrl,gitRemoteAliases:D.gitRemoteAliases}).from(D).where(L(D.gitRootCommit,l)).limit(1);h&&(i=[{id:h.id}],c="rootCommit",a&&h.gitRemoteUrl&&h.gitRemoteUrl!==a&&!(h.gitRemoteAliases??[]).includes(a)&&await d.update(D).set({gitRemoteUrl:a,gitRemoteAliases:H`array_append(${D.gitRemoteAliases}, ${h.gitRemoteUrl})`}).where(L(D.id,h.id)))}if(i.length===0&&a){let h=a.split("/").filter(Boolean).pop()??a,[w]=await d.insert(D).values({name:h,gitRemoteUrl:a,gitRootCommit:l,createdBy:t}).onConflictDoUpdate({target:D.gitRemoteUrl,targetWhere:H`${D.gitRemoteUrl} IS NOT NULL`,set:{gitRemoteUrl:a}}).returning({id:D.id});w&&(i=[{id:w.id}],c="remote")}}catch(h){console.warn("[sessions] Project match failed (non-fatal):",h)}let m=e.req.header("X-RuleMetric-Internal")==="true"||e.req.header("x-rulemetric-internal")==="true",y;m?y="internal_worker":r.clientName==="mcp"?y="mcp":r.externalSessionId?y="hook":y="proxy";let v;try{[v]=await d.insert(f).values({userId:t,externalSessionId:r.externalSessionId??null,projectId:i[0]?.id??null,orgId:o,runId:s,tool:r.tool,projectPath:r.projectPath??null,gitBranch:r.gitBranch??null,startedAt:r.startedAt?new Date(r.startedAt):new Date,origin:y,harnessVersion:sa(r.metadata)??void 0,metadata:{...r.metadata,clientName:r.clientName,mcpServerVersion:r.mcpServerVersion}}).returning()}catch(h){if(h.cause?.code==="23505"&&r.externalSessionId){let[b]=await d.select().from(f).where(qe(L(f.userId,t),L(f.externalSessionId,r.externalSessionId))).limit(1);if(b){let I={};return!b.orgId&&o&&(I.orgId=o,b.orgId=o),!b.runId&&s&&(I.runId=s,b.runId=s),Object.keys(I).length>0&&await d.update(f).set(I).where(L(f.id,b.id)),e.json(b,200)}}throw h}if(!v)return e.json({error:"Failed to create session"},500);let g=!!r.projectPath&&/^\/(Users|home)\/[^/]+\/?$/.test(r.projectPath);if(i.length>0&&r.projectPath&&!g){let h=r.metadata?.isWorktree===!0;try{await d.insert(ue).values({projectId:i[0].id,path:r.projectPath,isWorktree:h}).onConflictDoUpdate({target:[ue.projectId,ue.path],set:{lastSeen:new Date,isWorktree:h}})}catch(w){console.warn("[sessions] project_checkouts upsert failed (non-fatal):",w)}}try{if(i.length>0){let h=r.projectPath?r.projectPath.replace(/\/$/,"")+"/":null,w=h?H`${_.name} LIKE ${h+"%"}`:H`FALSE`,b=await d.select({instructionId:at.instructionId}).from(at).innerJoin(_,L(_.id,at.instructionId)).where(qe(H`${at.projectId} IN (${H.join(i.map(I=>H`${I.id}`),H`, `)})`,Iu(yR(_.type,"context_file"),w)));for(let{instructionId:I}of b)await d.insert(ne).values({sessionId:v.id,instructionId:I,linkMethod:"project_match"}).onConflictDoNothing()}}catch{}return e.json(v,201)});At.post("/sessions/:id/events",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=bR.parse(r),[s]=await d.select({id:f.id,eventCount:f.eventCount,userId:f.userId}).from(f).where(qe(L(f.id,n),L(f.userId,t)));if(!s)return e.json({error:"Session not found"},404);let i=s.eventCount??0;if(mu())return Ap().push({sessionId:n,userId:s.userId,input:o})?e.json({buffered:!0,count:1,durable:!1},202):(ji(),e.header("Retry-After","2"),e.json({error:"Ingest busy: the event buffer is full. Retry shortly."},503));let c={...o.metadata??{}};o.durationMs!=null&&(c.durationMs=o.durationMs),o.success!=null&&(c.success=o.success);let a=o.toolInput==null?null:JSON.stringify(o.toolInput),l=o.toolOutput==null?null:JSON.stringify(o.toolOutput),p=JSON.stringify(c),m=o.tokenUsage==null?null:JSON.stringify(o.tokenUsage),y=o.sequence,v=5;for(let g=0;g<=v;g++)try{let h=y!=null?H`${y}::int`:H`COALESCE((SELECT MAX(sequence) FROM session_events WHERE session_id = ${n}), 0) + 1`;y=(await d.execute(H`
|
|
263
263
|
WITH ins AS (
|
|
264
264
|
INSERT INTO session_events (id, session_id, sequence, event_type, content, tool_name, tool_input, tool_output, token_usage, model, timestamp, metadata)
|
|
265
265
|
SELECT
|
|
@@ -269,12 +269,12 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
269
269
|
${o.eventType},
|
|
270
270
|
${o.content??null},
|
|
271
271
|
${o.toolName??null},
|
|
272
|
-
${a==null?
|
|
273
|
-
${l==null?
|
|
274
|
-
${m==null?
|
|
272
|
+
${a==null?H`NULL`:H`${a}::jsonb`},
|
|
273
|
+
${l==null?H`NULL`:H`${l}::jsonb`},
|
|
274
|
+
${m==null?H`NULL`:H`${m}::jsonb`},
|
|
275
275
|
${o.model??null},
|
|
276
276
|
${new Date(o.timestamp).toISOString()}::timestamptz,
|
|
277
|
-
${
|
|
277
|
+
${H`${p}::jsonb`}
|
|
278
278
|
RETURNING sequence
|
|
279
279
|
),
|
|
280
280
|
upd AS (
|
|
@@ -284,7 +284,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
284
284
|
RETURNING id
|
|
285
285
|
)
|
|
286
286
|
SELECT ins.sequence FROM ins, upd
|
|
287
|
-
`))[0]?.sequence??
|
|
287
|
+
`))[0]?.sequence??y??1;break}catch(h){let w=h.cause;if(h instanceof Error&&(w?.code==="23505"||h.message.includes("unique")||h.message.includes("duplicate"))&&g<v){y=void 0;continue}throw h}if(o.instructionIds&&o.instructionIds.length>0)for(let g of o.instructionIds)try{await d.insert(ne).values({sessionId:n,instructionId:g,linkMethod:"auto_capture"}).onConflictDoNothing()}catch(h){console.warn("[events ingest] failed to auto-link instructionId:",h instanceof Error?h.message:h)}try{let g=i+1,w=[5,20,50].filter(b=>i<b&&g>=b);for(let b of w)await pu({sessionId:s.id,milestone:b,userId:s.userId})}catch(g){console.warn("[events ingest] failed to enqueue process_session_goal:",g instanceof Error?g.message:g)}return e.json({recorded:!0})});At.post("/sessions/:id/close",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:f.id,projectPath:f.projectPath}).from(f).where(qe(L(f.id,n),L(f.userId,t)));if(!r)return e.json({error:"Session not found"},404);if(await d.update(f).set({endedAt:new Date}).where(L(f.id,n)),r.projectPath)try{let o=new Date;o.setHours(0,0,0,0);let[s]=await d.select({id:W.id}).from(W).where(qe(L(W.userId,t),Np(W.createdAt,o),vu(W.projectPath,`%${et(r.projectPath)}%`))).limit(1);if(!s){let[i]=await d.select({completedAt:W.completedAt}).from(W).where(qe(L(W.userId,t),L(W.status,"completed"),vu(W.projectPath,`%${et(r.projectPath)}%`))).orderBy(Io(W.completedAt)).limit(1),c=i?.completedAt??new Date(0),[{count:a}]=await d.select({count:H`COUNT(*)`}).from(f).where(qe(L(f.userId,t),vu(f.projectPath,`%${et(r.projectPath)}%`),Np(f.startedAt,c)));Number(a)>=5&&await kt({taskName:"process_insights",payload:{projectPath:r.projectPath},userId:t,mirror:{userId:t,projectPath:r.projectPath}})}}catch{}return e.json({closed:!0})});async function SR(e,t,n){if(n)try{await d.execute(H`
|
|
288
288
|
insert into treatment_exposures
|
|
289
289
|
(session_id, user_id, treatment_type, treatment_id, treatment_version, method, exposed_at)
|
|
290
290
|
select ${e}::uuid, ${t}::uuid, 'suggestion', s.instruction_id, 1, 'injected', min(ise.created_at)
|
|
@@ -294,7 +294,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
294
294
|
and ise.event_type in ('surfaced', 'surfaced_with_content', 'proxy_injected')
|
|
295
295
|
group by s.instruction_id
|
|
296
296
|
on conflict on constraint treatment_exposures_unique do nothing
|
|
297
|
-
`)}catch(r){console.warn("[reimport] suggestion exposure reconcile failed:",r instanceof Error?r.message:r)}}u(
|
|
297
|
+
`)}catch(r){console.warn("[reimport] suggestion exposure reconcile failed:",r instanceof Error?r.message:r)}}u(SR,"reconcileSuggestionExposures");async function AR(e,t,n){if(n)try{await d.execute(H`
|
|
298
298
|
with drained as (
|
|
299
299
|
insert into treatment_exposures
|
|
300
300
|
(session_id, user_id, treatment_type, treatment_id, treatment_version, method, exposed_at)
|
|
@@ -309,12 +309,12 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
309
309
|
delete from pending_treatment_exposures
|
|
310
310
|
where external_session_id = ${n}
|
|
311
311
|
and user_id = ${t}::uuid
|
|
312
|
-
`)}catch(r){console.warn("[reimport] memory exposure reconcile failed:",r instanceof Error?r.message:r)}}u(
|
|
312
|
+
`)}catch(r){console.warn("[reimport] memory exposure reconcile failed:",r instanceof Error?r.message:r)}}u(AR,"reconcileMemoryExposures");var xR=6;async function kp(e,t,n,r,o){await SR(e,t,n),await AR(e,t,n),r&&o>=xR&&await Hy({sessionId:e,userId:t}).catch(s=>{console.warn("[reimport] distill enqueue failed:",s instanceof Error?s.message:s)})}u(kp,"finalizeSessionIntelligence");At.post("/sessions/:id/reimport",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=hw.parse(r),[s]=await d.select({id:f.id,eventCount:f.eventCount,externalSessionId:f.externalSessionId,projectId:f.projectId}).from(f).where(qe(L(f.id,n),L(f.userId,t)));if(!s)return e.json({error:"Session not found"},404);let i=o.tool??Zi(o.content);if(!i)return e.json({error:"Could not detect session format. Specify tool parameter."},400);let a=Qi(i).parse(o.content);if(a.events.length===s.eventCount)return await kp(n,t,s.externalSessionId,s.projectId,s.eventCount??0),e.json({reimported:!1,skipped:"unchanged",eventCount:s.eventCount});if(a.events.length===0&&(s.eventCount??0)>0)return await d.update(f).set({endedAt:a.endedAt?new Date(a.endedAt):new Date}).where(L(f.id,n)),await kp(n,t,s.externalSessionId,s.projectId,s.eventCount??0),e.json({reimported:!1,skipped:"empty_parse",eventCount:s.eventCount});let l=a.events.map(p=>({sessionId:n,sequence:p.sequence,eventType:p.eventType,content:p.content,toolName:p.toolName,toolInput:p.toolInput,toolOutput:p.toolOutput,tokenUsage:p.tokenUsage,timestamp:new Date(p.timestamp),metadata:p.metadata}));return await ft.transaction(async p=>{await p.execute(H`SET LOCAL statement_timeout = '60s'`),await p.delete(Le).where(L(Le.sessionId,n));for(let m=0;m<l.length;m+=500)await p.insert(Le).values(l.slice(m,m+500));await p.update(f).set({eventCount:a.events.length,endedAt:a.endedAt?new Date(a.endedAt):new Date,projectPath:a.projectPath??void 0,gitBranch:a.gitBranch??void 0,metadata:a.metadata?H`COALESCE(${f.metadata}, '{}'::jsonb) || ${JSON.stringify(a.metadata)}::jsonb`:void 0,model:vo(a.metadata?.model)??void 0,harnessVersion:sa(a.metadata)??void 0}).where(L(f.id,n))}),await kp(n,t,s.externalSessionId,s.projectId,a.events.length),e.json({reimported:!0,eventCount:a.events.length})});At.post("/sessions/import",async e=>{let t=e.get("userId"),n=await e.req.json(),r=hw.parse(n),o=r.tool??Zi(r.content);if(!o)return e.json({error:"Could not detect session format. Specify tool parameter."},400);let i=Qi(o).parse(r.content),c=vR(i),a=hR("sha256").update(r.content).digest("hex"),l,p=u(async()=>(l===void 0&&(l=await bu(t,r.orgId??null)),l),"resolveOrgId"),m=i.events.map(g=>({sequence:g.sequence,eventType:g.eventType,content:g.content,toolName:g.toolName,toolInput:g.toolInput,toolOutput:g.toolOutput,tokenUsage:g.tokenUsage,timestamp:new Date(g.timestamp),metadata:g.metadata})),y={...i.metadata??{},_importContentHash:a,_importContentLen:r.content.length,_importEventCount:i.events.length},v=3;for(let g=0;;g++){let h=c?(await d.select().from(f).where(qe(L(f.userId,t),L(f.externalSessionId,c))).limit(1))[0]??null:null;if(h&&h.metadata?._importContentHash===a)return e.json({...h,deduped:!0},200);let w=await p(),b=h?{tool:i.tool,projectPath:i.projectPath??void 0,gitBranch:i.gitBranch??void 0,startedAt:new Date(i.startedAt),endedAt:i.endedAt?new Date(i.endedAt):void 0,eventCount:i.events.length,metadata:H`COALESCE(${f.metadata}, '{}'::jsonb) || ${JSON.stringify(y)}::jsonb`,model:vo(i.metadata?.model)??void 0,harnessVersion:sa(i.metadata)??void 0,...w&&!h.orgId?{orgId:w}:{}}:null;try{if(h&&b&&fw.has(i.tool)){let S=pw(h.metadata);if(S&&m.length>S.eventCount&&m[S.eventCount]?.sequence===S.eventCount&&mw(r.content,S)){let[A]=await d.select({count:H`COUNT(*)::int`,maxSeq:H`MAX(${Le.sequence})::int`}).from(Le).where(L(Le.sessionId,h.id)),x=Number(A?.count??-1),T=A?.maxSeq==null?null:Number(A.maxSeq);if(x===S.eventCount&&(S.eventCount===0?T===null:T===S.eventCount-1)){let E=await ft.transaction(async j=>{await j.execute(H`SET LOCAL statement_timeout = '60s'`);let O=m.slice(S.eventCount).map(U=>({sessionId:h.id,...U}));for(let U=0;U<O.length;U+=500)await j.insert(Le).values(O.slice(U,U+500));let[F]=await j.update(f).set(b).where(L(f.id,h.id)).returning();return F});return e.json({...E,appended:!0},200)}}}let I=await ft.transaction(async S=>{if(await S.execute(H`SET LOCAL statement_timeout = '60s'`),h&&b){if(await S.delete(Le).where(L(Le.sessionId,h.id)),m.length>0){let T=m.map(P=>({sessionId:h.id,...P}));for(let P=0;P<T.length;P+=500)await S.insert(Le).values(T.slice(P,P+500))}let[x]=await S.update(f).set(b).where(L(f.id,h.id)).returning();return x}let[A]=await S.insert(f).values({userId:t,externalSessionId:c,tool:i.tool,projectPath:i.projectPath,gitBranch:i.gitBranch,startedAt:new Date(i.startedAt),endedAt:i.endedAt?new Date(i.endedAt):null,eventCount:i.events.length,metadata:y,model:vo(i.metadata?.model),harnessVersion:sa(i.metadata),orgId:w}).returning();if(m.length>0){let x=m.map(T=>({sessionId:A.id,...T}));for(let T=0;T<x.length;T+=500)await S.insert(Le).values(x.slice(T,T+500))}return A});return e.json(I,h?200:201)}catch(I){if(c&&nn(I)==="23505"&&g<v)continue;throw I}}});At.get("/sessions",async e=>{let t=e.get("userId"),n=e.req.query("tool"),r=e.req.query("outcome"),o=e.req.query("friction"),s=e.req.query("instructionId"),i=e.req.query("hasAnalysis"),c=e.req.query("projectPath"),a=e.req.query("projectId"),l=e.req.query("gitRemote"),p=Number(e.req.query("limit")??"50"),m=Number(e.req.query("offset")??"0"),y=[L(f.userId,t)];if(e.req.query("includeInternal")==="true"||y.push(H`${f.origin} <> 'internal_worker'`),n&&y.push(L(f.tool,n)),a){let w=[L(f.projectId,a)];l&&w.push(H`${f.metadata}->>'gitRemote' = ${l}`),y.push(w.length===1?w[0]:Iu(...w))}else if(c||l){let w=[];c&&w.push(vu(f.projectPath,`%${et(c)}%`)),l&&w.push(H`${f.metadata}->>'gitRemote' = ${l}`),y.push(w.length===1?w[0]:Iu(...w))}if(e.req.query("hideEmpty")!=="false"&&y.push(H`${f.eventCount} > 0`),i==="true"?y.push(H`${f.analysis} IS NOT NULL`):i==="false"&&y.push(H`${f.analysis} IS NULL`),r&&y.push(H`${f.analysis}->>'outcome' = ${r}`),o&&y.push(H`(${f.analysis}->'friction')::text ILIKE ${"%"+et(o)+"%"}`),s){let b=(await d.select({sessionId:ne.sessionId}).from(ne).where(L(ne.instructionId,s))).map(I=>I.sessionId);if(b.length===0)return e.json([]);y.push(H`${f.id} IN (${H.join(b.map(I=>H`${I}`),H`, `)})`)}if(e.req.query("summary")==="exists"){let[w]=await d.select({id:f.id}).from(f).where(qe(...y)).limit(1);return e.json({exists:!!w})}let h=await d.select().from(f).where(qe(...y)).orderBy(Io(f.startedAt)).limit(p).offset(m);if(h.length>0){let w=h.map(G=>G.id),b=Array.from(new Set(h.map(G=>G.projectId).filter(G=>!!G))),[I,S,A,x,T,P,E]=await Promise.all([d.select({sessionId:ne.sessionId,name:_.name,contextIdentity:_.contextIdentity,type:_.type}).from(ne).innerJoin(_,L(_.id,ne.instructionId)).where(ia(ne.sessionId,w)),d.select({sessionId:C.sessionId}).from(C).where(ia(C.sessionId,w)).groupBy(C.sessionId),d.execute(H`
|
|
313
313
|
SELECT session_id, MAX(timestamp) AS last_at
|
|
314
314
|
FROM session_events
|
|
315
|
-
WHERE session_id IN (${
|
|
315
|
+
WHERE session_id IN (${H.join(w.map(G=>H`${G}`),H`, `)})
|
|
316
316
|
GROUP BY session_id
|
|
317
|
-
`),d.execute(
|
|
317
|
+
`),d.execute(H`
|
|
318
318
|
SELECT DISTINCT ON (e.session_id)
|
|
319
319
|
e.session_id,
|
|
320
320
|
-- Collapse whitespace runs into a single space for preview rendering.
|
|
@@ -324,27 +324,27 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
324
324
|
-- lowercase s from every preview ever shown.
|
|
325
325
|
LEFT(REGEXP_REPLACE(COALESCE(e.content, ''), '[[:space:]]+', ' ', 'g'), 120) AS preview
|
|
326
326
|
FROM session_events e
|
|
327
|
-
WHERE e.session_id IN (${
|
|
327
|
+
WHERE e.session_id IN (${H.join(w.map(G=>H`${G}`),H`, `)})
|
|
328
328
|
AND e.event_type IN ('user_message', 'human')
|
|
329
329
|
AND e.content IS NOT NULL
|
|
330
330
|
AND e.content <> ''
|
|
331
331
|
ORDER BY e.session_id, e.timestamp DESC
|
|
332
|
-
`),d.execute(
|
|
332
|
+
`),d.execute(H`
|
|
333
333
|
SELECT DISTINCT ON (e.session_id)
|
|
334
334
|
e.session_id,
|
|
335
335
|
LEFT(REGEXP_REPLACE(COALESCE(e.content, ''), '[[:space:]]+', ' ', 'g'), 240) AS first_prompt
|
|
336
336
|
FROM session_events e
|
|
337
|
-
WHERE e.session_id IN (${
|
|
337
|
+
WHERE e.session_id IN (${H.join(w.map(G=>H`${G}`),H`, `)})
|
|
338
338
|
AND e.event_type IN ('user_message', 'human')
|
|
339
339
|
AND e.content IS NOT NULL
|
|
340
340
|
AND e.content <> ''
|
|
341
341
|
ORDER BY e.session_id, e.timestamp ASC
|
|
342
|
-
`),
|
|
342
|
+
`),b.length>0?d.select({id:D.id,name:D.name}).from(D).where(ia(D.id,b)):Promise.resolve([]),b.length>0?d.execute(H`
|
|
343
343
|
SELECT DISTINCT ON (project_id) project_id, path
|
|
344
344
|
FROM project_checkouts
|
|
345
|
-
WHERE project_id IN (${
|
|
345
|
+
WHERE project_id IN (${H.join(b.map(G=>H`${G}`),H`, `)})
|
|
346
346
|
ORDER BY project_id, is_worktree ASC, last_seen DESC
|
|
347
|
-
`):Promise.resolve([])]),
|
|
347
|
+
`):Promise.resolve([])]),j=new Map;for(let G of I){let ae=j.get(G.sessionId)??[];ae.push({name:G.name,contextIdentity:G.contextIdentity,type:G.type}),j.set(G.sessionId,ae)}let O=new Set;for(let G of S)G.sessionId&&O.add(G.sessionId);let F=new Map;for(let G of A)F.set(G.session_id,G.last_at);let U=new Map;for(let G of x)U.set(G.session_id,G.preview);let ee=new Map;for(let G of T)ee.set(G.session_id,G.first_prompt);let z=new Map,de=new Map;for(let G of P)z.set(G.id,G.name);for(let G of E)de.set(G.project_id,G.path);let ot=h.map(G=>({...G,linkedInstructions:j.get(G.id)??[],dataTier:O.has(G.id)?"full":(G.eventCount??0)>0?"events":"imported",lastMessagePreview:U.get(G.id)??G.analysis?.goalSummary??null,firstUserPrompt:ee.get(G.id)??null,projectName:G.projectId?z.get(G.projectId)??null:null,primaryCheckoutPath:G.projectId?de.get(G.projectId)??null:null,lastActivityAt:F.get(G.id)??G.startedAt}));return e.json(ot)}return e.json(h)});At.get("/sessions/project-paths",async e=>{let t=e.get("userId"),n=e.req.query("since"),r=Number(e.req.query("limit")??"20"),o=Math.min(Math.max(r,1),50),s=n?new Date(n):new Date(Date.now()-720*60*60*1e3);if(isNaN(s.getTime()))return e.json({error:"Invalid since timestamp"},400);let i=await d.execute(H`
|
|
348
348
|
WITH recent AS (
|
|
349
349
|
SELECT
|
|
350
350
|
s.project_id,
|
|
@@ -400,14 +400,14 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
400
400
|
) deduped
|
|
401
401
|
ORDER BY last_activity DESC
|
|
402
402
|
LIMIT ${o}
|
|
403
|
-
`),c=Array.from(i).map(a=>a.project_path).filter(a=>typeof a=="string"&&a!=="");return e.json({projectPaths:c})});
|
|
403
|
+
`),c=Array.from(i).map(a=>a.project_path).filter(a=>typeof a=="string"&&a!=="");return e.json({projectPaths:c})});At.get("/sessions/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(f).where(qe(L(f.id,n),L(f.userId,t)));if(!r)return e.json({error:"Session not found"},404);let o=await d.select({instructionId:ne.instructionId,linkMethod:ne.linkMethod,name:_.name,contextIdentity:_.contextIdentity,content:_.content,scope:_.scope,type:_.type,frontmatter:_.frontmatter}).from(ne).innerJoin(_,L(_.id,ne.instructionId)).where(qe(L(ne.sessionId,n),H`${_.content} IS NOT NULL AND ${_.content} != ''`)),s=await d.select({eventType:Le.eventType,count:H`count(*)::int`}).from(Le).where(L(Le.sessionId,n)).groupBy(Le.eventType),i={};for(let l of s)i[l.eventType]=Number(l.count);let c=null,a=null;if(r.projectId){let[l]=await d.select({name:D.name}).from(D).where(L(D.id,r.projectId));c=l?.name??null;let[p]=await d.select({path:ue.path}).from(ue).where(L(ue.projectId,r.projectId)).orderBy(Cp(ue.isWorktree),Io(ue.lastSeen)).limit(1);a=p?.path??null}return e.json({...r,linkedInstructions:o,projectName:c,primaryCheckoutPath:a,eventCounts:{total:Object.values(i).reduce((l,p)=>l+p,0),messages:(i.user_message??0)+(i.assistant_message??0),toolCalls:i.tool_call??0,assistantResponses:i.assistant_response??0,byType:i}})});At.get("/sessions/:id/events",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=Number(e.req.query("limit")??"100"),o=Number(e.req.query("offset")??"0"),s=e.req.query("sort")==="desc"?"desc":"asc",i=(e.req.query("eventType")??"").split(",").map(m=>m.trim()).filter(Boolean),c=e.req.query("hasContent")==="true",[a]=await d.select({id:f.id}).from(f).where(qe(L(f.id,n),L(f.userId,t)));if(!a)return e.json({error:"Session not found"},404);let l=[L(Le.sessionId,n)];i.length>0&&l.push(ia(Le.eventType,i)),c&&l.push(H`${Le.content} IS NOT NULL AND ${Le.content} != ''`);let p=await d.select().from(Le).where(qe(...l)).orderBy(s==="desc"?Io(Le.sequence):Cp(Le.sequence)).limit(r).offset(o);return e.json(p)});At.post("/sessions/:id/link",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),{instructionId:o}=te.object({instructionId:te.string().uuid()}).parse(r),[s]=await d.select({id:f.id}).from(f).where(qe(L(f.id,n),L(f.userId,t)));return s?(await d.insert(ne).values({sessionId:n,instructionId:o,linkMethod:"manual"}).onConflictDoNothing(),e.json({linked:!0})):e.json({error:"Session not found"},404)});At.post("/sessions/:id/analyze",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:f.id,tool:f.tool}).from(f).where(qe(L(f.id,n),L(f.userId,t)));if(!r)return e.json({error:"Session not found"},404);let{id:o}=await kt({taskName:"process_insights",payload:{config:{type:"analyze_session",sessionId:n}},userId:t,mirror:{userId:t,config:{type:"analyze_session",sessionId:n}}});return e.json({jobId:o,status:"pending",tool:r.tool},202)});At.get("/instructions/:id/insights",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await d.select({sessionId:ne.sessionId,analysis:f.analysis,tool:f.tool,startedAt:f.startedAt}).from(ne).innerJoin(f,L(f.id,ne.sessionId)).where(qe(L(ne.instructionId,n),L(f.userId,t))),o=r.filter(a=>a.analysis),s=o.map(a=>a.analysis),i=s.length>0?Math.round(s.reduce((a,l)=>a+(l.adherenceScore??0),0)/s.length):null,c=s.flatMap(a=>a.suggestions??[]).filter(a=>a.instructionId===n);return e.json({instructionId:n,totalSessions:r.length,analyzedSessions:o.length,averageAdherence:i,suggestions:c})});At.post("/sessions/repair-analyzed-at",async e=>{let t=e.get("userId"),n=await d.execute(H`
|
|
404
404
|
UPDATE sessions
|
|
405
405
|
SET analyzed_at = started_at
|
|
406
406
|
WHERE user_id = ${t}
|
|
407
407
|
AND analysis IS NOT NULL
|
|
408
408
|
AND analyzed_at IS NULL
|
|
409
409
|
RETURNING id
|
|
410
|
-
`);return e.json({repaired:n.length})});var
|
|
410
|
+
`);return e.json({repaired:n.length})});var ER=te.object({metadata:te.record(te.unknown()).optional(),analysis:te.record(te.unknown()).optional(),analyzedEventCount:te.number().int().nonnegative().optional(),analyzedTurnCount:te.number().int().nonnegative().optional(),tokenUsage:te.object({inputTokens:te.number().optional(),outputTokens:te.number().optional(),cacheReadTokens:te.number().optional(),cacheWriteTokens:te.number().optional()}).optional(),externalSessionId:te.string().uuid().optional()}).strict();At.patch("/sessions/:id/enrich",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=ER.parse(await e.req.json()),[o]=await d.select({id:f.id}).from(f).where(qe(L(f.id,n),L(f.userId,t)));if(!o)return e.json({error:"Session not found"},404);let s={};return r.metadata&&(s.metadata=H`COALESCE(${f.metadata}, '{}'::jsonb) || ${JSON.stringify(r.metadata)}::jsonb`),r.analysis&&(s.analysis=H`COALESCE(${f.analysis}, '{}'::jsonb) || ${JSON.stringify(r.analysis)}::jsonb`,s.analyzedAt=new Date),r.analyzedEventCount!=null&&(s.analyzedEventCount=r.analyzedEventCount),r.analyzedTurnCount!=null&&(s.analyzedTurnCount=r.analyzedTurnCount),r.tokenUsage&&(s.tokenUsage=r.tokenUsage),r.externalSessionId&&(s.externalSessionId=r.externalSessionId),Object.keys(s).length===0?e.json({error:"No enrichment data provided"},400):(await d.update(f).set(s).where(L(f.id,n)),e.json({enriched:!0,fields:Object.keys(s)}))});At.post("/sessions/:id/derive-enrichment",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:f.id,startedAt:f.startedAt,endedAt:f.endedAt,metadata:f.metadata}).from(f).where(qe(L(f.id,n),L(f.userId,t)));if(!r)return e.json({error:"Session not found"},404);let s=(await e.req.json().catch(()=>({}))).force===!0,c=r.metadata?.local_session_meta;if(c){if(!s)return e.json({skipped:!0,reason:"already_enriched"});if(!c.derived_from_events)return e.json({skipped:!0,reason:"hook_enriched"})}let[a]=await d.execute(H`
|
|
411
411
|
WITH usage_rows AS (
|
|
412
412
|
SELECT DISTINCT ON (coalesce(metadata->>'requestId', id::text))
|
|
413
413
|
coalesce(
|
|
@@ -442,15 +442,15 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
442
442
|
(SELECT max(timestamp) FROM session_events WHERE session_id = ${n}) AS last_ts,
|
|
443
443
|
(SELECT coalesce(sum(input_tokens), 0)::bigint FROM usage_rows) AS input_tokens,
|
|
444
444
|
(SELECT coalesce(sum(output_tokens), 0)::bigint FROM usage_rows) AS output_tokens
|
|
445
|
-
`);if(!a||Number(a.total_events)===0)return e.json({skipped:!0,reason:"no_events"});let l=Number(a.user_message_count),p=Number(a.assistant_message_count),m=Number(a.input_tokens),
|
|
445
|
+
`);if(!a||Number(a.total_events)===0)return e.json({skipped:!0,reason:"no_events"});let l=Number(a.user_message_count),p=Number(a.assistant_message_count),m=Number(a.input_tokens),y=Number(a.output_tokens),v=await d.execute(H`
|
|
446
446
|
SELECT coalesce(tool_name, 'unknown') AS tool, count(*)::int AS n
|
|
447
447
|
FROM session_events
|
|
448
448
|
WHERE session_id = ${n}
|
|
449
449
|
AND event_type IN ('tool_call', 'tool_use')
|
|
450
450
|
GROUP BY 1
|
|
451
|
-
`),g={};for(let
|
|
452
|
-
ELSE length(${
|
|
453
|
-
+ CASE WHEN right(${
|
|
451
|
+
`),g={};for(let O of v)g[O.tool]=Number(O.n);let h=u(O=>H.raw(`CASE WHEN ${O} IS NULL OR ${O} = '' THEN 0
|
|
452
|
+
ELSE length(${O}) - length(replace(${O}, chr(10), ''))
|
|
453
|
+
+ CASE WHEN right(${O}, 1) = chr(10) THEN 0 ELSE 1 END END`),"nl"),[w]=await d.execute(H`
|
|
454
454
|
WITH tool_events AS (
|
|
455
455
|
SELECT
|
|
456
456
|
tool_name,
|
|
@@ -498,7 +498,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
498
498
|
count(*) FILTER (
|
|
499
499
|
WHERE jsonb_typeof(tool_output) = 'object' AND tool_output ? 'error')::int AS tool_errors
|
|
500
500
|
FROM tool_events
|
|
501
|
-
`),
|
|
501
|
+
`),b={ts:"TypeScript",tsx:"TypeScript",js:"JavaScript",jsx:"JavaScript",py:"Python",sh:"Shell",bash:"Shell",sql:"SQL",md:"Markdown",json:"JSON",yml:"YAML",yaml:"YAML",css:"CSS",html:"HTML",go:"Go",rs:"Rust",rb:"Ruby",java:"Java",toml:"TOML"},I=await d.execute(H`
|
|
502
502
|
SELECT DISTINCT coalesce(tool_input->>'file_path', tool_input->>'notebook_path') AS path
|
|
503
503
|
FROM session_events
|
|
504
504
|
WHERE session_id = ${n}
|
|
@@ -506,7 +506,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
506
506
|
AND tool_name IN ('Edit','MultiEdit','Write','NotebookEdit')
|
|
507
507
|
AND jsonb_typeof(tool_input) = 'object'
|
|
508
508
|
AND coalesce(tool_input->>'file_path', tool_input->>'notebook_path') IS NOT NULL
|
|
509
|
-
`),S={};for(let
|
|
509
|
+
`),S={};for(let O of I){let F=O.path.split(".").pop()?.toLowerCase(),U=F?b[F]:void 0;U&&(S[U]=(S[U]??0)+1)}let A=a.first_ts,x=a.last_ts,P={duration_minutes:A&&x?Math.round((new Date(x).getTime()-new Date(A).getTime())/6e4):0,user_message_count:l,assistant_message_count:p,tool_counts:g,languages:S,git_commits:Number(w?.git_commits??0),git_pushes:Number(w?.git_pushes??0),user_interruptions:0,tool_errors:Number(w?.tool_errors??0),lines_added:Number(w?.lines_added??0),lines_removed:Number(w?.lines_removed??0),files_modified:Number(w?.files_modified??0),derived_from_events:!0},E=m>0||y>0?{input_tokens:m,output_tokens:y}:void 0,j={metadata:H`COALESCE(${f.metadata}, '{}'::jsonb) || ${JSON.stringify({local_session_meta:P})}::jsonb`};return E&&(j.tokenUsage=E),await d.update(f).set(j).where(L(f.id,n)),e.json({enriched:!0,metrics:P})});var jp=new Set(["claude_md","memory","skill_loaded"]);function TR(e,t){return Hl(e,t)??`${e}::${t}`}u(TR,"deriveContextIdentityForAutoCreate");function gw(e,t){return e==="claude_md"?`Auto-captured CLAUDE.md: ${t}`:e==="skill_loaded"?`Auto-captured skill: ${t}`:e==="memory"?`Auto-captured memory: ${t}`:`Auto-captured context: ${t}`}u(gw,"mapContextTypeToDescription");var RR=te.object({sessionId:te.string().uuid().optional(),backfill:te.boolean().optional()});async function kR(e,t,n,r){for(let s=0;s<=4;s++)try{await d.execute(H`
|
|
510
510
|
insert into instruction_version_identities
|
|
511
511
|
(instruction_id, content_hash, version_ordinal, content, first_seen_at, last_seen_at)
|
|
512
512
|
select
|
|
@@ -528,8 +528,8 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
528
528
|
first_seen_at = least(
|
|
529
529
|
instruction_version_identities.first_seen_at, excluded.first_seen_at),
|
|
530
530
|
content = coalesce(instruction_version_identities.content, excluded.content)
|
|
531
|
-
`);return}catch(i){if(i.cause?.code==="23505"&&s<4)continue;console.warn(`[link-instructions] version identity registration failed for ${e}:`,i instanceof Error?i.message:i);return}}u(
|
|
532
|
-
`):null;break}}}}if(
|
|
531
|
+
`);return}catch(i){if(i.cause?.code==="23505"&&s<4)continue;console.warn(`[link-instructions] version identity registration failed for ${e}:`,i instanceof Error?i.message:i);return}}u(kR,"registerVersionIdentity");async function jR(e,t){let n=await d.select({id:_.id,contentHash:_.contentHash,name:_.name,contextIdentity:_.contextIdentity,contentLen:H`COALESCE(LENGTH(${_.content}), 0)::int`}).from(_).where(L(_.createdBy,e)),r=new Map,o=new Map;for(let I of n){let S=Number(I.contentLen??0);I.contentHash&&r.set(I.contentHash,{id:I.id,name:I.name??"",contentLen:S}),I.contextIdentity&&o.set(I.contextIdentity,{id:I.id,name:I.name??"",contentHash:I.contentHash})}let s=await ft.selectDistinctOn([C.sessionId],{id:C.id,sessionId:C.sessionId,metadata:C.metadata}).from(C).where(t?qe(L(C.userId,e),L(C.sessionId,t)):L(C.userId,e)).orderBy(C.sessionId,Io(C.capturedAt)).limit(1e3),i=new Set,c=new Set,a=new Map,l=0,p=0,m=0,y=0,v=new Set,g=[],h=new Map;for(let I of s){if(!I.sessionId||i.has(I.sessionId))continue;i.add(I.sessionId);let A=I.metadata?.contextItems??[],x=null;async function T(){if(x)return x;let[E]=await ft.select({injectedInstructions:C.injectedInstructions,injectedHash:C.injectedHash}).from(C).where(L(C.id,I.id)).limit(1);return x=await yu(E?.injectedHash,E?.injectedInstructions??[]),x}u(T,"getInjected");async function P(){if(!I.sessionId)return[];let E=a.get(I.sessionId);if(E)return E;let j=I.sessionId,{messages:O}=await fu({fetchPage:u(async(U,ee)=>oa(await ft.select({sequence:C.sequence,messagesDelta:C.messagesDelta,messagesDeltaRef:C.messagesDeltaRef}).from(C).where(qe(L(C.sessionId,j),L(C.userId,e),H`${C.sequence} > ${U}`)).orderBy(Cp(C.sequence)).limit(ee)),"fetchPage")}),F=O;return a.set(I.sessionId,F),F}u(P,"getMessagesRaw");for(let E of A){let j=E.content_hash;if(!j)continue;c.add(j);let O=E.type??"",F=E.name??"";if(["user_input","core_system_prompt","available_tools","tool_definitions"].includes(F)||["system_reminder","system_prompt","hook_output","deferred_tools"].includes(O)||["date_change","current_date","task_reminder","git_status","unknown_reminder","available_skills"].includes(F)||O==="skill_catalog"||!jp.has(O)&&!O&&!F.includes(".md")&&!F.includes("rules"))continue;let U,ee=!1,z=null,de=r.get(j);if(de&&(U=de.id,jp.has(O)&&de.contentLen===0&&(ee=!0)),(!U||ee)&&jp.has(O)){let ae=TR(O,F),me=E.instruction_index,Te=null,Bt=me!=null?await T():[];if(me!=null&&Bt[me])Te=Bt[me];else if(O==="skill_loaded"&&E.message_index!=null){let le=await P(),Me=E.message_index,N=le[Me];if(N){let Q=N.content,st=(Array.isArray(Q)?Q.find(Fe=>Fe.type==="tool_use"&&(Fe.name==="Skill"||Fe.name==="execute_skill")):void 0)?.id;if(st)for(let Fe=Me+1;Fe<le.length&&Fe<Me+5;Fe++){let Lt=le[Fe];if(Lt?.role!=="user")continue;let Rn=Lt.content;if(!Array.isArray(Rn))continue;let Zr=!1,eo=[];for(let Sr of Rn)Sr.type==="tool_result"&&Sr.tool_use_id===st?Zr=!0:Sr.type==="text"&&Zr&&eo.push(Sr.text??"");if(Zr){Te=eo.length>0?eo.join(`
|
|
532
|
+
`):null;break}}}}if(z=Te,ee&&Te&&U)try{await d.update(_).set({content:Te,updatedAt:new Date}).where(L(_.id,U)),de.contentLen=Te.length,m++}catch(le){console.warn(`[link-instructions] Content backfill failed for instruction ${U}:`,le instanceof Error?le.message:le),y++}let Be=o.get(ae);if(Be&&Be.contentHash!==j){if(Te){let le=Te,Me=4,N=!1;for(let Q=0;Q<=Me;Q++)try{await d.transaction(async xe=>{await xe.select({id:_.id}).from(_).where(L(_.id,Be.id)).for("update");let[{maxVersion:st}]=await xe.select({maxVersion:H`COALESCE(MAX(${fe.versionNumber}), 0)`}).from(fe).where(L(fe.instructionId,Be.id)),Fe=st+1;await xe.insert(fe).values({instructionId:Be.id,versionNumber:Fe,content:le,frontmatter:{name:F,description:gw(O,F),type:"context_file",scope:"personal",version:`1.${Fe}.0`},changeSummary:"Auto-detected content change from context snapshot",createdBy:e}),await xe.update(_).set({content:le,contentHash:j,version:`1.${Fe}.0`,updatedAt:new Date}).where(L(_.id,Be.id))}),N=!0;break}catch(xe){if(xe.cause?.code==="23505"&&Q<Me)continue;console.warn(`[link-instructions] Version update failed for instruction ${Be.id} (identity: ${ae}):`,xe instanceof Error?xe.message:xe),y++;break}N&&(r.set(j,{id:Be.id,name:Be.name,contentLen:le.length}),Be.contentHash=j,m++)}U=Be.id}else if(!Be)try{let le=F,Me=gw(O,F),N=Te??"",Q={name:le,description:Me,type:"context_file",scope:"personal",version:"1.0.0"},xe;await d.transaction(async st=>{let[Fe]=await st.insert(_).values({name:le,description:Me,type:"context_file",scope:"personal",scopeRef:e,version:"1.0.0",content:N,frontmatter:Q,contentHash:j,contextIdentity:ae,createdBy:e}).onConflictDoNothing().returning({id:_.id});Fe&&(await st.insert(fe).values({instructionId:Fe.id,versionNumber:1,content:N,frontmatter:Q,changeSummary:"Auto-created from context snapshot",createdBy:e}),xe=Fe.id)}),xe&&(r.set(j,{id:xe,name:le,contentLen:N.length}),o.set(ae,{id:xe,name:le,contentHash:j}),U=xe,p++)}catch(le){console.warn(`[link-instructions] Auto-create failed for ${ae}:`,le instanceof Error?le.message:le),y++;try{let[Me]=await d.select({id:_.id}).from(_).where(qe(L(_.createdBy,e),L(_.contextIdentity,ae))).limit(1);Me&&(U=Me.id)}catch(Me){console.warn(`[link-instructions] Fallback identity lookup also failed for ${ae}:`,Me instanceof Error?Me.message:Me)}}}if(!U||!I.sessionId)continue;let ot=`${U}:${j}`,G=h.get(ot);G?!G.content&&z&&(G.content=z):h.set(ot,{instructionId:U,contentHash:j,content:z}),g.push({sessionId:I.sessionId,instructionId:U,linkMethod:"context_file",contentHash:j}),l++,v.add(I.sessionId)}}for(let I of h.values())await kR(I.instructionId,I.contentHash,I.content,new Date);for(let I=0;I<g.length;I+=500)try{await d.insert(ne).values(g.slice(I,I+500)).onConflictDoUpdate({target:[ne.sessionId,ne.instructionId],set:{contentHash:H`coalesce(${ne.contentHash}, excluded.content_hash)`}})}catch(S){console.warn("[link-instructions] batched link insert failed:",S instanceof Error?S.message:S)}let w=0;for(let I of s){if(!I.sessionId)continue;let[S]=await d.select({projectId:f.projectId,projectPath:f.projectPath}).from(f).where(L(f.id,I.sessionId)).limit(1);if(!S?.projectId||!S.projectPath)continue;let A=S.projectPath.replace(/\/$/,""),T=I.metadata?.contextItems??[];for(let P of T){let E=r.get(P.content_hash);if(!E)continue;let j=P.name??"";if(!(j.startsWith("/")&&!j.startsWith(A+"/")))try{await d.insert(at).values({projectId:S.projectId,instructionId:E.id,addedBy:e}).onConflictDoNothing(),w++}catch{}}break}let b=0;for(let[I,S]of r){if(!c.has(I)||!S.name.includes("CLAUDE")&&!S.name.includes("rules"))continue;let[A]=await d.select({id:k.id}).from(k).where(H`${k.metadata}->>'content_hash' = ${I}`).limit(1);if(A||S.contentLen===0)continue;let[x]=await d.select({content:_.content}).from(_).where(L(_.id,S.id)).limit(1),T=lw(x?.content,S.name);if(T&&!uw(T))try{let[P]=await d.insert(k).values({userId:e,name:S.name,type:"instruction",content:T,description:`Auto-generated from captured context: ${S.name}`,metadata:{content_hash:I,auto_generated:!0}}).returning({id:k.id}),E=/(?:^|\n)\s*[-*]?\s*((?:NEVER|ALWAYS|MUST|DO NOT|IMPORTANT)[^\n.]+[.\n])/gi,j=[...T.matchAll(E)].map(F=>F[1].trim()).slice(0,3),O=j.length>0?j.map(F=>({name:`rule-adherence: ${F.slice(0,60)}`,prompt:`Given the instruction "${S.name}", perform a task that would test whether this rule is followed: "${F}"`,expectations:[`The response should demonstrate adherence to: ${F}`]})):[{name:`general-adherence: ${S.name}`,prompt:`Perform a typical task guided by this instruction: "${S.name}"`,expectations:["The response should follow conventions described in the instruction"]}];for(let F of O)await d.insert(_e).values({evalTargetId:P.id,name:F.name,prompt:F.prompt,expectations:F.expectations}),b++}catch{}}return{linked:l,created:p,updated:m,failed:y,sessionsLinked:v.size,instructionsMatched:r.size,snapshotsScanned:i.size,projectsLinked:w,evalsGenerated:b,scope:t?"session":"backfill"}}u(jR,"runLinkInstructions");var NR=wu();At.post("/sessions/link-instructions",async e=>{let t=e.get("userId"),n=await e.req.json().catch(()=>({})),r=RR.safeParse(n??{});if(!r.success)return e.json({error:"Invalid body",details:r.error.flatten()},400);let{sessionId:o,backfill:s}=r.data;if(!o&&!s)return e.json({linked:0,created:0,updated:0,failed:0,sessionsLinked:0,instructionsMatched:0,snapshotsScanned:0,projectsLinked:0,evalsGenerated:0,skipped:"no_scope"});let i=await NR.run(`${t}:${o??"*backfill*"}`,()=>jR(t,o));return e.json(i)});At.delete("/sessions/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:f.id}).from(f).where(qe(L(f.id,n),L(f.userId,t))).limit(1);if(!r)return e.json({error:"Session not found"},404);let[[{eventCount:o}],[{snapshotCount:s}],i]=await Promise.all([d.select({eventCount:H`count(*)::int`}).from(Le).where(L(Le.sessionId,n)),d.select({snapshotCount:H`count(*)::int`}).from(C).where(L(C.sessionId,n)),d.selectDistinct({ref:C.messagesDeltaRef}).from(C).where(qe(L(C.sessionId,n),H`${C.messagesDeltaRef} IS NOT NULL`))]),c=i.map(m=>m.ref).filter(m=>!!m);await d.transaction(async m=>{await m.update(zt).set({sessionId:null}).where(L(zt.sessionId,n)),await m.execute(H`UPDATE scaffolding_fingerprints SET first_session_id = NULL WHERE first_session_id = ${n}`),await m.delete(f).where(L(f.id,n))});let a=0,l=0,p=0;if(c.length>0){let m=await d.selectDistinct({ref:C.messagesDeltaRef}).from(C).where(ia(C.messagesDeltaRef,c)),y=new Set(m.map(g=>g.ref)),v=c.filter(g=>!y.has(g));if(l=c.length-v.length,v.length>0)try{let{getSupabaseAdmin:g}=await Promise.resolve().then(()=>(na(),tw)),{SNAPSHOT_DELTA_BUCKET:h}=await Promise.resolve().then(()=>(_u(),sw)),{error:w}=await g().storage.from(h).remove(v);w?(p=v.length,console.warn(`[sessions:delete] blob GC failed for ${v.length} ref(s): ${w.message}`)):a=v.length}catch(g){p=v.length,console.warn(`[sessions:delete] blob GC unavailable: ${g.message}`)}}return e.json({deleted:!0,eventsDeleted:o,snapshotsDeleted:s,blobsDeleted:a,blobsRetained:l,blobsFailed:p})});import{Hono as CR}from"hono";import{eq as Pp}from"drizzle-orm";import{sql as ws}from"drizzle-orm";var aa=new CR;async function _w(e){let[t]=await d.select({activeOrgId:R.activeOrgId}).from(R).where(Pp(R.id,e));return t?.activeOrgId??null}u(_w,"getActiveOrgId");var yw="interval '30 minutes'";aa.get("/projects",async e=>{let t=e.get("userId"),n=Math.min(200,Math.max(1,Number(e.req.query("limit")??"50"))),r=Math.max(0,Number(e.req.query("offset")??"0")),o=await _w(t);if(!o)return e.json({projects:[],total:0});let s=await d.execute(ws`
|
|
533
533
|
WITH session_activity AS (
|
|
534
534
|
SELECT
|
|
535
535
|
s.id,
|
|
@@ -549,7 +549,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
549
549
|
project_id,
|
|
550
550
|
COUNT(*)::int AS session_count,
|
|
551
551
|
COUNT(*) FILTER (
|
|
552
|
-
WHERE ended_at IS NULL AND last_at >= now() - ${
|
|
552
|
+
WHERE ended_at IS NULL AND last_at >= now() - ${ws.raw(yw)}
|
|
553
553
|
)::int AS active_session_count,
|
|
554
554
|
MAX(last_at) AS last_activity_at
|
|
555
555
|
FROM session_activity
|
|
@@ -575,18 +575,18 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
575
575
|
JOIN projects p ON p.id = pa.project_id
|
|
576
576
|
ORDER BY pa.last_activity_at DESC NULLS LAST, p.created_at DESC
|
|
577
577
|
LIMIT ${n} OFFSET ${r}
|
|
578
|
-
`),[{count:i}={count:0}]=await d.execute(
|
|
578
|
+
`),[{count:i}={count:0}]=await d.execute(ws`
|
|
579
579
|
SELECT COUNT(DISTINCT s.project_id)::int AS count
|
|
580
580
|
FROM sessions s
|
|
581
581
|
WHERE s.org_id = ${o}
|
|
582
582
|
AND s.origin <> 'internal_worker'
|
|
583
583
|
AND s.project_id IS NOT NULL
|
|
584
|
-
`);return e.json({projects:s.map(c=>({id:c.id,name:c.name,description:c.description,gitRemoteUrl:c.git_remote_url,githubRepo:c.github_repo,createdAt:c.created_at,sessionCount:c.session_count,activeSessionCount:c.active_session_count,lastActivityAt:c.last_activity_at,primaryCheckoutPath:c.primary_checkout_path})),total:i})});aa.get("/projects/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await
|
|
584
|
+
`);return e.json({projects:s.map(c=>({id:c.id,name:c.name,description:c.description,gitRemoteUrl:c.git_remote_url,githubRepo:c.github_repo,createdAt:c.created_at,sessionCount:c.session_count,activeSessionCount:c.active_session_count,lastActivityAt:c.last_activity_at,primaryCheckoutPath:c.primary_checkout_path})),total:i})});aa.get("/projects/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await _w(t);if(!r)return e.json({error:"No active org"},404);let[o]=await d.select().from(D).where(Pp(D.id,n));if(!o)return e.json({error:"Project not found"},404);let[{has_session:s}={has_session:!1}]=await d.execute(ws`
|
|
585
585
|
SELECT EXISTS(
|
|
586
586
|
SELECT 1 FROM sessions
|
|
587
587
|
WHERE project_id = ${n} AND org_id = ${r} AND origin <> 'internal_worker'
|
|
588
588
|
) AS has_session
|
|
589
|
-
`);if(o.orgId!==r&&!s)return e.json({error:"Project not found"},404);let[i]=await d.execute(
|
|
589
|
+
`);if(o.orgId!==r&&!s)return e.json({error:"Project not found"},404);let[i]=await d.execute(ws`
|
|
590
590
|
WITH session_activity AS (
|
|
591
591
|
SELECT
|
|
592
592
|
s.id,
|
|
@@ -601,11 +601,11 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
601
601
|
SELECT
|
|
602
602
|
COUNT(*)::int AS session_count,
|
|
603
603
|
COUNT(*) FILTER (
|
|
604
|
-
WHERE ended_at IS NULL AND last_at >= now() - ${
|
|
604
|
+
WHERE ended_at IS NULL AND last_at >= now() - ${ws.raw(yw)}
|
|
605
605
|
)::int AS active_session_count,
|
|
606
606
|
MAX(last_at) AS last_activity_at
|
|
607
607
|
FROM session_activity
|
|
608
|
-
`),c=await d.select({path:
|
|
608
|
+
`),c=await d.select({path:ue.path,isWorktree:ue.isWorktree,firstSeen:ue.firstSeen,lastSeen:ue.lastSeen}).from(ue).where(Pp(ue.projectId,n));return c.sort((a,l)=>{let p=a.lastSeen?.getTime()??0;return(l.lastSeen?.getTime()??0)-p}),e.json({id:o.id,name:o.name,description:o.description,gitRemoteUrl:o.gitRemoteUrl,githubRepo:o.githubRepo,createdAt:o.createdAt,sessionCount:i?.session_count??0,activeSessionCount:i?.active_session_count??0,lastActivityAt:i?.last_activity_at??null,primaryCheckoutPath:c[0]?.path??null,checkouts:c})});import{Hono as PR}from"hono";import{z as In}from"zod";import{eq as rt,and as $r,sql as ww,desc as OR,inArray as DR}from"drizzle-orm";var Jn=new PR,MR=In.object({name:In.string().min(1).max(255),description:In.string().min(1),scope:In.enum(["org","team","personal"]),scopeRef:In.string().uuid().optional(),version:In.string().default("1.0.0"),tags:In.array(In.string()).optional()});Jn.get("/packs",async e=>{let t=e.get("userId"),n=e.req.query("scope"),r=parseInt(e.req.query("limit")??"100",10),o=[rt(Re.archived,!1),rt(Re.createdBy,t)];n&&o.push(rt(Re.scope,n));let s=await d.select().from(Re).where($r(...o)).orderBy(OR(Re.updatedAt)).limit(r),i=s.map(a=>a.id),c={};if(i.length>0){let a=await d.select({packId:Ee.packId,count:ww`COUNT(*)::int`}).from(Ee).where(DR(Ee.packId,i)).groupBy(Ee.packId);for(let l of a)c[l.packId]=l.count}return e.json(s.map(a=>{let l=c[a.id]??0;return{...a,instructionCount:l,tier:Fi(l)}}))});Jn.get("/packs/:id",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.select().from(Re).where($r(rt(Re.id,t),rt(Re.createdBy,n),rt(Re.archived,!1)));if(!r)return e.json({error:"Pack not found"},404);let o=await d.select({instruction:_,position:Ee.position,slotOverrides:Ee.slotOverrides,addedAt:Ee.addedAt}).from(Ee).innerJoin(_,rt(Ee.instructionId,_.id)).where(rt(Ee.packId,t)).orderBy(Ee.position),s=o.length;return e.json({...r,instructionCount:s,tier:Fi(s),instructions:o.map(i=>({...i.instruction,position:i.position,slotOverrides:i.slotOverrides,addedAt:i.addedAt}))})});Jn.post("/packs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=MR.parse(n),o=r.scope==="personal"?t:r.scopeRef??null,[s]=await d.insert(Re).values({name:r.name,description:r.description,scope:r.scope,scopeRef:o,version:r.version,tags:r.tags??[],createdBy:t}).returning();return e.json({...s,instructionCount:0,tier:Fi(0)},201)});Jn.post("/packs/:id/instructions",async e=>{let t=e.req.param("id"),n=e.get("userId"),r=await e.req.json(),{instructionId:o}=In.object({instructionId:In.string().uuid()}).parse(r),[s]=await d.select().from(Re).where($r(rt(Re.id,t),rt(Re.createdBy,n),rt(Re.archived,!1)));if(!s)return e.json({error:"Pack not found"},404);let[i]=await d.select().from(Ee).where($r(rt(Ee.packId,t),rt(Ee.instructionId,o)));if(i)return e.json({error:"Instruction already in this pack"},409);let[c]=await d.select({max:ww`COALESCE(MAX(${Ee.position}), -1)`}).from(Ee).where(rt(Ee.packId,t)),[a]=await d.insert(Ee).values({packId:t,instructionId:o,position:(c?.max??-1)+1,addedBy:n}).returning();return e.json(a,201)});Jn.delete("/packs/:id/instructions/:instructionId",async e=>{let t=e.req.param("id"),n=e.get("userId"),r=e.req.param("instructionId"),[o]=await d.select({id:Re.id}).from(Re).where($r(rt(Re.id,t),rt(Re.createdBy,n),rt(Re.archived,!1)));return o?(await d.delete(Ee).where($r(rt(Ee.packId,t),rt(Ee.instructionId,r))).returning()).length===0?e.json({error:"Instruction not in this pack"},404):e.json({success:!0}):e.json({error:"Pack not found"},404)});Jn.post("/packs/:id/apply",async e=>{let t=e.req.param("id"),n=e.get("userId"),r=await e.req.json(),{projectId:o}=In.object({projectId:In.string().uuid()}).parse(r),s=await d.select({instructionId:Ee.instructionId}).from(Ee).where(rt(Ee.packId,t));if(s.length===0)return e.json({error:"Pack has no instructions"},400);let i=0;for(let c of s){let[a]=await d.select().from(at).where($r(rt(at.projectId,o),rt(at.instructionId,c.instructionId)));a||(await d.insert(at).values({projectId:o,instructionId:c.instructionId,addedBy:n}),i++)}return e.json({success:!0,linked:i,total:s.length})});Jn.post("/packs/:id/fork",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(Re).where($r(rt(Re.id,n),rt(Re.archived,!1)));if(!r)return e.json({error:"Pack not found"},404);if(r.createdBy===t)return e.json({error:"Cannot fork your own pack"},400);let[o]=await d.insert(Re).values({name:`${r.name} (fork)`,description:r.description,scope:"personal",scopeRef:t,version:"1.0.0",tags:r.tags,createdBy:t,forkedFromId:r.id,upstreamVersion:r.version}).returning(),s=await d.select().from(Ee).where(rt(Ee.packId,n));return s.length>0&&await d.insert(Ee).values(s.map(i=>({packId:o.id,instructionId:i.instructionId,position:i.position,slotOverrides:i.slotOverrides,addedBy:t}))),e.json(o,201)});import{Hono as LR}from"hono";import{eq as Op,and as $R,sql as vw}from"drizzle-orm";var Su=new LR;function Iw(e){return{id:e.id,name:e.name,forkedFromId:e.forked_from_id,version:e.version,scope:e.scope,createdBy:e.created_by,createdAt:e.created_at,depth:e.depth}}u(Iw,"mapRow");Su.get("/instructions/:id/lineage",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:_.id,name:_.name,forkedFromId:_.forkedFromId,version:_.version,scope:_.scope,createdBy:_.createdBy,createdAt:_.createdAt}).from(_).where($R(Op(_.id,n),Op(_.archived,!1),Op(_.createdBy,t)));if(!r)return e.json({error:"Instruction not found"},404);let o=r.forkedFromId?await d.execute(vw`
|
|
609
609
|
WITH RECURSIVE ancestors AS (
|
|
610
610
|
SELECT id, name, forked_from_id, version, scope, created_by, created_at::text, 1 as depth
|
|
611
611
|
FROM instructions
|
|
@@ -618,7 +618,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
618
618
|
WHERE i.archived = false AND a.depth < 20
|
|
619
619
|
)
|
|
620
620
|
SELECT * FROM ancestors ORDER BY depth DESC
|
|
621
|
-
`):[],s=await d.execute(
|
|
621
|
+
`):[],s=await d.execute(vw`
|
|
622
622
|
WITH RECURSIVE descendants AS (
|
|
623
623
|
SELECT id, name, forked_from_id, version, scope, created_by, created_at::text, 1 as depth
|
|
624
624
|
FROM instructions
|
|
@@ -631,34 +631,34 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
631
631
|
WHERE i.archived = false AND d.depth < 20
|
|
632
632
|
)
|
|
633
633
|
SELECT * FROM descendants ORDER BY depth ASC
|
|
634
|
-
`),i=Array.isArray(o)?o.map(
|
|
634
|
+
`),i=Array.isArray(o)?o.map(Iw):[],c=s.map(Iw);return e.json({current:{id:r.id,name:r.name,forkedFromId:r.forkedFromId,version:r.version,scope:r.scope,createdBy:r.createdBy,createdAt:r.createdAt},ancestors:i,descendants:c})});import{Hono as UR}from"hono";import{z as bo}from"zod";import{eq as qr,and as ca,desc as Mp,gt as Lp,lt as BR,sql as Xt}from"drizzle-orm";function bw(e,t){let n=u(a=>e.capabilities===null||e.capabilities.includes(a),"claims"),r=t.filter(a=>n(a.kind)),o=t.filter(a=>!n(a.kind)),s=[],i,c;return e.present?e.active?e.busy?(i="ok",c=r.length>0?`Worker is running a job \u2014 ${Au(r)} more queued behind it.`:"Worker is online and running a job."):r.some(a=>a.oldestMinutes>=10)?(i="warn",c=`Worker is online but its queue is not draining \u2014 ${Au(r)} job(s) pending (${Dp(r)}).`,s.push("A handler may be wedged. Restart: `rulemetric worker:restart` (or reinstall the service).")):(i="ok",c="Worker is online and its queue is draining."):(i="fail",c=`Worker is not running \u2014 last heartbeat ${qR(e.ageSeconds)} ago.`,s.push("Restart it: `rulemetric service install --worker-only`"),s.push("If it keeps dying, `launchctl list | grep rulemetric` shows the exit status."),r.length>0&&s.push(`${Au(r)} job(s) are waiting on it (${Dp(r)}) \u2014 they will drain once it is back.`)):(i="fail",c="No worker has ever connected \u2014 nothing is analyzing your sessions.",s.push("Start one: `rulemetric service install --worker-only`"),s.push("Session capture works without it (hooks post directly), but analysis, insights, and Codex transcript import all require the worker.")),o.length>0&&(i==="ok"&&(i="warn"),s.push(`${Au(o)} job(s) cannot be claimed by this worker (${Dp(o)}). These handlers need direct database credentials, which a worker-only install does not have \u2014 they will stay pending until a worker with DATABASE_URL runs.`)),{severity:i,headline:c,hints:s,stuck:r,unclaimable:o}}u(bw,"assessWorkerHealth");function Au(e){return e.reduce((t,n)=>t+n.count,0)}u(Au,"totalOf");function Dp(e){return e.map(t=>`${t.kind}\xD7${t.count}`).join(", ")}u(Dp,"describe");function qR(e){if(e===null)return"never";if(e<90)return`${Math.round(e)}s`;let t=Math.round(e/60);return t<90?`${t}m`:`${Math.round(t/60)}h`}u(qR,"formatAge");var vs=new UR,$p=6e4,Sw=600*1e3,qp=3600*1e3,FR=10080*60*1e3,HR={"cli-worker":["process_eval","process_insights","process_launch","process_send_message","process_conversation","process_session_goal","distill_memories","memory_ab","process_announcement","process_run_cleanup","cron_suggest_instructions","cron_refresh_skills","cron_refresh_pricing","cron_eval_autorun","cron_instruction_evolution","process_judge_review"]},WR=new Set(["memory_ab","process_announcement","process_run_cleanup"]),zR=bo.object({workerType:bo.enum(["mcp","cli-worker","gateway","proxy"]),clientName:bo.string().min(1),clientVersion:bo.string().optional(),workerVersion:bo.string().optional(),metadata:bo.record(bo.unknown()).optional()}),Up=[{table:"session_send_jobs",defaultKind:"process_send_message"},{table:"launch_jobs",defaultKind:"process_launch"},{table:"eval_jobs",defaultKind:"process_eval"},{table:"insights_jobs",defaultKind:"process_insights"},{table:"agent_jobs",defaultKind:"agent_job"}];async function VR(e,t=0){let n=new Date(Date.now()-t).toISOString(),r=Up.map(({table:i,defaultKind:c})=>Xt`
|
|
635
635
|
SELECT coalesce(task_kind, ${c}) AS kind,
|
|
636
636
|
count(*)::int AS n,
|
|
637
637
|
min(created_at) AS oldest
|
|
638
|
-
FROM ${
|
|
638
|
+
FROM ${Xt.raw(i)}
|
|
639
639
|
WHERE user_id = ${e}
|
|
640
640
|
AND status = 'pending'
|
|
641
641
|
AND created_at < ${n}::timestamptz
|
|
642
642
|
GROUP BY 1
|
|
643
|
-
`),o=await d.execute(
|
|
643
|
+
`),o=await d.execute(Xt`${Xt.join(r,Xt` UNION ALL `)} ORDER BY oldest ASC`),s=Date.now();return o.map(i=>({kind:i.kind,count:Number(i.n),oldestMinutes:Math.round((s-new Date(i.oldest).getTime())/6e4)}))}u(VR,"queryPendingKinds");async function Aw(e){return(await d.execute(Xt`${Xt.join(Up.map(({table:n})=>Xt`
|
|
644
644
|
SELECT count(*)::int AS n
|
|
645
|
-
FROM ${
|
|
645
|
+
FROM ${Xt.raw(n)}
|
|
646
646
|
WHERE user_id = ${e}
|
|
647
647
|
AND status IN ('claimed', 'running')
|
|
648
648
|
AND lease_expires_at IS NOT NULL
|
|
649
649
|
AND lease_expires_at > now()
|
|
650
|
-
`),
|
|
650
|
+
`),Xt` UNION ALL `)}`)).reduce((n,r)=>n+Number(r.n),0)>0}u(Aw,"hasLiveInFlightJob");async function JR(e,t){let n=new Date(Date.now()-Sw).toISOString(),r=Up.map(({table:p,defaultKind:m})=>Xt`
|
|
651
651
|
SELECT coalesce(task_kind, ${m}) AS kind,
|
|
652
652
|
count(*)::int AS n,
|
|
653
653
|
min(created_at) AS oldest
|
|
654
|
-
FROM ${
|
|
654
|
+
FROM ${Xt.raw(p)}
|
|
655
655
|
WHERE user_id = ${e}
|
|
656
656
|
AND status = 'pending'
|
|
657
657
|
AND created_at < ${n}::timestamptz
|
|
658
658
|
GROUP BY 1
|
|
659
|
-
`),o=await d.execute(Yt`${Yt.join(r,Yt` UNION ALL `)} ORDER BY oldest ASC`),s=t===null?o:o.filter(p=>t.includes(p.kind));if(s.length===0||await Iw(e))return null;let i=s.reduce((p,m)=>p+Number(m.n),0),c=Date.now()-new Date(s[0].oldest).getTime(),a=Math.round(c/6e4),l=s.map(p=>`${p.kind}\xD7${p.n}`).join(", ");return{code:"STALE_PENDING",message:`${i} job(s) pending >${Math.round(vw/6e4)}m (oldest ${a}m: ${l}). The worker is heartbeating but its queue isn't draining \u2014 check for a wedged handler or restart it.`,meta:{total:i,oldestMinutes:a,byKind:s.map(p=>({kind:p.kind,count:Number(p.n)}))}}}u(zR,"checkStalePendingAdvisory");function bw(e){return!e||!Array.isArray(e.capabilities)?null:e.capabilities.filter(t=>typeof t=="string")}u(bw,"reportedCapabilities");function VR(e,t){let n=BR[e];if(!n||n.length===0)return null;let r=t&&Array.isArray(t.capabilities)?t.capabilities.filter(s=>typeof s=="string"):null;if(r===null)return{code:"NO_CAPABILITIES_REPORTED",message:`Worker did not report any capabilities. Expected ${n.join(", ")} \u2014 likely an outdated worker process. Restart it.`};let o=n.filter(s=>!r.includes(s)&&!FR.has(s));return o.length>0?{code:"MISSING_CAPABILITIES",message:`Worker is missing capabilities: ${o.join(", ")}. Jobs of those kinds will sit pending. Restart the worker after deploying API updates.`}:null}u(VR,"checkWorkerAdvisory");_s.post("/workers/heartbeat",async e=>{let t=e.get("userId"),n=await e.req.json(),r=HR.parse(n);await d.insert(we).values({userId:t,workerType:r.workerType,clientName:r.clientName,clientVersion:r.clientVersion??null,workerVersion:r.workerVersion??null,metadata:r.metadata??null}).onConflictDoUpdate({target:[we.userId,we.workerType,we.clientName],set:{lastHeartbeat:new Date,clientVersion:r.clientVersion??null,workerVersion:r.workerVersion??null,metadata:r.metadata??null}}),d.delete(we).where(ca($r(we.userId,t),qR(we.lastHeartbeat,new Date(Date.now()-UR)))).catch(()=>{});let o=VR(r.workerType,r.metadata);return!o&&r.workerType==="cli-worker"&&(o=await zR(t,bw(r.metadata))),o&&console.warn(`[workers/heartbeat] ${r.workerType} ${r.clientName} (version=${r.workerVersion??"unknown"}): ${o.code} \u2014 ${o.message}`),e.json({status:"ok",...o?{advisory:o}:{}})});async function Sw(e){let t=new Date(Date.now()-$p),n=await d.select({lastHeartbeat:we.lastHeartbeat}).from(we).where(ca($r(we.userId,e),$r(we.workerType,"cli-worker"),Mp(we.lastHeartbeat,t))),r=Date.now();return{cliEverConnected:n.length>0,workerActive:n.some(o=>r-new Date(o.lastHeartbeat).getTime()<Lp)}}u(Sw,"computeCliWorkerSetupSignals");async function Su(e){let t=await d.select({lastHeartbeat:we.lastHeartbeat,metadata:we.metadata}).from(we).where(ca($r(we.userId,e),$r(we.workerType,"cli-worker"))).orderBy(Dp(we.lastHeartbeat)).limit(10);for(let n of t){let r=n.metadata?.llmEngines;if(r&&typeof r=="object"){let o=r;return{claude:o.claude===!0,codex:o.codex===!0,codexModel:typeof o.codexModel=="string"?o.codexModel:null,observedAt:new Date(n.lastHeartbeat).toISOString()}}}return null}u(Su,"getLatestLlmEngines");_s.get("/workers/status",async e=>{let t=e.get("userId"),n=new Date(Date.now()-$p),r=await d.select().from(we).where(ca($r(we.userId,t),Mp(we.lastHeartbeat,n))).orderBy(Dp(we.lastHeartbeat)),o=Date.now(),s=r.map(i=>{let c=o-new Date(i.lastHeartbeat).getTime();return{id:i.id,workerType:i.workerType,clientName:i.clientName,clientVersion:i.clientVersion,workerVersion:i.workerVersion,lastHeartbeat:i.lastHeartbeat,connectedAt:i.connectedAt,status:c<Lp?"active":"inactive"}});return e.json(s)});_s.get("/workers/health",async e=>{let t=e.get("userId"),n=new Date(Date.now()-$p),[r,o,s]=await Promise.all([d.select({lastHeartbeat:we.lastHeartbeat,clientName:we.clientName,clientVersion:we.clientVersion,metadata:we.metadata}).from(we).where(ca($r(we.userId,t),$r(we.workerType,"cli-worker"),Mp(we.lastHeartbeat,n))).orderBy(Dp(we.lastHeartbeat)).limit(1),WR(t),Iw(t)]),i=r[0],c=i?Date.now()-new Date(i.lastHeartbeat).getTime():null,a={present:i!=null,active:c!=null&&c<Lp,ageSeconds:c==null?null:Math.round(c/1e3),capabilities:i?bw(i.metadata??void 0):null,busy:s},l=ww(a,o);return e.json({worker:{present:a.present,active:a.active,ageSeconds:a.ageSeconds,clientName:i?.clientName??null,clientVersion:i?.clientVersion??null,lastHeartbeat:i?.lastHeartbeat??null,capabilities:a.capabilities},pending:o,verdict:l})});import{Hono as JR}from"hono";import{and as GR,eq as KR,sql as YR}from"drizzle-orm";var Au=new JR;Au.get("/setup/status",async e=>{let t=e.get("userId"),[n,r,o]=await Promise.all([Sw(t),d.select({id:f.id}).from(f).where(GR(KR(f.userId,t),YR`${f.origin} <> 'internal_worker'`)).limit(1),Su(t)]);return e.json({cliEverConnected:n.cliEverConnected,anyCapturedSession:r.length>0,workerActive:n.workerActive,llmEngines:o})});import{Hono as XR}from"hono";import{z as ln}from"zod";import{eq as Io,and as Up,desc as QR,sql as ZR}from"drizzle-orm";var bo=new XR,ek=ln.object({name:ln.string().min(1).max(255),type:ln.enum(["instruction","skill","prompt","plan"]),content:ln.string().min(1),description:ln.string().default(""),metadata:ln.record(ln.unknown()).default({})}),tk=ln.object({name:ln.string().min(1).max(255).optional(),content:ln.string().min(1).optional(),description:ln.string().optional(),metadata:ln.record(ln.unknown()).optional()});bo.post("/eval-targets",async e=>{let t=e.get("userId"),n=await e.req.json(),r=ek.parse(n),[o]=await d.insert(R).values({userId:t,name:r.name,type:r.type,content:r.content,description:r.description,metadata:r.metadata}).returning();return e.json(o,201)});bo.get("/eval-targets",async e=>{let t=e.get("userId"),n=e.req.query("type"),r=e.req.query("content_hash"),o=[Io(R.userId,t)];n&&o.push(Io(R.type,n)),r&&o.push(ZR`${R.metadata}->>'content_hash' = ${r}`);let s=e.req.query("limit"),i=e.req.query("offset"),c=s?parseInt(s,10):NaN,a=Number.isFinite(c)?Math.min(Math.max(1,c),200):100,l=i?parseInt(i,10):NaN,p=Number.isFinite(l)?Math.max(0,l):0,m=await d.select({id:R.id,userId:R.userId,name:R.name,type:R.type,description:R.description,metadata:R.metadata,version:R.version,parentId:R.parentId,createdAt:R.createdAt,updatedAt:R.updatedAt}).from(R).where(Up(...o)).orderBy(QR(R.updatedAt)).limit(a).offset(p);return e.json(m)});bo.get("/eval-targets/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(R).where(Up(Io(R.id,n),Io(R.userId,t)));return r?e.json(r):e.json({error:"Eval target not found"},404)});bo.put("/eval-targets/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=tk.parse(r),[s]=await d.select().from(R).where(Up(Io(R.id,n),Io(R.userId,t)));if(!s)return e.json({error:"Eval target not found"},404);if(o.content&&o.content!==s.content){let[c]=await d.insert(R).values({userId:t,name:o.name??s.name,type:s.type,content:o.content,description:o.description??s.description,metadata:o.metadata??s.metadata,version:s.version+1,parentId:s.id}).returning();return e.json(c)}let[i]=await d.update(R).set({name:o.name??s.name,description:o.description??s.description,metadata:o.metadata??s.metadata,updatedAt:new Date}).where(Io(R.id,n)).returning();return e.json(i)});import{Hono as rk}from"hono";import{z as Ot}from"zod";import{eq as xu,and as xw,isNull as ok,desc as sk}from"drizzle-orm";import{and as nk,eq as Aw}from"drizzle-orm";async function Oe(e,t){let[n]=await d.select({id:R.id}).from(R).where(nk(Aw(R.id,e),Aw(R.userId,t)));return n}u(Oe,"verifyTargetOwnership");var ys=new rk,ik=Ot.object({name:Ot.string().min(1).max(255),prompt:Ot.string().min(1),expectedOutput:Ot.string().default(""),files:Ot.array(Ot.unknown()).default([]),expectations:Ot.array(Ot.string()).default([])});ys.post("/eval-targets/:id/evals",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=ik.parse(r);if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let[i]=await d.insert(he).values({evalTargetId:n,name:o.name,prompt:o.prompt,expectedOutput:o.expectedOutput,files:o.files,expectations:o.expectations}).returning();return e.json(i,201)});ys.get("/eval-targets/:id/evals",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.query("includeRetired")==="1";if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let s=await d.select().from(he).where(r?xu(he.evalTargetId,n):xw(xu(he.evalTargetId,n),ok(he.retiredAt))).orderBy(sk(he.createdAt));return e.json(s)});var ak=Ot.object({retire:Ot.boolean().optional(),retiredReason:Ot.string().max(500).optional(),name:Ot.string().min(1).max(255).optional(),prompt:Ot.string().min(1).optional(),expectedOutput:Ot.string().optional(),files:Ot.array(Ot.unknown()).optional(),expectations:Ot.array(Ot.string()).optional()}).refine(e=>e.retire!==void 0||e.name!==void 0||e.prompt!==void 0||e.expectedOutput!==void 0||e.files!==void 0||e.expectations!==void 0,{message:"nothing to update"});ys.patch("/eval-targets/:id/evals/:evalId",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.param("evalId"),o=ak.parse(await e.req.json());if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let i={updatedAt:new Date};o.retire!==void 0&&(i.retiredAt=o.retire?new Date:null,i.retiredReason=o.retire?o.retiredReason??null:null),o.name!==void 0&&(i.name=o.name),o.prompt!==void 0&&(i.prompt=o.prompt),o.expectedOutput!==void 0&&(i.expectedOutput=o.expectedOutput),o.files!==void 0&&(i.files=o.files),o.expectations!==void 0&&(i.expectations=o.expectations),(o.prompt!==void 0||o.expectations!==void 0||o.files!==void 0||o.expectedOutput!==void 0)&&(i.contentUpdatedAt=new Date);let[c]=await d.update(he).set(i).where(xw(xu(he.id,r),xu(he.evalTargetId,n))).returning();return c?e.json(c):e.json({error:"Eval case not found"},404)});import{Hono as Ik}from"hono";import{z as Se}from"zod";import{createHash as bk}from"node:crypto";import{and as Lw,eq as Br,gte as Sk,desc as Ak,sql as $w}from"drizzle-orm";function Bp(e,t){let n=e,r=t,o=n+r;if(o===0)return{pValue:1,nDiscordant:0};let s=Math.min(n,r),i=Math.pow(.5,o),c=i;for(let a=1;a<=s;a++)i*=(o-a+1)/a,c+=i;return{pValue:Math.min(1,2*c),nDiscordant:o}}u(Bp,"mcnemarExact");function Fp(e,t,n=10){return{sufficient:e>=n&&t>=n,minN:n,nWith:e,nWithout:t,shortfall:{with:Math.max(0,n-e),without:Math.max(0,n-t)}}}u(Fp,"assessSufficiency");var qr=1.959963984540054;function Eu(e,t,n=qr){if(t===0)return{lower:0,upper:1};let r=e/t,o=n*n,s=1+o/t,i=(r+o/(2*t))/s,c=n/s*Math.sqrt(r*(1-r)/t+o/(4*t*t));return{lower:Math.max(0,i-c),upper:Math.min(1,i+c)}}u(Eu,"wilsonInterval");function ua(e){let t=e>>>0;return()=>{t=t+1831565813|0;let n=Math.imul(t^t>>>15,1|t);return n=n+Math.imul(n^n>>>7,61|n)^n,((n^n>>>14)>>>0)/4294967296}}u(ua,"seededRandom");function Tu(e,t){let n=e.length;if(n===1)return e[0];let r=(n-1)*t,o=Math.floor(r),s=Math.ceil(r);return o===s?e[o]:e[o]+(r-o)*(e[s]-e[o])}u(Tu,"sortedQuantile");function Hp(e,t={}){let n=e.length;if(n===0)return{estimate:0,lower:0,upper:0,iterations:0};let r=t.iterations??1e4,o=t.ciLevel??.95,s=ua(t.seed??1),i=e.reduce((l,p)=>l+p,0)/n,c=new Array(r);for(let l=0;l<r;l++){let p=0;for(let m=0;m<n;m++)p+=e[s()*n|0];c[l]=p/n}c.sort((l,p)=>l-p);let a=(1-o)/2;return{estimate:i,lower:Tu(c,a),upper:Tu(c,1-a),iterations:r}}u(Hp,"pairedBootstrapCI");function Wp(e,t={}){let n=e.filter(h=>h.withScores.length>0&&h.withoutScores.length>0);if(n.length===0)return{estimate:0,lower:0,upper:0,pValue:1,iterations:0};let r=u(h=>h.reduce((w,I)=>w+I,0)/h.length,"mean"),o=n.map(h=>h.withScores.length*h.withoutScores.length/(h.withScores.length+h.withoutScores.length)),s=o.reduce((h,w)=>h+w,0),i=u(h=>h.reduce((w,I,b)=>w+o[b]*I,0)/s,"combine"),c=i(n.map(h=>r(h.withScores)-r(h.withoutScores))),a=t.iterations??1e4,l=t.ciLevel??.95,p=ua(t.seed??1),m=new Array(a),_=0,v=0;for(let h=0;h<a;h++){let w=n.map(b=>{let S=0;for(let x=0;x<b.withScores.length;x++)S+=b.withScores[p()*b.withScores.length|0];let A=0;for(let x=0;x<b.withoutScores.length;x++)A+=b.withoutScores[p()*b.withoutScores.length|0];return S/b.withScores.length-A/b.withoutScores.length}),I=i(w);m[h]=I,I<=0&&_++,I>=0&&v++}m.sort((h,w)=>h-w);let g=(1-l)/2;return{estimate:c,lower:Tu(m,g),upper:Tu(m,1-g),pValue:Math.min(1,2*Math.min(_,v)/a),iterations:a}}u(Wp,"stratifiedBootstrapCI");function zp(e,t=.05){return e.map(n=>{let r=Math.abs(n.withPassRate-n.withoutPassRate),o=r>t,s;return o?s=`discriminates: ${(n.withPassRate*100).toFixed(0)}% with vs ${(n.withoutPassRate*100).toFixed(0)}% without`:n.withPassRate>=1-t&&n.withoutPassRate>=1-t?s="always passes in both cohorts \u2014 measures nothing about the treatment":n.withPassRate<=t&&n.withoutPassRate<=t?s="always fails in both cohorts \u2014 measures nothing about the treatment":s="similar pass rate in both cohorts \u2014 non-discriminating",{...n,discriminating:o,separation:r,note:s}})}u(zp,"diagnoseAssertions");function Vp(e,t={}){let n=t.unpaired??0,r=t.materialFraction??.5,o=e.filter(l=>l.discriminating).length,s=e.length-o,i=e.length+n,c=s+n,a=null;if(i>0&&c>0&&c/i>=r){let l=n>0?` (${n} with no baseline cohort)`:"";a=`${c}/${i} cases do not discriminate with vs without${l} \u2014 cull or replace them before adding runs; more runs of a non-discriminating case cannot lower the MDE`}return{total:i,discriminating:o,nonDiscriminating:s,unpaired:n,diagnoses:e,gateReason:a}}u(Vp,"summarizeDiscrimination");function Ew(e,t){let n=e.length,r=t.length;if(n===0||r===0)return 0;let o=[...e.map(l=>({t:l,exposed:!0})),...t.map(l=>({t:l,exposed:!1}))].sort((l,p)=>l.t-p.t),s=0,i=0;for(;i<o.length;){let l=i;for(;l+1<o.length&&o[l+1].t===o[i].t;)l++;let p=(i+1+l+1)/2;for(let m=i;m<=l;m++)o[m].exposed&&(s+=p);i=l+1}let a=(s-n*(n+1)/2)/(n*r);return Math.abs(a-.5)}u(Ew,"cohortTimeSeparation");var Ru=.35,ku=900*1e3;function Jp(e,t,n=Ru,r=ku){if(e.length===0||t.length===0)return!1;let o=[...e,...t];return Math.max(...o)-Math.min(...o)<r?!1:Ew(e,t)>n}u(Jp,"isTimeSeparated");var Tw=u(e=>e===0||e===1,"isBinary");function Rw(e,t,n){return e.every(o=>o[t]!=null&&o[n]!=null)?e.reduce((o,s)=>o+(s[t]-s[n]),0)/e.length:null}u(Rw,"meanPairDelta");function ju(e,t={}){let n=t.baseline??"no-rule",r=t.minN??10,o=e.length,s=e.map(h=>h.withScore-h.withoutScore),i=o===0?0:s.reduce((h,w)=>h+w,0)/o,c=Hp(s,{seed:t.seed,iterations:t.iterations}),a={lower:c.lower,upper:c.upper},l=e.every(h=>Tw(h.withScore)&&Tw(h.withoutScore)),p=null;if(l&&o>0){let h=0,w=0;for(let I of e)I.withScore===1&&I.withoutScore===0?h++:I.withScore===0&&I.withoutScore===1&&w++;p=Bp(h,w).pValue}let{sufficient:m}=Fp(o,o,r),_=a.lower>0||a.upper<0,g={mode:"controlled",baseline:n,delta:i,ci:a,pValue:p,significant:m&&_,sufficient:m,nWith:o,nWithout:o,costDelta:Rw(e,"withCost","withoutCost"),latencyDelta:Rw(e,"withLatency","withoutLatency"),confounded:!1};return m||(g.insufficientReason=`insufficient data: need >= ${r} paired tasks per cohort, have ${o}`),g}u(ju,"buildControlledVerdict");var dk=2;function pn(e,t={}){let n=t.minN??10,r=t.minPerStratum??dk,o=t.maxTimeSeparation??Ru,s=t.minStratumSpanMs??ku,i=e.filter(E=>E.withScores.length>=r&&E.withoutScores.length>=r),c=i.filter(E=>E.withTimes!=null&&E.withoutTimes!=null&&Jp(E.withTimes,E.withoutTimes,o,s)),a=new Set(c.map(E=>E.key)),l=i.filter(E=>!a.has(E.key)),p=e.filter(E=>E.withScores.length>0&&E.withoutScores.length>0&&(E.withScores.length<r||E.withoutScores.length<r)).length,m=l.reduce((E,P)=>E+P.withScores.length,0),_=l.reduce((E,P)=>E+P.withoutScores.length,0),v=Wp(l,{seed:t.seed,iterations:t.iterations}),g={lower:v.lower,upper:v.upper},h=v.estimate,w=l.length>0&&m>=n&&_>=n,I=l.length>0?v.pValue:null,b=w&&(g.lower>0||g.upper<0),S=e.reduce((E,P)=>E+P.withScores.length+P.withoutScores.length,0),A=S>0?(m+_)/S:0,x={mode:"observational",baseline:t.baseline??"no-rule",delta:h,ci:g,pValue:I,significant:b,sufficient:w,nWith:m,nWithout:_,costDelta:null,latencyDelta:null,confounded:!0,strata:l.length,strataDroppedForTimeSeparation:c.length,coverage:A};if(!w){let E=p>0?` (${p} project(s) had both cohorts but fewer than ${r} sessions in one of them)`:"",P=c.length>0?` ${c.length} project-month(s) held both cohorts but their sessions are separated in time (exposure predicts when a session ran), so the difference within them is a calendar difference, not a treatment effect`:"";x.insufficientReason=l.length===0?c.length>0?`insufficient data: no comparable cohort.${P}${E}`:`insufficient data: no project has >= ${r} exposed AND >= ${r} unexposed sessions to compare within${E}`:`insufficient data: need >= ${n} sessions per cohort across comparable projects, have ${m} exposed / ${_} unexposed${E}${P?`.${P}`:""}`}return x}u(pn,"buildStratifiedVerdict");function Gp(e,t,n={}){return{overall:pn(e,n),segments:Nu(t,n)}}u(Gp,"buildSegmentedVerdict");function Nu(e,t={}){return e.map(n=>({segment:n.segment,verdict:pn(n.strata,t)}))}u(Nu,"buildSegmentVerdicts");function ws(e){return e.sufficient?e.significant?e.delta<0?"harmful":"helpful":"neutral":"insufficient"}u(ws,"classifyEffect");function Kp(e){return ws(e)==="harmful"}u(Kp,"isMeasuredHarmful");var vs={achieved:1,fully_achieved:1,mostly_achieved:.75,partially_achieved:.5,unclear_from_transcript:.25,not_achieved:0,abandoned:0},la=u(e=>{let t=e?vs[e]:void 0;return t===void 0?null:t},"scoreOutcome");var Is=10,Cu=u(e=>e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length,"mean"),Yp=u(e=>{if(e.length<2)return 0;let t=Cu(e);return e.reduce((n,r)=>n+(r-t)**2,0)/(e.length-1)},"sampleVar"),kw=u((e,t)=>{let n=t.reduce((l,p)=>l+p,0);if(n<=0||e.length===0)return{mean:0,varOfMean:0,nEff:0};let r=t.reduce((l,p)=>l+p*p,0),o=n*n/r,s=e.reduce((l,p,m)=>l+t[m]*p,0)/n,i=n-r/n,a=(i>0?e.reduce((l,p,m)=>l+t[m]*(p-s)**2,0)/i:0)*r/(n*n);return{mean:s,varOfMean:a,nEff:o}},"weightedStats");function Xp(e,t,n={}){let r=n.minAnchors??Is,o=n.z??qr,s=e.length,i=t.length,c=[...e,...t.map(A=>A.judge)],a=Cu(c),l=t.map(A=>A.weight??1),p=t.map(A=>A.human-A.judge),m=kw(p,l),_=m.mean,v=i>0?m.nEff:0,g=t.filter(A=>A.validated!==!1).length;if(n.pooledRectifier){let A=n.pooledRectifier,x=s>0?e:t.map(z=>z.judge);if(x.length===0)return{estimate:NaN,ci:{lower:NaN,upper:NaN},se:1/0,naive:a,rectifier:A.rectifier,nLabeled:i,nUnlabeled:s,nEffective:v,nValidated:g,sufficient:!1,insufficientReason:"no judge scores to correct with the pooled rectifier"};let E=Cu(x)+A.rectifier,P=Yp(x)/x.length+A.variance,N=Math.sqrt(P),C={estimate:E,ci:{lower:E-o*N,upper:E+o*N},se:N,naive:a,rectifier:A.rectifier,nLabeled:i,nUnlabeled:s,nEffective:v,nValidated:g,sufficient:A.sufficient};return A.sufficient||(C.insufficientReason="pooled rectifier not yet adequate"),C}let h,w;if(i===0)h=a,w=c.length>0?Yp(c)/c.length:0;else if(s===0){let A=kw(t.map(x=>x.human),l);h=A.mean,w=A.varOfMean}else h=Cu(e)+_,w=Yp(e)/s+m.varOfMean;let I=Math.sqrt(w),b=g>=r,S={estimate:h,ci:{lower:h-o*I,upper:h+o*I},se:I,naive:a,rectifier:_,nLabeled:i,nUnlabeled:s,nEffective:v,nValidated:g,sufficient:b};if(!b){let A=i-g;S.insufficientReason=`insufficient anchors: need >= ${r} VALIDATED human-labeled items, have ${g}${A>0?` (+${A} passive, which don't count toward the floor)`:""}`}return S}u(Xp,"ppiMeanEstimate");function pa(e,t,n={}){let r=Xp(e.unlabeledJudge,e.labeled,{...n,pooledRectifier:n.withPooledRectifier}),o=Xp(t.unlabeledJudge,t.labeled,{...n,pooledRectifier:n.withoutPooledRectifier}),s=n.z??qr,i=r.estimate-o.estimate,c=Math.sqrt(r.se**2+o.se**2),a={lower:i-s*c,upper:i+s*c},l=r.sufficient&&o.sufficient,p=l&&(a.lower>0||a.upper<0),m={delta:i,ci:a,se:c,with:r,without:o,sufficient:l,significant:p};return l||(m.insufficientReason=r.insufficientReason??o.insufficientReason),m}u(pa,"ppiDifference");var Pu=50,Cw=.2,Pw=.8416212335729143,lk=u(e=>e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length,"mean"),ma=u(e=>{if(e.length<2)return 0;let t=lk(e);return e.reduce((n,r)=>n+(r-t)**2,0)/(e.length-1)},"sampleVar");function jw(e,t){let n=e.labeled.length,r=e.unlabeledJudge.length;return n>0&&r>0?{fixed:ma(e.unlabeledJudge)/r,scaling:ma(e.labeled.map(o=>o.human-o.judge)),n}:n>0?{fixed:0,scaling:ma(e.labeled.map(o=>o.human)),n}:{fixed:r>0?ma(e.unlabeledJudge)/r:0,scaling:t.labeled.length>0?ma(t.labeled.map(o=>o.human-o.judge)):null,n:0}}u(jw,"varianceComponents");var Nw=1e6;function pk(e,t){if(e.some(s=>s.scaling===null))return null;let n=u(s=>e.reduce((i,c)=>i+c.fixed+(c.scaling===0?0:c.scaling/(c.n+s)),0),"se2");if(n(Nw)>t)return null;let r=0,o=Nw;for(;r<o;){let s=Math.floor((r+o)/2);n(s)<=t?o=s:r=s+1}return r}u(pk,"solvePerCohortIncrement");function Qp(e,t,n={}){let r=n.pilotTarget??Pu,o=n.targetEffect??Cw,s=n.minAnchors??Is,i=n.z??qr,c=n.zPower??Pw,a=i+c,l=u(N=>(N*100).toFixed(0),"pp"),p=e.labeled.length,m=t.labeled.length,_=n.humanLabeledRuns??p+m,v=e.unlabeledJudge.length+p+t.unlabeledJudge.length+m,g={nAnchors:_,nAnchorsWith:p,nAnchorsWithout:m,pilotTarget:r,pilotMet:_>=r,targetEffect:o};if(v===0)return{...g,seDelta:null,mde:null,powered:!1,adequate:!1,reasons:["no graded runs to calibrate against"],additionalAnchorsNeeded:r};let h=pa(e,t,{minAnchors:s,z:i,withPooledRectifier:n.pool?.withPooledRectifier,withoutPooledRectifier:n.pool?.withoutPooledRectifier}).se,w=a*h,I=w<=o;if(n.pool){let{totalAnchors:N,targets:C}=n.pool,z=N>=r,B=C>=3,q=z&&B&&I,oe=[];return B||oe.push(`pool spans ${C}/3 same-judge targets \u2014 between-target variance is assumed, not measured`),z||oe.push(`pool floor not met: ${N}/${r} human-labeled runs across the same-judge pool`),I||oe.push(`MDE \xB1${l(w)}pp exceeds the \xB1${l(o)}pp target effect \u2014 pooling lowers the label cost, not this; more graded runs are needed (\xA76d(f))`),{...g,seDelta:h,mde:w,powered:I,adequate:q,reasons:oe,additionalAnchorsNeeded:z?null:r-N,pooled:!0,poolAnchors:N,poolTargets:C}}let b=p>=s,S=m>=s,A=g.pilotMet&&b&&S&&I,x,E=0;if(!I){let N=(o/a)**2,C=pk([jw(e,t),jw(t,e)],N);E=C===null?null:2*C}if(!g.pilotMet)x=r-_;else if(E===null)x=null;else{let N=Math.max(0,s-p)+Math.max(0,s-m);x=Math.max(N,E)}let P=[];if(g.pilotMet||P.push(`pilot target not met: ${_}/${r} human-labeled runs`),b||P.push(`with-target cohort has ${p}/${s} labeled runs (minimum for a corrected estimate)`),S||P.push(`without-target cohort has ${m}/${s} labeled runs (minimum for a corrected estimate)`),!I){let N=E===null?" \u2014 anchors alone cannot reach it; more graded runs are needed":g.pilotMet&&E>0?` \u2014 ~${E} more labeled runs projected to reach it`:"";P.push(`MDE \xB1${l(w)}pp exceeds the \xB1${l(o)}pp target effect${N}`)}return{...g,seDelta:h,mde:w,powered:I,adequate:A,reasons:P,additionalAnchorsNeeded:x}}u(Qp,"anchorPowerCheck");function Zp(e,t){return{rectifierUsed:e.rectifier,variance:e.variance,lambda:0,pooled:e.rectifier,pooledVariance:e.variance,tau2:0,i2:0,k:1,pooledApplied:!1,assumedExchangeability:!1,...t}}u(Zp,"localOnly");function Ou(e,t,n={}){let r=n.maxI2??.6,o=[e,...t].filter(q=>q.n>=1&&Number.isFinite(q.variance)&&q.variance>=0),s=o.length;if(s<2)return e.n<1||!Number.isFinite(e.variance)?Zp(e,{rectifierUsed:NaN,variance:1/0,reason:"no anchors on this target and none to pool from"}):Zp(e,{reason:"only one target with anchors \u2014 nothing to pool"});let i=o.map(q=>q.variance).filter(q=>q>0),c=i.length?i.reduce((q,oe)=>q+oe,0)/i.length:0,a=Math.max(c*.001,1e-12),l=u(q=>Math.max(q,a),"flooredVar"),p=o.map(q=>1/l(q.variance)),m=p.reduce((q,oe)=>q+oe,0),_=p.reduce((q,oe)=>q+oe*oe,0),v=o.reduce((q,oe,V)=>q+p[V]*oe.rectifier,0)/m,g=o.reduce((q,oe,V)=>q+p[V]*(oe.rectifier-v)**2,0),h=s-1,w=m-_/m,I=w>0?Math.max(0,(g-h)/w):0,b=g>0?Math.max(0,(g-h)/g):0,S=o.map(q=>1/(l(q.variance)+I)),A=S.reduce((q,oe)=>q+oe,0),x=o.reduce((q,oe,V)=>q+S[V]*oe.rectifier,0)/A,E=1/A,P=s<3;if(b>r)return e.n>=1&&Number.isFinite(e.variance)?Zp(e,{pooled:x,pooledVariance:E,tau2:I,i2:b,k:s,assumedExchangeability:P,reason:`heterogeneity too high (I\xB2=${(b*100).toFixed(0)}%) \u2014 targets disagree; not pooling`}):{rectifierUsed:x,variance:E,lambda:1,pooled:x,pooledVariance:E,tau2:I,i2:b,k:s,pooledApplied:!1,assumedExchangeability:P,reason:`no anchors on this target; pooled estimate is high-heterogeneity (I\xB2=${(b*100).toFixed(0)}%) \u2014 treat as unknown`};let N=e.n<1||!Number.isFinite(e.variance),C=N?1:l(e.variance)/(l(e.variance)+I),z=N?x:C*x+(1-C)*e.rectifier,B=N?E+I:(1-C)*e.variance+C*C*E;return{rectifierUsed:z,variance:B,lambda:C,pooled:x,pooledVariance:E,tau2:I,i2:b,k:s,pooledApplied:!0,assumedExchangeability:P}}u(Ou,"shrinkRectifier");var Mu=3,em=7,tm="(preamble)",yk=/^\s*(`{3,}|~{3,})/,wk=/^(#{1,6})\s+(.*)$/;function fa(e){let t=e.split(`
|
|
659
|
+
`),o=await d.execute(Xt`${Xt.join(r,Xt` UNION ALL `)} ORDER BY oldest ASC`),s=t===null?o:o.filter(p=>t.includes(p.kind));if(s.length===0||await Aw(e))return null;let i=s.reduce((p,m)=>p+Number(m.n),0),c=Date.now()-new Date(s[0].oldest).getTime(),a=Math.round(c/6e4),l=s.map(p=>`${p.kind}\xD7${p.n}`).join(", ");return{code:"STALE_PENDING",message:`${i} job(s) pending >${Math.round(Sw/6e4)}m (oldest ${a}m: ${l}). The worker is heartbeating but its queue isn't draining \u2014 check for a wedged handler or restart it.`,meta:{total:i,oldestMinutes:a,byKind:s.map(p=>({kind:p.kind,count:Number(p.n)}))}}}u(JR,"checkStalePendingAdvisory");function xw(e){return!e||!Array.isArray(e.capabilities)?null:e.capabilities.filter(t=>typeof t=="string")}u(xw,"reportedCapabilities");function GR(e,t){let n=HR[e];if(!n||n.length===0)return null;let r=t&&Array.isArray(t.capabilities)?t.capabilities.filter(s=>typeof s=="string"):null;if(r===null)return{code:"NO_CAPABILITIES_REPORTED",message:`Worker did not report any capabilities. Expected ${n.join(", ")} \u2014 likely an outdated worker process. Restart it.`};let o=n.filter(s=>!r.includes(s)&&!WR.has(s));return o.length>0?{code:"MISSING_CAPABILITIES",message:`Worker is missing capabilities: ${o.join(", ")}. Jobs of those kinds will sit pending. Restart the worker after deploying API updates.`}:null}u(GR,"checkWorkerAdvisory");vs.post("/workers/heartbeat",async e=>{let t=e.get("userId"),n=await e.req.json(),r=zR.parse(n);await d.insert(ve).values({userId:t,workerType:r.workerType,clientName:r.clientName,clientVersion:r.clientVersion??null,workerVersion:r.workerVersion??null,metadata:r.metadata??null}).onConflictDoUpdate({target:[ve.userId,ve.workerType,ve.clientName],set:{lastHeartbeat:new Date,clientVersion:r.clientVersion??null,workerVersion:r.workerVersion??null,metadata:r.metadata??null}}),d.delete(ve).where(ca(qr(ve.userId,t),BR(ve.lastHeartbeat,new Date(Date.now()-FR)))).catch(()=>{});let o=GR(r.workerType,r.metadata);return!o&&r.workerType==="cli-worker"&&(o=await JR(t,xw(r.metadata))),o&&console.warn(`[workers/heartbeat] ${r.workerType} ${r.clientName} (version=${r.workerVersion??"unknown"}): ${o.code} \u2014 ${o.message}`),e.json({status:"ok",...o?{advisory:o}:{}})});async function Ew(e){let t=new Date(Date.now()-qp),n=await d.select({lastHeartbeat:ve.lastHeartbeat}).from(ve).where(ca(qr(ve.userId,e),qr(ve.workerType,"cli-worker"),Lp(ve.lastHeartbeat,t))),r=Date.now();return{cliEverConnected:n.length>0,workerActive:n.some(o=>r-new Date(o.lastHeartbeat).getTime()<$p)}}u(Ew,"computeCliWorkerSetupSignals");async function xu(e){let t=await d.select({lastHeartbeat:ve.lastHeartbeat,metadata:ve.metadata}).from(ve).where(ca(qr(ve.userId,e),qr(ve.workerType,"cli-worker"))).orderBy(Mp(ve.lastHeartbeat)).limit(10);for(let n of t){let r=n.metadata?.llmEngines;if(r&&typeof r=="object"){let o=r;return{claude:o.claude===!0,codex:o.codex===!0,codexModel:typeof o.codexModel=="string"?o.codexModel:null,observedAt:new Date(n.lastHeartbeat).toISOString()}}}return null}u(xu,"getLatestLlmEngines");vs.get("/workers/status",async e=>{let t=e.get("userId"),n=new Date(Date.now()-qp),r=await d.select().from(ve).where(ca(qr(ve.userId,t),Lp(ve.lastHeartbeat,n))).orderBy(Mp(ve.lastHeartbeat)),o=Date.now(),s=r.map(i=>{let c=o-new Date(i.lastHeartbeat).getTime();return{id:i.id,workerType:i.workerType,clientName:i.clientName,clientVersion:i.clientVersion,workerVersion:i.workerVersion,lastHeartbeat:i.lastHeartbeat,connectedAt:i.connectedAt,status:c<$p?"active":"inactive"}});return e.json(s)});vs.get("/workers/health",async e=>{let t=e.get("userId"),n=new Date(Date.now()-qp),[r,o,s]=await Promise.all([d.select({lastHeartbeat:ve.lastHeartbeat,clientName:ve.clientName,clientVersion:ve.clientVersion,metadata:ve.metadata}).from(ve).where(ca(qr(ve.userId,t),qr(ve.workerType,"cli-worker"),Lp(ve.lastHeartbeat,n))).orderBy(Mp(ve.lastHeartbeat)).limit(1),VR(t),Aw(t)]),i=r[0],c=i?Date.now()-new Date(i.lastHeartbeat).getTime():null,a={present:i!=null,active:c!=null&&c<$p,ageSeconds:c==null?null:Math.round(c/1e3),capabilities:i?xw(i.metadata??void 0):null,busy:s},l=bw(a,o);return e.json({worker:{present:a.present,active:a.active,ageSeconds:a.ageSeconds,clientName:i?.clientName??null,clientVersion:i?.clientVersion??null,lastHeartbeat:i?.lastHeartbeat??null,capabilities:a.capabilities},pending:o,verdict:l})});import{Hono as KR}from"hono";import{and as YR,eq as XR,sql as QR}from"drizzle-orm";var Eu=new KR;Eu.get("/setup/status",async e=>{let t=e.get("userId"),[n,r,o]=await Promise.all([Ew(t),d.select({id:f.id}).from(f).where(YR(XR(f.userId,t),QR`${f.origin} <> 'internal_worker'`)).limit(1),xu(t)]);return e.json({cliEverConnected:n.cliEverConnected,anyCapturedSession:r.length>0,workerActive:n.workerActive,llmEngines:o})});import{Hono as ZR}from"hono";import{z as pn}from"zod";import{eq as So,and as Bp,desc as ek,sql as tk}from"drizzle-orm";var Ao=new ZR,nk=pn.object({name:pn.string().min(1).max(255),type:pn.enum(["instruction","skill","prompt","plan"]),content:pn.string().min(1),description:pn.string().default(""),metadata:pn.record(pn.unknown()).default({})}),rk=pn.object({name:pn.string().min(1).max(255).optional(),content:pn.string().min(1).optional(),description:pn.string().optional(),metadata:pn.record(pn.unknown()).optional()});Ao.post("/eval-targets",async e=>{let t=e.get("userId"),n=await e.req.json(),r=nk.parse(n),[o]=await d.insert(k).values({userId:t,name:r.name,type:r.type,content:r.content,description:r.description,metadata:r.metadata}).returning();return e.json(o,201)});Ao.get("/eval-targets",async e=>{let t=e.get("userId"),n=e.req.query("type"),r=e.req.query("content_hash"),o=[So(k.userId,t)];n&&o.push(So(k.type,n)),r&&o.push(tk`${k.metadata}->>'content_hash' = ${r}`);let s=e.req.query("limit"),i=e.req.query("offset"),c=s?parseInt(s,10):NaN,a=Number.isFinite(c)?Math.min(Math.max(1,c),200):100,l=i?parseInt(i,10):NaN,p=Number.isFinite(l)?Math.max(0,l):0,m=await d.select({id:k.id,userId:k.userId,name:k.name,type:k.type,description:k.description,metadata:k.metadata,version:k.version,parentId:k.parentId,createdAt:k.createdAt,updatedAt:k.updatedAt}).from(k).where(Bp(...o)).orderBy(ek(k.updatedAt)).limit(a).offset(p);return e.json(m)});Ao.get("/eval-targets/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(k).where(Bp(So(k.id,n),So(k.userId,t)));return r?e.json(r):e.json({error:"Eval target not found"},404)});Ao.put("/eval-targets/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=rk.parse(r),[s]=await d.select().from(k).where(Bp(So(k.id,n),So(k.userId,t)));if(!s)return e.json({error:"Eval target not found"},404);if(o.content&&o.content!==s.content){let[c]=await d.insert(k).values({userId:t,name:o.name??s.name,type:s.type,content:o.content,description:o.description??s.description,metadata:o.metadata??s.metadata,version:s.version+1,parentId:s.id}).returning();return e.json(c)}let[i]=await d.update(k).set({name:o.name??s.name,description:o.description??s.description,metadata:o.metadata??s.metadata,updatedAt:new Date}).where(So(k.id,n)).returning();return e.json(i)});import{Hono as sk}from"hono";import{z as Ot}from"zod";import{eq as Tu,and as Rw,isNull as ik,desc as ak}from"drizzle-orm";import{and as ok,eq as Tw}from"drizzle-orm";async function De(e,t){let[n]=await d.select({id:k.id}).from(k).where(ok(Tw(k.id,e),Tw(k.userId,t)));return n}u(De,"verifyTargetOwnership");var Is=new sk,ck=Ot.object({name:Ot.string().min(1).max(255),prompt:Ot.string().min(1),expectedOutput:Ot.string().default(""),files:Ot.array(Ot.unknown()).default([]),expectations:Ot.array(Ot.string()).default([])});Is.post("/eval-targets/:id/evals",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=ck.parse(r);if(!await De(n,t))return e.json({error:"Eval target not found"},404);let[i]=await d.insert(_e).values({evalTargetId:n,name:o.name,prompt:o.prompt,expectedOutput:o.expectedOutput,files:o.files,expectations:o.expectations}).returning();return e.json(i,201)});Is.get("/eval-targets/:id/evals",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.query("includeRetired")==="1";if(!await De(n,t))return e.json({error:"Eval target not found"},404);let s=await d.select().from(_e).where(r?Tu(_e.evalTargetId,n):Rw(Tu(_e.evalTargetId,n),ik(_e.retiredAt))).orderBy(ak(_e.createdAt));return e.json(s)});var uk=Ot.object({retire:Ot.boolean().optional(),retiredReason:Ot.string().max(500).optional(),name:Ot.string().min(1).max(255).optional(),prompt:Ot.string().min(1).optional(),expectedOutput:Ot.string().optional(),files:Ot.array(Ot.unknown()).optional(),expectations:Ot.array(Ot.string()).optional()}).refine(e=>e.retire!==void 0||e.name!==void 0||e.prompt!==void 0||e.expectedOutput!==void 0||e.files!==void 0||e.expectations!==void 0,{message:"nothing to update"});Is.patch("/eval-targets/:id/evals/:evalId",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.param("evalId"),o=uk.parse(await e.req.json());if(!await De(n,t))return e.json({error:"Eval target not found"},404);let i={updatedAt:new Date};o.retire!==void 0&&(i.retiredAt=o.retire?new Date:null,i.retiredReason=o.retire?o.retiredReason??null:null),o.name!==void 0&&(i.name=o.name),o.prompt!==void 0&&(i.prompt=o.prompt),o.expectedOutput!==void 0&&(i.expectedOutput=o.expectedOutput),o.files!==void 0&&(i.files=o.files),o.expectations!==void 0&&(i.expectations=o.expectations),(o.prompt!==void 0||o.expectations!==void 0||o.files!==void 0||o.expectedOutput!==void 0)&&(i.contentUpdatedAt=new Date);let[c]=await d.update(_e).set(i).where(Rw(Tu(_e.id,r),Tu(_e.evalTargetId,n))).returning();return c?e.json(c):e.json({error:"Eval case not found"},404)});import{Hono as Sk}from"hono";import{z as Ae}from"zod";import{createHash as Ak}from"node:crypto";import{and as Uw,eq as Fr,gte as xk,desc as Ek,sql as Bw}from"drizzle-orm";function Fp(e,t){let n=e,r=t,o=n+r;if(o===0)return{pValue:1,nDiscordant:0};let s=Math.min(n,r),i=Math.pow(.5,o),c=i;for(let a=1;a<=s;a++)i*=(o-a+1)/a,c+=i;return{pValue:Math.min(1,2*c),nDiscordant:o}}u(Fp,"mcnemarExact");function Hp(e,t,n=10){return{sufficient:e>=n&&t>=n,minN:n,nWith:e,nWithout:t,shortfall:{with:Math.max(0,n-e),without:Math.max(0,n-t)}}}u(Hp,"assessSufficiency");var Ur=1.959963984540054;function Ru(e,t,n=Ur){if(t===0)return{lower:0,upper:1};let r=e/t,o=n*n,s=1+o/t,i=(r+o/(2*t))/s,c=n/s*Math.sqrt(r*(1-r)/t+o/(4*t*t));return{lower:Math.max(0,i-c),upper:Math.min(1,i+c)}}u(Ru,"wilsonInterval");function ua(e){let t=e>>>0;return()=>{t=t+1831565813|0;let n=Math.imul(t^t>>>15,1|t);return n=n+Math.imul(n^n>>>7,61|n)^n,((n^n>>>14)>>>0)/4294967296}}u(ua,"seededRandom");function ku(e,t){let n=e.length;if(n===1)return e[0];let r=(n-1)*t,o=Math.floor(r),s=Math.ceil(r);return o===s?e[o]:e[o]+(r-o)*(e[s]-e[o])}u(ku,"sortedQuantile");function Wp(e,t={}){let n=e.length;if(n===0)return{estimate:0,lower:0,upper:0,iterations:0};let r=t.iterations??1e4,o=t.ciLevel??.95,s=ua(t.seed??1),i=e.reduce((l,p)=>l+p,0)/n,c=new Array(r);for(let l=0;l<r;l++){let p=0;for(let m=0;m<n;m++)p+=e[s()*n|0];c[l]=p/n}c.sort((l,p)=>l-p);let a=(1-o)/2;return{estimate:i,lower:ku(c,a),upper:ku(c,1-a),iterations:r}}u(Wp,"pairedBootstrapCI");function zp(e,t={}){let n=e.filter(h=>h.withScores.length>0&&h.withoutScores.length>0);if(n.length===0)return{estimate:0,lower:0,upper:0,pValue:1,iterations:0};let r=u(h=>h.reduce((w,b)=>w+b,0)/h.length,"mean"),o=n.map(h=>h.withScores.length*h.withoutScores.length/(h.withScores.length+h.withoutScores.length)),s=o.reduce((h,w)=>h+w,0),i=u(h=>h.reduce((w,b,I)=>w+o[I]*b,0)/s,"combine"),c=i(n.map(h=>r(h.withScores)-r(h.withoutScores))),a=t.iterations??1e4,l=t.ciLevel??.95,p=ua(t.seed??1),m=new Array(a),y=0,v=0;for(let h=0;h<a;h++){let w=n.map(I=>{let S=0;for(let x=0;x<I.withScores.length;x++)S+=I.withScores[p()*I.withScores.length|0];let A=0;for(let x=0;x<I.withoutScores.length;x++)A+=I.withoutScores[p()*I.withoutScores.length|0];return S/I.withScores.length-A/I.withoutScores.length}),b=i(w);m[h]=b,b<=0&&y++,b>=0&&v++}m.sort((h,w)=>h-w);let g=(1-l)/2;return{estimate:c,lower:ku(m,g),upper:ku(m,1-g),pValue:Math.min(1,2*Math.min(y,v)/a),iterations:a}}u(zp,"stratifiedBootstrapCI");function Vp(e,t=.05){return e.map(n=>{let r=Math.abs(n.withPassRate-n.withoutPassRate),o=r>t,s;return o?s=`discriminates: ${(n.withPassRate*100).toFixed(0)}% with vs ${(n.withoutPassRate*100).toFixed(0)}% without`:n.withPassRate>=1-t&&n.withoutPassRate>=1-t?s="always passes in both cohorts \u2014 measures nothing about the treatment":n.withPassRate<=t&&n.withoutPassRate<=t?s="always fails in both cohorts \u2014 measures nothing about the treatment":s="similar pass rate in both cohorts \u2014 non-discriminating",{...n,discriminating:o,separation:r,note:s}})}u(Vp,"diagnoseAssertions");function Jp(e,t={}){let n=t.unpaired??0,r=t.materialFraction??.5,o=e.filter(l=>l.discriminating).length,s=e.length-o,i=e.length+n,c=s+n,a=null;if(i>0&&c>0&&c/i>=r){let l=n>0?` (${n} with no baseline cohort)`:"";a=`${c}/${i} cases do not discriminate with vs without${l} \u2014 cull or replace them before adding runs; more runs of a non-discriminating case cannot lower the MDE`}return{total:i,discriminating:o,nonDiscriminating:s,unpaired:n,diagnoses:e,gateReason:a}}u(Jp,"summarizeDiscrimination");function kw(e,t){let n=e.length,r=t.length;if(n===0||r===0)return 0;let o=[...e.map(l=>({t:l,exposed:!0})),...t.map(l=>({t:l,exposed:!1}))].sort((l,p)=>l.t-p.t),s=0,i=0;for(;i<o.length;){let l=i;for(;l+1<o.length&&o[l+1].t===o[i].t;)l++;let p=(i+1+l+1)/2;for(let m=i;m<=l;m++)o[m].exposed&&(s+=p);i=l+1}let a=(s-n*(n+1)/2)/(n*r);return Math.abs(a-.5)}u(kw,"cohortTimeSeparation");var ju=.35,Nu=900*1e3;function Gp(e,t,n=ju,r=Nu){if(e.length===0||t.length===0)return!1;let o=[...e,...t];return Math.max(...o)-Math.min(...o)<r?!1:kw(e,t)>n}u(Gp,"isTimeSeparated");var jw=u(e=>e===0||e===1,"isBinary");function Nw(e,t,n){return e.every(o=>o[t]!=null&&o[n]!=null)?e.reduce((o,s)=>o+(s[t]-s[n]),0)/e.length:null}u(Nw,"meanPairDelta");function Cu(e,t={}){let n=t.baseline??"no-rule",r=t.minN??10,o=e.length,s=e.map(h=>h.withScore-h.withoutScore),i=o===0?0:s.reduce((h,w)=>h+w,0)/o,c=Wp(s,{seed:t.seed,iterations:t.iterations}),a={lower:c.lower,upper:c.upper},l=e.every(h=>jw(h.withScore)&&jw(h.withoutScore)),p=null;if(l&&o>0){let h=0,w=0;for(let b of e)b.withScore===1&&b.withoutScore===0?h++:b.withScore===0&&b.withoutScore===1&&w++;p=Fp(h,w).pValue}let{sufficient:m}=Hp(o,o,r),y=a.lower>0||a.upper<0,g={mode:"controlled",baseline:n,delta:i,ci:a,pValue:p,significant:m&&y,sufficient:m,nWith:o,nWithout:o,costDelta:Nw(e,"withCost","withoutCost"),latencyDelta:Nw(e,"withLatency","withoutLatency"),confounded:!1};return m||(g.insufficientReason=`insufficient data: need >= ${r} paired tasks per cohort, have ${o}`),g}u(Cu,"buildControlledVerdict");var pk=2;function mn(e,t={}){let n=t.minN??10,r=t.minPerStratum??pk,o=t.maxTimeSeparation??ju,s=t.minStratumSpanMs??Nu,i=e.filter(T=>T.withScores.length>=r&&T.withoutScores.length>=r),c=i.filter(T=>T.withTimes!=null&&T.withoutTimes!=null&&Gp(T.withTimes,T.withoutTimes,o,s)),a=new Set(c.map(T=>T.key)),l=i.filter(T=>!a.has(T.key)),p=e.filter(T=>T.withScores.length>0&&T.withoutScores.length>0&&(T.withScores.length<r||T.withoutScores.length<r)).length,m=l.reduce((T,P)=>T+P.withScores.length,0),y=l.reduce((T,P)=>T+P.withoutScores.length,0),v=zp(l,{seed:t.seed,iterations:t.iterations}),g={lower:v.lower,upper:v.upper},h=v.estimate,w=l.length>0&&m>=n&&y>=n,b=l.length>0?v.pValue:null,I=w&&(g.lower>0||g.upper<0),S=e.reduce((T,P)=>T+P.withScores.length+P.withoutScores.length,0),A=S>0?(m+y)/S:0,x={mode:"observational",baseline:t.baseline??"no-rule",delta:h,ci:g,pValue:b,significant:I,sufficient:w,nWith:m,nWithout:y,costDelta:null,latencyDelta:null,confounded:!0,strata:l.length,strataDroppedForTimeSeparation:c.length,coverage:A};if(!w){let T=p>0?` (${p} project(s) had both cohorts but fewer than ${r} sessions in one of them)`:"",P=c.length>0?` ${c.length} project-month(s) held both cohorts but their sessions are separated in time (exposure predicts when a session ran), so the difference within them is a calendar difference, not a treatment effect`:"";x.insufficientReason=l.length===0?c.length>0?`insufficient data: no comparable cohort.${P}${T}`:`insufficient data: no project has >= ${r} exposed AND >= ${r} unexposed sessions to compare within${T}`:`insufficient data: need >= ${n} sessions per cohort across comparable projects, have ${m} exposed / ${y} unexposed${T}${P?`.${P}`:""}`}return x}u(mn,"buildStratifiedVerdict");function Kp(e,t,n={}){return{overall:mn(e,n),segments:Pu(t,n)}}u(Kp,"buildSegmentedVerdict");function Pu(e,t={}){return e.map(n=>({segment:n.segment,verdict:mn(n.strata,t)}))}u(Pu,"buildSegmentVerdicts");function xo(e){return e.sufficient?e.significant?e.delta<0?"harmful":"helpful":"neutral":"insufficient"}u(xo,"classifyEffect");var bs={achieved:1,fully_achieved:1,mostly_achieved:.75,partially_achieved:.5,unclear_from_transcript:.25,not_achieved:0,abandoned:0},la=u(e=>{let t=e?bs[e]:void 0;return t===void 0?null:t},"scoreOutcome");var Ss=10,Ou=u(e=>e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length,"mean"),Yp=u(e=>{if(e.length<2)return 0;let t=Ou(e);return e.reduce((n,r)=>n+(r-t)**2,0)/(e.length-1)},"sampleVar"),Cw=u((e,t)=>{let n=t.reduce((l,p)=>l+p,0);if(n<=0||e.length===0)return{mean:0,varOfMean:0,nEff:0};let r=t.reduce((l,p)=>l+p*p,0),o=n*n/r,s=e.reduce((l,p,m)=>l+t[m]*p,0)/n,i=n-r/n,a=(i>0?e.reduce((l,p,m)=>l+t[m]*(p-s)**2,0)/i:0)*r/(n*n);return{mean:s,varOfMean:a,nEff:o}},"weightedStats");function Xp(e,t,n={}){let r=n.minAnchors??Ss,o=n.z??Ur,s=e.length,i=t.length,c=[...e,...t.map(A=>A.judge)],a=Ou(c),l=t.map(A=>A.weight??1),p=t.map(A=>A.human-A.judge),m=Cw(p,l),y=m.mean,v=i>0?m.nEff:0,g=t.filter(A=>A.validated!==!1).length;if(n.pooledRectifier){let A=n.pooledRectifier,x=s>0?e:t.map(O=>O.judge);if(x.length===0)return{estimate:NaN,ci:{lower:NaN,upper:NaN},se:1/0,naive:a,rectifier:A.rectifier,nLabeled:i,nUnlabeled:s,nEffective:v,nValidated:g,sufficient:!1,insufficientReason:"no judge scores to correct with the pooled rectifier"};let T=Ou(x)+A.rectifier,P=Yp(x)/x.length+A.variance,E=Math.sqrt(P),j={estimate:T,ci:{lower:T-o*E,upper:T+o*E},se:E,naive:a,rectifier:A.rectifier,nLabeled:i,nUnlabeled:s,nEffective:v,nValidated:g,sufficient:A.sufficient};return A.sufficient||(j.insufficientReason="pooled rectifier not yet adequate"),j}let h,w;if(i===0)h=a,w=c.length>0?Yp(c)/c.length:0;else if(s===0){let A=Cw(t.map(x=>x.human),l);h=A.mean,w=A.varOfMean}else h=Ou(e)+y,w=Yp(e)/s+m.varOfMean;let b=Math.sqrt(w),I=g>=r,S={estimate:h,ci:{lower:h-o*b,upper:h+o*b},se:b,naive:a,rectifier:y,nLabeled:i,nUnlabeled:s,nEffective:v,nValidated:g,sufficient:I};if(!I){let A=i-g;S.insufficientReason=`insufficient anchors: need >= ${r} VALIDATED human-labeled items, have ${g}${A>0?` (+${A} passive, which don't count toward the floor)`:""}`}return S}u(Xp,"ppiMeanEstimate");function pa(e,t,n={}){let r=Xp(e.unlabeledJudge,e.labeled,{...n,pooledRectifier:n.withPooledRectifier}),o=Xp(t.unlabeledJudge,t.labeled,{...n,pooledRectifier:n.withoutPooledRectifier}),s=n.z??Ur,i=r.estimate-o.estimate,c=Math.sqrt(r.se**2+o.se**2),a={lower:i-s*c,upper:i+s*c},l=r.sufficient&&o.sufficient,p=l&&(a.lower>0||a.upper<0),m={delta:i,ci:a,se:c,with:r,without:o,sufficient:l,significant:p};return l||(m.insufficientReason=r.insufficientReason??o.insufficientReason),m}u(pa,"ppiDifference");var Du=50,Dw=.2,Mw=.8416212335729143,mk=u(e=>e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length,"mean"),ma=u(e=>{if(e.length<2)return 0;let t=mk(e);return e.reduce((n,r)=>n+(r-t)**2,0)/(e.length-1)},"sampleVar");function Pw(e,t){let n=e.labeled.length,r=e.unlabeledJudge.length;return n>0&&r>0?{fixed:ma(e.unlabeledJudge)/r,scaling:ma(e.labeled.map(o=>o.human-o.judge)),n}:n>0?{fixed:0,scaling:ma(e.labeled.map(o=>o.human)),n}:{fixed:r>0?ma(e.unlabeledJudge)/r:0,scaling:t.labeled.length>0?ma(t.labeled.map(o=>o.human-o.judge)):null,n:0}}u(Pw,"varianceComponents");var Ow=1e6;function fk(e,t){if(e.some(s=>s.scaling===null))return null;let n=u(s=>e.reduce((i,c)=>i+c.fixed+(c.scaling===0?0:c.scaling/(c.n+s)),0),"se2");if(n(Ow)>t)return null;let r=0,o=Ow;for(;r<o;){let s=Math.floor((r+o)/2);n(s)<=t?o=s:r=s+1}return r}u(fk,"solvePerCohortIncrement");function Qp(e,t,n={}){let r=n.pilotTarget??Du,o=n.targetEffect??Dw,s=n.minAnchors??Ss,i=n.z??Ur,c=n.zPower??Mw,a=i+c,l=u(E=>(E*100).toFixed(0),"pp"),p=e.labeled.length,m=t.labeled.length,y=n.humanLabeledRuns??p+m,v=e.unlabeledJudge.length+p+t.unlabeledJudge.length+m,g={nAnchors:y,nAnchorsWith:p,nAnchorsWithout:m,pilotTarget:r,pilotMet:y>=r,targetEffect:o};if(v===0)return{...g,seDelta:null,mde:null,powered:!1,adequate:!1,reasons:["no graded runs to calibrate against"],additionalAnchorsNeeded:r};let h=pa(e,t,{minAnchors:s,z:i,withPooledRectifier:n.pool?.withPooledRectifier,withoutPooledRectifier:n.pool?.withoutPooledRectifier}).se,w=a*h,b=w<=o;if(n.pool){let{totalAnchors:E,targets:j}=n.pool,O=E>=r,F=j>=3,U=O&&F&&b,ee=[];return F||ee.push(`pool spans ${j}/3 same-judge targets \u2014 between-target variance is assumed, not measured`),O||ee.push(`pool floor not met: ${E}/${r} human-labeled runs across the same-judge pool`),b||ee.push(`MDE \xB1${l(w)}pp exceeds the \xB1${l(o)}pp target effect \u2014 pooling lowers the label cost, not this; more graded runs are needed (\xA76d(f))`),{...g,seDelta:h,mde:w,powered:b,adequate:U,reasons:ee,additionalAnchorsNeeded:O?null:r-E,pooled:!0,poolAnchors:E,poolTargets:j}}let I=p>=s,S=m>=s,A=g.pilotMet&&I&&S&&b,x,T=0;if(!b){let E=(o/a)**2,j=fk([Pw(e,t),Pw(t,e)],E);T=j===null?null:2*j}if(!g.pilotMet)x=r-y;else if(T===null)x=null;else{let E=Math.max(0,s-p)+Math.max(0,s-m);x=Math.max(E,T)}let P=[];if(g.pilotMet||P.push(`pilot target not met: ${y}/${r} human-labeled runs`),I||P.push(`with-target cohort has ${p}/${s} labeled runs (minimum for a corrected estimate)`),S||P.push(`without-target cohort has ${m}/${s} labeled runs (minimum for a corrected estimate)`),!b){let E=T===null?" \u2014 anchors alone cannot reach it; more graded runs are needed":g.pilotMet&&T>0?` \u2014 ~${T} more labeled runs projected to reach it`:"";P.push(`MDE \xB1${l(w)}pp exceeds the \xB1${l(o)}pp target effect${E}`)}return{...g,seDelta:h,mde:w,powered:b,adequate:A,reasons:P,additionalAnchorsNeeded:x}}u(Qp,"anchorPowerCheck");function Zp(e,t){return{rectifierUsed:e.rectifier,variance:e.variance,lambda:0,pooled:e.rectifier,pooledVariance:e.variance,tau2:0,i2:0,k:1,pooledApplied:!1,assumedExchangeability:!1,...t}}u(Zp,"localOnly");function Mu(e,t,n={}){let r=n.maxI2??.6,o=[e,...t].filter(U=>U.n>=1&&Number.isFinite(U.variance)&&U.variance>=0),s=o.length;if(s<2)return e.n<1||!Number.isFinite(e.variance)?Zp(e,{rectifierUsed:NaN,variance:1/0,reason:"no anchors on this target and none to pool from"}):Zp(e,{reason:"only one target with anchors \u2014 nothing to pool"});let i=o.map(U=>U.variance).filter(U=>U>0),c=i.length?i.reduce((U,ee)=>U+ee,0)/i.length:0,a=Math.max(c*.001,1e-12),l=u(U=>Math.max(U,a),"flooredVar"),p=o.map(U=>1/l(U.variance)),m=p.reduce((U,ee)=>U+ee,0),y=p.reduce((U,ee)=>U+ee*ee,0),v=o.reduce((U,ee,z)=>U+p[z]*ee.rectifier,0)/m,g=o.reduce((U,ee,z)=>U+p[z]*(ee.rectifier-v)**2,0),h=s-1,w=m-y/m,b=w>0?Math.max(0,(g-h)/w):0,I=g>0?Math.max(0,(g-h)/g):0,S=o.map(U=>1/(l(U.variance)+b)),A=S.reduce((U,ee)=>U+ee,0),x=o.reduce((U,ee,z)=>U+S[z]*ee.rectifier,0)/A,T=1/A,P=s<3;if(I>r)return e.n>=1&&Number.isFinite(e.variance)?Zp(e,{pooled:x,pooledVariance:T,tau2:b,i2:I,k:s,assumedExchangeability:P,reason:`heterogeneity too high (I\xB2=${(I*100).toFixed(0)}%) \u2014 targets disagree; not pooling`}):{rectifierUsed:x,variance:T,lambda:1,pooled:x,pooledVariance:T,tau2:b,i2:I,k:s,pooledApplied:!1,assumedExchangeability:P,reason:`no anchors on this target; pooled estimate is high-heterogeneity (I\xB2=${(I*100).toFixed(0)}%) \u2014 treat as unknown`};let E=e.n<1||!Number.isFinite(e.variance),j=E?1:l(e.variance)/(l(e.variance)+b),O=E?x:j*x+(1-j)*e.rectifier,F=E?T+b:(1-j)*e.variance+j*j*T;return{rectifierUsed:O,variance:F,lambda:j,pooled:x,pooledVariance:T,tau2:b,i2:I,k:s,pooledApplied:!0,assumedExchangeability:P}}u(Mu,"shrinkRectifier");var $u=3,em=7,tm="(preamble)",vk=/^\s*(`{3,}|~{3,})/,Ik=/^(#{1,6})\s+(.*)$/;function fa(e){let t=e.split(`
|
|
660
660
|
`),n=[],r=[],o={heading:"",level:0,path:[tm],body:[]},s=null,i=u(()=>{n.push({heading:o.heading,level:o.level,path:o.path,body:o.body.join(`
|
|
661
|
-
`).trim()})},"flush");for(let c of t){let a=
|
|
661
|
+
`).trim()})},"flush");for(let c of t){let a=vk.exec(c);if(a){let p=a[1];s==null?s={marker:p}:p[0]===s.marker[0]&&p.length>=s.marker.length&&(s=null),o.body.push(c);continue}if(s!=null){o.body.push(c);continue}let l=Ik.exec(c);if(l){i();let p=l[1].length,m=l[2].trim();r.length=Math.max(0,p-1),r[p-1]=m,o={heading:m,level:p,path:Array.from({length:p},(y,v)=>r[v]??`(unnamed level ${v+1})`),body:[]};continue}o.body.push(c)}return i(),n.filter((c,a)=>!(a===0&&c.level===0&&c.body===""))}u(fa,"splitMarkdownSections");function Lu(e){let t=new Map,n=new Map;for(let r of e){let o=r.level===0?tm:r.path.join(" > "),s=(t.get(o)??0)+1;t.set(o,s),n.set(s===1?o:`${o} #${s}`,r)}return n}u(Lu,"sectionKeys");function nm(e,t){let n=Lu(fa(e)),r=Lu(fa(t)),o=[],s=[],i=[];for(let[c,a]of r){let l=n.get(c);l?l.body!==a.body&&o.push(c):s.push(c)}for(let c of n.keys())r.has(c)||i.push(c);return{changed:o.sort(),added:s.sort(),removed:i.sort()}}u(nm,"diffSections");function rm(e){return[...new Set([...e.changed,...e.added,...e.removed])].sort()}u(rm,"touchedSections");var Lw=u(e=>e.trim().toLowerCase(),"normalize");function $w(e,t,n){if(n.length===0)return[];let r=new Set(n.map(Lw)),o=nm(e,t),s=new Set(rm(o)),i=new Map([...Lu(fa(e)),...Lu(fa(t))]),c=[];for(let a of s){let l=i.get(a);(l?l.path:a.split(" > ")).some(m=>r.has(Lw(m)))&&c.push(a)}return c.sort()}u($w,"protectedViolations");function om(e){let{verdict:t,canaryGreen:n,adequate:r,adequacyReasons:o=[],promotionsInWindow:s,maxPromotionsPerWindow:i=$u,immutableSections:c=[],beforeContent:a,afterContent:l,measurementMatchesPredecessor:p}=e,m=rm(nm(a,l)),y=xo(t),v=[];if(a===l&&v.push("proposal is identical to the current version \u2014 nothing to promote"),t.mode!=="controlled"&&v.push(`verdict is ${t.mode}, not controlled \u2014 Phase 2 measured that an observational version-vs-version comparison is refused on 99.4% of real version pairs, because versions are disjoint in time by construction`),t.baseline!=="prior-version"&&v.push(`verdict baseline is '${t.baseline}', not 'prior-version' \u2014 a no-rule comparison says the instruction beats having no instruction, not that this edit beats the last one`),t.confounded&&v.push("verdict is flagged confounded"),p===!1&&v.push("pairs were measured against a different predecessor than the one now live \u2014 the target's content changed after the eval batch ran, so this verdict is about a comparison that no longer exists"),n||v.push("A/A canary is red \u2014 the verdict path can manufacture effects from noise, so no verdict it produces may be promoted"),!r){let b=o.length>0?`: ${o.join("; ")}`:"";v.push(`verdict is not adequately powered${b}`)}s>=i&&v.push(`change budget exhausted: ${s}/${i} promotions already made in the current window`);let g=$w(a,l,c);if(g.length>0&&v.push(`proposal edits protected section(s): ${g.join(", ")}`),y==="insufficient"&&v.push(t.insufficientReason??"verdict did not clear min-n, so no effect was measured"),v.length>0)return{decision:"refuse",refusals:v,rationale:`refused: ${v.length} gate(s) blocked promotion`,effect:y,touched:m};let h=u(b=>`${b>=0?"+":""}${(b*100).toFixed(1)}pp`,"pp"),w=`[${h(t.ci.lower)}, ${h(t.ci.upper)}]`;return y==="helpful"?{decision:"promote",refusals:[],rationale:`promote: ${h(t.delta)} CI ${w} over the prior version, n=${t.nWith} paired cases`,effect:y,touched:m}:y==="harmful"?{decision:"revert",refusals:[],rationale:`revert: proposal measured WORSE than its predecessor, ${h(t.delta)} CI ${w}`,effect:y,touched:m}:{decision:"revert",refusals:[],rationale:`revert: no detectable improvement, ${h(t.delta)} CI ${w} spans zero`,effect:y,touched:m}}u(om,"evaluatePromotion");import{eq as bk,sql as Br}from"drizzle-orm";async function As(e,t){let r=await d.execute(Br`
|
|
662
662
|
SELECT
|
|
663
663
|
r.configuration,
|
|
664
664
|
r.created_at,
|
|
@@ -701,7 +701,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
701
701
|
AND ev.retired_at IS NULL
|
|
702
702
|
AND r.grading->'summary'->>'pass_rate' IS NOT NULL
|
|
703
703
|
AND r.configuration IN ('with_target', 'without_target')
|
|
704
|
-
`),o=null,s=-1;for(let
|
|
704
|
+
`),o=null,s=-1;for(let N of r){if(!N.judge_model)continue;let Q=new Date(N.created_at).getTime();(Q>s||Q===s&&N.judge_model>(o??""))&&(s=Q,o=N.judge_model)}let i=null,c=-1;for(let N of r){let Q=new Date(N.created_at).getTime();Q>c&&(c=Q,i=N.methodology)}let a={with_target:{unlabeledJudge:[],labeled:[]},without_target:{unlabeledJudge:[],labeled:[]}},l={with_target:[],without_target:[]},p=0,m=new Map,y=0,v=0,g=0,h=0;for(let N of r){let Q=a[N.configuration];if(!Q)continue;let xe=N.methodology!==i||N.pre_edit;N.methodology!==i&&(g+=1),N.pre_edit&&(h+=1);let st=N.judge_pass?1:0,Fe=N.llm_annotated>=N.llm_total;if(N.llm_total>0){let Lt=N.judge_model,Rn=m.get(Lt)??{runs:0,labeledRuns:0,latestRunAt:N.created_at};if(Rn.runs+=1,Fe&&(Rn.labeledRuns+=1),new Date(N.created_at).getTime()>new Date(Rn.latestRunAt).getTime()&&(Rn.latestRunAt=N.created_at),m.set(Lt,Rn),Lt!==o){y+=1,Fe&&(v+=1);continue}}if(Fe){let Lt=N.det_all_passed&&N.llm_truly_passed===N.llm_total?1:0;l[N.configuration]?.push({human:Lt,judge:st}),N.llm_total>0&&(p+=1)}if(!xe)if(Fe){let Lt=N.det_all_passed&&N.llm_truly_passed===N.llm_total?1:0;Q.labeled.push({human:Lt,judge:st})}else Q.unlabeledJudge.push(st)}let[w]=await d.select({total:Br`count(*)::int`,llmAnchors:Br`count(*) FILTER (WHERE ${ze.judgeMethod} = 'llm' AND ${ze.judgeModel} IS NOT DISTINCT FROM ${o})::int`,llmApproved:Br`count(*) FILTER (WHERE ${ze.judgeMethod} = 'llm' AND ${ze.judgeModel} IS NOT DISTINCT FROM ${o} AND ${ze.verdict} = 'approve')::int`,staleLlmAnchors:Br`count(*) FILTER (WHERE ${ze.judgeMethod} = 'llm' AND ${ze.judgeModel} IS DISTINCT FROM ${o})::int`,flagged:Br`count(*) FILTER (WHERE ${ze.flag} IS NOT NULL)::int`}).from(ze).where(bk(ze.evalTargetId,t)),b=a.with_target.unlabeledJudge.length+a.with_target.labeled.length+a.without_target.unlabeledJudge.length+a.without_target.labeled.length,I=await d.execute(Br`
|
|
705
705
|
SELECT
|
|
706
706
|
r.eval_target_id::text AS target_id,
|
|
707
707
|
r.configuration,
|
|
@@ -743,7 +743,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
743
743
|
AND r.grading->'summary'->>'pass_rate' IS NOT NULL
|
|
744
744
|
AND r.configuration IN ('with_target', 'without_target')
|
|
745
745
|
AND r.grading->>'judge_model' IS NOT DISTINCT FROM ${o}
|
|
746
|
-
`),S=new Map;for(let
|
|
746
|
+
`),S=new Map;for(let N of I){if(N.llm_total<=0||N.llm_annotated<N.llm_total)continue;let Q=S.get(N.target_id)??{with_target:[],without_target:[]},xe=N.det_all_passed&&N.llm_truly_passed===N.llm_total?1:0,st=N.judge_pass?1:0;N.configuration==="with_target"?Q.with_target.push(xe-st):Q.without_target.push(xe-st),S.set(N.target_id,Q)}let A=u(N=>{let Q=N.length;if(Q===0)return{rectifier:0,variance:1/0,n:0};let xe=N.reduce((Fe,Lt)=>Fe+Lt,0)/Q,st=Q<2?0:N.reduce((Fe,Lt)=>Fe+(Lt-xe)**2,0)/(Q-1);return{rectifier:xe,variance:st/Q,n:Q}},"toRectifier"),x=u(N=>N.map(Q=>Q.human-Q.judge),"selfDeltas"),T=[...S.values()].map(N=>A(N.with_target)),P=[...S.values()].map(N=>A(N.without_target)),E=Mu(A(x(l.with_target)),T),j=Mu(A(x(l.without_target)),P),O=[...S.values()].reduce((N,Q)=>N+Q.with_target.length+Q.without_target.length,0),F=p+O,U=(p>0?1:0)+[...S.values()].filter(N=>N.with_target.length+N.without_target.length>0).length,ee=E.pooledApplied||j.pooledApplied,z=U>=3&&F>=Du,de=u(N=>({rectifier:N.rectifierUsed,variance:N.variance,sufficient:z}),"asInput"),ot=b>0?pa(a.with_target,a.without_target,ee?{withPooledRectifier:de(E),withoutPooledRectifier:de(j)}:{}):null,G=Qp(a.with_target,a.without_target,{humanLabeledRuns:p,...ee?{pool:{withPooledRectifier:de(E),withoutPooledRectifier:de(j),totalAnchors:F,targets:U}}:{}}),ae=new Map;for(let N of r){if(N.judge_model!==o||N.methodology!==i||N.pre_edit||N.pass_rate==null)continue;let Q=ae.get(N.eval_id)??{name:N.eval_name,withRates:[],withoutRates:[]};N.configuration==="with_target"?Q.withRates.push(N.pass_rate):N.configuration==="without_target"&&Q.withoutRates.push(N.pass_rate),ae.set(N.eval_id,Q)}let me=[],Te=[],Bt=u(N=>N.length?N.reduce((Q,xe)=>Q+xe,0)/N.length:null,"mean_"),Be=[];for(let[N,{name:Q,withRates:xe,withoutRates:st}]of ae.entries())xe.length>0&&st.length>0?(me.push({name:Q,withPassRate:Bt(xe),withoutPassRate:Bt(st)}),Te.push(N)):Be.push({evalId:N,name:Q,withPassRate:Bt(xe),withoutPassRate:Bt(st)});let le=Jp(Vp(me),{unpaired:Be.length}),Me=le.gateReason?[le.gateReason,...G.reasons]:G.reasons;return{judge:{currentModel:o,models:[...m.entries()].map(([N,Q])=>({model:N,...Q})).sort((N,Q)=>new Date(Q.latestRunAt).getTime()-new Date(N.latestRunAt).getTime()),staleRuns:y,staleLabeledRuns:v,staleAnchors:w?.staleLlmAnchors??0},anchors:{total:w?.total??0,llmAnchors:w?.llmAnchors??0,agreementRate:w&&w.llmAnchors>0?w.llmApproved/w.llmAnchors:null,agreementCi:w&&w.llmAnchors>0?Ru(w.llmApproved,w.llmAnchors):null,flagged:w?.flagged??0,minAnchors:Ss,labeledRuns:{with:l.with_target.length,without:l.without_target.length}},methodology:{current:i,supersededRuns:g,preEditRuns:h,runsInSegment:b},calibration:ot,powerCheck:{...G,reasons:Me},pooling:{engaged:ee,judgeModel:o,poolTargets:U,poolAnchors:F,assumedExchangeability:E.assumedExchangeability||j.assumedExchangeability,sufficient:z,withLambda:E.lambda,withoutLambda:j.lambda,tau2:E.tau2,i2:E.i2,withReason:E.reason??null,withoutReason:j.reason??null},caseDiscrimination:{total:le.total,discriminating:le.discriminating,nonDiscriminating:le.nonDiscriminating,unpaired:le.unpaired,cases:le.diagnoses.map((N,Q)=>({evalId:Te[Q],name:N.name,withPassRate:N.withPassRate,withoutPassRate:N.withoutPassRate,separation:N.separation,discriminating:N.discriminating,note:N.note})).sort((N,Q)=>N.separation-Q.separation),unpairedCases:Be}}}u(As,"computeJudgeCalibration");async function qw(e){return(await d.execute(Br`
|
|
747
747
|
WITH current_judge AS (
|
|
748
748
|
SELECT r.grading->>'judge_model' AS model
|
|
749
749
|
FROM eval_runs r
|
|
@@ -772,7 +772,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
772
772
|
AND (SELECT count(*) FROM jsonb_array_elements(r.grading->'expectations') e
|
|
773
773
|
WHERE COALESCE(e->>'method', 'llm') = 'llm'
|
|
774
774
|
AND COALESCE(e->>'errored', 'false') <> 'true') > COALESCE(a.llm_annotated, 0)
|
|
775
|
-
`))[0]?.remaining??0}u(Mw,"countRunsAwaitingReview");var Ss=new Ik,sm=u(e=>bk("sha256").update(e).digest("hex"),"sha256"),xk=Se.object({withScore:Se.number().min(0).max(1),withoutScore:Se.number().min(0).max(1),withCost:Se.number().nonnegative().optional(),withoutCost:Se.number().nonnegative().optional(),withLatency:Se.number().nonnegative().optional(),withoutLatency:Se.number().nonnegative().optional()}),Ek=Se.object({candidateContent:Se.string().min(1),proposalSource:Se.enum(["llm","groom","human"]),proposalRationale:Se.string().default(""),pairs:Se.array(xk).default([]),canaryGreen:Se.boolean(),measuredAgainstContentHash:Se.string().optional(),accumulation:Se.object({candidateContentHash:Se.string(),priorContentHash:Se.string(),targetPairs:Se.number().int().positive(),carriedPairs:Se.number().int().nonnegative(),runs:Se.number().int().positive()}).optional(),immutableSections:Se.array(Se.string()).default([]),maxPromotionsPerWindow:Se.number().int().positive().optional(),windowDays:Se.number().int().positive().optional(),measurementCost:Se.object({modelCalls:Se.number().int().nonnegative(),proposalCalls:Se.number().int().nonnegative(),executorCalls:Se.number().int().nonnegative(),graderCalls:Se.number().int().nonnegative(),plannedPairs:Se.number().int().nonnegative(),usablePairs:Se.number().int().nonnegative(),verdictPairs:Se.number().int().nonnegative().optional(),passes:Se.number().int().nonnegative(),liveCases:Se.number().int().nonnegative(),mde:Se.number().nonnegative().nullable(),wallMs:Se.number().nonnegative()}).optional(),apply:Se.boolean().default(!0)});Ss.post("/eval-targets/:id/promotions",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=Ek.parse(await e.req.json());if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let[s]=await d.select({id:R.id,content:R.content,version:R.version,metadata:R.metadata}).from(R).where(Br(R.id,n));if(!s)return e.json({error:"Eval target not found"},404);let i=s.content,c=r.candidateContent,a=r.pairs,l=ju(a,{baseline:"prior-version"}),p=!1,m=["adequacy could not be computed for this target"];try{let P=await bs(t,n);p=P.powerCheck.adequate,m=P.powerCheck.reasons??[]}catch(P){m=[`adequacy check failed: ${P instanceof Error?P.message:String(P)}`]}let _=r.windowDays??em,v=r.maxPromotionsPerWindow??Mu,g=new Date(Date.now()-_*24*60*60*1e3),[h]=await d.select({n:$w`count(*)::int`}).from(ke).where(Lw(Br(ke.evalTargetId,n),Br(ke.applied,!0),Sk(ke.createdAt,g))),w=h?.n??0,I=sm(i),b=r.measuredAgainstContentHash===void 0?void 0:r.measuredAgainstContentHash===I,S=om({verdict:l,canaryGreen:r.canaryGreen,adequate:p,adequacyReasons:m,promotionsInWindow:w,maxPromotionsPerWindow:v,immutableSections:r.immutableSections,beforeContent:i,afterContent:c,measurementMatchesPredecessor:b}),A={canaryGreen:r.canaryGreen,adequate:p,adequacyReasons:m,promotionsInWindow:w,maxPromotionsPerWindow:v,windowDays:_,immutableSections:r.immutableSections,nPairs:a.length,measurementMatchesPredecessor:b??null,measuredAgainstContentHash:r.measuredAgainstContentHash??null,cost:r.measurementCost??null,accumulation:r.accumulation?{...r.accumulation,pairs:a}:null,applied:!1},x=S.decision==="promote"&&r.apply;A.applied=x;let E;try{E=await d.transaction(async P=>{if(x){let C=s.metadata&&typeof s.metadata=="object"&&!Array.isArray(s.metadata)?s.metadata:{};await P.update(R).set({content:c,version:(s.version??1)+1,metadata:{...C,content_hash:sm(c)},updatedAt:new Date}).where(Br(R.id,n))}let[N]=await P.insert(ke).values({userId:t,evalTargetId:n,fromContentHash:I,toContentHash:sm(c),fromContent:i,toContent:c,proposalSource:r.proposalSource,proposalRationale:r.proposalRationale,decision:S.decision,applied:x,refusals:S.refusals,rationale:S.rationale,effectClass:S.effect,verdict:l,gates:A,touchedSections:S.touched}).returning({id:ke.id,createdAt:ke.createdAt});return N})}catch(P){if(P?.code==="23505")return e.json({error:"This edit has already been applied to this target",code:"PROMOTION_ALREADY_APPLIED"},409);throw P}return e.json({id:E.id,createdAt:E.createdAt,decision:S.decision,applied:x,rationale:S.rationale,refusals:S.refusals,effectClass:S.effect,touchedSections:S.touched,verdict:l,gates:A},201)});Ss.get("/eval-targets/:id/promotions",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=Math.min(Number(e.req.query("limit")??50)||50,200),o=Math.max(Number(e.req.query("offset")??0)||0,0);if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let i=await d.select({id:ke.id,createdAt:ke.createdAt,decision:ke.decision,applied:ke.applied,effectClass:ke.effectClass,rationale:ke.rationale,refusals:ke.refusals,proposalSource:ke.proposalSource,proposalRationale:ke.proposalRationale,fromContentHash:ke.fromContentHash,toContentHash:ke.toContentHash,touchedSections:ke.touchedSections,verdict:ke.verdict,gates:ke.gates}).from(ke).where(Br(ke.evalTargetId,n)).orderBy(Ak(ke.createdAt)).limit(r).offset(o),c=await d.select({decision:ke.decision,n:$w`count(*)::int`}).from(ke).where(Br(ke.evalTargetId,n)).groupBy(ke.decision),a={promote:0,revert:0,refuse:0};for(let l of c)a[l.decision]=l.n;return e.json({promotions:i,counts:a,total:Object.values(a).reduce((l,p)=>l+p,0),limit:r,offset:o})});Ss.get("/promotions/:promotionId",async e=>{let t=e.get("userId"),n=e.req.param("promotionId"),[r]=await d.select().from(ke).where(Lw(Br(ke.id,n),Br(ke.userId,t)));return r?e.json(r):e.json({error:"Promotion not found"},404)});import{Hono as Tk}from"hono";import{z as it}from"zod";import{eq as Nn,and as im,asc as Rk,desc as qw,isNull as kk,inArray as jk}from"drizzle-orm";var So=new Tk,Nk=it.object({jobId:it.string().uuid().optional(),evalId:it.string().uuid(),evalTargetId:it.string().uuid(),evalTargetVersion:it.number().int(),configuration:it.enum(["with_target","without_target","baseline","with_candidate","with_prior_version"]),runNumber:it.number().int().default(1),iteration:it.number().int().default(1),status:it.enum(["pending","running","completed","failed"]).default("completed"),outputs:it.record(it.unknown()).default({}),timing:it.record(it.unknown()).default({}),grading:it.record(it.unknown()).default({}),comparison:it.record(it.unknown()).nullable().optional()}),Ck=it.object({iteration:it.number().int().default(1),runSummary:it.record(it.unknown()).default({}),notes:it.array(it.string()).default([])});So.post("/eval-runs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=Nk.parse(n);if(!await Oe(r.evalTargetId,t))return e.json({error:"Eval target not found"},404);let[s]=await d.insert(_e).values({jobId:r.jobId??null,evalId:r.evalId,evalTargetId:r.evalTargetId,evalTargetVersion:r.evalTargetVersion,configuration:r.configuration,runNumber:r.runNumber,iteration:r.iteration,status:r.status,outputs:r.outputs,timing:r.timing,grading:r.grading,comparison:r.comparison??null}).onConflictDoNothing().returning();if(s)return e.json(s,201);if(!r.jobId)return e.json({error:"Insert conflicted without a jobId"},409);let[i]=await d.select().from(_e).where(im(Nn(_e.jobId,r.jobId),Nn(_e.evalId,r.evalId),Nn(_e.configuration,r.configuration),Nn(_e.runNumber,r.runNumber),Nn(_e.iteration,r.iteration))).limit(1);return i?e.json({...i,deduped:!0},200):e.json({error:"Run conflicted but existing row not found"},409)});So.get("/eval-targets/:id/runs",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.query("iteration"),o=e.req.query("configuration");if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let i=e.req.query("limit"),c=e.req.query("offset"),a=i?parseInt(i,10):NaN,l=Number.isFinite(a)?Math.min(Math.max(1,a),100):50,p=c?parseInt(c,10):NaN,m=Number.isFinite(p)?Math.max(0,p):0,_=[Nn(_e.evalTargetId,n)];r&&_.push(Nn(_e.iteration,parseInt(r,10))),o&&_.push(Nn(_e.configuration,o)),e.req.query("activeCasesOnly")==="1"&&_.push(jk(_e.evalId,d.select({id:he.id}).from(he).where(im(Nn(he.evalTargetId,n),kk(he.retiredAt)))));let v=e.req.query("jobId");if(v){let w=it.string().uuid().safeParse(v);if(!w.success)return e.json({error:"Invalid jobId"},400);_.push(Nn(_e.jobId,w.data))}let h=(await d.select().from(_e).where(im(..._)).orderBy(qw(_e.createdAt),Rk(_e.id)).limit(l).offset(m)).map(w=>{let I=w.outputs??{},{diff:b,...S}=I;return{...w,outputs:S,comparison:null}});return e.json(h)});So.post("/eval-targets/:id/benchmarks",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=Ck.parse(r);if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let[i]=await d.insert(Rn).values({evalTargetId:n,iteration:o.iteration,runSummary:o.runSummary,notes:o.notes}).returning();return e.json(i,201)});So.get("/eval-targets/:id/benchmarks",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let o=await d.select().from(Rn).where(Nn(Rn.evalTargetId,n)).orderBy(qw(Rn.createdAt));return e.json(o)});import{Hono as Pk}from"hono";import{z as Dt}from"zod";import{eq as Ao,and as Bw,or as Ok,desc as Dk,asc as Mk}from"drizzle-orm";import{alias as Uw}from"drizzle-orm/pg-core";var As=new Pk,Lk=Dt.object({targetAId:Dt.string().uuid(),targetBId:Dt.string().uuid(),targetAVersion:Dt.number().int(),targetBVersion:Dt.number().int(),isSwapped:Dt.boolean(),winnerTargetId:Dt.string().uuid().nullable(),perEval:Dt.array(Dt.object({evalName:Dt.string(),winnerTargetId:Dt.string().uuid().nullable(),reasoning:Dt.string().default("")})).default([]),overall:Dt.record(Dt.unknown()).default({}),rawOutput:Dt.string().nullable().optional(),model:Dt.string().nullable().optional(),status:Dt.enum(["completed","parse_failed"]).default("completed")});As.post("/eval-comparisons",async e=>{let t=e.get("userId"),n=await e.req.json(),r=Lk.parse(n),[o,s]=await Promise.all([Oe(r.targetAId,t),Oe(r.targetBId,t)]);if(!o||!s)return e.json({error:"Eval target not found"},404);let i=u(a=>a===null||a===r.targetAId||a===r.targetBId,"validWinner");if(!i(r.winnerTargetId)||!r.perEval.every(a=>i(a.winnerTargetId)))return e.json({error:"winnerTargetId must be one of the compared targets or null"},400);let[c]=await d.insert(Ke).values({userId:t,targetAId:r.targetAId,targetBId:r.targetBId,targetAVersion:r.targetAVersion,targetBVersion:r.targetBVersion,isSwapped:r.isSwapped,winnerTargetId:r.winnerTargetId,perEval:r.perEval,overall:r.overall,rawOutput:r.rawOutput??null,model:r.model??null,status:r.status}).returning();return e.json(c,201)});As.get("/eval-targets/:id/comparisons",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await Oe(n,t))return e.json({error:"Eval target not found"},404);let o=e.req.query("limit"),s=e.req.query("offset"),i=o?parseInt(o,10):NaN,c=Number.isFinite(i)?Math.min(Math.max(1,i),100):50,a=s?parseInt(s,10):NaN,l=Number.isFinite(a)?Math.max(0,a):0,p=Uw(R,"targets_a"),m=Uw(R,"targets_b"),_=await d.select({id:Ke.id,userId:Ke.userId,targetAId:Ke.targetAId,targetBId:Ke.targetBId,targetAName:p.name,targetBName:m.name,targetAVersion:Ke.targetAVersion,targetBVersion:Ke.targetBVersion,isSwapped:Ke.isSwapped,winnerTargetId:Ke.winnerTargetId,perEval:Ke.perEval,overall:Ke.overall,model:Ke.model,status:Ke.status,createdAt:Ke.createdAt}).from(Ke).innerJoin(p,Ao(Ke.targetAId,p.id)).innerJoin(m,Ao(Ke.targetBId,m.id)).where(Bw(Ao(Ke.userId,t),Ok(Ao(Ke.targetAId,n),Ao(Ke.targetBId,n)))).orderBy(Dk(Ke.createdAt),Mk(Ke.id)).limit(c).offset(l);return e.json(_.map(v=>({...v,rawOutput:null})))});As.get("/eval-comparisons/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=Dt.string().uuid().safeParse(n);if(!r.success)return e.json({error:"Invalid comparison id"},400);let[o]=await d.select().from(Ke).where(Bw(Ao(Ke.id,r.data),Ao(Ke.userId,t)));return o?e.json(o):e.json({error:"Comparison not found"},404)});import{Hono as Bk}from"hono";import{z as xs}from"zod";import{eq as Es,and as am,desc as Fk,asc as Hk,inArray as Wk,sql as zk}from"drizzle-orm";import{sql as $k}from"drizzle-orm";function Fw(e){if(e.n===0)return null;let t=e.agree/e.n,n=e.aYes/e.n,r=e.bYes/e.n,o=n*r+(1-n)*(1-r);return o>=1?null:(t-o)/(1-o)}u(Fw,"kappaFromCounts");var Hw=u((e,t)=>({agree:e,total:t,rate:t>0?e/t:null}),"slice");function qk(e){let t=e.pairs>0?e.agreeHuman/e.pairs:null;return{engine:e.reviewerEngine,models:e.models,pairs:e.pairs,orphaned:e.orphaned,agreementRate:t,kappa:Fw({n:e.pairs,agree:e.agreeHuman,aYes:e.humanYes,bYes:e.reviewerYes}),snapshotAgreementRate:e.pairs>0?e.snapshotAgree/e.pairs:null,snapshotKappa:Fw({n:e.pairs,agree:e.snapshotAgree,aYes:e.snapshotHumanYes,bYes:e.reviewerYes}),judgeAgreementRate:e.pairs>0?e.judgeAgreeHuman/e.pairs:null,onJudgePass:Hw(e.judgePassAgree,e.judgePassPairs),onJudgeFail:Hw(e.agreeHuman-e.judgePassAgree,e.pairs-e.judgePassPairs),suggestedAnchorWeight:t==null?null:Math.max(0,2*t-1)**2,unresolvedFlags:e.unresolvedFlags,kept:e.kept,relabeled:e.relabeled,lastReviewedAt:e.lastReviewedAt}}u(qk,"reviewerAgreementReport");async function Ww(e){return(await d.execute($k`
|
|
775
|
+
`))[0]?.remaining??0}u(qw,"countRunsAwaitingReview");var xs=new Sk,sm=u(e=>Ak("sha256").update(e).digest("hex"),"sha256"),Tk=Ae.object({withScore:Ae.number().min(0).max(1),withoutScore:Ae.number().min(0).max(1),withCost:Ae.number().nonnegative().optional(),withoutCost:Ae.number().nonnegative().optional(),withLatency:Ae.number().nonnegative().optional(),withoutLatency:Ae.number().nonnegative().optional()}),Rk=Ae.object({candidateContent:Ae.string().min(1),proposalSource:Ae.enum(["llm","groom","human"]),proposalRationale:Ae.string().default(""),pairs:Ae.array(Tk).default([]),canaryGreen:Ae.boolean(),measuredAgainstContentHash:Ae.string().optional(),accumulation:Ae.object({candidateContentHash:Ae.string(),priorContentHash:Ae.string(),targetPairs:Ae.number().int().positive(),carriedPairs:Ae.number().int().nonnegative(),runs:Ae.number().int().positive()}).optional(),immutableSections:Ae.array(Ae.string()).default([]),maxPromotionsPerWindow:Ae.number().int().positive().optional(),windowDays:Ae.number().int().positive().optional(),measurementCost:Ae.object({modelCalls:Ae.number().int().nonnegative(),proposalCalls:Ae.number().int().nonnegative(),executorCalls:Ae.number().int().nonnegative(),graderCalls:Ae.number().int().nonnegative(),plannedPairs:Ae.number().int().nonnegative(),usablePairs:Ae.number().int().nonnegative(),verdictPairs:Ae.number().int().nonnegative().optional(),passes:Ae.number().int().nonnegative(),liveCases:Ae.number().int().nonnegative(),mde:Ae.number().nonnegative().nullable(),wallMs:Ae.number().nonnegative()}).optional(),apply:Ae.boolean().default(!0)});xs.post("/eval-targets/:id/promotions",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=Rk.parse(await e.req.json());if(!await De(n,t))return e.json({error:"Eval target not found"},404);let[s]=await d.select({id:k.id,content:k.content,version:k.version,metadata:k.metadata}).from(k).where(Fr(k.id,n));if(!s)return e.json({error:"Eval target not found"},404);let i=s.content,c=r.candidateContent,a=r.pairs,l=Cu(a,{baseline:"prior-version"}),p=!1,m=["adequacy could not be computed for this target"];try{let P=await As(t,n);p=P.powerCheck.adequate,m=P.powerCheck.reasons??[]}catch(P){m=[`adequacy check failed: ${P instanceof Error?P.message:String(P)}`]}let y=r.windowDays??em,v=r.maxPromotionsPerWindow??$u,g=new Date(Date.now()-y*24*60*60*1e3),[h]=await d.select({n:Bw`count(*)::int`}).from(Ne).where(Uw(Fr(Ne.evalTargetId,n),Fr(Ne.applied,!0),xk(Ne.createdAt,g))),w=h?.n??0,b=sm(i),I=r.measuredAgainstContentHash===void 0?void 0:r.measuredAgainstContentHash===b,S=om({verdict:l,canaryGreen:r.canaryGreen,adequate:p,adequacyReasons:m,promotionsInWindow:w,maxPromotionsPerWindow:v,immutableSections:r.immutableSections,beforeContent:i,afterContent:c,measurementMatchesPredecessor:I}),A={canaryGreen:r.canaryGreen,adequate:p,adequacyReasons:m,promotionsInWindow:w,maxPromotionsPerWindow:v,windowDays:y,immutableSections:r.immutableSections,nPairs:a.length,measurementMatchesPredecessor:I??null,measuredAgainstContentHash:r.measuredAgainstContentHash??null,cost:r.measurementCost??null,accumulation:r.accumulation?{...r.accumulation,pairs:a}:null,applied:!1},x=S.decision==="promote"&&r.apply;A.applied=x;let T;try{T=await d.transaction(async P=>{if(x){let j=s.metadata&&typeof s.metadata=="object"&&!Array.isArray(s.metadata)?s.metadata:{};await P.update(k).set({content:c,version:(s.version??1)+1,metadata:{...j,content_hash:sm(c)},updatedAt:new Date}).where(Fr(k.id,n))}let[E]=await P.insert(Ne).values({userId:t,evalTargetId:n,fromContentHash:b,toContentHash:sm(c),fromContent:i,toContent:c,proposalSource:r.proposalSource,proposalRationale:r.proposalRationale,decision:S.decision,applied:x,refusals:S.refusals,rationale:S.rationale,effectClass:S.effect,verdict:l,gates:A,touchedSections:S.touched}).returning({id:Ne.id,createdAt:Ne.createdAt});return E})}catch(P){if(P?.code==="23505")return e.json({error:"This edit has already been applied to this target",code:"PROMOTION_ALREADY_APPLIED"},409);throw P}return e.json({id:T.id,createdAt:T.createdAt,decision:S.decision,applied:x,rationale:S.rationale,refusals:S.refusals,effectClass:S.effect,touchedSections:S.touched,verdict:l,gates:A},201)});xs.get("/eval-targets/:id/promotions",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=Math.min(Number(e.req.query("limit")??50)||50,200),o=Math.max(Number(e.req.query("offset")??0)||0,0);if(!await De(n,t))return e.json({error:"Eval target not found"},404);let i=await d.select({id:Ne.id,createdAt:Ne.createdAt,decision:Ne.decision,applied:Ne.applied,effectClass:Ne.effectClass,rationale:Ne.rationale,refusals:Ne.refusals,proposalSource:Ne.proposalSource,proposalRationale:Ne.proposalRationale,fromContentHash:Ne.fromContentHash,toContentHash:Ne.toContentHash,touchedSections:Ne.touchedSections,verdict:Ne.verdict,gates:Ne.gates}).from(Ne).where(Fr(Ne.evalTargetId,n)).orderBy(Ek(Ne.createdAt)).limit(r).offset(o),c=await d.select({decision:Ne.decision,n:Bw`count(*)::int`}).from(Ne).where(Fr(Ne.evalTargetId,n)).groupBy(Ne.decision),a={promote:0,revert:0,refuse:0};for(let l of c)a[l.decision]=l.n;return e.json({promotions:i,counts:a,total:Object.values(a).reduce((l,p)=>l+p,0),limit:r,offset:o})});xs.get("/promotions/:promotionId",async e=>{let t=e.get("userId"),n=e.req.param("promotionId"),[r]=await d.select().from(Ne).where(Uw(Fr(Ne.id,n),Fr(Ne.userId,t)));return r?e.json(r):e.json({error:"Promotion not found"},404)});import{Hono as kk}from"hono";import{z as ut}from"zod";import{eq as Cn,and as im,asc as jk,desc as Fw,isNull as Nk,inArray as Ck}from"drizzle-orm";var Eo=new kk,Pk=ut.object({jobId:ut.string().uuid().optional(),evalId:ut.string().uuid(),evalTargetId:ut.string().uuid(),evalTargetVersion:ut.number().int(),configuration:ut.enum(["with_target","without_target","baseline","with_candidate","with_prior_version"]),runNumber:ut.number().int().default(1),iteration:ut.number().int().default(1),status:ut.enum(["pending","running","completed","failed"]).default("completed"),outputs:ut.record(ut.unknown()).default({}),timing:ut.record(ut.unknown()).default({}),grading:ut.record(ut.unknown()).default({}),comparison:ut.record(ut.unknown()).nullable().optional()}),Ok=ut.object({iteration:ut.number().int().default(1),runSummary:ut.record(ut.unknown()).default({}),notes:ut.array(ut.string()).default([])});Eo.post("/eval-runs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=Pk.parse(n);if(!await De(r.evalTargetId,t))return e.json({error:"Eval target not found"},404);let[s]=await d.insert(ye).values({jobId:r.jobId??null,evalId:r.evalId,evalTargetId:r.evalTargetId,evalTargetVersion:r.evalTargetVersion,configuration:r.configuration,runNumber:r.runNumber,iteration:r.iteration,status:r.status,outputs:r.outputs,timing:r.timing,grading:r.grading,comparison:r.comparison??null}).onConflictDoNothing().returning();if(s)return e.json(s,201);if(!r.jobId)return e.json({error:"Insert conflicted without a jobId"},409);let[i]=await d.select().from(ye).where(im(Cn(ye.jobId,r.jobId),Cn(ye.evalId,r.evalId),Cn(ye.configuration,r.configuration),Cn(ye.runNumber,r.runNumber),Cn(ye.iteration,r.iteration))).limit(1);return i?e.json({...i,deduped:!0},200):e.json({error:"Run conflicted but existing row not found"},409)});Eo.get("/eval-targets/:id/runs",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.query("iteration"),o=e.req.query("configuration");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let i=e.req.query("limit"),c=e.req.query("offset"),a=i?parseInt(i,10):NaN,l=Number.isFinite(a)?Math.min(Math.max(1,a),100):50,p=c?parseInt(c,10):NaN,m=Number.isFinite(p)?Math.max(0,p):0,y=[Cn(ye.evalTargetId,n)];r&&y.push(Cn(ye.iteration,parseInt(r,10))),o&&y.push(Cn(ye.configuration,o)),e.req.query("activeCasesOnly")==="1"&&y.push(Ck(ye.evalId,d.select({id:_e.id}).from(_e).where(im(Cn(_e.evalTargetId,n),Nk(_e.retiredAt)))));let v=e.req.query("jobId");if(v){let w=ut.string().uuid().safeParse(v);if(!w.success)return e.json({error:"Invalid jobId"},400);y.push(Cn(ye.jobId,w.data))}let h=(await d.select().from(ye).where(im(...y)).orderBy(Fw(ye.createdAt),jk(ye.id)).limit(l).offset(m)).map(w=>{let b=w.outputs??{},{diff:I,...S}=b;return{...w,outputs:S,comparison:null}});return e.json(h)});Eo.post("/eval-targets/:id/benchmarks",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=Ok.parse(r);if(!await De(n,t))return e.json({error:"Eval target not found"},404);let[i]=await d.insert(kn).values({evalTargetId:n,iteration:o.iteration,runSummary:o.runSummary,notes:o.notes}).returning();return e.json(i,201)});Eo.get("/eval-targets/:id/benchmarks",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let o=await d.select().from(kn).where(Cn(kn.evalTargetId,n)).orderBy(Fw(kn.createdAt));return e.json(o)});import{Hono as Dk}from"hono";import{z as Dt}from"zod";import{eq as To,and as Ww,or as Mk,desc as Lk,asc as $k}from"drizzle-orm";import{alias as Hw}from"drizzle-orm/pg-core";var Es=new Dk,qk=Dt.object({targetAId:Dt.string().uuid(),targetBId:Dt.string().uuid(),targetAVersion:Dt.number().int(),targetBVersion:Dt.number().int(),isSwapped:Dt.boolean(),winnerTargetId:Dt.string().uuid().nullable(),perEval:Dt.array(Dt.object({evalName:Dt.string(),winnerTargetId:Dt.string().uuid().nullable(),reasoning:Dt.string().default("")})).default([]),overall:Dt.record(Dt.unknown()).default({}),rawOutput:Dt.string().nullable().optional(),model:Dt.string().nullable().optional(),status:Dt.enum(["completed","parse_failed"]).default("completed")});Es.post("/eval-comparisons",async e=>{let t=e.get("userId"),n=await e.req.json(),r=qk.parse(n),[o,s]=await Promise.all([De(r.targetAId,t),De(r.targetBId,t)]);if(!o||!s)return e.json({error:"Eval target not found"},404);let i=u(a=>a===null||a===r.targetAId||a===r.targetBId,"validWinner");if(!i(r.winnerTargetId)||!r.perEval.every(a=>i(a.winnerTargetId)))return e.json({error:"winnerTargetId must be one of the compared targets or null"},400);let[c]=await d.insert(Ke).values({userId:t,targetAId:r.targetAId,targetBId:r.targetBId,targetAVersion:r.targetAVersion,targetBVersion:r.targetBVersion,isSwapped:r.isSwapped,winnerTargetId:r.winnerTargetId,perEval:r.perEval,overall:r.overall,rawOutput:r.rawOutput??null,model:r.model??null,status:r.status}).returning();return e.json(c,201)});Es.get("/eval-targets/:id/comparisons",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let o=e.req.query("limit"),s=e.req.query("offset"),i=o?parseInt(o,10):NaN,c=Number.isFinite(i)?Math.min(Math.max(1,i),100):50,a=s?parseInt(s,10):NaN,l=Number.isFinite(a)?Math.max(0,a):0,p=Hw(k,"targets_a"),m=Hw(k,"targets_b"),y=await d.select({id:Ke.id,userId:Ke.userId,targetAId:Ke.targetAId,targetBId:Ke.targetBId,targetAName:p.name,targetBName:m.name,targetAVersion:Ke.targetAVersion,targetBVersion:Ke.targetBVersion,isSwapped:Ke.isSwapped,winnerTargetId:Ke.winnerTargetId,perEval:Ke.perEval,overall:Ke.overall,model:Ke.model,status:Ke.status,createdAt:Ke.createdAt}).from(Ke).innerJoin(p,To(Ke.targetAId,p.id)).innerJoin(m,To(Ke.targetBId,m.id)).where(Ww(To(Ke.userId,t),Mk(To(Ke.targetAId,n),To(Ke.targetBId,n)))).orderBy(Lk(Ke.createdAt),$k(Ke.id)).limit(c).offset(l);return e.json(y.map(v=>({...v,rawOutput:null})))});Es.get("/eval-comparisons/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=Dt.string().uuid().safeParse(n);if(!r.success)return e.json({error:"Invalid comparison id"},400);let[o]=await d.select().from(Ke).where(Ww(To(Ke.id,r.data),To(Ke.userId,t)));return o?e.json(o):e.json({error:"Comparison not found"},404)});import{Hono as Hk}from"hono";import{z as Ts}from"zod";import{eq as Rs,and as am,desc as Wk,asc as zk,inArray as Vk,sql as Jk}from"drizzle-orm";import{sql as Uk}from"drizzle-orm";function zw(e){if(e.n===0)return null;let t=e.agree/e.n,n=e.aYes/e.n,r=e.bYes/e.n,o=n*r+(1-n)*(1-r);return o>=1?null:(t-o)/(1-o)}u(zw,"kappaFromCounts");var Vw=u((e,t)=>({agree:e,total:t,rate:t>0?e/t:null}),"slice");function Bk(e){let t=e.pairs>0?e.agreeHuman/e.pairs:null;return{engine:e.reviewerEngine,models:e.models,pairs:e.pairs,orphaned:e.orphaned,agreementRate:t,kappa:zw({n:e.pairs,agree:e.agreeHuman,aYes:e.humanYes,bYes:e.reviewerYes}),snapshotAgreementRate:e.pairs>0?e.snapshotAgree/e.pairs:null,snapshotKappa:zw({n:e.pairs,agree:e.snapshotAgree,aYes:e.snapshotHumanYes,bYes:e.reviewerYes}),judgeAgreementRate:e.pairs>0?e.judgeAgreeHuman/e.pairs:null,onJudgePass:Vw(e.judgePassAgree,e.judgePassPairs),onJudgeFail:Vw(e.agreeHuman-e.judgePassAgree,e.pairs-e.judgePassPairs),suggestedAnchorWeight:t==null?null:Math.max(0,2*t-1)**2,unresolvedFlags:e.unresolvedFlags,kept:e.kept,relabeled:e.relabeled,lastReviewedAt:e.lastReviewedAt}}u(Bk,"reviewerAgreementReport");async function Jw(e){return(await d.execute(Uk`
|
|
776
776
|
SELECT
|
|
777
777
|
j.reviewer_engine,
|
|
778
778
|
array_agg(DISTINCT j.reviewer_model) AS models,
|
|
@@ -804,7 +804,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
804
804
|
) j
|
|
805
805
|
GROUP BY j.reviewer_engine
|
|
806
806
|
ORDER BY j.reviewer_engine
|
|
807
|
-
`)).map(n=>
|
|
807
|
+
`)).map(n=>Bk({reviewerEngine:n.reviewer_engine,models:n.models,pairs:n.pairs,orphaned:n.orphaned,agreeHuman:n.agree_human,humanYes:n.human_yes,reviewerYes:n.reviewer_yes,judgeAgreeHuman:n.judge_agree_human,judgePassPairs:n.judge_pass_pairs,judgePassAgree:n.judge_pass_agree,snapshotAgree:n.snapshot_agree,snapshotHumanYes:n.snapshot_human_yes,unresolvedFlags:n.unresolved_flags,kept:n.kept,relabeled:n.relabeled,lastReviewedAt:n.last_reviewed_at}))}u(Jw,"computeReviewerAgreement");import{eq as Fk}from"drizzle-orm";async function ga(e,t,n={}){let{nudge:r=!0}=n;try{let[o]=await d.select({name:k.name,userId:k.userId}).from(k).where(Fk(k.id,t));if(!o||o.userId!==e)return;let s=await As(e,t);if(s.powerCheck.adequate){await tn({userId:e,type:"calibration_ready",title:"Anchor set adequate \u2014 calibrated verdicts unlocked",body:`${o.name}: enough human labels for a calibrated judge verdict. Automated updates (optimize / auto-run) can now be trusted on this target.`,url:`/eval-targets/${t}?tab=review`,sourceTable:"eval_targets",sourceId:`calibration:${t}:${s.pooling.judgeModel??"unstamped"}`,metadata:{evalTargetId:t,judgeModel:s.pooling.judgeModel,labeledRuns:s.anchors.labeledRuns,pooled:s.pooling.engaged}});let a=await xu(e);a&&!(a.claude&&a.codex)&&await tn({userId:e,type:"second_engine_needed",title:"Add a second engine to validate your judge",body:`${o.name}: your judge is calibrated. Cross-vendor validation (rulemetric evals validate-judge) needs a second LLM engine \u2014 `+(a.codex?"the claude CLI was not detected on your worker machine.":"install the Codex CLI (npm install -g @openai/codex) on your worker machine."),url:"/connect",sourceTable:"profiles",sourceId:"second-engine",metadata:{evalTargetId:t,engines:a}});return}if(!r)return;let i=await qw(t);if(i<=0)return;let c=s.powerCheck.reasons[0];await tn({userId:e,type:"labels_needed",title:"Review needed to calibrate the judge",body:`${o.name}: ${i} graded output${i===1?"":"s"} awaiting your review.${c?` ${c}.`:""}`,url:`/eval-targets/${t}?tab=review`,sourceTable:"eval_targets",sourceId:`labels:${t}:${new Date().toISOString().slice(0,10)}`,metadata:{evalTargetId:t,remaining:i}})}catch(o){console.error("[label-notifications] notify failed:",o instanceof Error?o.stack:o)}}u(ga,"notifyLabelState");var mr=new Hk,Gk=Ts.object({verdict:Ts.enum(["approve","reject"]),flag:Ts.enum(["bad_grade","bad_assertion"]).nullable().optional(),note:Ts.string().max(2e3).nullable().optional()});async function Gw(e,t){let n=Ts.string().uuid().safeParse(e);if(!n.success)return null;let[r]=await d.select().from(ye).where(Rs(ye.id,n.data));return r&&await De(r.evalTargetId,t)?r:null}u(Gw,"loadOwnedRun");mr.put("/eval-runs/:runId/annotations/:index",async e=>{let t=e.get("userId"),n=e.req.param("runId"),r=e.req.param("index"),o=Gk.parse(await e.req.json()),s=parseInt(r,10);if(!Number.isInteger(s)||s<0||String(s)!==r)return e.json({error:"Invalid expectation index"},400);let i=await Gw(n,t);if(!i)return e.json({error:"Eval run not found"},404);let c=i.grading.expectations;if(!Array.isArray(c)||s>=c.length)return e.json({error:"Expectation index out of range for this run"},400);let a=c[s];if(typeof a?.passed!="boolean")return e.json({error:"Expectation has no grade to annotate"},400);if(a.errored===!0)return e.json({error:"Expectation errored during grading \u2014 no judge verdict exists to annotate"},400);let l=a.method==="deterministic"?"deterministic":"llm",p=i.grading.judge_model??null,[m]=await d.insert(ze).values({userId:t,evalRunId:i.id,evalTargetId:i.evalTargetId,expectationIndex:s,expectationText:a.text??"",judgePassed:a.passed,judgeMethod:l,judgeModel:p,verdict:o.verdict,flag:o.flag??null,note:o.note??null}).onConflictDoUpdate({target:[ze.evalRunId,ze.expectationIndex],set:{verdict:o.verdict,...o.flag!==void 0?{flag:o.flag}:{},...o.note!==void 0?{note:o.note}:{},expectationText:a.text??"",judgePassed:a.passed,judgeMethod:l,judgeModel:p,updatedAt:new Date}}).returning();await ga(t,i.evalTargetId,{nudge:!1});try{await zy({evalTargetId:i.evalTargetId,userId:t})}catch(y){console.error("[eval-annotations] judge-review enqueue failed:",y instanceof Error?y.message:y)}return e.json(m)});mr.delete("/eval-runs/:runId/annotations/:index",async e=>{let t=e.get("userId"),n=e.req.param("runId"),r=parseInt(e.req.param("index"),10);if(!Number.isInteger(r)||r<0)return e.json({error:"Invalid expectation index"},400);let o=await Gw(n,t);return o?(await d.delete(ze).where(am(Rs(ze.evalRunId,o.id),Rs(ze.expectationIndex,r))).returning({id:ze.id})).length===0?e.json({error:"Annotation not found"},404):e.json({deleted:!0}):e.json({error:"Eval run not found"},404)});mr.post("/eval-targets/:id/label-state",async e=>{let t=e.get("userId"),n=e.req.param("id");return await De(n,t)?(await ga(t,n),e.json({ok:!0})):e.json({error:"Eval target not found"},404)});mr.get("/eval-targets/:id/annotations",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let o=e.req.query("limit"),s=e.req.query("offset"),i=o?parseInt(o,10):NaN,c=Number.isFinite(i)?Math.min(Math.max(1,i),500):200,a=s?parseInt(s,10):NaN,l=Number.isFinite(a)?Math.max(0,a):0,p=[Rs(ze.evalTargetId,n)],m=e.req.query("runId");if(m){let v=Ts.string().uuid().safeParse(m);if(!v.success)return e.json({error:"Invalid runId"},400);p.push(Rs(ze.evalRunId,v.data))}let y=await d.select().from(ze).where(am(...p)).orderBy(Wk(ze.createdAt),zk(ze.id)).limit(c).offset(l);return e.json(y)});mr.get("/eval-targets/:id/judge-calibration",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let[o,s]=await Promise.all([As(t,n),Jw(n)]);return e.json({...o,reviewers:s})});mr.get("/eval-targets/:id/annotation-queue",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let o=e.req.query("limit"),s=o?parseInt(o,10):NaN,i=Number.isFinite(s)?Math.min(Math.max(1,s),20):5,c=await d.execute(Jk`
|
|
808
808
|
WITH current_judge AS (
|
|
809
809
|
-- Same definition as judge-calibration: most recently stamped run's
|
|
810
810
|
-- model; empty (NULL) until any grading carries judge_model. Labeling a
|
|
@@ -849,36 +849,36 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
849
849
|
WHERE llm_total > llm_annotated
|
|
850
850
|
ORDER BY (llm_annotated > 0) DESC, random()
|
|
851
851
|
LIMIT ${i}
|
|
852
|
-
`),a=c.map(m=>m.id),l=a.length?await d.select().from(ze).where(am(
|
|
852
|
+
`),a=c.map(m=>m.id),l=a.length?await d.select().from(ze).where(am(Rs(ze.evalTargetId,n),Vk(ze.evalRunId,a))):[],p=new Map(l.map(m=>[`${m.evalRunId}:${m.expectationIndex}`,m]));return e.json({remaining:c[0]?.remaining??0,runs:c.map(m=>({id:m.id,configuration:m.configuration,runNumber:m.run_number,iteration:m.iteration,createdAt:m.created_at,evalName:m.eval_name,prompt:m.prompt,output:m.output,outputTruncated:m.output_truncated,expectations:(m.expectations??[]).map((y,v)=>{let g=p.get(`${m.id}:${v}`);return{index:v,text:y.text??"",passed:y.passed??!1,evidence:y.evidence??"",method:y.method==="deterministic"?"deterministic":"llm",errored:y.errored===!0,annotation:g?{verdict:g.verdict,flag:g.flag}:null}})}))})});import{Hono as Kk}from"hono";import{z as rn}from"zod";import{eq as bn,and as ha,isNull as cm,sql as ks,inArray as Yk}from"drizzle-orm";var Ro=new Kk,Xk=rn.object({evalRunId:rn.string().uuid(),expectationIndex:rn.number().int().min(0),expectationText:rn.string(),judgePassed:rn.boolean(),humanPassed:rn.boolean(),reviewerPassed:rn.boolean()}),Qk=rn.object({reviewerEngine:rn.enum(["claude","codex"]),reviewerModel:rn.string().min(1).max(200),verdicts:rn.array(Xk).min(1).max(500)});Ro.put("/eval-targets/:id/judge-reviews",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let o=Qk.parse(await e.req.json()),s=[...new Set(o.verdicts.map(a=>a.evalRunId))];if((await d.select({id:ye.id}).from(ye).where(ha(Yk(ye.id,s),bn(ye.evalTargetId,n)))).length!==s.length)return e.json({error:"One or more runs do not belong to this target"},400);let c=0;for(let a of o.verdicts)await d.insert(ce).values({userId:t,evalTargetId:n,evalRunId:a.evalRunId,expectationIndex:a.expectationIndex,expectationText:a.expectationText,judgePassed:a.judgePassed,humanPassed:a.humanPassed,reviewerEngine:o.reviewerEngine,reviewerModel:o.reviewerModel,reviewerPassed:a.reviewerPassed}).onConflictDoUpdate({target:[ce.evalRunId,ce.expectationIndex,ce.reviewerModel],set:{expectationText:a.expectationText,judgePassed:a.judgePassed,humanPassed:a.humanPassed,reviewerEngine:o.reviewerEngine,reviewerPassed:a.reviewerPassed,resolvedAt:ks`CASE WHEN ${ce.reviewerPassed} <> ${a.reviewerPassed} THEN NULL ELSE ${ce.resolvedAt} END`,resolution:ks`CASE WHEN ${ce.reviewerPassed} <> ${a.reviewerPassed} THEN NULL ELSE ${ce.resolution} END`,updatedAt:new Date}}),c+=1;if(o.verdicts.some(a=>a.reviewerPassed!==a.humanPassed))try{let[{count:a}]=await d.select({count:ks`count(*)::int`}).from(ce).where(ha(bn(ce.evalTargetId,n),cm(ce.resolvedAt),ks`${ce.reviewerPassed} <> ${ce.humanPassed}`));if(a>0){let[l]=await d.select({name:k.name}).from(k).where(bn(k.id,n));await tn({userId:t,type:"second_opinions_flagged",title:"Second opinions flag some of your labels",body:`${l?.name??"Eval target"}: a ${o.reviewerModel} review pass disagrees with ${a} of your label${a===1?"":"s"} \u2014 worth a second look; genuine judge errors become reject anchors.`,url:`/eval-targets/${n}?tab=review`,sourceTable:"eval_targets",sourceId:`second-opinions:${n}:${new Date().toISOString().slice(0,10)}`,metadata:{evalTargetId:n,unresolved:a,reviewerModel:o.reviewerModel}})}}catch(a){console.error("[judge-reviews] flag notification failed:",a instanceof Error?a.message:a)}return e.json({upserted:c})});Ro.get("/eval-targets/:id/judge-reviews",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let o=await d.select({evalRunId:ce.evalRunId,expectationIndex:ce.expectationIndex,reviewerEngine:ce.reviewerEngine,reviewerModel:ce.reviewerModel,reviewerPassed:ce.reviewerPassed,humanPassed:ce.humanPassed,resolvedAt:ce.resolvedAt}).from(ce).where(bn(ce.evalTargetId,n));return e.json(o)});Ro.get("/eval-targets/:id/judge-reviews/disagreements",async e=>{let t=e.get("userId"),n=e.req.param("id");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let o=await d.select({id:ce.id,evalRunId:ce.evalRunId,expectationIndex:ce.expectationIndex,expectationText:ce.expectationText,judgePassed:ce.judgePassed,humanPassed:ce.humanPassed,reviewerEngine:ce.reviewerEngine,reviewerModel:ce.reviewerModel,reviewerPassed:ce.reviewerPassed,evalName:_e.name,configuration:ye.configuration,runNumber:ye.runNumber,outputExcerpt:ks`LEFT(${ye.outputs}->>'transcript', 1200)`}).from(ce).innerJoin(ye,bn(ye.id,ce.evalRunId)).leftJoin(_e,bn(_e.id,ye.evalId)).where(ha(bn(ce.evalTargetId,n),cm(ce.resolvedAt),ks`${ce.reviewerPassed} <> ${ce.humanPassed}`)).orderBy(ce.evalRunId,ce.expectationIndex);return e.json(o)});var Zk=rn.object({resolution:rn.enum(["kept","relabeled"])});Ro.patch("/judge-reviews/:id/resolve",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=rn.string().uuid().safeParse(n);if(!r.success)return e.json({error:"Invalid id"},400);let o=Zk.parse(await e.req.json()),[s]=await d.select().from(ce).where(ha(bn(ce.id,r.data),bn(ce.userId,t)));if(!s)return e.json({error:"Not found"},404);let i=await d.update(ce).set({resolvedAt:new Date,resolution:o.resolution,updatedAt:new Date}).where(ha(bn(ce.evalRunId,s.evalRunId),bn(ce.expectationIndex,s.expectationIndex),bn(ce.userId,t),cm(ce.resolvedAt))).returning({id:ce.id});return e.json({resolved:i.length})});import{Hono as ej}from"hono";import{z as jt}from"zod";import{eq as js,and as Kw,desc as tj}from"drizzle-orm";var Ns=new ej,nj=jt.object({queries:jt.array(jt.object({query:jt.string().min(1),should_trigger:jt.boolean()})).min(1),trainIndices:jt.array(jt.number().int()).default([]),testIndices:jt.array(jt.number().int()).default([])}),rj=jt.object({queries:jt.array(jt.object({query:jt.string().min(1),should_trigger:jt.boolean()})).optional(),status:jt.enum(["pending_review","approved"]).optional(),trainIndices:jt.array(jt.number().int()).optional(),testIndices:jt.array(jt.number().int()).optional()});Ns.post("/eval-targets/:id/trigger-evals",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=nj.parse(r);if(!await De(n,t))return e.json({error:"Eval target not found"},404);let[i]=await d.insert(Ct).values({evalTargetId:n,userId:t,queries:o.queries,trainIndices:o.trainIndices,testIndices:o.testIndices}).returning();return e.json(i,201)});Ns.get("/eval-targets/:id/trigger-evals",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.query("status");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let s=[js(Ct.evalTargetId,n),js(Ct.userId,t)];r&&s.push(js(Ct.status,r));let i=await d.select().from(Ct).where(Kw(...s)).orderBy(tj(Ct.createdAt));return e.json(i)});Ns.put("/trigger-evals/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=rj.parse(r),[s]=await d.select().from(Ct).where(Kw(js(Ct.id,n),js(Ct.userId,t)));if(!s)return e.json({error:"Trigger eval not found"},404);let i={updatedAt:new Date};o.queries&&(i.queries=o.queries),o.status&&(i.status=o.status),o.trainIndices&&(i.trainIndices=o.trainIndices),o.testIndices&&(i.testIndices=o.testIndices);let[c]=await d.update(Ct).set(i).where(js(Ct.id,n)).returning();return e.json(c)});import{Hono as oj}from"hono";import{z as Pn}from"zod";import{eq as Yw,and as sj,desc as ij}from"drizzle-orm";var _a=new oj,aj=Pn.object({evalTargetId:Pn.string().uuid(),type:Pn.enum(["content","description"]),iteration:Pn.number().int(),inputVersion:Pn.number().int(),outputVersion:Pn.number().int().nullable().optional(),trainScore:Pn.number().nullable().optional(),testScore:Pn.number().nullable().optional(),analysis:Pn.record(Pn.unknown()).default({}),status:Pn.enum(["running","completed","failed"]).default("running")});_a.post("/optimization-runs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=aj.parse(n);if(!await De(r.evalTargetId,t))return e.json({error:"Eval target not found"},404);let[s]=await d.insert(hn).values({evalTargetId:r.evalTargetId,userId:t,type:r.type,iteration:r.iteration,inputVersion:r.inputVersion,outputVersion:r.outputVersion??null,trainScore:r.trainScore??null,testScore:r.testScore??null,analysis:r.analysis,status:r.status}).returning();return e.json(s,201)});_a.get("/eval-targets/:id/optimization-runs",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.query("type");if(!await De(n,t))return e.json({error:"Eval target not found"},404);let s=[Yw(hn.evalTargetId,n)];r&&s.push(Yw(hn.type,r));let i=await d.select().from(hn).where(sj(...s)).orderBy(ij(hn.createdAt));return e.json(i)});import{createHash as uj}from"node:crypto";import{Hono as dj}from"hono";import{z as Z}from"zod";import{eq as Jt,and as Cs,desc as dm,asc as lj,sql as Gn,isNull as pj}from"drizzle-orm";import{alias as Xw}from"drizzle-orm/pg-core";function cj(e){if(e===null||typeof e!="object")return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}u(cj,"isPlainObject");function qu(e){if(typeof e=="string")return e.indexOf("\0")===-1?e:e.split("\0").join("");if(Array.isArray(e)){let t=null;for(let n=0;n<e.length;n++){let r=qu(e[n]);t===null&&r!==e[n]&&(t=e.slice(0,n)),t!==null&&t.push(r)}return t??e}if(cj(e)){let t=Object.entries(e),n=null;for(let r=0;r<t.length;r++){let[o,s]=t[r],i=o.indexOf("\0")===-1?o:o.split("\0").join(""),c=qu(s);if(n===null&&(i!==o||c!==s)){n={};for(let a=0;a<r;a++)n[t[a][0]]=t[a][1]}n!==null&&(n[i]=c)}return n??e}return e}u(qu,"stripNullBytes");_u();function mj(){return{enabled:process.env.RULEMETRIC_OFFLOAD_DELTAS==="1"||process.env.RULEMETRIC_OFFLOAD_DELTAS==="true",thresholdBytes:Number(process.env.OFFLOAD_GZIP_THRESHOLD_BYTES)||49152}}u(mj,"offloadConfig");function Qw(e){return uj("sha256").update(JSON.stringify(e)).digest("hex")}u(Qw,"hashJson");function Zw(e,t){return Array.isArray(e)?e:Array.isArray(t)?t:[]}u(Zw,"arrayOr");function ev(e,t){return Gn`COALESCE(
|
|
853
853
|
CASE WHEN jsonb_typeof(${e}) = 'array' THEN ${e} END,
|
|
854
854
|
CASE WHEN jsonb_typeof(${t}) = 'array' THEN ${t} END,
|
|
855
855
|
'[]'::jsonb
|
|
856
|
-
)`}u(
|
|
856
|
+
)`}u(ev,"resolvedJsonArray");async function fj(e){let{enabled:t,thresholdBytes:n}=mj();if(!t||e.length===0)return{messagesDelta:e,messagesDeltaRef:null};let r=Ep(e);if(r.bytes<=n)return{messagesDelta:e,messagesDeltaRef:null};try{let{ref:o}=await Tp(r);return{messagesDelta:null,messagesDeltaRef:o}}catch(o){return console.error("[context-snapshots] delta offload failed, writing inline:",o instanceof Error?o.message:o),{messagesDelta:e,messagesDeltaRef:null}}}u(fj,"resolveDeltaStorage");async function um(e,t,n){let r=JSON.stringify(n);await d.insert(cn).values({hash:e,contentType:t,content:n,sizeBytes:Buffer.byteLength(r,"utf-8")}).onConflictDoNothing()}u(um,"upsertBlob");var Ps=new dj,gj=Z.object({provider:Z.string(),model:Z.string(),system_prompt:Z.string(),system_blocks:Z.array(Z.unknown()).default([]),injected_instructions:Z.union([Z.array(Z.string()),Z.string()]).default([]),messages:Z.array(Z.unknown()).optional(),messages_raw:Z.array(Z.unknown()).optional(),messages_summary:Z.unknown().optional(),tools:Z.array(Z.unknown()).default([]),system_hash:Z.string(),request_hash:Z.string().optional(),sequence:Z.number().int().optional(),max_tokens:Z.number().nullable().optional(),temperature:Z.number().nullable().optional(),top_p:Z.number().nullable().optional(),top_k:Z.number().nullable().optional(),stop_sequences:Z.array(Z.string()).optional(),stream:Z.boolean().optional(),tool_choice:Z.unknown().optional(),thinking:Z.unknown().optional(),api_metadata:Z.unknown().optional(),request_headers:Z.record(Z.string()).optional(),response_headers:Z.record(Z.string()).optional(),response_status:Z.number().optional(),beta_features:Z.array(Z.string()).optional(),usage:Z.object({input_tokens:Z.number().nullable().optional(),output_tokens:Z.number().nullable().optional(),cache_creation_input_tokens:Z.number().nullable().optional(),cache_read_input_tokens:Z.number().nullable().optional(),total_tokens:Z.number().nullable().optional()}).optional(),response:Z.record(Z.unknown()).optional(),estimated_tokens:Z.number().nullable().optional(),captured_at:Z.string().optional(),metadata:Z.record(Z.unknown()).optional(),context_items:Z.array(Z.object({type:Z.string(),name:Z.string(),content_hash:Z.string().optional(),char_count:Z.number().optional(),estimated_tokens:Z.number().optional(),triggered_by:Z.string().optional(),message_index:Z.number().optional(),preview:Z.string().optional(),skill_names:Z.array(Z.string()).optional(),tool_names:Z.array(Z.string()).optional()}).passthrough()).optional()}),hj=100,_j=500;async function tv(e,t){let[n]=await d.select({id:C.id,sequence:C.sequence}).from(C).where(Cs(Jt(C.sessionId,e),Jt(C.requestHash,t))).limit(1);return n??null}u(tv,"findSnapshotByHash");Ps.post("/sessions/:id/context-snapshots",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),o=qu(gj.parse(r)),[s]=await d.select({id:f.id,projectPath:f.projectPath,projectId:f.projectId}).from(f).where(Cs(Jt(f.id,n),Jt(f.userId,t)));if(!s)return e.json({error:"Session not found"},404);if(!s.projectPath&&o.context_items?.length){let g=o.context_items.find(h=>h.type==="claude_md"&&typeof h.name=="string"&&h.name.startsWith("/")&&h.name.endsWith("/CLAUDE.md"));if(g){let h=g.name.slice(0,-10),w=null;if(!s.projectId){let[b]=await d.select({projectId:ue.projectId}).from(ue).where(Jt(ue.path,h)).limit(1);w=b?.projectId??null}await d.update(f).set({projectPath:h,...w?{projectId:w}:{}}).where(Cs(Jt(f.id,n),pj(f.projectPath)))}}let i=o.messages??o.messages_summary??[],c=o.messages_raw??[],a=o.request_hash??"",l=Array.isArray(o.injected_instructions)?o.injected_instructions:[o.injected_instructions];if(a){let g=await tv(n,a);if(g)return e.json({id:g.id,sequence:g.sequence,deduplicated:!0})}let p=Qw(o.tools),m=Qw(l);await Promise.all([um(o.system_hash,"system_prompt",o.system_prompt),um(p,"tools",o.tools),um(m,"injected_instructions",l)]);let y={sessionId:n,userId:t,provider:o.provider,model:o.model,systemPrompt:"",injectedInstructions:[],messagesSummary:i,tools:[],systemHash:o.system_hash,toolsHash:p,injectedHash:m,requestHash:a,maxTokens:o.max_tokens??null,temperature:o.temperature??null,estimatedTokens:o.estimated_tokens??null,capturedAt:o.captured_at?new Date(o.captured_at):new Date,metadata:{...o.metadata,...o.context_items?.length&&{contextItems:o.context_items},...o.top_p!=null&&{topP:o.top_p},...o.top_k!=null&&{topK:o.top_k},...o.stop_sequences?.length&&{stopSequences:o.stop_sequences},...o.stream!=null&&{stream:o.stream},...o.tool_choice!=null&&{toolChoice:o.tool_choice},...o.thinking!=null&&{thinking:o.thinking},...o.api_metadata!=null&&{apiMetadata:o.api_metadata},...o.request_headers!=null&&{requestHeaders:o.request_headers},...o.response_headers!=null&&{responseHeaders:o.response_headers},...o.response_status!=null&&{responseStatus:o.response_status},...o.beta_features?.length&&{betaFeatures:o.beta_features},...o.usage!=null&&{usage:o.usage},...o.response!=null&&{response:o.response}}},v=5;for(let g=0;g<=v;g++){let[h]=await d.select({sequence:C.sequence,messagesSummary:C.messagesSummary}).from(C).where(Jt(C.sessionId,n)).orderBy(dm(C.sequence)).limit(1),w=(h?.sequence??-1)+1,b=Array.isArray(h?.messagesSummary)?h.messagesSummary:[],I=c,S=0,A=Math.min(b.length,I.length);for(;S<A&&JSON.stringify(b[S])===JSON.stringify(I[S]);)S++;let x=I.slice(S),T=await fj(x);try{let[P]=await d.insert(C).values({...y,sequence:w,...T}).returning({id:C.id,sequence:C.sequence});return e.json({id:P.id,sequence:P.sequence},201)}catch(P){let E=P.cause,j=E?.constraint_name??"",O=`${P instanceof Error?P.message:""} ${E?.message??""}`.toLowerCase();if(E?.code==="23505"){if((j==="idx_snapshots_session_request"||O.includes("request"))&&a){let F=await tv(n,a);if(F)return e.json({id:F.id,sequence:F.sequence,deduplicated:!0})}if(g<v)continue;return e.json({error:"snapshot sequence assignment failed after retries"},503)}if(O.includes("foreign key"))return e.json({error:"Session no longer exists"},404);throw P}}return e.json({error:"snapshot sequence assignment failed after retries"},503)});Ps.get("/sessions/:id/context-snapshots",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=Number(e.req.query("limit")||hj),o=Math.min(Math.max(1,r),_j),s=Math.max(0,Number(e.req.query("offset")||0)),[i]=await d.select({id:f.id}).from(f).where(Cs(Jt(f.id,n),Jt(f.userId,t)));if(!i)return e.json({error:"Session not found"},404);if(!(e.req.query("full")==="true")){let l=Xw(cn,"cb_tools"),p=Xw(cn,"cb_injected"),y=(await d.select({id:C.id,sessionId:C.sessionId,userId:C.userId,sequence:C.sequence,provider:C.provider,model:C.model,systemHash:C.systemHash,requestHash:C.requestHash,maxTokens:C.maxTokens,temperature:C.temperature,estimatedTokens:C.estimatedTokens,capturedAt:C.capturedAt,injectedCount:Gn`jsonb_array_length(${ev(p.content,C.injectedInstructions)})`,toolsLight:Gn`COALESCE((
|
|
857
857
|
SELECT jsonb_agg(jsonb_build_object('name', t->'name', 'description', left(COALESCE(t->>'description', ''), 80)))
|
|
858
|
-
FROM jsonb_array_elements(${
|
|
859
|
-
), '[]'::jsonb)`,metadataLight:
|
|
860
|
-
'usage', ${
|
|
861
|
-
'response', ${
|
|
862
|
-
'thinking', ${
|
|
863
|
-
'stream', ${
|
|
864
|
-
'betaFeatures', ${
|
|
865
|
-
'responseStatus', ${
|
|
866
|
-
'apiMetadata', ${
|
|
858
|
+
FROM jsonb_array_elements(${ev(l.content,C.tools)}) AS t
|
|
859
|
+
), '[]'::jsonb)`,metadataLight:Gn`jsonb_strip_nulls(jsonb_build_object(
|
|
860
|
+
'usage', ${C.metadata}->'usage',
|
|
861
|
+
'response', ${C.metadata}->'response',
|
|
862
|
+
'thinking', ${C.metadata}->'thinking',
|
|
863
|
+
'stream', ${C.metadata}->'stream',
|
|
864
|
+
'betaFeatures', ${C.metadata}->'betaFeatures',
|
|
865
|
+
'responseStatus', ${C.metadata}->'responseStatus',
|
|
866
|
+
'apiMetadata', ${C.metadata}->'apiMetadata',
|
|
867
867
|
'contextItems', CASE
|
|
868
|
-
WHEN jsonb_typeof(${
|
|
868
|
+
WHEN jsonb_typeof(${C.metadata}->'contextItems') = 'array' THEN (
|
|
869
869
|
SELECT jsonb_agg(jsonb_build_object('type', ci->'type', 'name', ci->'name', 'estimated_tokens', ci->'estimated_tokens'))
|
|
870
|
-
FROM jsonb_array_elements(${
|
|
870
|
+
FROM jsonb_array_elements(${C.metadata}->'contextItems') AS ci
|
|
871
871
|
)
|
|
872
872
|
ELSE NULL
|
|
873
873
|
END
|
|
874
|
-
))`}).from(
|
|
874
|
+
))`}).from(C).leftJoin(l,Jt(l.hash,C.toolsHash)).leftJoin(p,Jt(p.hash,C.injectedHash)).where(Jt(C.sessionId,n)).orderBy(dm(C.capturedAt)).limit(o).offset(s)).map(v=>({id:v.id,sessionId:v.sessionId,userId:v.userId,sequence:v.sequence,provider:v.provider,model:v.model,systemHash:v.systemHash,requestHash:v.requestHash,maxTokens:v.maxTokens,temperature:v.temperature,estimatedTokens:v.estimatedTokens,capturedAt:v.capturedAt,metadata:v.metadataLight??{},systemPrompt:"",messagesSummary:[],tools:v.toolsLight??[],injectedInstructions:new Array(Number(v.injectedCount??0)).fill("[omitted]")}));return e.json(y)}let a=await ft.select().from(C).where(Jt(C.sessionId,n)).orderBy(dm(C.capturedAt)).limit(o).offset(s);return e.json(await cw(await Rp(a)))});Ps.get("/context-snapshots/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await ft.select().from(C).where(Cs(Jt(C.id,n),Jt(C.userId,t)));if(!r)return e.json({error:"Snapshot not found"},404);let o=r.messagesDeltaRef?await ra(r.messagesDeltaRef):r.messagesDelta;if(r.systemPrompt||r.tools?.length>0)return e.json(r.messagesDeltaRef?{...r,messagesDelta:o}:r);let s=[r.systemHash,r.toolsHash,r.injectedHash].filter(Boolean),i=s.length>0?await d.select().from(cn).where(Gn`${cn.hash} IN (${Gn.join(s.map(p=>Gn`${p}`),Gn`, `)})`):[],c=new Map(i.map(p=>[p.hash,p.content])),a=[],l=!1;if(o){let{messages:p,truncated:m}=await fu({fetchPage:u(async(y,v)=>oa(await ft.select({sequence:C.sequence,messagesDelta:C.messagesDelta,messagesDeltaRef:C.messagesDeltaRef}).from(C).where(Cs(Jt(C.sessionId,r.sessionId),Gn`${C.sequence} <= ${r.sequence}`,Gn`${C.sequence} > ${y}`)).orderBy(lj(C.sequence)).limit(v)),"fetchPage")});a=p,l=m}return e.json({...r,systemPrompt:c.get(r.systemHash)??r.systemPrompt??"",tools:Zw(c.get(r.toolsHash??""),r.tools),injectedInstructions:Zw(c.get(r.injectedHash??""),r.injectedInstructions),messagesDelta:o,messagesRaw:a,messagesTruncated:l})});import{Hono as yj}from"hono";import{z as Hr}from"zod";import{eq as On,and as ya,desc as wj,ne as vj}from"drizzle-orm";import{z as Kn}from"zod";var Uu=Kn.object({parallel:Kn.number().int().positive().default(1),runsPerEval:Kn.number().int().positive().default(1),iteration:Kn.number().int().positive().default(1),skipBaseline:Kn.boolean().default(!1),skipGrading:Kn.boolean().default(!1),generateIfEmpty:Kn.boolean().default(!1),model:Kn.string().optional(),graderModel:Kn.string().optional(),timeout:Kn.number().int().positive().default(12e4)}).default({});var Wr=new yj,Ij=Hr.object({evalTargetId:Hr.string().uuid(),config:Uu});Wr.post("/eval-jobs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=Ij.parse(n),{id:o,noLiveWorker:s}=await kt({taskName:"process_eval",payload:{evalTargetId:r.evalTargetId,config:r.config},userId:t,mirror:{userId:t,evalTargetId:r.evalTargetId,config:r.config}}),[i]=await d.select().from(Se).where(On(Se.id,o));return e.json({...i,noLiveWorker:s},201)});Wr.get("/eval-targets/:id/jobs",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await d.select().from(Se).where(ya(On(Se.evalTargetId,n),On(Se.userId,t))).orderBy(wj(Se.createdAt));return e.json(r)});Wr.patch("/eval-jobs/:id/progress",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),s=["running","paused"].includes(r.status)?r.status:"running",[i]=await d.update(Se).set({status:s,progress:r.progress,updatedAt:new Date}).where(ya(On(Se.id,n),On(Se.userId,t))).returning();return i?e.json(i):e.json({error:"Job not found"},404)});var bj=Hr.object({status:Hr.enum(["running","completed","failed"]).optional(),attempts:Hr.number().int().nonnegative().optional(),error:Hr.string().optional(),result:Hr.record(Hr.unknown()).optional()});Wr.patch("/eval-jobs/:id/state",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=bj.parse(await e.req.json()),o={updatedAt:new Date};r.attempts!==void 0&&(o.attempts=r.attempts),r.status&&(o.status=r.status),r.error&&(o.error=r.error),r.result!==void 0&&(o.result=r.result),(r.status==="completed"||r.status==="failed")&&(o.completedAt=new Date);let[s]=await d.update(Se).set(o).where(ya(On(Se.id,n),On(Se.userId,t),vj(Se.status,"cancelled"))).returning();if(!s){let[i]=await d.select().from(Se).where(ya(On(Se.id,n),On(Se.userId,t)));return i?e.json(i):e.json({error:"Job not found"},404)}return e.json(s)});Wr.post("/eval-jobs/:id/cancel",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.update(Se).set({status:"cancelled",updatedAt:new Date}).where(ya(On(Se.id,n),On(Se.userId,t))).returning();return r?e.json(r):e.json({error:"Job not found"},404)});import{Hono as Sj}from"hono";import{z as ko}from"zod";import{eq as wa,and as lm,isNull as Aj,desc as xj,sql as nv}from"drizzle-orm";var Bu=new Sj,Ej=ko.object({contentHash:ko.string().min(1).optional(),evalTargetId:ko.string().uuid().optional(),name:ko.string().min(1).max(255),type:ko.enum(["instruction","skill","prompt","plan"]).default("instruction"),content:ko.string().optional(),sessionId:ko.string().uuid().optional(),config:Uu});async function Tj(e){let t=await d.select({systemPrompt:C.systemPrompt,systemHash:C.systemHash,metadata:C.metadata}).from(C).where(nv`${C.metadata}->'contextItems' @> ${JSON.stringify([{content_hash:e}])}::jsonb`).orderBy(xj(C.capturedAt)).limit(1);if(t.length===0)return null;let n=t[0],r=await yu(n.systemHash,n.systemPrompt),i=(n.metadata?.contextItems??[]).find(p=>p.content_hash===e);if(!i?.name)return r;let c=i.name.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`Contents of [^\\n]*${c}[^\\n]*\\n([\\s\\S]*?)(?=Contents of |$)`,"i"),l=r.match(a);return l?l[1].trim():r}u(Tj,"resolveContentFromSnapshot");Bu.post("/eval-from-context",async e=>{let t=e.get("userId"),n=await e.req.json(),r=Ej.parse(n),o=!1,s;if(r.evalTargetId){let[y]=await d.select({id:k.id}).from(k).where(lm(wa(k.id,r.evalTargetId),wa(k.userId,t))).limit(1);if(!y)return e.json({error:"Eval target not found"},404);s=y.id}else if(r.contentHash){let[y]=await d.select({id:k.id}).from(k).where(lm(wa(k.userId,t),nv`${k.metadata}->>'content_hash' = ${r.contentHash}`)).limit(1);if(y)s=y.id;else{let v=r.content;if(v||(v=await Tj(r.contentHash)??void 0),!v)return e.json({error:"Content not provided and could not be resolved from snapshots"},400);let[g]=await d.insert(k).values({userId:t,name:r.name,type:r.type,content:v,description:`Auto-created from session context item: ${r.name}`,metadata:{content_hash:r.contentHash,source_session_id:r.sessionId}}).returning();s=g.id,o=!0}}else return e.json({error:"Provide contentHash or evalTargetId"},400);let c=(await d.select({id:_e.id}).from(_e).where(lm(wa(_e.evalTargetId,s),Aj(_e.retiredAt))).limit(1)).length===0,a=c?{...r.config,generateIfEmpty:!0}:r.config,{id:l,noLiveWorker:p}=await kt({taskName:"process_eval",payload:{evalTargetId:s,config:a},userId:t,mirror:{userId:t,evalTargetId:s,config:a}}),[m]=await d.select().from(Se).where(wa(Se.id,l));return e.json({evalTargetId:s,evalJobId:m.id,evalCasesCreated:0,generationDeferred:c,isNewTarget:o,noLiveWorker:p},201)});import{Hono as dN}from"hono";import{Hono as Rj}from"hono";import{and as rv,eq as pm,sql as on}from"drizzle-orm";var mm=new Rj;mm.get("/insights/projects",async e=>{let t=e.get("userId"),n=await d.select({projectId:f.projectId,name:D.name,gitRemoteUrl:D.gitRemoteUrl,sessionCount:on`COUNT(*)`,enrichedCount:on`COUNT(CASE WHEN ${f.metadata}->'local_session_meta' IS NOT NULL THEN 1 END)`,analyzedCount:on`COUNT(CASE WHEN ${f.analysis} IS NOT NULL THEN 1 END)`,firstSession:on`MIN(${f.startedAt})`,lastSession:on`MAX(${f.startedAt})`}).from(f).innerJoin(D,pm(D.id,f.projectId)).where(rv(pm(f.userId,t),on`${f.projectId} IS NOT NULL`)).groupBy(f.projectId,D.name,D.gitRemoteUrl),r=await d.execute(on`
|
|
875
875
|
select project_id, project_path, count(*)::int as n
|
|
876
876
|
from sessions
|
|
877
877
|
where user_id = ${t}
|
|
878
878
|
and project_id is not null
|
|
879
879
|
and project_path is not null
|
|
880
880
|
group by project_id, project_path
|
|
881
|
-
`),o=new Map,s=new Map;for(let p of r){let m=s.get(p.project_id)??-1;p.n>m&&(s.set(p.project_id,p.n),o.set(p.project_id,p.project_path))}let i=n.map(p=>({projectId:p.projectId,name:p.name,projectPath:p.projectId?o.get(p.projectId)??"":"",gitRemoteUrl:p.gitRemoteUrl,sessionCount:Number(p.sessionCount),enrichedCount:Number(p.enrichedCount),analyzedCount:Number(p.analyzedCount),firstSession:p.firstSession,lastSession:p.lastSession})),a=(await d.select({projectPath:f.projectPath,sessionCount:on`COUNT(*)`,enrichedCount:on`COUNT(CASE WHEN ${f.metadata}->'local_session_meta' IS NOT NULL THEN 1 END)`,analyzedCount:on`COUNT(CASE WHEN ${f.analysis} IS NOT NULL THEN 1 END)`,firstSession:on`MIN(${f.startedAt})`,lastSession:on`MAX(${f.startedAt})`}).from(f).where(ev(pm(f.userId,t),on`${f.projectId} IS NULL`,on`${f.projectPath} IS NOT NULL`)).groupBy(f.projectPath)).map(p=>({projectId:null,name:(p.projectPath??"").split("/").pop()||"unknown",projectPath:p.projectPath??"",gitRemoteUrl:null,sessionCount:Number(p.sessionCount),enrichedCount:Number(p.enrichedCount),analyzedCount:Number(p.analyzedCount),firstSession:p.firstSession,lastSession:p.lastSession})),l=[...i,...a].sort((p,m)=>m.sessionCount-p.sessionCount);return e.json(l)});import Oj from"node:fs";import Dj from"node:path";import{Hono as Mj}from"hono";import{and as nv,desc as rv,eq as Cs,gte as Lj,ilike as ov,lte as $j,sql as ba}from"drizzle-orm";var fm=[{provider:"anthropic",modelId:"claude-fable-5",inputPerMTok:10,outputPerMTok:50,cacheReadPerMTok:1,cacheWrite5mPerMTok:12.5,cacheWrite1hPerMTok:20,contextWindow:1e6},{provider:"anthropic",modelId:"claude-opus-4-8",inputPerMTok:5,outputPerMTok:25,cacheReadPerMTok:.5,cacheWrite5mPerMTok:6.25,cacheWrite1hPerMTok:10,contextWindow:1e6},{provider:"anthropic",modelId:"claude-opus-4-7",inputPerMTok:5,outputPerMTok:25,cacheReadPerMTok:.5,cacheWrite5mPerMTok:6.25,cacheWrite1hPerMTok:10,contextWindow:1e6},{provider:"anthropic",modelId:"claude-opus-4-6",inputPerMTok:5,outputPerMTok:25,cacheReadPerMTok:.5,cacheWrite5mPerMTok:6.25,cacheWrite1hPerMTok:10,contextWindow:1e6},{provider:"anthropic",modelId:"claude-sonnet-5",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.3,cacheWrite5mPerMTok:3.75,cacheWrite1hPerMTok:6,contextWindow:1e6},{provider:"anthropic",modelId:"claude-sonnet-4-6",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.3,cacheWrite5mPerMTok:3.75,cacheWrite1hPerMTok:6,contextWindow:2e5},{provider:"anthropic",modelId:"claude-haiku-4-5-20251001",inputPerMTok:1,outputPerMTok:5,cacheReadPerMTok:.1,cacheWrite5mPerMTok:1.25,cacheWrite1hPerMTok:2,contextWindow:2e5},{provider:"anthropic",modelId:"claude-haiku-4-5",inputPerMTok:1,outputPerMTok:5,cacheReadPerMTok:.1,cacheWrite5mPerMTok:1.25,cacheWrite1hPerMTok:2,contextWindow:2e5},{provider:"openai",modelId:"gpt-5.5",inputPerMTok:5,outputPerMTok:30,cacheReadPerMTok:.5,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:4e5},{provider:"openai",modelId:"gpt-4o",inputPerMTok:2.5,outputPerMTok:10,cacheReadPerMTok:1.25,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:128e3},{provider:"openai",modelId:"gpt-4o-mini",inputPerMTok:.15,outputPerMTok:.6,cacheReadPerMTok:.075,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:128e3},{provider:"openai",modelId:"gpt-4.1",inputPerMTok:2,outputPerMTok:8,cacheReadPerMTok:.5,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"openai",modelId:"gpt-4.1-mini",inputPerMTok:.4,outputPerMTok:1.6,cacheReadPerMTok:.1,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"openai",modelId:"o1",inputPerMTok:15,outputPerMTok:60,cacheReadPerMTok:7.5,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:2e5},{provider:"openai",modelId:"o3",inputPerMTok:2,outputPerMTok:8,cacheReadPerMTok:.5,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:2e5},{provider:"openai",modelId:"o4-mini",inputPerMTok:1.1,outputPerMTok:4.4,cacheReadPerMTok:.275,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:2e5},{provider:"google",modelId:"gemini-2.5-pro",inputPerMTok:1.25,outputPerMTok:10,cacheReadPerMTok:.31,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"google",modelId:"gemini-2.5-flash",inputPerMTok:.3,outputPerMTok:2.5,cacheReadPerMTok:.075,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"google",modelId:"gemini-2.0-flash",inputPerMTok:.1,outputPerMTok:.4,cacheReadPerMTok:.025,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"google",modelId:"gemini-1.5-pro",inputPerMTok:1.25,outputPerMTok:5,cacheReadPerMTok:.3125,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:2e6},{provider:"google",modelId:"gemini-1.5-flash",inputPerMTok:.075,outputPerMTok:.3,cacheReadPerMTok:.01875,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"xai",modelId:"grok-4",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.75,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:256e3},{provider:"xai",modelId:"grok-3",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.75,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:131072},{provider:"deepseek",modelId:"deepseek-chat",inputPerMTok:.27,outputPerMTok:1.1,cacheReadPerMTok:.07,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:128e3},{provider:"deepseek",modelId:"deepseek-reasoner",inputPerMTok:.55,outputPerMTok:2.19,cacheReadPerMTok:.14,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:128e3}];function Wr(e){if(!e)return"anthropic";let t=fm.find(r=>r.modelId===e);if(t)return t.provider;let n=e.toLowerCase();return n.startsWith("claude")?"anthropic":n.startsWith("gpt")||n.startsWith("o1")||n.startsWith("o3")||n.startsWith("o4")||n.startsWith("chatgpt")?"openai":n.startsWith("gemini")?"google":n.startsWith("grok")?"xai":n.startsWith("deepseek")?"deepseek":n.startsWith("mistral")||n.startsWith("mixtral")||n.startsWith("magistral")||n.startsWith("codestral")?"mistral":n.startsWith("llama")||n.startsWith("meta-llama")?"meta":"anthropic"}u(Wr,"providerFromModelId");var gm={provider:"anthropic",modelId:"default-sonnet-equivalent",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.3,cacheWrite5mPerMTok:3.75,cacheWrite1hPerMTok:6,contextWindow:2e5};function hm(e){return fm.find(t=>t.modelId===e)}u(hm,"findModel");var va=1e6;function Tj(e){return Math.round(e*100)/100}u(Tj,"roundCents");function Uu(e,t,n){let r=e.input_tokens??0,o=e.output_tokens??0,s=e.cache_read_input_tokens??0,i=(e.cache_creation_5m??0)+(e.cache_creation_input_tokens??0),c=e.cache_creation_1h??0,a=r*t.inputPerMTok/va,l=o*t.outputPerMTok/va,p=s*t.cacheReadPerMTok/va,m=i*t.cacheWrite5mPerMTok/va,_=c*t.cacheWrite1hPerMTok/va,v=m+_,g=a+l+p+v;return{inputUsd:a,outputUsd:l,cacheReadUsd:p,cacheWriteUsd:v,totalUsd:Tj(g),estimated:n}}u(Uu,"computePrice");function _m(e,t,n){let r=hm(t);return Uu(e,r??gm,!r)}u(_m,"priceUsage");import{and as Rj,desc as kj,eq as tv,isNull as jj,lte as Nj,or as Cj,gt as Pj}from"drizzle-orm";function Ia(e){return e==null?0:typeof e=="number"?e:Number(e)}u(Ia,"toNumber");async function mr(e,t,n,r,o="anthropic"){let s=await e.select().from(Ye).where(Rj(tv(Ye.provider,o),tv(Ye.modelId,n),Nj(Ye.effectiveFrom,r),Cj(jj(Ye.effectiveUntil),Pj(Ye.effectiveUntil,r)))).orderBy(kj(Ye.effectiveFrom)).limit(1);if(s.length===0)return _m(t,n,r);let i=s[0];return Uu(t,{inputPerMTok:Ia(i.inputPerM),outputPerMTok:Ia(i.outputPerM),cacheReadPerMTok:Ia(i.cacheReadPerM),cacheWrite5mPerMTok:Ia(i.cacheWrite5mPerM),cacheWrite1hPerMTok:Ia(i.cacheWrite1hPerM)},!1)}u(mr,"priceUsageFromDb");var ym=new Mj;function qj(e){let t=[],n=[];if(e.sessionsUsingMcp===0&&e.totalSessions>=5&&t.push({feature:"MCP Servers",one_liner:"Extend Claude with external tools via MCP",why_for_you:`Across ${e.totalSessions} sessions, you haven't used any MCP servers. MCP lets Claude access databases, APIs, and custom tools directly. Set up the RuleMetric MCP server from the /connect page in the dashboard.`,example_code:"claude mcp add <server-name> -- <command>"}),e.sessionsUsingTaskAgent===0&&e.totalSessions>=5&&t.push({feature:"Task Agents",one_liner:"Parallelize work with subagents",why_for_you:"You haven't used task agents yet. They can parallelize independent tasks \u2014 like running tests while editing code \u2014 saving significant time.",example_code:"claude -p 'Use an explore agent to map the architecture of this project, then use parallel agents to implement each change independently.'"}),e.totalToolErrors>10){let _=Object.entries(e.toolErrorCategories).sort(([,v],[,g])=>g-v)[0];_&&t.push({feature:"Hooks",one_liner:"Auto-run checks after tool calls",why_for_you:`You had ${e.totalToolErrors} tool errors, with "${_[0]}" being the most common (${_[1]}). Hooks can auto-run type-checks or linters after every edit to catch errors immediately.`,example_code:'Add to .claude/settings.json: {"hooks": {"PostToolUse": [{"matcher": "Edit|Write", "hooks": [{"type": "command", "command": "pnpm type-check 2>&1 | head -5"}]}]}}'})}if(e.totalMessages>100&&e.totalSessions>=10&&t.push({feature:"Headless Mode",one_liner:"Run Claude non-interactively for batch tasks",why_for_you:`With ${e.totalMessages} messages across ${e.totalSessions} sessions, you could automate repetitive tasks using headless mode.`,example_code:"claude -p 'Run pnpm type-check and pnpm test. Report only failures with file paths and line numbers.' --allowedTools 'Bash,Read,Grep'"}),Object.values(e.friction).reduce((_,v)=>_+v,0)>5){let v=Object.entries(e.friction).sort(([,g],[,h])=>h-g).slice(0,2).map(([g,h])=>`${g.replace(/_/g," ")} (${h}x)`).join(", ");n.push({title:"Reduce Friction with Structured Prompts",suggestion:`Your top friction points are: ${v}. Giving Claude more context upfront reduces back-and-forth.`,detail:"Start each session with a clear goal statement and constraints.",copyable_prompt:"This session has ONE goal: [describe goal]. Before making any changes, read the relevant files and explain your plan. Do not modify code until I approve the approach."})}e.sessionsWithAnalysis<e.totalSessions*.3&&e.totalSessions>=5&&n.push({title:"Enrich Sessions for Better Insights",suggestion:`Only ${e.sessionsWithAnalysis} of ${e.totalSessions} sessions have quality analysis. Enriching them unlocks outcome tracking, friction detection, and deeper recommendations.`,detail:"Sessions are analyzed automatically by the background worker. Start it with `rulemetric evals agent` (or use the Regenerate button on the dashboard) and enrichment catches up on its own.",copyable_prompt:"rulemetric evals agent"});let o=(e.outcomes.not_achieved??0)+(e.outcomes.partially_achieved??0),s=Object.values(e.outcomes).reduce((_,v)=>_+v,0);s>5&&o/s>.3&&n.push({title:"Scope Sessions to One Goal",suggestion:`${Math.round(o/s*100)}% of analyzed sessions didn't fully achieve their goal. Breaking work into focused, single-goal sessions improves success rates.`,detail:"Start each session with a clear, narrow objective.",copyable_prompt:"This session has ONE goal: [describe specific goal]. Do not touch any other code. When this specific task is done and verified, stop."});let i=[];e.totalToolErrors>10&&i.push({skillId:"type-check-hook",reason:`You had ${e.totalToolErrors} tool errors. This hook auto-runs type-check after every edit to catch them immediately.`});let c=e.friction.wrong_approach??0,a=e.friction.buggy_code??0;c+a>3&&i.push({skillId:"structured-debugging",reason:`${c+a} sessions had wrong-approach or buggy-code friction. Structured debugging prevents spiraling.`}),((e.toolErrorCategories.test_failure??e.toolErrorCategories.assertion??0)>3||(e.friction.buggy_code??0)>2)&&i.push({skillId:"tdd-workflow",reason:"Frequent test failures or buggy code suggest adopting red-green-refactor discipline."});let p=e.friction.excessive_changes??0;return p>2&&i.push({skillId:"git-commit-conventions",reason:`${p} sessions had excessive changes. Conventional commits enforce focused, atomic changes.`}),Object.entries(e.toolErrorCategories).filter(([_])=>_.includes("auth")||_.includes("security")||_.includes("permission")).reduce((_,[,v])=>_+v,0)>0&&i.push({skillId:"security-review",reason:"Security-related errors detected. A security review checklist catches vulnerabilities before they ship."}),t.length===0&&n.length===0&&i.length===0?null:{suggestions:{features_to_try:t,usage_patterns:n,claude_md_additions:[]},recommended_skills:i.length>0?i:void 0,_auto_generated:!0}}u(qj,"generateAutoSuggestions");var Uj=45e3,Bu=new Map,Bj=_u();ym.get("/insights/compute",async e=>{let t=e.get("userId"),n=e.req.query("projectPath"),r=e.req.query("projectId"),o=e.req.query("since"),s=e.req.query("until"),i=e.req.query("tool"),c=`${t}:${r??n??""}:${o??""}:${s??""}:${i??""}`,a=Bu.get(c);if(a&&Date.now()-a.at<Uj)return e.json(a.data);let l=await Bj.run(c,async()=>{let p=[Cs(f.userId,t)];r?p.push(Cs(f.projectId,r)):n&&p.push(ov(f.projectPath,`%${Ze(n)}%`)),i&&p.push(Cs(f.tool,i)),o&&p.push(Lj(f.startedAt,new Date(o))),s&&p.push($j(f.startedAt,new Date(s)));let m=500,_=await lt.select({id:f.id,externalSessionId:f.externalSessionId,tool:f.tool,projectPath:f.projectPath,startedAt:f.startedAt,endedAt:f.endedAt,eventCount:f.eventCount,tokenUsage:f.tokenUsage,analysis:f.analysis,analyzedAt:f.analyzedAt,metadata:f.metadata}).from(f).where(nv(...p)).orderBy(rv(f.startedAt)).limit(m),v=1e6,g=new Map,h=u((D,se)=>{let Re=g.get(D);return Re||(Re=(async()=>{let Ce={input_tokens:v},He={output_tokens:v},xt={cache_read_input_tokens:v},Kt={cache_creation_5m:v},$t={cache_creation_1h:v},qt=Wr(D),[Ge,rt,Qe,Ft,or]=await Promise.all([mr(lt,Ce,D,se,qt),mr(lt,He,D,se,qt),mr(lt,xt,D,se,qt),mr(lt,Kt,D,se,qt),mr(lt,$t,D,se,qt)]);return{inputPerM:Ge.inputUsd,outputPerM:rt.outputUsd,cacheReadPerM:Qe.cacheReadUsd,cacheWrite5mPerM:Ft.cacheWriteUsd,cacheWrite1hPerM:or.cacheWriteUsd,estimated:Ge.estimated}})(),g.set(D,Re)),Re},"getRates"),w=u(async(D,se,Re)=>{let Ce=await h(se,Re),He=D.input_tokens??0,xt=D.output_tokens??0,Kt=D.cache_read_input_tokens??0,$t=(D.cache_creation_5m??0)+(D.cache_creation_input_tokens??0),qt=D.cache_creation_1h??0,Ge=He*Ce.inputPerM/v,rt=xt*Ce.outputPerM/v,Qe=Kt*Ce.cacheReadPerM/v,Ft=$t*Ce.cacheWrite5mPerM/v+qt*Ce.cacheWrite1hPerM/v,or=Math.round((Ge+rt+Qe+Ft)*100)/100;return{inputUsd:Ge,outputUsd:rt,cacheReadUsd:Qe,cacheWriteUsd:Ft,totalUsd:or,estimated:Ce.estimated}},"getPriced"),I={},b={},S={},A={},x={},E={},P={},N={},C={},z={},B=[],q=[],oe=[],V=0,le=0,mt=0,J=0,ue=0,je=0,Ne=0,Bt=0,Be=0,de=0,De=0,k=0,X=0,Ae=0,nt=0,Fe=0,Lt=0,Tn=0,Qr=0,Zr=0,Ir=0,uf=0,df=0,lf=0,Qs=null,Zs=null,t0=Date.now()-720*60*60*1e3,vd=[],Ja="claude-sonnet-4-6",Ga=u(()=>({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),"newBucket"),Ka=u((D,se,Re,Ce,He,xt)=>{D.input_tokens+=se,D.output_tokens+=Re,D.cache_read_tokens+=Ce,D.cache_write_tokens+=He,D.cost_usd+=xt},"accumulateBucket"),ei={},ti={},n0=new Map(_.map(D=>[D.id,D.startedAt])),r0=new Map(_.map(D=>[D.id,D.tool??"unknown"])),pf=new Set,mf=_.length>0?await lt.execute(ba`
|
|
881
|
+
`),o=new Map,s=new Map;for(let p of r){let m=s.get(p.project_id)??-1;p.n>m&&(s.set(p.project_id,p.n),o.set(p.project_id,p.project_path))}let i=n.map(p=>({projectId:p.projectId,name:p.name,projectPath:p.projectId?o.get(p.projectId)??"":"",gitRemoteUrl:p.gitRemoteUrl,sessionCount:Number(p.sessionCount),enrichedCount:Number(p.enrichedCount),analyzedCount:Number(p.analyzedCount),firstSession:p.firstSession,lastSession:p.lastSession})),a=(await d.select({projectPath:f.projectPath,sessionCount:on`COUNT(*)`,enrichedCount:on`COUNT(CASE WHEN ${f.metadata}->'local_session_meta' IS NOT NULL THEN 1 END)`,analyzedCount:on`COUNT(CASE WHEN ${f.analysis} IS NOT NULL THEN 1 END)`,firstSession:on`MIN(${f.startedAt})`,lastSession:on`MAX(${f.startedAt})`}).from(f).where(rv(pm(f.userId,t),on`${f.projectId} IS NULL`,on`${f.projectPath} IS NOT NULL`)).groupBy(f.projectPath)).map(p=>({projectId:null,name:(p.projectPath??"").split("/").pop()||"unknown",projectPath:p.projectPath??"",gitRemoteUrl:null,sessionCount:Number(p.sessionCount),enrichedCount:Number(p.enrichedCount),analyzedCount:Number(p.analyzedCount),firstSession:p.firstSession,lastSession:p.lastSession})),l=[...i,...a].sort((p,m)=>m.sessionCount-p.sessionCount);return e.json(l)});import Mj from"node:fs";import Lj from"node:path";import{Hono as $j}from"hono";import{and as sv,desc as iv,eq as Os,gte as qj,ilike as av,lte as Uj,sql as ba}from"drizzle-orm";var fm=[{provider:"anthropic",modelId:"claude-fable-5",inputPerMTok:10,outputPerMTok:50,cacheReadPerMTok:1,cacheWrite5mPerMTok:12.5,cacheWrite1hPerMTok:20,contextWindow:1e6},{provider:"anthropic",modelId:"claude-opus-4-8",inputPerMTok:5,outputPerMTok:25,cacheReadPerMTok:.5,cacheWrite5mPerMTok:6.25,cacheWrite1hPerMTok:10,contextWindow:1e6},{provider:"anthropic",modelId:"claude-opus-4-7",inputPerMTok:5,outputPerMTok:25,cacheReadPerMTok:.5,cacheWrite5mPerMTok:6.25,cacheWrite1hPerMTok:10,contextWindow:1e6},{provider:"anthropic",modelId:"claude-opus-4-6",inputPerMTok:5,outputPerMTok:25,cacheReadPerMTok:.5,cacheWrite5mPerMTok:6.25,cacheWrite1hPerMTok:10,contextWindow:1e6},{provider:"anthropic",modelId:"claude-sonnet-5",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.3,cacheWrite5mPerMTok:3.75,cacheWrite1hPerMTok:6,contextWindow:1e6},{provider:"anthropic",modelId:"claude-sonnet-4-6",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.3,cacheWrite5mPerMTok:3.75,cacheWrite1hPerMTok:6,contextWindow:2e5},{provider:"anthropic",modelId:"claude-haiku-4-5-20251001",inputPerMTok:1,outputPerMTok:5,cacheReadPerMTok:.1,cacheWrite5mPerMTok:1.25,cacheWrite1hPerMTok:2,contextWindow:2e5},{provider:"anthropic",modelId:"claude-haiku-4-5",inputPerMTok:1,outputPerMTok:5,cacheReadPerMTok:.1,cacheWrite5mPerMTok:1.25,cacheWrite1hPerMTok:2,contextWindow:2e5},{provider:"openai",modelId:"gpt-5.5",inputPerMTok:5,outputPerMTok:30,cacheReadPerMTok:.5,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:4e5},{provider:"openai",modelId:"gpt-4o",inputPerMTok:2.5,outputPerMTok:10,cacheReadPerMTok:1.25,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:128e3},{provider:"openai",modelId:"gpt-4o-mini",inputPerMTok:.15,outputPerMTok:.6,cacheReadPerMTok:.075,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:128e3},{provider:"openai",modelId:"gpt-4.1",inputPerMTok:2,outputPerMTok:8,cacheReadPerMTok:.5,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"openai",modelId:"gpt-4.1-mini",inputPerMTok:.4,outputPerMTok:1.6,cacheReadPerMTok:.1,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"openai",modelId:"o1",inputPerMTok:15,outputPerMTok:60,cacheReadPerMTok:7.5,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:2e5},{provider:"openai",modelId:"o3",inputPerMTok:2,outputPerMTok:8,cacheReadPerMTok:.5,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:2e5},{provider:"openai",modelId:"o4-mini",inputPerMTok:1.1,outputPerMTok:4.4,cacheReadPerMTok:.275,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:2e5},{provider:"google",modelId:"gemini-2.5-pro",inputPerMTok:1.25,outputPerMTok:10,cacheReadPerMTok:.31,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"google",modelId:"gemini-2.5-flash",inputPerMTok:.3,outputPerMTok:2.5,cacheReadPerMTok:.075,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"google",modelId:"gemini-2.0-flash",inputPerMTok:.1,outputPerMTok:.4,cacheReadPerMTok:.025,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"google",modelId:"gemini-1.5-pro",inputPerMTok:1.25,outputPerMTok:5,cacheReadPerMTok:.3125,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:2e6},{provider:"google",modelId:"gemini-1.5-flash",inputPerMTok:.075,outputPerMTok:.3,cacheReadPerMTok:.01875,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:1e6},{provider:"xai",modelId:"grok-4",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.75,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:256e3},{provider:"xai",modelId:"grok-3",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.75,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:131072},{provider:"deepseek",modelId:"deepseek-chat",inputPerMTok:.27,outputPerMTok:1.1,cacheReadPerMTok:.07,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:128e3},{provider:"deepseek",modelId:"deepseek-reasoner",inputPerMTok:.55,outputPerMTok:2.19,cacheReadPerMTok:.14,cacheWrite5mPerMTok:0,cacheWrite1hPerMTok:0,contextWindow:128e3}];function zr(e){if(!e)return"anthropic";let t=fm.find(r=>r.modelId===e);if(t)return t.provider;let n=e.toLowerCase();return n.startsWith("claude")?"anthropic":n.startsWith("gpt")||n.startsWith("o1")||n.startsWith("o3")||n.startsWith("o4")||n.startsWith("chatgpt")?"openai":n.startsWith("gemini")?"google":n.startsWith("grok")?"xai":n.startsWith("deepseek")?"deepseek":n.startsWith("mistral")||n.startsWith("mixtral")||n.startsWith("magistral")||n.startsWith("codestral")?"mistral":n.startsWith("llama")||n.startsWith("meta-llama")?"meta":"anthropic"}u(zr,"providerFromModelId");var gm={provider:"anthropic",modelId:"default-sonnet-equivalent",inputPerMTok:3,outputPerMTok:15,cacheReadPerMTok:.3,cacheWrite5mPerMTok:3.75,cacheWrite1hPerMTok:6,contextWindow:2e5};function hm(e){return fm.find(t=>t.modelId===e)}u(hm,"findModel");var va=1e6;function kj(e){return Math.round(e*100)/100}u(kj,"roundCents");function Fu(e,t,n){let r=e.input_tokens??0,o=e.output_tokens??0,s=e.cache_read_input_tokens??0,i=(e.cache_creation_5m??0)+(e.cache_creation_input_tokens??0),c=e.cache_creation_1h??0,a=r*t.inputPerMTok/va,l=o*t.outputPerMTok/va,p=s*t.cacheReadPerMTok/va,m=i*t.cacheWrite5mPerMTok/va,y=c*t.cacheWrite1hPerMTok/va,v=m+y,g=a+l+p+v;return{inputUsd:a,outputUsd:l,cacheReadUsd:p,cacheWriteUsd:v,totalUsd:kj(g),estimated:n}}u(Fu,"computePrice");function _m(e,t,n){let r=hm(t);return Fu(e,r??gm,!r)}u(_m,"priceUsage");import{and as jj,desc as Nj,eq as ov,isNull as Cj,lte as Pj,or as Oj,gt as Dj}from"drizzle-orm";function Ia(e){return e==null?0:typeof e=="number"?e:Number(e)}u(Ia,"toNumber");async function fr(e,t,n,r,o="anthropic"){let s=await e.select().from(Ye).where(jj(ov(Ye.provider,o),ov(Ye.modelId,n),Pj(Ye.effectiveFrom,r),Oj(Cj(Ye.effectiveUntil),Dj(Ye.effectiveUntil,r)))).orderBy(Nj(Ye.effectiveFrom)).limit(1);if(s.length===0)return _m(t,n,r);let i=s[0];return Fu(t,{inputPerMTok:Ia(i.inputPerM),outputPerMTok:Ia(i.outputPerM),cacheReadPerMTok:Ia(i.cacheReadPerM),cacheWrite5mPerMTok:Ia(i.cacheWrite5mPerM),cacheWrite1hPerMTok:Ia(i.cacheWrite1hPerM)},!1)}u(fr,"priceUsageFromDb");var ym=new $j;function Bj(e){let t=[],n=[];if(e.sessionsUsingMcp===0&&e.totalSessions>=5&&t.push({feature:"MCP Servers",one_liner:"Extend Claude with external tools via MCP",why_for_you:`Across ${e.totalSessions} sessions, you haven't used any MCP servers. MCP lets Claude access databases, APIs, and custom tools directly. Set up the RuleMetric MCP server from the /connect page in the dashboard.`,example_code:"claude mcp add <server-name> -- <command>"}),e.sessionsUsingTaskAgent===0&&e.totalSessions>=5&&t.push({feature:"Task Agents",one_liner:"Parallelize work with subagents",why_for_you:"You haven't used task agents yet. They can parallelize independent tasks \u2014 like running tests while editing code \u2014 saving significant time.",example_code:"claude -p 'Use an explore agent to map the architecture of this project, then use parallel agents to implement each change independently.'"}),e.totalToolErrors>10){let y=Object.entries(e.toolErrorCategories).sort(([,v],[,g])=>g-v)[0];y&&t.push({feature:"Hooks",one_liner:"Auto-run checks after tool calls",why_for_you:`You had ${e.totalToolErrors} tool errors, with "${y[0]}" being the most common (${y[1]}). Hooks can auto-run type-checks or linters after every edit to catch errors immediately.`,example_code:'Add to .claude/settings.json: {"hooks": {"PostToolUse": [{"matcher": "Edit|Write", "hooks": [{"type": "command", "command": "pnpm type-check 2>&1 | head -5"}]}]}}'})}if(e.totalMessages>100&&e.totalSessions>=10&&t.push({feature:"Headless Mode",one_liner:"Run Claude non-interactively for batch tasks",why_for_you:`With ${e.totalMessages} messages across ${e.totalSessions} sessions, you could automate repetitive tasks using headless mode.`,example_code:"claude -p 'Run pnpm type-check and pnpm test. Report only failures with file paths and line numbers.' --allowedTools 'Bash,Read,Grep'"}),Object.values(e.friction).reduce((y,v)=>y+v,0)>5){let v=Object.entries(e.friction).sort(([,g],[,h])=>h-g).slice(0,2).map(([g,h])=>`${g.replace(/_/g," ")} (${h}x)`).join(", ");n.push({title:"Reduce Friction with Structured Prompts",suggestion:`Your top friction points are: ${v}. Giving Claude more context upfront reduces back-and-forth.`,detail:"Start each session with a clear goal statement and constraints.",copyable_prompt:"This session has ONE goal: [describe goal]. Before making any changes, read the relevant files and explain your plan. Do not modify code until I approve the approach."})}e.sessionsWithAnalysis<e.totalSessions*.3&&e.totalSessions>=5&&n.push({title:"Enrich Sessions for Better Insights",suggestion:`Only ${e.sessionsWithAnalysis} of ${e.totalSessions} sessions have quality analysis. Enriching them unlocks outcome tracking, friction detection, and deeper recommendations.`,detail:"Sessions are analyzed automatically by the background worker. Start it with `rulemetric evals agent` (or use the Regenerate button on the dashboard) and enrichment catches up on its own.",copyable_prompt:"rulemetric evals agent"});let o=(e.outcomes.not_achieved??0)+(e.outcomes.partially_achieved??0),s=Object.values(e.outcomes).reduce((y,v)=>y+v,0);s>5&&o/s>.3&&n.push({title:"Scope Sessions to One Goal",suggestion:`${Math.round(o/s*100)}% of analyzed sessions didn't fully achieve their goal. Breaking work into focused, single-goal sessions improves success rates.`,detail:"Start each session with a clear, narrow objective.",copyable_prompt:"This session has ONE goal: [describe specific goal]. Do not touch any other code. When this specific task is done and verified, stop."});let i=[];e.totalToolErrors>10&&i.push({skillId:"type-check-hook",reason:`You had ${e.totalToolErrors} tool errors. This hook auto-runs type-check after every edit to catch them immediately.`});let c=e.friction.wrong_approach??0,a=e.friction.buggy_code??0;c+a>3&&i.push({skillId:"structured-debugging",reason:`${c+a} sessions had wrong-approach or buggy-code friction. Structured debugging prevents spiraling.`}),((e.toolErrorCategories.test_failure??e.toolErrorCategories.assertion??0)>3||(e.friction.buggy_code??0)>2)&&i.push({skillId:"tdd-workflow",reason:"Frequent test failures or buggy code suggest adopting red-green-refactor discipline."});let p=e.friction.excessive_changes??0;return p>2&&i.push({skillId:"git-commit-conventions",reason:`${p} sessions had excessive changes. Conventional commits enforce focused, atomic changes.`}),Object.entries(e.toolErrorCategories).filter(([y])=>y.includes("auth")||y.includes("security")||y.includes("permission")).reduce((y,[,v])=>y+v,0)>0&&i.push({skillId:"security-review",reason:"Security-related errors detected. A security review checklist catches vulnerabilities before they ship."}),t.length===0&&n.length===0&&i.length===0?null:{suggestions:{features_to_try:t,usage_patterns:n,claude_md_additions:[]},recommended_skills:i.length>0?i:void 0,_auto_generated:!0}}u(Bj,"generateAutoSuggestions");var Fj=45e3,Hu=new Map,Hj=wu();ym.get("/insights/compute",async e=>{let t=e.get("userId"),n=e.req.query("projectPath"),r=e.req.query("projectId"),o=e.req.query("since"),s=e.req.query("until"),i=e.req.query("tool"),c=`${t}:${r??n??""}:${o??""}:${s??""}:${i??""}`,a=Hu.get(c);if(a&&Date.now()-a.at<Fj)return e.json(a.data);let l=await Hj.run(c,async()=>{let p=[Os(f.userId,t)];r?p.push(Os(f.projectId,r)):n&&p.push(av(f.projectPath,`%${et(n)}%`)),i&&p.push(Os(f.tool,i)),o&&p.push(qj(f.startedAt,new Date(o))),s&&p.push(Uj(f.startedAt,new Date(s)));let m=500,y=await ft.select({id:f.id,externalSessionId:f.externalSessionId,tool:f.tool,projectPath:f.projectPath,startedAt:f.startedAt,endedAt:f.endedAt,eventCount:f.eventCount,tokenUsage:f.tokenUsage,analysis:f.analysis,analyzedAt:f.analyzedAt,metadata:f.metadata}).from(f).where(sv(...p)).orderBy(iv(f.startedAt)).limit(m),v=1e6,g=new Map,h=u((M,se)=>{let je=g.get(M);return je||(je=(async()=>{let Pe={input_tokens:v},He={output_tokens:v},Et={cache_read_input_tokens:v},Kt={cache_creation_5m:v},$t={cache_creation_1h:v},qt=zr(M),[Ge,it,Ze,Ft,or]=await Promise.all([fr(ft,Pe,M,se,qt),fr(ft,He,M,se,qt),fr(ft,Et,M,se,qt),fr(ft,Kt,M,se,qt),fr(ft,$t,M,se,qt)]);return{inputPerM:Ge.inputUsd,outputPerM:it.outputUsd,cacheReadPerM:Ze.cacheReadUsd,cacheWrite5mPerM:Ft.cacheWriteUsd,cacheWrite1hPerM:or.cacheWriteUsd,estimated:Ge.estimated}})(),g.set(M,je)),je},"getRates"),w=u(async(M,se,je)=>{let Pe=await h(se,je),He=M.input_tokens??0,Et=M.output_tokens??0,Kt=M.cache_read_input_tokens??0,$t=(M.cache_creation_5m??0)+(M.cache_creation_input_tokens??0),qt=M.cache_creation_1h??0,Ge=He*Pe.inputPerM/v,it=Et*Pe.outputPerM/v,Ze=Kt*Pe.cacheReadPerM/v,Ft=$t*Pe.cacheWrite5mPerM/v+qt*Pe.cacheWrite1hPerM/v,or=Math.round((Ge+it+Ze+Ft)*100)/100;return{inputUsd:Ge,outputUsd:it,cacheReadUsd:Ze,cacheWriteUsd:Ft,totalUsd:or,estimated:Pe.estimated}},"getPriced"),b={},I={},S={},A={},x={},T={},P={},E={},j={},O={},F=[],U=[],ee=[],z=0,de=0,ot=0,G=0,ae=0,me=0,Te=0,Bt=0,Be=0,le=0,Me=0,N=0,Q=0,xe=0,st=0,Fe=0,Lt=0,Rn=0,Zr=0,eo=0,Sr=0,lf=0,pf=0,mf=0,Zs=null,ei=null,r0=Date.now()-720*60*60*1e3,bd=[],Ja="claude-sonnet-4-6",Ga=u(()=>({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),"newBucket"),Ka=u((M,se,je,Pe,He,Et)=>{M.input_tokens+=se,M.output_tokens+=je,M.cache_read_tokens+=Pe,M.cache_write_tokens+=He,M.cost_usd+=Et},"accumulateBucket"),ti={},ni={},o0=new Map(y.map(M=>[M.id,M.startedAt])),s0=new Map(y.map(M=>[M.id,M.tool??"unknown"])),ff=new Set,gf=y.length>0?await ft.execute(ba`
|
|
882
882
|
SELECT
|
|
883
883
|
deduped.session_id AS "sessionId",
|
|
884
884
|
COALESCE(deduped.model, ${Ja}) AS "model",
|
|
@@ -892,26 +892,26 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
892
892
|
SELECT DISTINCT ON (se.session_id, COALESCE(se.metadata->>'requestId', se.id::text))
|
|
893
893
|
se.session_id, se.model, se.token_usage
|
|
894
894
|
FROM session_events se
|
|
895
|
-
WHERE se.session_id IN (${ba.join(
|
|
895
|
+
WHERE se.session_id IN (${ba.join(y.map(M=>ba`${M.id}`),ba`, `)})
|
|
896
896
|
AND se.token_usage IS NOT NULL
|
|
897
897
|
ORDER BY se.session_id, COALESCE(se.metadata->>'requestId', se.id::text), se.sequence
|
|
898
898
|
) deduped
|
|
899
899
|
GROUP BY deduped.session_id, deduped.model
|
|
900
|
-
`):[];for(let D of mf)pf.add(D.sessionId);for(let D of _){let se=D.metadata?.local_session_meta,Re=D.analysis,Ce=D.tokenUsage;if(D.tool&&(b[D.tool]=(b[D.tool]||0)+1),D.projectPath){let He=D.projectPath.split("/").pop()??D.projectPath;A[He]=(A[He]||0)+1}if(Ce&&!pf.has(D.id)){let He=Ce.input_tokens??0,xt=Ce.output_tokens??0,Kt=Ce.cache_read_input_tokens??0,$t=Ce.cache_creation_5m??0,qt=Ce.cache_creation_1h??0,Ge=Ce.cache_creation_input_tokens??0,rt=$t+qt||Ge;mt+=He,J+=xt,ue+=Kt,je+=rt;let Qe=await w(Ce,Ja,D.startedAt);Ne+=Qe.inputUsd,Bt+=Qe.outputUsd,Be+=Qe.cacheReadUsd,de+=Qe.cacheWriteUsd;let Ft=Qe.inputUsd+Qe.outputUsd+Qe.cacheReadUsd+Qe.cacheWriteUsd,or=D.tool??"unknown",hf=ei[Ja]??Ga();Ka(hf,He,xt,Kt,rt,Ft),ei[Ja]=hf;let _f=ti[or]??Ga();Ka(_f,He,xt,Kt,rt,Ft),ti[or]=_f}if(se){Tn++;let He=se.user_message_count??0;V+=He,le+=(se.duration_minutes??0)/60,De+=se.git_commits??0,k+=se.git_pushes??0,X+=se.lines_added??0,Ae+=se.lines_removed??0,nt+=se.files_modified??0,Fe+=se.tool_errors??0;let xt=se.tool_counts;if(xt)for(let[Qe,Ft]of Object.entries(xt))I[Qe]=(I[Qe]||0)+Ft;let Kt=se.languages;if(Kt)for(let[Qe,Ft]of Object.entries(Kt))S[Qe]=(S[Qe]||0)+Ft;let $t=se.message_hours;$t&&B.push(...$t);let qt=se.tool_error_categories;if(qt)for(let[Qe,Ft]of Object.entries(qt))z[Qe]=(z[Qe]||0)+Ft;let Ge=se.user_response_times;Ge&&q.push(...Ge),Lt+=se.user_interruptions??0,se.uses_task_agent&&Zr++,se.uses_mcp&&Ir++;let rt=se.user_message_timestamps;rt&&rt.length>0&&oe.push({id:D.id,start:D.startedAt.toISOString(),timestamps:rt})}if(Re)if(D.analyzedAt){uf++;let He=new Date(D.analyzedAt).getTime();(Qs===null||He<Qs)&&(Qs=He),(Zs===null||He>Zs)&&(Zs=He),He<t0&&lf++}else df++;if(Re){Qr++;let He=Re.goal_categories;if(He)for(let[Ge,rt]of Object.entries(He))rt>0&&(x[Ge]=(x[Ge]||0)+rt);let xt=Re.outcome;xt&&(E[xt]=(E[xt]||0)+1);let Kt=Re.user_satisfaction;if(Kt)for(let[Ge,rt]of Object.entries(Kt))rt>0&&(P[Ge]=(P[Ge]||0)+rt);let $t=Re.session_type;$t&&(N[$t]=(N[$t]||0)+1);let qt=Re.friction??Re.friction_counts;if(qt)for(let[Ge,rt]of Object.entries(qt))rt>0&&(C[Ge]=(C[Ge]||0)+rt);vd.length<50&&vd.push({id:D.id,externalId:D.externalSessionId,date:D.startedAt.toISOString().split("T")[0]??"",summary:Re.brief_summary??"",goal:Re.underlying_goal,outcome:xt})}}let Ya=_.map(D=>D.startedAt.toISOString()).sort(),Id=new Set(Ya.map(D=>D.split("T")[0]));for(let D of mf){let se=Number(D.inputTokens)||0,Re=Number(D.outputTokens)||0,Ce=Number(D.cacheReadTokens)||0,He=Number(D.cacheWrite5m)||0,xt=Number(D.cacheWrite1h)||0,Kt=Number(D.cacheWriteLegacy)||0,$t=He+xt||Kt,qt=n0.get(D.sessionId)??new Date,Ge=await w({input_tokens:se,output_tokens:Re,cache_read_input_tokens:Ce,cache_creation_input_tokens:$t},D.model,qt);Ne+=Ge.inputUsd,Bt+=Ge.outputUsd,Be+=Ge.cacheReadUsd,de+=Ge.cacheWriteUsd,mt+=se,J+=Re,ue+=Ce,je+=$t;let rt=Ge.inputUsd+Ge.outputUsd+Ge.cacheReadUsd+Ge.cacheWriteUsd,Qe=ei[D.model]??Ga();Ka(Qe,se,Re,Ce,$t,rt),ei[D.model]=Qe;let Ft=r0.get(D.sessionId)??"unknown",or=ti[Ft]??Ga();Ka(or,se,Re,Ce,$t,rt),ti[Ft]=or}let eo=u(D=>Math.round(D*100)/100,"round2"),o0=Ne+Bt+Be+de,s0=eo(o0),i0={inputUsd:eo(Ne),outputUsd:eo(Bt),cacheReadUsd:eo(Be),cacheWriteUsd:eo(de)},bd={};for(let[D,se]of Object.entries(ei))bd[D]={input_tokens:se.input_tokens,output_tokens:se.output_tokens,cache_read_tokens:se.cache_read_tokens,cache_write_tokens:se.cache_write_tokens,cost_usd:eo(se.cost_usd)};let Sd={};for(let[D,se]of Object.entries(ti))Sd[D]={input_tokens:se.input_tokens,output_tokens:se.output_tokens,cache_read_tokens:se.cache_read_tokens,cache_write_tokens:se.cache_write_tokens,cost_usd:eo(se.cost_usd)};let br={"2-10s":0,"10-30s":0,"30s-1m":0,"1-2m":0,"2-5m":0,"5-15m":0,">15m":0};for(let D of q)D<10?br["2-10s"]++:D<30?br["10-30s"]++:D<60?br["30s-1m"]++:D<120?br["1-2m"]++:D<300?br["2-5m"]++:D<900?br["5-15m"]++:br[">15m"]++;let Lo=[...q].sort((D,se)=>D-se),a0=Lo.length>0?Lo[Math.floor(Lo.length/2)]:0,c0=Lo.length>0?Lo.reduce((D,se)=>D+se,0)/Lo.length:0,ff=0,gf=0;if(oe.length>1){let D=oe.flatMap(Re=>Re.timestamps.map(Ce=>({sessionId:Re.id,time:new Date(Ce).getTime()}))).sort((Re,Ce)=>Re.time-Ce.time),se=new Set;for(let Re=0;Re<D.length-1;Re++){let Ce=D[Re],He=D[Re+1];Ce.sessionId!==He.sessionId&&He.time-Ce.time<1800*1e3&&(se.add(Ce.sessionId),se.add(He.sessionId),ff++)}gf=se.size}let ni={computed:!0,total_sessions:_.length,window:{since:o??null,until:s??null},truncated:_.length>=m,sessions_with_meta:Tn,sessions_with_analysis:Qr,tools_used:b,date_range:{start:Ya[0]?.split("T")[0]??"",end:Ya[Ya.length-1]?.split("T")[0]??""},total_messages:V,total_duration_hours:Math.round(le*10)/10,total_input_tokens:mt,total_output_tokens:J,total_cache_read_tokens:ue,total_cache_write_tokens:je,estimated_cost_usd:s0,estimated_cost_breakdown:i0,estimated_cost_by_model:Object.keys(bd).length>0?bd:void 0,estimated_cost_by_tool:Object.keys(Sd).length>0?Sd:void 0,tool_counts:I,languages:S,git_commits:De,git_pushes:k,projects:A,goal_categories:x,outcomes:E,satisfaction:P,session_types:N,friction:C,tool_error_categories:z,session_summaries:vd,total_tool_errors:Fe,total_interruptions:Lt,total_lines_added:X,total_lines_removed:Ae,total_files_modified:nt,days_active:Id.size,messages_per_day:Id.size>0?Math.round(V/Id.size*10)/10:0,message_hours:B,sessions_using_task_agent:Zr,sessions_using_mcp:Ir,response_time:{median_seconds:Math.round(a0*10)/10,avg_seconds:Math.round(c0*10)/10,histogram:br,total_samples:q.length},parallel_sessions:{events:ff,sessions_involved:gf},analysis_freshness:{with_timestamp:uf,pre_instrumentation:df,stale_30d:lf,oldest_analyzed_at:Qs?new Date(Qs).toISOString():null,newest_analyzed_at:Zs?new Date(Zs).toISOString():null}};ni.autoAddAvailable=!!(n&&Oj.existsSync(Dj.join(n,"CLAUDE.md")));let Xa=[Cs(F.userId,t),Cs(F.status,"completed")];r?Xa.push(Cs(F.projectId,r)):n?Xa.push(ov(F.projectPath,`%${Ze(n)}%`)):Xa.push(ba`${F.projectPath} IS NULL`);let[u0]=await lt.select({result:F.result}).from(F).where(nv(...Xa)).orderBy(rv(F.completedAt)).limit(1),d0=u0?.result,Ad=Fl(d0?.recommendations);if(Ad&&Object.keys(Ad).length>0)ni.recommendations=Ad;else if(_.length>=3){let D=qj({totalSessions:_.length,sessionsWithAnalysis:Qr,toolCounts:I,toolErrorCategories:z,friction:C,outcomes:E,sessionsUsingMcp:Ir,sessionsUsingTaskAgent:Zr,totalToolErrors:Fe,totalMessages:V,totalDurationHours:le});D&&(ni.recommendations=D)}return Bu.size>1e3&&Bu.clear(),Bu.set(c,{at:Date.now(),data:ni}),ni});return e.json(l)});import{Hono as Fj}from"hono";import{and as On,count as Hj,eq as Ue,ilike as Wj,inArray as zj,sql as bn}from"drizzle-orm";var Ro=new Fj,To=u(e=>la(e?.outcome??null),"scoreOf");Ro.get("/insights/linked-instructions",async e=>{let t=e.get("userId"),n=e.req.query("projectPath"),r=Number(e.req.query("limit")??20),o=[Ue(f.userId,t)];n&&o.push(Wj(f.projectPath,`%${Ze(n)}%`));let s=await d.select({id:y.id,name:y.name,contentHash:y.contentHash,linkedSessions:bn`COUNT(DISTINCT ${te.sessionId})`}).from(te).innerJoin(f,Ue(f.id,te.sessionId)).innerJoin(y,Ue(y.id,te.instructionId)).where(On(...o)).groupBy(y.id,y.name,y.contentHash).orderBy(bn`COUNT(DISTINCT ${te.sessionId}) DESC`).limit(r);return e.json(s.map(i=>({id:i.id,name:i.name,contentHash:i.contentHash,linkedSessions:Number(i.linkedSessions)})))});Ro.get("/insights/instruction-impact",async e=>{let t=e.get("userId"),n=e.req.query("instructionId");if(!n)return e.json({error:"instructionId query param required"},400);let r=await d.select({id:f.id,projectId:f.projectId,model:f.model,tool:f.tool,tokenUsage:f.tokenUsage,analysis:f.analysis,metadata:f.metadata,eventCount:f.eventCount,startedAt:f.startedAt}).from(f).innerJoin(ee,Ue(ee.sessionId,f.id)).where(On(Ue(f.userId,t),Ue(ee.treatmentType,"instruction"),Ue(ee.treatmentId,n))),o=r.map(V=>V.id),s=await d.select({id:f.id,projectId:f.projectId,model:f.model,tool:f.tool,tokenUsage:f.tokenUsage,analysis:f.analysis,metadata:f.metadata,eventCount:f.eventCount,startedAt:f.startedAt}).from(f).where(On(Ue(f.userId,t),bn`${f.analysis} IS NOT NULL`)),i=await d.selectDistinct({sessionId:ee.sessionId}).from(ee).where(On(Ue(ee.userId,t),Ue(ee.treatmentType,"instruction"))),c=new Set(i.map(V=>V.sessionId)),a=new Set(o),l=s.filter(V=>!a.has(V.id)&&c.has(V.id));function p(V){let le=0,mt=0,J=0,ue=0,je=[],Ne={},Bt={achieved:1,fully_achieved:1,mostly_achieved:.75,partially_achieved:.5,unclear_from_transcript:.25,not_achieved:0,abandoned:0};for(let Be of V){let de=Be.analysis,De=Be.metadata?.local_session_meta;if(de?.outcome){let X=Bt[de.outcome];X!==void 0&&je.push(X)}De&&(ue++,le+=De.tool_errors??0,mt+=De.duration_minutes??0,J+=(De.lines_added??0)+(De.lines_removed??0));let k=de?.goal_categories??{};for(let[X,Ae]of Object.entries(k))Ae>0&&(Ne[X]=(Ne[X]||0)+Ae)}return{sessionCount:V.length,enrichedCount:ue,outcomeScores:je,avgOutcomeScore:je.length>0?Math.round(je.reduce((Be,de)=>Be+de,0)/je.length*100)/100:null,avgToolErrors:ue>0?Math.round(le/ue*10)/10:null,avgDurationMinutes:ue>0?Math.round(mt/ue*10)/10:null,avgLinesChanged:ue>0?Math.round(J/ue):null,topGoalCategories:Ne}}u(p,"computeCohort");let m=p(r),_=p(l),v=u(V=>{if(!V)return"(no-date)";let le=typeof V=="string"?new Date(V):V;return Number.isNaN(le.getTime())?"(no-date)":`${le.getUTCFullYear()}-${String(le.getUTCMonth()+1).padStart(2,"0")}`},"monthKey"),g=u(V=>{if(!V)return 0;let le=typeof V=="string"?new Date(V):V;return Number.isNaN(le.getTime())?0:le.getTime()},"timeOf"),h=new Map,w=u((V,le,mt,J)=>{let ue=`${V??"(no-project)"}|${v(le)}`,je=h.get(ue);je||(je={key:ue,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},h.set(ue,je)),(J?je.withScores:je.withoutScores).push(mt),(J?je.withTimes:je.withoutTimes).push(g(le))},"addToStratum");for(let V of r){let le=To(V.analysis);le!=null&&w(V.projectId,V.startedAt,le,!0)}for(let V of l){let le=To(V.analysis);le!=null&&w(V.projectId,V.startedAt,le,!1)}let I=u(V=>{let le=new Map,mt=new Set,J=u((ue,je,Ne,Bt,Be)=>{let de=le.get(ue);de||(de=new Map,le.set(ue,de));let De=`${je??"(no-project)"}|${v(Ne)}`,k=de.get(De);k||(k={key:De,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},de.set(De,k)),(Be?k.withScores:k.withoutScores).push(Bt),(Be?k.withTimes:k.withoutTimes).push(g(Ne))},"add");for(let ue of r){let je=To(ue.analysis),Ne=V(ue);je==null||!Ne||(mt.add(Ne),J(Ne,ue.projectId,ue.startedAt,je,!0))}for(let ue of l){let je=To(ue.analysis),Ne=V(ue);je==null||!Ne||!mt.has(Ne)||J(Ne,ue.projectId,ue.startedAt,je,!1)}return[...mt].map(ue=>({segment:ue,strata:[...le.get(ue)?.values()??[]]}))},"buildAxisSegments"),b=u(V=>[...V].sort((le,mt)=>Number(mt.verdict.sufficient)-Number(le.verdict.sufficient)||mt.verdict.nWith-le.verdict.nWith),"sortSegs"),S=Gp([...h.values()],I(V=>yo(V.model))),A=S.overall,x=b(S.segments).map(V=>({model:V.segment,verdict:V.verdict})),E=b(Nu(I(V=>V.tool??null))).map(V=>({harness:V.segment,verdict:V.verdict})),{outcomeScores:P,...N}=m,{outcomeScores:C,...z}=_,[B]=await d.select({name:y.name}).from(y).where(Ue(y.id,n)).limit(1),[q]=await d.select({n:Hj(),lastAssignedAt:bn`max(${Et.assignedAt})`}).from(Et).where(On(Ue(Et.userId,t),Ue(Et.treatmentType,"instruction"),Ue(Et.treatmentId,n),Ue(Et.method,"auto_added"))),oe=q&&Number(q.n)>0?{count:Number(q.n),lastAssignedAt:q.lastAssignedAt}:null;return e.json({instructionId:n,instructionName:B?.name??"Unknown",verdict:A,segments:x,harnessSegments:E,autoAdded:oe,with:N,without:z,comparison:{outcomeScoreDelta:m.avgOutcomeScore!=null&&_.avgOutcomeScore!=null?Math.round((m.avgOutcomeScore-_.avgOutcomeScore)*100)/100:null,toolErrorsDelta:m.avgToolErrors!=null&&_.avgToolErrors!=null?Math.round((m.avgToolErrors-_.avgToolErrors)*10)/10:null,durationDelta:m.avgDurationMinutes!=null&&_.avgDurationMinutes!=null?Math.round((m.avgDurationMinutes-_.avgDurationMinutes)*10)/10:null}})});Ro.get("/insights/instruction-version-impact",async e=>{let t=e.get("userId"),n=e.req.query("instructionId");if(!n)return e.json({error:"instructionId query param required"},400);let r=await d.select({versionOrdinal:Bn.versionOrdinal,contentHash:Bn.contentHash,firstSeenAt:Bn.firstSeenAt,contentLength:bn`COALESCE(LENGTH(${Bn.content}), 0)::int`}).from(Bn).where(Ue(Bn.instructionId,n)).orderBy(Bn.versionOrdinal),o=await d.select({id:f.id,projectId:f.projectId,analysis:f.analysis,startedAt:f.startedAt,version:ee.treatmentVersion}).from(f).innerJoin(ee,Ue(ee.sessionId,f.id)).where(On(Ue(f.userId,t),Ue(ee.treatmentType,"instruction"),Ue(ee.treatmentId,n),bn`${ee.treatmentVersion} > 0`)),s=new Map;for(let b of o){let S=s.get(b.version)??[];S.push(b),s.set(b.version,S)}let i=r.map(b=>({version:b.versionOrdinal,contentHash:b.contentHash,firstSeenAt:b.firstSeenAt,sessions:s.get(b.versionOrdinal)?.length??0,replayable:Number(b.contentLength)>0})),c=i.filter(b=>b.sessions>0).map(b=>b.version).sort((b,S)=>b-S),a=Number(e.req.query("version")),l=Number(e.req.query("baselineVersion")),p=Number.isFinite(a)&&a>0?a:c.at(-1),m=Number.isFinite(l)&&l>0?l:c.filter(b=>b!==p).at(-1);if(p==null||m==null)return e.json({instructionId:n,versions:i,version:p??null,baselineVersion:m??null,verdict:null,insufficientReason:"only one version of this instruction has attributed sessions; there is no prior version to compare against"});let _=u(b=>{if(!b)return"(no-date)";let S=typeof b=="string"?new Date(b):b;return Number.isNaN(S.getTime())?"(no-date)":`${S.getUTCFullYear()}-${String(S.getUTCMonth()+1).padStart(2,"0")}`},"monthKey"),v=u(b=>{if(!b)return 0;let S=typeof b=="string"?new Date(b):b;return Number.isNaN(S.getTime())?0:S.getTime()},"timeOf"),g=new Map,h=u((b,S)=>{let A=To(b.analysis);if(A==null)return;let x=`${b.projectId??"(no-project)"}|${_(b.startedAt)}`,E=g.get(x);E||(E={key:x,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},g.set(x,E)),(S?E.withScores:E.withoutScores).push(A),(S?E.withTimes:E.withoutTimes).push(v(b.startedAt))},"add");for(let b of s.get(p)??[])h(b,!0);for(let b of s.get(m)??[])h(b,!1);let w=pn([...g.values()],{baseline:"prior-version"}),[I]=await d.select({name:y.name}).from(y).where(Ue(y.id,n)).limit(1);return e.json({instructionId:n,instructionName:I?.name??"Unknown",version:p,baselineVersion:m,versions:i,verdict:w,replayableVersions:i.filter(b=>b.replayable).length})});Ro.get("/insights/memory-impact",async e=>{let t=e.get("userId"),n=e.req.query("memoryId");if(!n)return e.json({error:"memoryId query param required"},400);let[r]=await d.select({id:L.id,title:L.title,kind:L.kind,version:L.version,status:L.status}).from(L).where(On(Ue(L.id,n),Ue(L.userId,t))).limit(1);if(!r)return e.json({error:"memory not found"},404);let o=await d.select({sessionId:ee.sessionId,treatmentVersion:ee.treatmentVersion}).from(ee).where(On(Ue(ee.userId,t),Ue(ee.treatmentType,"memory"),Ue(ee.treatmentId,n))),s=new Map,i=new Set;for(let h of o){let w=s.get(h.treatmentVersion);w||(w=new Set,s.set(h.treatmentVersion,w)),w.add(h.sessionId),i.add(h.sessionId)}let c=await d.select({id:f.id,projectId:f.projectId,outcome:bn`${f.analysis}->>'outcome'`,startedAt:f.startedAt,inputTokens:bn`coalesce((${f.tokenUsage}->>'input_tokens')::numeric, 0)`,outputTokens:bn`coalesce((${f.tokenUsage}->>'output_tokens')::numeric, 0)`}).from(f).where(On(Ue(f.userId,t),bn`${f.analysis} is not null`)).orderBy(f.id),a=u((h,w)=>w>0?Math.round(h/w*100)/100:null,"avg"),l=u(()=>({n:0,scoreSum:0,scoreN:0,tokenSum:0}),"cohort"),p=u(h=>h.n>0?Math.round(h.tokenSum/h.n):null,"avgTokens"),m=u(h=>{let w=s.get(h)??new Set,I=new Map,b=l(),S=l();for(let N of c){let C=w.has(N.id);if(!C&&i.has(N.id))continue;let z=C?b:S;z.n++,z.tokenSum+=Number(N.inputTokens)+Number(N.outputTokens);let B=To({outcome:N.outcome});if(B!=null){z.scoreSum+=B,z.scoreN++;let q=N.projectId??"(no-project)",oe=I.get(q);oe||(oe={key:q,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},I.set(q,oe)),(C?oe.withScores:oe.withoutScores).push(B),(C?oe.withTimes:oe.withoutTimes).push(N.startedAt?.getTime()??0)}}let A=pn([...I.values()]),x={sessionCount:b.n,avgOutcomeScore:a(b.scoreSum,b.scoreN),avgTotalTokens:p(b)},E={sessionCount:S.n,avgOutcomeScore:a(S.scoreSum,S.scoreN),avgTotalTokens:p(S)},P={outcomeScoreDelta:x.avgOutcomeScore!=null&&E.avgOutcomeScore!=null?Math.round((x.avgOutcomeScore-E.avgOutcomeScore)*100)/100:null,totalTokensDelta:x.avgTotalTokens!=null&&E.avgTotalTokens!=null?x.avgTotalTokens-E.avgTotalTokens:null};return{verdict:A,with:x,without:E,comparison:P}},"computeVersion"),v=[...new Set([r.version,...s.keys()])].sort((h,w)=>w-h).map(h=>({version:h,isCurrent:h===r.version,...m(h)})),g=v.find(h=>h.isCurrent);return e.json({memoryId:n,memoryTitle:r.title,memoryKind:r.kind,memoryVersion:r.version,verdict:g.verdict,with:g.with,without:g.without,comparison:g.comparison,versions:v.map(({version:h,isCurrent:w,verdict:I,with:b,without:S})=>({version:h,isCurrent:w,verdict:I,with:b,without:S})),cost:{estimated:!0}})});var Vj=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;Ro.get("/insights/suggestion-impact",async e=>{let t=e.get("userId"),n=e.req.query("instructionIds")??e.req.query("instructionId")??"",r=[...new Set(n.split(",").map(l=>l.trim()).filter(l=>Vj.test(l)))].slice(0,200);if(r.length===0)return e.json({error:"instructionIds query param (comma-separated uuids) required"},400);let o=await d.select({sessionId:ee.sessionId,treatmentId:ee.treatmentId}).from(ee).where(On(Ue(ee.userId,t),Ue(ee.treatmentType,"suggestion"),zj(ee.treatmentId,r))),s=new Map;for(let l of o){let p=s.get(l.treatmentId);p||(p=new Set,s.set(l.treatmentId,p)),p.add(l.sessionId)}let c=(await d.select({id:f.id,projectId:f.projectId,outcome:bn`${f.analysis}->>'outcome'`,startedAt:f.startedAt}).from(f).where(On(Ue(f.userId,t),bn`${f.analysis} is not null`)).orderBy(f.id)).map(l=>({id:l.id,key:l.projectId??"(no-project)",score:To({outcome:l.outcome}),time:l.startedAt?.getTime()??0})).filter(l=>l.score!=null),a={};for(let l of r){let p=s.get(l);if(!p||p.size===0){a[l]=pn([]);continue}let m=new Map;for(let _ of c){let v=m.get(_.key);v||(v={key:_.key,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},m.set(_.key,v));let g=p.has(_.id);(g?v.withScores:v.withoutScores).push(_.score),(g?v.withTimes:v.withoutTimes).push(_.time)}a[l]=pn([...m.values()],{iterations:2e3})}return e.json({impacts:a})});import{Hono as Jj}from"hono";import{and as Ps,count as sv,eq as Kn,inArray as Gj,sql as ko}from"drizzle-orm";var wm=new Jj,iv=/force[- ]?push|rm\s+-rf|git\s+reset\s+--hard|drop\s+table|truncate\b|--no-verify|chmod\s+777|\bsudo\b|secret|credential|password|api[- ]?key|never\s+(delete|drop|force|push|commit|run|deploy)|do\s+not\s+(delete|drop|force|push|commit|run|deploy)/i;wm.get("/insights/groom-candidates",async e=>{let t=e.get("userId"),[n]=await d.select({n:sv()}).from(f).where(Ps(Kn(f.userId,t),ko`${f.startedAt} > now() - interval '7 days'`));if(Number(n?.n??0)===0)return e.json({captureHealthy:!1,reason:'No sessions captured in the last 7 days \u2014 cannot tell "unused" from "uncaptured". Grooming paused (never trust a dark pipeline).',candidates:[],harmful:[],safetyGuarded:0,harmfulSafetyGuarded:0});let[r,o,s,i]=await Promise.all([d.select({id:y.id,name:y.name,type:y.type,content:y.content,lastExposedAt:ko`max(${ee.exposedAt})`,totalExposures:sv(ee.id)}).from(y).leftJoin(ee,Ps(Kn(ee.treatmentId,y.id),Kn(ee.userId,t))).where(Ps(Kn(y.createdBy,t),Kn(y.archived,!1),ko`${y.createdAt} < now() - interval '30 days'`)).groupBy(y.id).having(ko`max(${ee.exposedAt}) is null or max(${ee.exposedAt}) < now() - interval '30 days'`),d.select({id:y.id,name:y.name,type:y.type}).from(y).where(Ps(Kn(y.createdBy,t),Kn(y.archived,!1))),d.select({treatmentId:ee.treatmentId,sessionId:ee.sessionId}).from(ee).where(Ps(Kn(ee.userId,t),Kn(ee.treatmentType,"instruction"),ko`${ee.sessionId} is not null`)),d.select({id:f.id,projectId:f.projectId,outcome:ko`${f.analysis}->>'outcome'`,startedAt:f.startedAt}).from(f).where(Ps(Kn(f.userId,t),ko`${f.analysis} is not null`))]),c=r.filter(I=>!(I.content&&iv.test(I.content))),a=r.length-c.length,l=c.map(I=>({id:I.id,name:I.name,type:I.type,reason:Number(I.totalExposures)===0?"never used":"not used in 30+ days",lastExposedAt:I.lastExposedAt,totalExposures:Number(I.totalExposures)})).sort((I,b)=>I.totalExposures-b.totalExposures).slice(0,50),p=new Map;for(let I of i){let b=I.outcome!=null?vs[I.outcome]:void 0;b!==void 0&&p.set(I.id,{projectId:I.projectId,score:b,time:I.startedAt?.getTime()??0})}let m=new Map;for(let I of s){if(!I.sessionId)continue;let b=m.get(I.treatmentId);b||(b=new Set,m.set(I.treatmentId,b)),b.add(I.sessionId)}let _=[];for(let I of o){let b=m.get(I.id);if(!b)continue;let S=0;for(let E of b)p.has(E)&&S++;if(S<10)continue;let A=new Map;for(let[E,{projectId:P,score:N,time:C}]of p){let z=P??"(no-project)",B=A.get(z);B||(B={key:z,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},A.set(z,B));let q=b.has(E);(q?B.withScores:B.withoutScores).push(N),(q?B.withTimes:B.withoutTimes).push(C)}let x=pn([...A.values()]);Kp(x)&&_.push({id:I.id,name:I.name,type:I.type,verdict:x,exposures:x.nWith})}let v=0,g=_;if(_.length>0){let I=await d.select({id:y.id,content:y.content}).from(y).where(Gj(y.id,_.map(S=>S.id))),b=new Map(I.map(S=>[S.id,S.content]));g=_.filter(S=>{let A=b.get(S.id);return A&&iv.test(A)?(v++,!1):!0})}g.sort((I,b)=>I.verdict.delta-b.verdict.delta);let h=new Set(g.map(I=>I.id)),w=l.filter(I=>!h.has(I.id));return e.json({captureHealthy:!0,candidates:w,safetyGuarded:a,harmful:g,harmfulSafetyGuarded:v})});import{Hono as Yj}from"hono";import{z as Os}from"zod";import{and as Dn,desc as cv,eq as at,getTableColumns as Xj,gte as vm,ilike as Fu,isNull as Qj,ne as Zj,or as eN,sql as Yn}from"drizzle-orm";import{desc as Kj,eq as av}from"drizzle-orm";async function Sa(e){if(!e)return null;try{let[t]=await d.select({projectId:ce.projectId}).from(ce).where(av(ce.path,e)).orderBy(Kj(ce.lastSeen)).limit(1);if(t)return t.projectId;let[n]=await d.select({id:O.id}).from(O).where(av(O.gitRemoteUrl,e)).limit(1);return n?.id??null}catch{return null}}u(Sa,"resolveProjectIdForPath");var zr=new Yj;function tN(e,t){let n=t?Fu(F.projectPath,`%${Ze(t)}%`):void 0;return e&&n?eN(at(F.projectId,e),Dn(Qj(F.projectId),n)):e?at(F.projectId,e):n}u(tN,"insightsJobProjectScope");zr.post("/insights-jobs",async e=>{let t=e.get("userId"),n=await e.req.json().catch(()=>({})),r=n.dedup,o=n.projectPath??null,s=await Sa(o);if(r==="daily"){let p=new Date;p.setHours(0,0,0,0);let m=o,_=[at(F.userId,t),vm(F.createdAt,p)];s?_.push(at(F.projectId,s)):m?_.push(Fu(F.projectPath,`%${Ze(m)}%`)):_.push(Yn`${F.projectPath} IS NULL`);let[v]=await d.select({id:F.id}).from(F).where(Dn(..._)).limit(1);if(v)return e.json({skipped:!0,reason:"already_generated_today",existingJobId:v.id},200);let g=[at(F.userId,t),at(F.status,"completed")];s?g.push(at(F.projectId,s)):m?g.push(Fu(F.projectPath,`%${Ze(m)}%`)):g.push(Yn`${F.projectPath} IS NULL`);let[h]=await d.select({completedAt:F.completedAt}).from(F).where(Dn(...g)).orderBy(cv(F.completedAt)).limit(1),w=h?.completedAt??new Date(0),I=[at(f.userId,t),vm(f.startedAt,w)];s?I.push(at(f.projectId,s)):m&&I.push(Fu(f.projectPath,`%${Ze(m)}%`));let[{count:b}]=await d.select({count:Yn`COUNT(*)`}).from(f).where(Dn(...I));if(Number(b)<5)return e.json({skipped:!0,reason:"insufficient_sessions",sessionsSinceLastRun:Number(b),threshold:5},200)}let i=o,{id:c,noLiveWorker:a}=await kt({taskName:"process_insights",payload:{projectPath:i,projectId:s},userId:t,mirror:{userId:t,projectPath:i,projectId:s}}),[l]=await d.select().from(F).where(at(F.id,c));return e.json({...l,noLiveWorker:a},201)});zr.get("/insights-jobs",async e=>{let t=e.get("userId"),n=Number(e.req.query("limit")??10),r=e.req.query("projectPath"),o=e.req.query("projectId")??await Sa(r??null),s=[at(F.userId,t)],i=tN(o,r??null);i&&s.push(i);let{result:c,...a}=Xj(F),l=await d.select(a).from(F).where(Dn(...s)).orderBy(cv(F.createdAt)).limit(n);return e.json(l)});zr.get("/insights-jobs/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(F).where(Dn(at(F.id,n),at(F.userId,t)));return r?e.json(r):e.json({error:"Job not found"},404)});zr.patch("/insights-jobs/:id/progress",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),s=["running","paused"].includes(r.status)?r.status:"running",[i]=await d.update(F).set({status:s,progress:r.progress,updatedAt:new Date}).where(Dn(at(F.id,n),at(F.userId,t))).returning();return i?e.json(i):e.json({error:"Job not found"},404)});var nN=Os.object({status:Os.enum(["running","completed","failed"]).optional(),attempts:Os.number().int().nonnegative().optional(),error:Os.string().optional(),result:Os.record(Os.unknown()).optional()});zr.patch("/insights-jobs/:id/state",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=nN.parse(await e.req.json()),o={updatedAt:new Date};r.attempts!==void 0&&(o.attempts=r.attempts),r.status&&(o.status=r.status),r.error&&(o.error=r.error),r.result!==void 0&&(o.result=r.result),(r.status==="completed"||r.status==="failed")&&(o.completedAt=new Date);let[s]=await d.update(F).set(o).where(Dn(at(F.id,n),at(F.userId,t),Zj(F.status,"cancelled"))).returning();if(!s){let[i]=await d.select().from(F).where(Dn(at(F.id,n),at(F.userId,t)));return i?e.json(i):e.json({error:"Job not found"},404)}return e.json(s)});var rN=14400*1e3;zr.post("/insights-jobs/regenerate-all",async e=>{let t=e.get("userId"),n=await e.req.json().catch(()=>({})),r=Number(n.minSessions??3),o=n.force===!0,s=new Date(Date.now()-rN),i=await d.select({projectId:f.projectId,sessionCount:Yn`COUNT(*)`}).from(f).where(Dn(at(f.userId,t),Yn`${f.projectId} IS NOT NULL`)).groupBy(f.projectId).orderBy(Yn`COUNT(*) DESC`),c=i.map(v=>v.projectId).filter(v=>!!v),a=new Map;if(c.length>0){let v=await d.execute(Yn`
|
|
900
|
+
`):[];for(let M of gf)ff.add(M.sessionId);for(let M of y){let se=M.metadata?.local_session_meta,je=M.analysis,Pe=M.tokenUsage;if(M.tool&&(I[M.tool]=(I[M.tool]||0)+1),M.projectPath){let He=M.projectPath.split("/").pop()??M.projectPath;A[He]=(A[He]||0)+1}if(Pe&&!ff.has(M.id)){let He=Pe.input_tokens??0,Et=Pe.output_tokens??0,Kt=Pe.cache_read_input_tokens??0,$t=Pe.cache_creation_5m??0,qt=Pe.cache_creation_1h??0,Ge=Pe.cache_creation_input_tokens??0,it=$t+qt||Ge;ot+=He,G+=Et,ae+=Kt,me+=it;let Ze=await w(Pe,Ja,M.startedAt);Te+=Ze.inputUsd,Bt+=Ze.outputUsd,Be+=Ze.cacheReadUsd,le+=Ze.cacheWriteUsd;let Ft=Ze.inputUsd+Ze.outputUsd+Ze.cacheReadUsd+Ze.cacheWriteUsd,or=M.tool??"unknown",yf=ti[Ja]??Ga();Ka(yf,He,Et,Kt,it,Ft),ti[Ja]=yf;let wf=ni[or]??Ga();Ka(wf,He,Et,Kt,it,Ft),ni[or]=wf}if(se){Rn++;let He=se.user_message_count??0;z+=He,de+=(se.duration_minutes??0)/60,Me+=se.git_commits??0,N+=se.git_pushes??0,Q+=se.lines_added??0,xe+=se.lines_removed??0,st+=se.files_modified??0,Fe+=se.tool_errors??0;let Et=se.tool_counts;if(Et)for(let[Ze,Ft]of Object.entries(Et))b[Ze]=(b[Ze]||0)+Ft;let Kt=se.languages;if(Kt)for(let[Ze,Ft]of Object.entries(Kt))S[Ze]=(S[Ze]||0)+Ft;let $t=se.message_hours;$t&&F.push(...$t);let qt=se.tool_error_categories;if(qt)for(let[Ze,Ft]of Object.entries(qt))O[Ze]=(O[Ze]||0)+Ft;let Ge=se.user_response_times;Ge&&U.push(...Ge),Lt+=se.user_interruptions??0,se.uses_task_agent&&eo++,se.uses_mcp&&Sr++;let it=se.user_message_timestamps;it&&it.length>0&&ee.push({id:M.id,start:M.startedAt.toISOString(),timestamps:it})}if(je)if(M.analyzedAt){lf++;let He=new Date(M.analyzedAt).getTime();(Zs===null||He<Zs)&&(Zs=He),(ei===null||He>ei)&&(ei=He),He<r0&&mf++}else pf++;if(je){Zr++;let He=je.goal_categories;if(He)for(let[Ge,it]of Object.entries(He))it>0&&(x[Ge]=(x[Ge]||0)+it);let Et=je.outcome;Et&&(T[Et]=(T[Et]||0)+1);let Kt=je.user_satisfaction;if(Kt)for(let[Ge,it]of Object.entries(Kt))it>0&&(P[Ge]=(P[Ge]||0)+it);let $t=je.session_type;$t&&(E[$t]=(E[$t]||0)+1);let qt=je.friction??je.friction_counts;if(qt)for(let[Ge,it]of Object.entries(qt))it>0&&(j[Ge]=(j[Ge]||0)+it);bd.length<50&&bd.push({id:M.id,externalId:M.externalSessionId,date:M.startedAt.toISOString().split("T")[0]??"",summary:je.brief_summary??"",goal:je.underlying_goal,outcome:Et})}}let Ya=y.map(M=>M.startedAt.toISOString()).sort(),Sd=new Set(Ya.map(M=>M.split("T")[0]));for(let M of gf){let se=Number(M.inputTokens)||0,je=Number(M.outputTokens)||0,Pe=Number(M.cacheReadTokens)||0,He=Number(M.cacheWrite5m)||0,Et=Number(M.cacheWrite1h)||0,Kt=Number(M.cacheWriteLegacy)||0,$t=He+Et||Kt,qt=o0.get(M.sessionId)??new Date,Ge=await w({input_tokens:se,output_tokens:je,cache_read_input_tokens:Pe,cache_creation_input_tokens:$t},M.model,qt);Te+=Ge.inputUsd,Bt+=Ge.outputUsd,Be+=Ge.cacheReadUsd,le+=Ge.cacheWriteUsd,ot+=se,G+=je,ae+=Pe,me+=$t;let it=Ge.inputUsd+Ge.outputUsd+Ge.cacheReadUsd+Ge.cacheWriteUsd,Ze=ti[M.model]??Ga();Ka(Ze,se,je,Pe,$t,it),ti[M.model]=Ze;let Ft=s0.get(M.sessionId)??"unknown",or=ni[Ft]??Ga();Ka(or,se,je,Pe,$t,it),ni[Ft]=or}let to=u(M=>Math.round(M*100)/100,"round2"),i0=Te+Bt+Be+le,a0=to(i0),c0={inputUsd:to(Te),outputUsd:to(Bt),cacheReadUsd:to(Be),cacheWriteUsd:to(le)},Ad={};for(let[M,se]of Object.entries(ti))Ad[M]={input_tokens:se.input_tokens,output_tokens:se.output_tokens,cache_read_tokens:se.cache_read_tokens,cache_write_tokens:se.cache_write_tokens,cost_usd:to(se.cost_usd)};let xd={};for(let[M,se]of Object.entries(ni))xd[M]={input_tokens:se.input_tokens,output_tokens:se.output_tokens,cache_read_tokens:se.cache_read_tokens,cache_write_tokens:se.cache_write_tokens,cost_usd:to(se.cost_usd)};let Ar={"2-10s":0,"10-30s":0,"30s-1m":0,"1-2m":0,"2-5m":0,"5-15m":0,">15m":0};for(let M of U)M<10?Ar["2-10s"]++:M<30?Ar["10-30s"]++:M<60?Ar["30s-1m"]++:M<120?Ar["1-2m"]++:M<300?Ar["2-5m"]++:M<900?Ar["5-15m"]++:Ar[">15m"]++;let Uo=[...U].sort((M,se)=>M-se),u0=Uo.length>0?Uo[Math.floor(Uo.length/2)]:0,d0=Uo.length>0?Uo.reduce((M,se)=>M+se,0)/Uo.length:0,hf=0,_f=0;if(ee.length>1){let M=ee.flatMap(je=>je.timestamps.map(Pe=>({sessionId:je.id,time:new Date(Pe).getTime()}))).sort((je,Pe)=>je.time-Pe.time),se=new Set;for(let je=0;je<M.length-1;je++){let Pe=M[je],He=M[je+1];Pe.sessionId!==He.sessionId&&He.time-Pe.time<1800*1e3&&(se.add(Pe.sessionId),se.add(He.sessionId),hf++)}_f=se.size}let ri={computed:!0,total_sessions:y.length,window:{since:o??null,until:s??null},truncated:y.length>=m,sessions_with_meta:Rn,sessions_with_analysis:Zr,tools_used:I,date_range:{start:Ya[0]?.split("T")[0]??"",end:Ya[Ya.length-1]?.split("T")[0]??""},total_messages:z,total_duration_hours:Math.round(de*10)/10,total_input_tokens:ot,total_output_tokens:G,total_cache_read_tokens:ae,total_cache_write_tokens:me,estimated_cost_usd:a0,estimated_cost_breakdown:c0,estimated_cost_by_model:Object.keys(Ad).length>0?Ad:void 0,estimated_cost_by_tool:Object.keys(xd).length>0?xd:void 0,tool_counts:b,languages:S,git_commits:Me,git_pushes:N,projects:A,goal_categories:x,outcomes:T,satisfaction:P,session_types:E,friction:j,tool_error_categories:O,session_summaries:bd,total_tool_errors:Fe,total_interruptions:Lt,total_lines_added:Q,total_lines_removed:xe,total_files_modified:st,days_active:Sd.size,messages_per_day:Sd.size>0?Math.round(z/Sd.size*10)/10:0,message_hours:F,sessions_using_task_agent:eo,sessions_using_mcp:Sr,response_time:{median_seconds:Math.round(u0*10)/10,avg_seconds:Math.round(d0*10)/10,histogram:Ar,total_samples:U.length},parallel_sessions:{events:hf,sessions_involved:_f},analysis_freshness:{with_timestamp:lf,pre_instrumentation:pf,stale_30d:mf,oldest_analyzed_at:Zs?new Date(Zs).toISOString():null,newest_analyzed_at:ei?new Date(ei).toISOString():null}};ri.autoAddAvailable=!!(n&&Mj.existsSync(Lj.join(n,"CLAUDE.md")));let Xa=[Os(W.userId,t),Os(W.status,"completed")];r?Xa.push(Os(W.projectId,r)):n?Xa.push(av(W.projectPath,`%${et(n)}%`)):Xa.push(ba`${W.projectPath} IS NULL`);let[l0]=await ft.select({result:W.result}).from(W).where(sv(...Xa)).orderBy(iv(W.completedAt)).limit(1),p0=l0?.result,Ed=Wl(p0?.recommendations);if(Ed&&Object.keys(Ed).length>0)ri.recommendations=Ed;else if(y.length>=3){let M=Bj({totalSessions:y.length,sessionsWithAnalysis:Zr,toolCounts:b,toolErrorCategories:O,friction:j,outcomes:T,sessionsUsingMcp:Sr,sessionsUsingTaskAgent:eo,totalToolErrors:Fe,totalMessages:z,totalDurationHours:de});M&&(ri.recommendations=M)}return Hu.size>1e3&&Hu.clear(),Hu.set(c,{at:Date.now(),data:ri}),ri});return e.json(l)});import{Hono as Wj}from"hono";import{and as Dn,count as zj,eq as Ue,ilike as Vj,inArray as Jj,sql as Sn}from"drizzle-orm";var No=new Wj,jo=u(e=>la(e?.outcome??null),"scoreOf");No.get("/insights/linked-instructions",async e=>{let t=e.get("userId"),n=e.req.query("projectPath"),r=Number(e.req.query("limit")??20),o=[Ue(f.userId,t)];n&&o.push(Vj(f.projectPath,`%${et(n)}%`));let s=await d.select({id:_.id,name:_.name,contentHash:_.contentHash,linkedSessions:Sn`COUNT(DISTINCT ${ne.sessionId})`}).from(ne).innerJoin(f,Ue(f.id,ne.sessionId)).innerJoin(_,Ue(_.id,ne.instructionId)).where(Dn(...o)).groupBy(_.id,_.name,_.contentHash).orderBy(Sn`COUNT(DISTINCT ${ne.sessionId}) DESC`).limit(r);return e.json(s.map(i=>({id:i.id,name:i.name,contentHash:i.contentHash,linkedSessions:Number(i.linkedSessions)})))});No.get("/insights/instruction-impact",async e=>{let t=e.get("userId"),n=e.req.query("instructionId");if(!n)return e.json({error:"instructionId query param required"},400);let r=await d.select({id:f.id,projectId:f.projectId,model:f.model,tool:f.tool,tokenUsage:f.tokenUsage,analysis:f.analysis,metadata:f.metadata,eventCount:f.eventCount,startedAt:f.startedAt}).from(f).innerJoin(X,Ue(X.sessionId,f.id)).where(Dn(Ue(f.userId,t),Ue(X.treatmentType,"instruction"),Ue(X.treatmentId,n))),o=r.map(z=>z.id),s=await d.select({id:f.id,projectId:f.projectId,model:f.model,tool:f.tool,tokenUsage:f.tokenUsage,analysis:f.analysis,metadata:f.metadata,eventCount:f.eventCount,startedAt:f.startedAt}).from(f).where(Dn(Ue(f.userId,t),Sn`${f.analysis} IS NOT NULL`)),i=await d.selectDistinct({sessionId:X.sessionId}).from(X).where(Dn(Ue(X.userId,t),Ue(X.treatmentType,"instruction"))),c=new Set(i.map(z=>z.sessionId)),a=new Set(o),l=s.filter(z=>!a.has(z.id)&&c.has(z.id));function p(z){let de=0,ot=0,G=0,ae=0,me=[],Te={},Bt={achieved:1,fully_achieved:1,mostly_achieved:.75,partially_achieved:.5,unclear_from_transcript:.25,not_achieved:0,abandoned:0};for(let Be of z){let le=Be.analysis,Me=Be.metadata?.local_session_meta;if(le?.outcome){let Q=Bt[le.outcome];Q!==void 0&&me.push(Q)}Me&&(ae++,de+=Me.tool_errors??0,ot+=Me.duration_minutes??0,G+=(Me.lines_added??0)+(Me.lines_removed??0));let N=le?.goal_categories??{};for(let[Q,xe]of Object.entries(N))xe>0&&(Te[Q]=(Te[Q]||0)+xe)}return{sessionCount:z.length,enrichedCount:ae,outcomeScores:me,avgOutcomeScore:me.length>0?Math.round(me.reduce((Be,le)=>Be+le,0)/me.length*100)/100:null,avgToolErrors:ae>0?Math.round(de/ae*10)/10:null,avgDurationMinutes:ae>0?Math.round(ot/ae*10)/10:null,avgLinesChanged:ae>0?Math.round(G/ae):null,topGoalCategories:Te}}u(p,"computeCohort");let m=p(r),y=p(l),v=u(z=>{if(!z)return"(no-date)";let de=typeof z=="string"?new Date(z):z;return Number.isNaN(de.getTime())?"(no-date)":`${de.getUTCFullYear()}-${String(de.getUTCMonth()+1).padStart(2,"0")}`},"monthKey"),g=u(z=>{if(!z)return 0;let de=typeof z=="string"?new Date(z):z;return Number.isNaN(de.getTime())?0:de.getTime()},"timeOf"),h=new Map,w=u((z,de,ot,G)=>{let ae=`${z??"(no-project)"}|${v(de)}`,me=h.get(ae);me||(me={key:ae,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},h.set(ae,me)),(G?me.withScores:me.withoutScores).push(ot),(G?me.withTimes:me.withoutTimes).push(g(de))},"addToStratum");for(let z of r){let de=jo(z.analysis);de!=null&&w(z.projectId,z.startedAt,de,!0)}for(let z of l){let de=jo(z.analysis);de!=null&&w(z.projectId,z.startedAt,de,!1)}let b=u(z=>{let de=new Map,ot=new Set,G=u((ae,me,Te,Bt,Be)=>{let le=de.get(ae);le||(le=new Map,de.set(ae,le));let Me=`${me??"(no-project)"}|${v(Te)}`,N=le.get(Me);N||(N={key:Me,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},le.set(Me,N)),(Be?N.withScores:N.withoutScores).push(Bt),(Be?N.withTimes:N.withoutTimes).push(g(Te))},"add");for(let ae of r){let me=jo(ae.analysis),Te=z(ae);me==null||!Te||(ot.add(Te),G(Te,ae.projectId,ae.startedAt,me,!0))}for(let ae of l){let me=jo(ae.analysis),Te=z(ae);me==null||!Te||!ot.has(Te)||G(Te,ae.projectId,ae.startedAt,me,!1)}return[...ot].map(ae=>({segment:ae,strata:[...de.get(ae)?.values()??[]]}))},"buildAxisSegments"),I=u(z=>[...z].sort((de,ot)=>Number(ot.verdict.sufficient)-Number(de.verdict.sufficient)||ot.verdict.nWith-de.verdict.nWith),"sortSegs"),S=Kp([...h.values()],b(z=>vo(z.model))),A=S.overall,x=I(S.segments).map(z=>({model:z.segment,verdict:z.verdict})),T=I(Pu(b(z=>z.tool??null))).map(z=>({harness:z.segment,verdict:z.verdict})),{outcomeScores:P,...E}=m,{outcomeScores:j,...O}=y,[F]=await d.select({name:_.name}).from(_).where(Ue(_.id,n)).limit(1),[U]=await d.select({n:zj(),lastAssignedAt:Sn`max(${Tt.assignedAt})`}).from(Tt).where(Dn(Ue(Tt.userId,t),Ue(Tt.treatmentType,"instruction"),Ue(Tt.treatmentId,n),Ue(Tt.method,"auto_added"))),ee=U&&Number(U.n)>0?{count:Number(U.n),lastAssignedAt:U.lastAssignedAt}:null;return e.json({instructionId:n,instructionName:F?.name??"Unknown",verdict:A,segments:x,harnessSegments:T,autoAdded:ee,with:E,without:O,comparison:{outcomeScoreDelta:m.avgOutcomeScore!=null&&y.avgOutcomeScore!=null?Math.round((m.avgOutcomeScore-y.avgOutcomeScore)*100)/100:null,toolErrorsDelta:m.avgToolErrors!=null&&y.avgToolErrors!=null?Math.round((m.avgToolErrors-y.avgToolErrors)*10)/10:null,durationDelta:m.avgDurationMinutes!=null&&y.avgDurationMinutes!=null?Math.round((m.avgDurationMinutes-y.avgDurationMinutes)*10)/10:null}})});No.get("/insights/instruction-version-impact",async e=>{let t=e.get("userId"),n=e.req.query("instructionId");if(!n)return e.json({error:"instructionId query param required"},400);let r=await d.select({versionOrdinal:Fn.versionOrdinal,contentHash:Fn.contentHash,firstSeenAt:Fn.firstSeenAt,contentLength:Sn`COALESCE(LENGTH(${Fn.content}), 0)::int`}).from(Fn).where(Ue(Fn.instructionId,n)).orderBy(Fn.versionOrdinal),o=await d.select({id:f.id,projectId:f.projectId,analysis:f.analysis,startedAt:f.startedAt,version:X.treatmentVersion}).from(f).innerJoin(X,Ue(X.sessionId,f.id)).where(Dn(Ue(f.userId,t),Ue(X.treatmentType,"instruction"),Ue(X.treatmentId,n),Sn`${X.treatmentVersion} > 0`)),s=new Map;for(let I of o){let S=s.get(I.version)??[];S.push(I),s.set(I.version,S)}let i=r.map(I=>({version:I.versionOrdinal,contentHash:I.contentHash,firstSeenAt:I.firstSeenAt,sessions:s.get(I.versionOrdinal)?.length??0,replayable:Number(I.contentLength)>0})),c=i.filter(I=>I.sessions>0).map(I=>I.version).sort((I,S)=>I-S),a=Number(e.req.query("version")),l=Number(e.req.query("baselineVersion")),p=Number.isFinite(a)&&a>0?a:c.at(-1),m=Number.isFinite(l)&&l>0?l:c.filter(I=>I!==p).at(-1);if(p==null||m==null)return e.json({instructionId:n,versions:i,version:p??null,baselineVersion:m??null,verdict:null,insufficientReason:"only one version of this instruction has attributed sessions; there is no prior version to compare against"});let y=u(I=>{if(!I)return"(no-date)";let S=typeof I=="string"?new Date(I):I;return Number.isNaN(S.getTime())?"(no-date)":`${S.getUTCFullYear()}-${String(S.getUTCMonth()+1).padStart(2,"0")}`},"monthKey"),v=u(I=>{if(!I)return 0;let S=typeof I=="string"?new Date(I):I;return Number.isNaN(S.getTime())?0:S.getTime()},"timeOf"),g=new Map,h=u((I,S)=>{let A=jo(I.analysis);if(A==null)return;let x=`${I.projectId??"(no-project)"}|${y(I.startedAt)}`,T=g.get(x);T||(T={key:x,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},g.set(x,T)),(S?T.withScores:T.withoutScores).push(A),(S?T.withTimes:T.withoutTimes).push(v(I.startedAt))},"add");for(let I of s.get(p)??[])h(I,!0);for(let I of s.get(m)??[])h(I,!1);let w=mn([...g.values()],{baseline:"prior-version"}),[b]=await d.select({name:_.name}).from(_).where(Ue(_.id,n)).limit(1);return e.json({instructionId:n,instructionName:b?.name??"Unknown",version:p,baselineVersion:m,versions:i,verdict:w,replayableVersions:i.filter(I=>I.replayable).length})});No.get("/insights/memory-impact",async e=>{let t=e.get("userId"),n=e.req.query("memoryId");if(!n)return e.json({error:"memoryId query param required"},400);let[r]=await d.select({id:$.id,title:$.title,kind:$.kind,version:$.version,status:$.status}).from($).where(Dn(Ue($.id,n),Ue($.userId,t))).limit(1);if(!r)return e.json({error:"memory not found"},404);let o=await d.select({sessionId:X.sessionId,treatmentVersion:X.treatmentVersion}).from(X).where(Dn(Ue(X.userId,t),Ue(X.treatmentType,"memory"),Ue(X.treatmentId,n))),s=new Map,i=new Set;for(let h of o){let w=s.get(h.treatmentVersion);w||(w=new Set,s.set(h.treatmentVersion,w)),w.add(h.sessionId),i.add(h.sessionId)}let c=await d.select({id:f.id,projectId:f.projectId,outcome:Sn`${f.analysis}->>'outcome'`,startedAt:f.startedAt,inputTokens:Sn`coalesce((${f.tokenUsage}->>'input_tokens')::numeric, 0)`,outputTokens:Sn`coalesce((${f.tokenUsage}->>'output_tokens')::numeric, 0)`}).from(f).where(Dn(Ue(f.userId,t),Sn`${f.analysis} is not null`)).orderBy(f.id),a=u((h,w)=>w>0?Math.round(h/w*100)/100:null,"avg"),l=u(()=>({n:0,scoreSum:0,scoreN:0,tokenSum:0}),"cohort"),p=u(h=>h.n>0?Math.round(h.tokenSum/h.n):null,"avgTokens"),m=u(h=>{let w=s.get(h)??new Set,b=new Map,I=l(),S=l();for(let E of c){let j=w.has(E.id);if(!j&&i.has(E.id))continue;let O=j?I:S;O.n++,O.tokenSum+=Number(E.inputTokens)+Number(E.outputTokens);let F=jo({outcome:E.outcome});if(F!=null){O.scoreSum+=F,O.scoreN++;let U=E.projectId??"(no-project)",ee=b.get(U);ee||(ee={key:U,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},b.set(U,ee)),(j?ee.withScores:ee.withoutScores).push(F),(j?ee.withTimes:ee.withoutTimes).push(E.startedAt?.getTime()??0)}}let A=mn([...b.values()]),x={sessionCount:I.n,avgOutcomeScore:a(I.scoreSum,I.scoreN),avgTotalTokens:p(I)},T={sessionCount:S.n,avgOutcomeScore:a(S.scoreSum,S.scoreN),avgTotalTokens:p(S)},P={outcomeScoreDelta:x.avgOutcomeScore!=null&&T.avgOutcomeScore!=null?Math.round((x.avgOutcomeScore-T.avgOutcomeScore)*100)/100:null,totalTokensDelta:x.avgTotalTokens!=null&&T.avgTotalTokens!=null?x.avgTotalTokens-T.avgTotalTokens:null};return{verdict:A,with:x,without:T,comparison:P}},"computeVersion"),v=[...new Set([r.version,...s.keys()])].sort((h,w)=>w-h).map(h=>({version:h,isCurrent:h===r.version,...m(h)})),g=v.find(h=>h.isCurrent);return e.json({memoryId:n,memoryTitle:r.title,memoryKind:r.kind,memoryVersion:r.version,verdict:g.verdict,with:g.with,without:g.without,comparison:g.comparison,versions:v.map(({version:h,isCurrent:w,verdict:b,with:I,without:S})=>({version:h,isCurrent:w,verdict:b,with:I,without:S})),cost:{estimated:!0}})});var Gj=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;No.get("/insights/suggestion-impact",async e=>{let t=e.get("userId"),n=e.req.query("instructionIds")??e.req.query("instructionId")??"",r=[...new Set(n.split(",").map(l=>l.trim()).filter(l=>Gj.test(l)))].slice(0,200);if(r.length===0)return e.json({error:"instructionIds query param (comma-separated uuids) required"},400);let o=await d.select({sessionId:X.sessionId,treatmentId:X.treatmentId}).from(X).where(Dn(Ue(X.userId,t),Ue(X.treatmentType,"suggestion"),Jj(X.treatmentId,r))),s=new Map;for(let l of o){let p=s.get(l.treatmentId);p||(p=new Set,s.set(l.treatmentId,p)),p.add(l.sessionId)}let c=(await d.select({id:f.id,projectId:f.projectId,outcome:Sn`${f.analysis}->>'outcome'`,startedAt:f.startedAt}).from(f).where(Dn(Ue(f.userId,t),Sn`${f.analysis} is not null`)).orderBy(f.id)).map(l=>({id:l.id,key:l.projectId??"(no-project)",score:jo({outcome:l.outcome}),time:l.startedAt?.getTime()??0})).filter(l=>l.score!=null),a={};for(let l of r){let p=s.get(l);if(!p||p.size===0){a[l]=mn([]);continue}let m=new Map;for(let y of c){let v=m.get(y.key);v||(v={key:y.key,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},m.set(y.key,v));let g=p.has(y.id);(g?v.withScores:v.withoutScores).push(y.score),(g?v.withTimes:v.withoutTimes).push(y.time)}a[l]=mn([...m.values()],{iterations:2e3})}return e.json({impacts:a})});import{Hono as Kj}from"hono";import{and as Co,count as wm,eq as fn,inArray as cv,sql as gr}from"drizzle-orm";var Im=new Kj,vm=/force[- ]?push|rm\s+-rf|git\s+reset\s+--hard|drop\s+table|truncate\b|--no-verify|chmod\s+777|\bsudo\b|secret|credential|password|api[- ]?key|never\s+(delete|drop|force|push|commit|run|deploy)|do\s+not\s+(delete|drop|force|push|commit|run|deploy)/i;Im.get("/insights/groom-candidates",async e=>{let t=e.get("userId"),[n]=await d.select({n:wm()}).from(f).where(Co(fn(f.userId,t),gr`${f.startedAt} > now() - interval '7 days'`));if(Number(n?.n??0)===0)return e.json({captureHealthy:!1,reason:'No sessions captured in the last 7 days \u2014 cannot tell "unused" from "uncaptured". Grooming paused (never trust a dark pipeline).',candidates:[],harmful:[],safetyGuarded:0,harmfulSafetyGuarded:0,bloated:[],trimSafetyFlagged:0});let[r,o,s,i]=await Promise.all([d.select({id:_.id,name:_.name,type:_.type,content:_.content,lastExposedAt:gr`max(${X.exposedAt})`,totalExposures:wm(X.id)}).from(_).leftJoin(X,Co(fn(X.treatmentId,_.id),fn(X.userId,t))).where(Co(fn(_.createdBy,t),fn(_.archived,!1),gr`${_.createdAt} < now() - interval '30 days'`)).groupBy(_.id).having(gr`max(${X.exposedAt}) is null or max(${X.exposedAt}) < now() - interval '30 days'`),d.select({id:_.id,name:_.name,type:_.type}).from(_).where(Co(fn(_.createdBy,t),fn(_.archived,!1))),d.select({treatmentId:X.treatmentId,sessionId:X.sessionId}).from(X).where(Co(fn(X.userId,t),fn(X.treatmentType,"instruction"),gr`${X.sessionId} is not null`)),d.select({id:f.id,projectId:f.projectId,outcome:gr`${f.analysis}->>'outcome'`,startedAt:f.startedAt}).from(f).where(Co(fn(f.userId,t),gr`${f.analysis} is not null`))]),c=await d.select({treatmentId:X.treatmentId,projectId:f.projectId,n:wm()}).from(X).innerJoin(f,fn(f.id,X.sessionId)).where(Co(fn(X.userId,t),fn(X.treatmentType,"instruction"),gr`${f.projectId} is not null`)).groupBy(X.treatmentId,f.projectId),a=new Map;for(let E of c){if(!E.projectId)continue;let j=Number(E.n),O=a.get(E.treatmentId);(!O||j>O.n||j===O.n&&E.projectId<O.projectId)&&a.set(E.treatmentId,{projectId:E.projectId,n:j})}let l=u(E=>a.get(E)?.projectId??null,"topProjectId"),p=r.filter(E=>!(E.content&&vm.test(E.content))),m=r.length-p.length,y=p.map(E=>({id:E.id,name:E.name,type:E.type,reason:Number(E.totalExposures)===0?"never used":"not used in 30+ days",lastExposedAt:E.lastExposedAt,totalExposures:Number(E.totalExposures),topProjectId:l(E.id)})).sort((E,j)=>E.totalExposures-j.totalExposures).slice(0,50),v=new Map;for(let E of i){let j=E.outcome!=null?bs[E.outcome]:void 0;j!==void 0&&v.set(E.id,{projectId:E.projectId,score:j,time:E.startedAt?.getTime()??0})}let g=new Map;for(let E of s){if(!E.sessionId)continue;let j=g.get(E.treatmentId);j||(j=new Set,g.set(E.treatmentId,j)),j.add(E.sessionId)}let h=[],w=[];for(let E of o){let j=g.get(E.id);if(!j)continue;let O=0;for(let z of j)v.has(z)&&O++;if(O<10)continue;let F=new Map;for(let[z,{projectId:de,score:ot,time:G}]of v){let ae=de??"(no-project)",me=F.get(ae);me||(me={key:ae,withScores:[],withoutScores:[],withTimes:[],withoutTimes:[]},F.set(ae,me));let Te=j.has(z);(Te?me.withScores:me.withoutScores).push(ot),(Te?me.withTimes:me.withoutTimes).push(G)}let U=mn([...F.values()]),ee=xo(U);ee==="harmful"?h.push({id:E.id,name:E.name,type:E.type,verdict:U,exposures:U.nWith,topProjectId:l(E.id)}):ee==="neutral"&&w.push({id:E.id,name:E.name,type:E.type,verdict:U,exposures:U.nWith,topProjectId:l(E.id)})}let b=0,I=h;if(h.length>0){let E=await d.select({id:_.id,content:_.content}).from(_).where(cv(_.id,h.map(O=>O.id))),j=new Map(E.map(O=>[O.id,O.content]));I=h.filter(O=>{let F=j.get(O.id);return F&&vm.test(F)?(b++,!1):!0})}I.sort((E,j)=>E.verdict.delta-j.verdict.delta);let S=1500,A=[],x=0;if(w.length>0){let E=await d.select({id:_.id,estimatedTokens:gr`(length(${_.content}) / 4)::int`,content:_.content}).from(_).where(cv(_.id,w.map(O=>O.id))),j=new Map(E.map(O=>[O.id,O]));for(let O of w){let F=j.get(O.id),U=Number(F?.estimatedTokens??0);if(U<S)continue;let ee=!!(F?.content&&vm.test(F.content));ee&&x++,A.push({...O,estimatedTokens:U,containsSafetyLanguage:ee})}A.sort((O,F)=>F.estimatedTokens-O.estimatedTokens),A=A.slice(0,20)}let T=new Set(I.map(E=>E.id)),P=y.filter(E=>!T.has(E.id));return e.json({captureHealthy:!0,candidates:P,safetyGuarded:m,harmful:I,harmfulSafetyGuarded:b,bloated:A,trimSafetyFlagged:x})});import{Hono as Xj}from"hono";import{z as Ds}from"zod";import{and as Mn,desc as dv,eq as dt,getTableColumns as Qj,gte as bm,ilike as Wu,isNull as Zj,ne as eN,or as tN,sql as Yn}from"drizzle-orm";import{desc as Yj,eq as uv}from"drizzle-orm";async function Sa(e){if(!e)return null;try{let[t]=await d.select({projectId:ue.projectId}).from(ue).where(uv(ue.path,e)).orderBy(Yj(ue.lastSeen)).limit(1);if(t)return t.projectId;let[n]=await d.select({id:D.id}).from(D).where(uv(D.gitRemoteUrl,e)).limit(1);return n?.id??null}catch{return null}}u(Sa,"resolveProjectIdForPath");var Vr=new Xj;function nN(e,t){let n=t?Wu(W.projectPath,`%${et(t)}%`):void 0;return e&&n?tN(dt(W.projectId,e),Mn(Zj(W.projectId),n)):e?dt(W.projectId,e):n}u(nN,"insightsJobProjectScope");Vr.post("/insights-jobs",async e=>{let t=e.get("userId"),n=await e.req.json().catch(()=>({})),r=n.dedup,o=n.projectPath??null,s=await Sa(o);if(r==="daily"){let p=new Date;p.setHours(0,0,0,0);let m=o,y=[dt(W.userId,t),bm(W.createdAt,p)];s?y.push(dt(W.projectId,s)):m?y.push(Wu(W.projectPath,`%${et(m)}%`)):y.push(Yn`${W.projectPath} IS NULL`);let[v]=await d.select({id:W.id}).from(W).where(Mn(...y)).limit(1);if(v)return e.json({skipped:!0,reason:"already_generated_today",existingJobId:v.id},200);let g=[dt(W.userId,t),dt(W.status,"completed")];s?g.push(dt(W.projectId,s)):m?g.push(Wu(W.projectPath,`%${et(m)}%`)):g.push(Yn`${W.projectPath} IS NULL`);let[h]=await d.select({completedAt:W.completedAt}).from(W).where(Mn(...g)).orderBy(dv(W.completedAt)).limit(1),w=h?.completedAt??new Date(0),b=[dt(f.userId,t),bm(f.startedAt,w)];s?b.push(dt(f.projectId,s)):m&&b.push(Wu(f.projectPath,`%${et(m)}%`));let[{count:I}]=await d.select({count:Yn`COUNT(*)`}).from(f).where(Mn(...b));if(Number(I)<5)return e.json({skipped:!0,reason:"insufficient_sessions",sessionsSinceLastRun:Number(I),threshold:5},200)}let i=o,{id:c,noLiveWorker:a}=await kt({taskName:"process_insights",payload:{projectPath:i,projectId:s},userId:t,mirror:{userId:t,projectPath:i,projectId:s}}),[l]=await d.select().from(W).where(dt(W.id,c));return e.json({...l,noLiveWorker:a},201)});Vr.get("/insights-jobs",async e=>{let t=e.get("userId"),n=Number(e.req.query("limit")??10),r=e.req.query("projectPath"),o=e.req.query("projectId")??await Sa(r??null),s=[dt(W.userId,t)],i=nN(o,r??null);i&&s.push(i);let{result:c,...a}=Qj(W),l=await d.select(a).from(W).where(Mn(...s)).orderBy(dv(W.createdAt)).limit(n);return e.json(l)});Vr.get("/insights-jobs/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(W).where(Mn(dt(W.id,n),dt(W.userId,t)));return r?e.json(r):e.json({error:"Job not found"},404)});Vr.patch("/insights-jobs/:id/progress",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json(),s=["running","paused"].includes(r.status)?r.status:"running",[i]=await d.update(W).set({status:s,progress:r.progress,updatedAt:new Date}).where(Mn(dt(W.id,n),dt(W.userId,t))).returning();return i?e.json(i):e.json({error:"Job not found"},404)});var rN=Ds.object({status:Ds.enum(["running","completed","failed"]).optional(),attempts:Ds.number().int().nonnegative().optional(),error:Ds.string().optional(),result:Ds.record(Ds.unknown()).optional()});Vr.patch("/insights-jobs/:id/state",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=rN.parse(await e.req.json()),o={updatedAt:new Date};r.attempts!==void 0&&(o.attempts=r.attempts),r.status&&(o.status=r.status),r.error&&(o.error=r.error),r.result!==void 0&&(o.result=r.result),(r.status==="completed"||r.status==="failed")&&(o.completedAt=new Date);let[s]=await d.update(W).set(o).where(Mn(dt(W.id,n),dt(W.userId,t),eN(W.status,"cancelled"))).returning();if(!s){let[i]=await d.select().from(W).where(Mn(dt(W.id,n),dt(W.userId,t)));return i?e.json(i):e.json({error:"Job not found"},404)}return e.json(s)});var oN=14400*1e3;Vr.post("/insights-jobs/regenerate-all",async e=>{let t=e.get("userId"),n=await e.req.json().catch(()=>({})),r=Number(n.minSessions??3),o=n.force===!0,s=new Date(Date.now()-oN),i=await d.select({projectId:f.projectId,sessionCount:Yn`COUNT(*)`}).from(f).where(Mn(dt(f.userId,t),Yn`${f.projectId} IS NOT NULL`)).groupBy(f.projectId).orderBy(Yn`COUNT(*) DESC`),c=i.map(v=>v.projectId).filter(v=>!!v),a=new Map;if(c.length>0){let v=await d.execute(Yn`
|
|
901
901
|
SELECT DISTINCT ON (project_id) project_id, path
|
|
902
902
|
FROM project_checkouts
|
|
903
903
|
WHERE project_id IN (${Yn.join(c.map(g=>Yn`${g}`),Yn`, `)})
|
|
904
904
|
ORDER BY project_id, is_worktree ASC, last_seen DESC
|
|
905
|
-
`);for(let g of v)a.set(g.project_id,g.path)}let l=[],p=[],m=[],
|
|
905
|
+
`);for(let g of v)a.set(g.project_id,g.path)}let l=[],p=[],m=[],y=!1;for(let v of i){if(Number(v.sessionCount)<r||!v.projectId)continue;let g=a.get(v.projectId);if(!g){p.push({projectPath:"<unknown>",reason:"no_checkout"});continue}try{if(!o){let[I]=await d.select({id:W.id}).from(W).where(Mn(dt(W.userId,t),dt(W.status,"completed"),dt(W.projectPath,g),bm(W.completedAt,s))).limit(1);if(I){p.push({projectPath:g,reason:"fresh"});continue}}let{id:h,noLiveWorker:w}=await kt({taskName:"process_insights",payload:{projectPath:g},userId:t,mirror:{userId:t,projectPath:g}});w&&(y=!0);let[b]=await d.select().from(W).where(dt(W.id,h));b&&l.push(b)}catch(h){let w=h instanceof Error?h.message:String(h);m.push({projectPath:g,error:w})}}return e.json({created:l.length,jobs:l,skipped:p,errors:m,noLiveWorker:y},201)});import zu from"node:fs";import sN from"node:path";import{createHash as iN}from"node:crypto";import{Hono as aN}from"hono";import{and as lv,desc as cN,eq as Aa}from"drizzle-orm";var Sm=new aN;async function uN(e,t,n){try{let r=`${Wc.claude_md}::${n}`,[o]=await d.select({id:_.id,version:_.version}).from(_).where(lv(Aa(_.contextIdentity,r),Aa(_.createdBy,e),Aa(_.archived,!1))).orderBy(cN(_.createdAt)).limit(1);if(!o){let c=zu.readFileSync(n,"utf-8"),a=iN("sha256").update(c).digest("hex"),l={name:n,description:"Project CLAUDE.md",type:"context_file",scope:"personal",version:"1.0.0"},[p]=await d.insert(_).values({name:n,description:"Project CLAUDE.md",type:"context_file",scope:"personal",scopeRef:e,version:"1.0.0",content:c,frontmatter:l,contentHash:a,contextIdentity:r,createdBy:e}).onConflictDoNothing().returning({id:_.id,version:_.version});o=p}if(!o)return null;let s=await Sa(t),[i]=await d.insert(Tt).values({userId:e,treatmentType:"instruction",treatmentId:o.id,projectId:s??void 0,assignedBy:e,method:"auto_added"}).returning({id:Tt.id});return i?.id??null}catch(r){return console.warn("[auto-add] failed to record treatment_assignment:",r instanceof Error?r.message:r),null}}u(uN,"recordAutoAddAssignment");Sm.post("/insights/auto-add",async e=>{let t=e.get("userId"),n=await e.req.json(),{projectPath:r,addition:o}=n;if(!r||!o)return e.json({error:"projectPath and addition are required"},400);let[s]=await d.select({id:f.id}).from(f).where(lv(Aa(f.userId,t),Aa(f.projectPath,r))).limit(1);if(!s)return e.json({error:"projectPath is not a known project for this user"},403);let i=sN.join(r,"CLAUDE.md");if(!zu.existsSync(i))return e.json({error:`CLAUDE.md not found at ${i} on the API host \u2014 auto-add only works when the API runs on the same machine as the project (local mode)`,code:"not_local_mode"},501);try{let c=zu.readFileSync(i,"utf-8");if(c.includes(o.trim()))return e.json({success:!1,reason:"already_present"},200);let a=c.endsWith(`
|
|
906
906
|
`)?`
|
|
907
907
|
`:`
|
|
908
908
|
|
|
909
|
-
`;
|
|
910
|
-
`);let l=await
|
|
911
|
-
when ${
|
|
912
|
-
when ${
|
|
909
|
+
`;zu.writeFileSync(i,c+a+o.trim()+`
|
|
910
|
+
`);let l=await uN(t,r,i);return e.json({success:!0,path:i,addedAt:new Date().toISOString(),assignmentId:l,tracked:l!=null})}catch(c){let a=c instanceof Error?c.message:String(c);return e.json({error:`Failed to write: ${a}`},500)}});var hr=new dN;hr.route("/",mm);hr.route("/",ym);hr.route("/",No);hr.route("/",Im);hr.route("/",Vr);hr.route("/",Sm);import{Hono as lN}from"hono";import{z as vt}from"zod";import{and as _r,desc as Vu,eq as yt,sql as Qt}from"drizzle-orm";var An=new lN,Am=["fact","decision","correction","convention"],pv=4e3,pN=vt.object({kind:vt.enum(Am),title:vt.string().min(1).max(300),body:vt.string().min(1).max(pv),projectId:vt.string().uuid().optional(),projectPath:vt.string().optional(),source:vt.enum(["manual","distilled"]).optional()}),mN=vt.object({kind:vt.enum(Am).optional(),title:vt.string().min(1).max(300).optional(),body:vt.string().min(1).max(pv).optional(),status:vt.enum(["active","archived"]).optional()});async function xm(e){if(!e)return null;try{let[t]=await d.select({projectId:ue.projectId}).from(ue).where(yt(ue.path,e)).orderBy(Vu(ue.lastSeen)).limit(1);if(t)return t.projectId;let[n]=await d.select({id:D.id}).from(D).where(yt(D.gitRemoteUrl,e)).limit(1);return n?.id??null}catch{return null}}u(xm,"resolveProjectId");An.get("/memories",async e=>{let t=e.get("userId"),n=e.req.query("projectId"),r=e.req.query("projectPath"),o=e.req.query("status")??"active",s=Number(e.req.query("limit")??"50"),i=Math.min(Math.max(Number.isFinite(s)?s:50,1),200),c=Number(e.req.query("offset")??"0"),a=Math.max(Number.isFinite(c)?c:0,0),l=e.req.query("rank"),p=n??await xm(r??null),m=[yt($.userId,t)];o!=="all"&&m.push(yt($.status,o));let y=e.req.query("kind");y&&Am.includes(y)&&m.push(yt($.kind,y));let v=e.req.query("search")?.trim();if(v){let b=`%${et(v)}%`;m.push(Qt`(${$.title} ilike ${b} or ${$.body} ilike ${b})`)}(n||r)&&m.push(p?Qt`(${$.projectId} = ${p} or ${$.projectId} is null)`:Qt`${$.projectId} is null`);let g=Qt`${$.trustVersion} = ${$.version}`;l==="trust"&&m.push(Qt`coalesce(${$.trustClass} = 'harmful' and ${g}, false) = false`);let h=Qt`case
|
|
911
|
+
when ${$.source} = 'manual' or (${$.trustClass} = 'helpful' and ${g}) then 0
|
|
912
|
+
when ${$.trustClass} = 'neutral' and ${g} then 1
|
|
913
913
|
else 2
|
|
914
|
-
end`,w=await d.select({id
|
|
914
|
+
end`,w=await d.select({id:$.id,version:$.version,kind:$.kind,title:$.title,body:$.body,source:$.source,status:$.status,projectId:$.projectId,createdAt:$.createdAt,updatedAt:$.updatedAt}).from($).where(_r(...m)).orderBy(...l==="trust"?[h,Vu($.updatedAt)]:[Vu($.updatedAt)]).limit(i).offset(l==="trust"?0:a);return e.json({memories:w})});An.post("/memories/relevant",async e=>{let t=e.get("userId"),n=await e.req.json().catch(()=>({})),r=typeof n.prompt=="string"?n.prompt.slice(0,2e3):"";if(!r.trim())return e.json({memories:[]});let o=Number(n.limit),s=Math.min(Math.max(Number.isFinite(o)?o:10,1),50),i=.035,c=Number(n.minRank),a=Number.isFinite(c)?Math.min(Math.max(c,0),1):i,l=Array.isArray(n.excludeIds)?n.excludeIds.filter(w=>typeof w=="string").slice(0,500):[],p=typeof n.projectId=="string"?n.projectId:void 0,m=typeof n.projectPath=="string"?n.projectPath:void 0,y=p??await xm(m??null),v=p||m?y?Qt`(m.project_id = ${y} or m.project_id is null)`:Qt`m.project_id is null`:Qt`true`,g=l.length?Qt`and m.id not in (${Qt.join(l.map(w=>Qt`${w}::uuid`),Qt`, `)})`:Qt``,h=await d.execute(Qt`
|
|
915
915
|
with raw as (
|
|
916
916
|
select websearch_to_tsquery('english', ${r})::text as t
|
|
917
917
|
), q as (
|
|
@@ -942,7 +942,7 @@ Only include instructions with a relevance score >= 0.5. Order by score descendi
|
|
|
942
942
|
else 2 end,
|
|
943
943
|
m.updated_at desc
|
|
944
944
|
limit ${s}
|
|
945
|
-
`);return e.json({memories:[...h]})});Sn.get("/memories/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(L).where(gr(ht(L.id,n),ht(L.userId,t))).limit(1);return r?e.json(r):e.json({error:"not found"},404)});Sn.post("/memories",async e=>{let t=e.get("userId"),n=lN.safeParse(await e.req.json().catch(()=>({})));if(!n.success)return e.json({error:"invalid body",details:n.error.flatten()},400);let{kind:r,title:o,body:s,projectId:i,projectPath:c,source:a}=n.data,l=i??await Sm(c??null),[p]=await d.select({orgId:T.activeOrgId}).from(T).where(ht(T.id,t)).limit(1),[m]=await d.insert(L).values({userId:t,orgId:p?.orgId??null,projectId:l,kind:r,title:o,body:s,source:a??"manual",status:"active"}).returning();return e.json(m,201)});Sn.patch("/memories/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=pN.safeParse(await e.req.json().catch(()=>({})));if(!r.success)return e.json({error:"invalid body",details:r.error.flatten()},400);let[o]=await d.select().from(L).where(gr(ht(L.id,n),ht(L.userId,t))).limit(1);if(!o)return e.json({error:"not found"},404);let{kind:s,title:i,body:c,status:a}=r.data,l=s!==void 0&&s!==o.kind||i!==void 0&&i!==o.title||c!==void 0&&c!==o.body,[p]=await d.update(L).set({kind:s??o.kind,title:i??o.title,body:c??o.body,status:a??o.status,version:l?o.version+1:o.version,updatedAt:new Date}).where(gr(ht(L.id,n),ht(L.userId,t))).returning();return e.json(p)});Sn.delete("/memories/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.update(L).set({status:"archived",updatedAt:new Date}).where(gr(ht(L.id,n),ht(L.userId,t))).returning({id:L.id,status:L.status});return r?e.json({ok:!0,id:r.id,status:r.status}):e.json({error:"not found"},404)});var mN=wt.object({externalSessionId:wt.string().min(1),projectPath:wt.string().optional()});Sn.post("/memories/:id/exposures",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=mN.safeParse(await e.req.json().catch(()=>({})));if(!r.success)return e.json({error:"invalid body",details:r.error.flatten()},400);let[o]=await d.select({id:L.id,version:L.version,projectId:L.projectId}).from(L).where(gr(ht(L.id,n),ht(L.userId,t))).limit(1);return o?(await d.insert(uc).values({userId:t,externalSessionId:r.data.externalSessionId,treatmentType:"memory",treatmentId:o.id,treatmentVersion:o.version,method:"injected",projectId:o.projectId}).onConflictDoNothing(),e.json({ok:!0})):e.json({error:"not found"},404)});var fN=wt.object({taskPrompt:wt.string().min(1).max(8e3),expectations:wt.array(wt.string().min(1)).min(1).max(20),trials:wt.number().int().min(1).max(50).default(10),model:wt.string().min(1).max(100).optional()});Sn.post("/memories/:id/experiments",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=fN.safeParse(await e.req.json().catch(()=>({})));if(!r.success)return e.json({error:"invalid body",details:r.error.flatten()},400);let[o]=await d.select({id:L.id,version:L.version}).from(L).where(gr(ht(L.id,n),ht(L.userId,t))).limit(1);if(!o)return e.json({error:"not found"},404);let[s]=await d.insert(Ar).values({memoryId:o.id,userId:t,memoryVersion:o.version,taskPrompt:r.data.taskPrompt,expectations:r.data.expectations,trials:r.data.trials,model:r.data.model??null,status:"pending"}).returning(),{noLiveWorker:i}=await Hy({experimentId:s.id,userId:t});return e.json({experiment:s,noLiveWorker:i},201)});Sn.get("/memories/:id/experiments",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:L.id}).from(L).where(gr(ht(L.id,n),ht(L.userId,t))).limit(1);if(!r)return e.json({error:"not found"},404);let o=await d.select().from(Ar).where(gr(ht(Ar.memoryId,n),ht(Ar.userId,t))).orderBy(Wu(Ar.createdAt)).limit(20);return e.json({experiments:o})});import{randomBytes as gN,createHash as hN}from"node:crypto";import{Hono as _N}from"hono";import{z as lv}from"zod";import{eq as zu,and as yN,isNull as wN}from"drizzle-orm";var Ds=new _N;function vN(){let n=`rm_${gN(32).toString("base64url")}`,r=hN("sha256").update(n).digest("hex"),o=n.slice(0,11);return{plaintext:n,hash:r,prefix:o}}u(vN,"generateApiKey");var IN=lv.object({name:lv.string().min(1).max(100)});Ds.post("/auth/api-keys",async e=>{let t=e.get("userId"),n=await e.req.json(),r=IN.parse(n),{plaintext:o,hash:s,prefix:i}=vN(),[c]=await d.insert(ye).values({userId:t,name:r.name,keyHash:s,keyPrefix:i}).returning();return e.json({id:c.id,name:c.name,key:o,keyPrefix:i,createdAt:c.createdAt},201)});Ds.get("/auth/api-keys",async e=>{let t=e.get("userId"),n=await d.select({id:ye.id,name:ye.name,keyPrefix:ye.keyPrefix,lastUsedAt:ye.lastUsedAt,expiresAt:ye.expiresAt,revokedAt:ye.revokedAt,createdAt:ye.createdAt}).from(ye).where(zu(ye.userId,t)).orderBy(ye.createdAt);return e.json(n)});Ds.delete("/auth/api-keys/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:ye.id}).from(ye).where(yN(zu(ye.id,n),zu(ye.userId,t),wN(ye.revokedAt)));return r?(await d.update(ye).set({revokedAt:new Date}).where(zu(ye.id,n)),e.json({revoked:!0})):e.json({error:"API key not found"},404)});import{Hono as bN}from"hono";import{z as hr}from"zod";import{eq as vt,and as _r,isNull as SN,sql as Am}from"drizzle-orm";import{randomUUID as xm}from"node:crypto";var yr=new bN;yr.post("/eval-targets/:id/conversations",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:R.id}).from(R).where(_r(vt(R.id,n),vt(R.userId,t)));if(!r)return e.json({error:"Target not found"},404);let[o]=await d.select().from(Te).where(_r(vt(Te.evalTargetId,n),vt(Te.userId,t),vt(Te.status,"active")));if(o)return e.json(o);let[s]=await d.insert(Te).values({evalTargetId:n,userId:t}).returning();return e.json(s,201)});yr.get("/eval-targets/:id/conversations",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(Te).where(_r(vt(Te.evalTargetId,n),vt(Te.userId,t),vt(Te.status,"active")));return r?e.json(r):e.json(null)});var AN=hr.object({content:hr.string().min(1).max(5e3)});yr.post("/eval-conversations/:id/messages",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=AN.parse(await e.req.json()),[o]=await d.select().from(Te).where(_r(vt(Te.id,n),vt(Te.userId,t)));if(!o)return e.json({error:"Conversation not found"},404);let s=xm(),i={id:s,role:"user",content:r.content,createdAt:new Date().toISOString()};await d.update(Te).set({messages:Am`${Te.messages} || ${JSON.stringify([i])}::jsonb`,updatedAt:new Date}).where(vt(Te.id,n));let c={type:"conversation",conversationId:n,messageId:s,messageContent:r.content},{id:a,noLiveWorker:l}=await kt({taskName:"process_conversation",payload:{evalTargetId:o.evalTargetId,config:c},userId:t,mirror:{userId:t,evalTargetId:o.evalTargetId,config:c}});return e.json({message:i,jobId:a,noLiveWorker:l},201)});var xN=hr.object({content:hr.string(),type:hr.enum(["text","status","results","proposal","applied","generated","comparison"]).default("text"),data:hr.record(hr.unknown()).optional()});yr.post("/eval-conversations/:id/messages/assistant",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=xN.parse(await e.req.json()),o={id:xm(),role:"assistant",content:r.content,type:r.type,data:r.data,createdAt:new Date().toISOString()};return await d.update(Te).set({messages:Am`${Te.messages} || ${JSON.stringify([o])}::jsonb`,updatedAt:new Date}).where(_r(vt(Te.id,n),vt(Te.userId,t))),e.json(o,201)});yr.get("/eval-conversations/:id/messages",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.query("after"),[o]=await d.select().from(Te).where(_r(vt(Te.id,n),vt(Te.userId,t)));if(!o)return e.json({error:"Conversation not found"},404);let s=o.messages;if(r){let i=s.filter(c=>c.createdAt>r);return e.json(i)}return e.json(s)});var EN=hr.object({messageId:hr.string().uuid()});yr.post("/eval-conversations/:id/apply-proposal",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=EN.parse(await e.req.json()),[o]=await d.select().from(Te).where(_r(vt(Te.id,n),vt(Te.userId,t)));if(!o)return e.json({error:"Conversation not found"},404);let i=o.messages.find(m=>m.id===r.messageId&&m.type==="proposal");if(!i?.data?.proposedContent)return e.json({error:"Proposal message not found or has no content"},400);let[c]=await d.select().from(R).where(_r(vt(R.id,o.evalTargetId),vt(R.userId,t)));if(!c)return e.json({error:"Target not found"},404);let[a]=await d.insert(R).values({userId:t,name:c.name,type:c.type,content:i.data.proposedContent,description:c.description,metadata:c.metadata,version:c.version+1,parentId:c.id}).returning(),l=await d.select().from(he).where(_r(vt(he.evalTargetId,c.id),SN(he.retiredAt)));l.length>0&&await d.insert(he).values(l.map(m=>({evalTargetId:a.id,name:m.name,prompt:m.prompt,expectedOutput:m.expectedOutput,files:m.files,expectations:m.expectations})));let p={id:xm(),role:"assistant",content:`Applied changes \u2014 created v${a.version}`,type:"applied",data:{newVersion:a.version,evalTargetId:a.id},createdAt:new Date().toISOString()};return await d.update(Te).set({evalTargetId:a.id,messages:Am`${Te.messages} || ${JSON.stringify([p])}::jsonb`,updatedAt:new Date}).where(vt(Te.id,n)),e.json({newTarget:a,message:p})});import*as Ms from"node:fs";import*as No from"node:path";import{createHash as TN}from"node:crypto";import{fileURLToPath as RN}from"node:url";import{createRequire as kN}from"node:module";import{Hono as jN}from"hono";import{z as pt}from"zod";import{eq as jo,desc as NN,and as CN,sql as PN}from"drizzle-orm";var ON=No.dirname(RN(import.meta.url)),Vr=new jN,Vu=null,Ju=null;function DN(){let e=process.env.RULEMETRIC_SKILLS_REGISTRY_PATH;if(e&&Ms.existsSync(e))return e;try{let n=kN(import.meta.url),r=No.dirname(n.resolve("@rulemetric/skills-registry/package.json")),o=No.join(r,"registry.json");if(Ms.existsSync(o))return o}catch{}let t=No.resolve(ON,"../../../../packages/skills-registry/registry.json");return Ms.existsSync(t)?t:null}u(DN,"resolveRegistryPath");function pv(){if(Vu)return Vu;let e=DN();return e?(Vu=JSON.parse(Ms.readFileSync(e,"utf-8")),Vu):null}u(pv,"loadRegistry");function MN(){if(Ju)return Ju;let e=pv();return e?(Ju={version:e.version,generatedAt:e.generatedAt,skills:e.skills.map(({content:t,...n})=>n)},Ju):null}u(MN,"loadRegistryIndex");Vr.get("/skills",e=>{let t=MN();return t?e.json(t):e.json({error:"Skills registry not found"},404)});Vr.post("/skills/publish",async e=>{let t=e.get("userId"),n=await e.req.json();if(!n.id||!n.name||!n.content)return e.json({error:"Missing required fields: id, name, content"},400);if(n.content.trim().length<20)return e.json({error:"Content too short (minimum 20 characters)"},400);let[r]=await d.insert(Rr).values({skillId:n.id,name:n.name,description:n.description,category:n.category,tools:n.tools,tags:n.tags,content:n.content,submittedBy:t}).returning({id:Rr.id});return e.json({id:r.id,skillId:n.id,message:`Skill "${n.name}" submitted for review. It will appear in the registry after approval.`},201)});Vr.get("/skills/submissions/approved",async e=>{let n=(await d.select().from(Rr).where(jo(Rr.status,"approved")).orderBy(NN(Rr.createdAt))).map(r=>({id:r.skillId,name:r.name,description:r.description,category:r.category,tags:r.tags??[],tools:r.tools,source:{repo:"community",path:`published/${r.skillId}.md`,url:"",license:"MIT"},content:r.content,popularity:{installs:0},updatedAt:r.updatedAt?.toISOString()??new Date().toISOString()}));return e.json(n)});var mv=pt.object({id:pt.string().min(1),name:pt.string().min(1),description:pt.string(),content:pt.string().min(1),source:pt.object({repo:pt.string(),path:pt.string(),url:pt.string(),license:pt.string().optional()}),tags:pt.array(pt.string()).optional(),category:pt.string().optional(),updatedAt:pt.string().optional(),sourceUpdatedAt:pt.string().optional(),popularity:pt.object({stars:pt.number().int().nonnegative().optional(),installs:pt.number().int().nonnegative().optional()}).optional()}),r6=pt.object({skills:pt.array(mv).max(5e3)});Vr.post("/skills/sync-public",async e=>{let t=process.env.RULEMETRIC_REGISTRY_BOT_TOKEN;if(!t)return e.json({error:"Registry bot token not configured"},503);let n=e.req.header("authorization")??"";if((n.startsWith("Bearer ")?n.slice(7):"")!==t)return e.json({error:"Invalid bot token"},401);let o=await e.req.json(),s=pt.object({skills:pt.array(pt.unknown()).max(5e3)}).safeParse(o);if(!s.success)return e.json({error:"Invalid request body",issues:s.error.issues},400);let i=s.data.skills,c=0,a=0,l=0,p=0,m=0;for(let _ of i){let v=mv.safeParse(_);if(!v.success){console.warn("[sync-public] Skipping invalid skill entry:",JSON.stringify(v.error.issues)),m++;continue}let g=v.data,h=TN("sha256").update(g.content).digest("hex"),w=`public_skill::${g.source.repo}::${g.id}`,I=g.updatedAt??"1.0.0",[b]=await d.select({id:y.id,contentHash:y.contentHash,popularityScore:y.popularityScore,sourceUpdatedAt:y.sourceUpdatedAt}).from(y).where(CN(jo(y.name,g.id),jo(y.scope,"public"))),S=g.popularity&&Math.max(g.popularity.stars??0,g.popularity.installs??0)||null,A=g.sourceUpdatedAt?new Date(g.sourceUpdatedAt):null,x=A&&!Number.isNaN(A.getTime())?A:null;if(b)if(b.contentHash!==h){let P=!1;for(let N=0;N<=4;N++)try{await d.transaction(async C=>{await C.select({id:y.id}).from(y).where(jo(y.id,b.id)).for("update"),await C.update(y).set({description:g.description||g.name,content:g.content,contentHash:h,version:I,upstreamVersion:I,popularityScore:S,sourceUpdatedAt:x,frontmatter:{name:g.name,source:g.source,category:g.category??null,popularity:g.popularity??null},updatedAt:new Date}).where(jo(y.id,b.id));let[z]=await C.select({max:PN`coalesce(max(${me.versionNumber}), 0)`}).from(me).where(jo(me.instructionId,b.id));await C.insert(me).values({instructionId:b.id,versionNumber:(z?.max??0)+1,content:g.content,frontmatter:{name:g.name,source:g.source,category:g.category??null},changeSummary:`Synced from registry (${I})`})}),P=!0;break}catch(C){if(C.cause?.code==="23505"){if(N<4)continue;break}throw C}if(!P)continue;a++,p++}else{let E=b.sourceUpdatedAt?.getTime()??null,P=x?.getTime()??null,N=b.popularityScore!==S,C=x!==null&&E!==P;(N||C)&&await d.update(y).set({...N?{popularityScore:S}:{},...C?{sourceUpdatedAt:x}:{}}).where(jo(y.id,b.id)),l++}else{let[E]=await d.insert(y).values({name:g.id,description:g.description||g.name,type:"skill",scope:"public",scopeRef:null,version:I,content:g.content,frontmatter:{name:g.name,source:g.source,category:g.category??null,popularity:g.popularity??null},tags:g.tags??null,contentHash:h,contextIdentity:w,upstreamVersion:I,popularityScore:S,sourceUpdatedAt:x}).returning({id:y.id});E&&(c++,await d.insert(me).values({instructionId:E.id,versionNumber:1,content:g.content,frontmatter:{name:g.name,source:g.source,category:g.category??null},changeSummary:"Initial sync from public registry"}),p++)}}return e.json({inserted:c,updated:a,unchanged:l,versionsCreated:p,skipped:m})});Vr.get("/skills/:id",e=>{let t=pv();if(!t?.skills)return e.json({error:"Skills registry not found"},404);let n=t.skills.find(r=>r.id===e.req.param("id"));return n?e.json(n):e.json({error:"Skill not found"},404)});import{Hono as GN}from"hono";import{desc as KN,eq as YN}from"drizzle-orm";import{eq as gv,and as VN}from"drizzle-orm";var LN=/pricing|rate.?limit|rate.?cap|messages.?per|tokens.?per|RPM|TPM|TPD|cache.?write|cache.?read|context.?window|5.?hour|five.?hour|7.?day|seven.?day|weekly.?limit/i,$N="claude-haiku-4-5-20251001",qN=1e3,UN=.7,BN=`You extract pricing and rate-limit changes from AI provider release notes.
|
|
945
|
+
`);return e.json({memories:[...h]})});An.get("/memories/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from($).where(_r(yt($.id,n),yt($.userId,t))).limit(1);return r?e.json(r):e.json({error:"not found"},404)});An.post("/memories",async e=>{let t=e.get("userId"),n=pN.safeParse(await e.req.json().catch(()=>({})));if(!n.success)return e.json({error:"invalid body",details:n.error.flatten()},400);let{kind:r,title:o,body:s,projectId:i,projectPath:c,source:a}=n.data,l=i??await xm(c??null),[p]=await d.select({orgId:R.activeOrgId}).from(R).where(yt(R.id,t)).limit(1),[m]=await d.insert($).values({userId:t,orgId:p?.orgId??null,projectId:l,kind:r,title:o,body:s,source:a??"manual",status:"active"}).returning();return e.json(m,201)});An.patch("/memories/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=mN.safeParse(await e.req.json().catch(()=>({})));if(!r.success)return e.json({error:"invalid body",details:r.error.flatten()},400);let[o]=await d.select().from($).where(_r(yt($.id,n),yt($.userId,t))).limit(1);if(!o)return e.json({error:"not found"},404);let{kind:s,title:i,body:c,status:a}=r.data,l=s!==void 0&&s!==o.kind||i!==void 0&&i!==o.title||c!==void 0&&c!==o.body,[p]=await d.update($).set({kind:s??o.kind,title:i??o.title,body:c??o.body,status:a??o.status,version:l?o.version+1:o.version,updatedAt:new Date}).where(_r(yt($.id,n),yt($.userId,t))).returning();return e.json(p)});An.delete("/memories/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.update($).set({status:"archived",updatedAt:new Date}).where(_r(yt($.id,n),yt($.userId,t))).returning({id:$.id,status:$.status});return r?e.json({ok:!0,id:r.id,status:r.status}):e.json({error:"not found"},404)});var fN=vt.object({externalSessionId:vt.string().min(1),projectPath:vt.string().optional()});An.post("/memories/:id/exposures",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=fN.safeParse(await e.req.json().catch(()=>({})));if(!r.success)return e.json({error:"invalid body",details:r.error.flatten()},400);let[o]=await d.select({id:$.id,version:$.version,projectId:$.projectId}).from($).where(_r(yt($.id,n),yt($.userId,t))).limit(1);return o?(await d.insert(uc).values({userId:t,externalSessionId:r.data.externalSessionId,treatmentType:"memory",treatmentId:o.id,treatmentVersion:o.version,method:"injected",projectId:o.projectId}).onConflictDoNothing(),e.json({ok:!0})):e.json({error:"not found"},404)});var gN=vt.object({taskPrompt:vt.string().min(1).max(8e3),expectations:vt.array(vt.string().min(1)).min(1).max(20),trials:vt.number().int().min(1).max(50).default(10),model:vt.string().min(1).max(100).optional()});An.post("/memories/:id/experiments",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=gN.safeParse(await e.req.json().catch(()=>({})));if(!r.success)return e.json({error:"invalid body",details:r.error.flatten()},400);let[o]=await d.select({id:$.id,version:$.version}).from($).where(_r(yt($.id,n),yt($.userId,t))).limit(1);if(!o)return e.json({error:"not found"},404);let[s]=await d.insert(Er).values({memoryId:o.id,userId:t,memoryVersion:o.version,taskPrompt:r.data.taskPrompt,expectations:r.data.expectations,trials:r.data.trials,model:r.data.model??null,status:"pending"}).returning(),{noLiveWorker:i}=await Vy({experimentId:s.id,userId:t});return e.json({experiment:s,noLiveWorker:i},201)});An.get("/memories/:id/experiments",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:$.id}).from($).where(_r(yt($.id,n),yt($.userId,t))).limit(1);if(!r)return e.json({error:"not found"},404);let o=await d.select().from(Er).where(_r(yt(Er.memoryId,n),yt(Er.userId,t))).orderBy(Vu(Er.createdAt)).limit(20);return e.json({experiments:o})});import{randomBytes as hN,createHash as _N}from"node:crypto";import{Hono as yN}from"hono";import{z as mv}from"zod";import{eq as Ju,and as wN,isNull as vN}from"drizzle-orm";var Ms=new yN;function IN(){let n=`rm_${hN(32).toString("base64url")}`,r=_N("sha256").update(n).digest("hex"),o=n.slice(0,11);return{plaintext:n,hash:r,prefix:o}}u(IN,"generateApiKey");var bN=mv.object({name:mv.string().min(1).max(100)});Ms.post("/auth/api-keys",async e=>{let t=e.get("userId"),n=await e.req.json(),r=bN.parse(n),{plaintext:o,hash:s,prefix:i}=IN(),[c]=await d.insert(we).values({userId:t,name:r.name,keyHash:s,keyPrefix:i}).returning();return e.json({id:c.id,name:c.name,key:o,keyPrefix:i,createdAt:c.createdAt},201)});Ms.get("/auth/api-keys",async e=>{let t=e.get("userId"),n=await d.select({id:we.id,name:we.name,keyPrefix:we.keyPrefix,lastUsedAt:we.lastUsedAt,expiresAt:we.expiresAt,revokedAt:we.revokedAt,createdAt:we.createdAt}).from(we).where(Ju(we.userId,t)).orderBy(we.createdAt);return e.json(n)});Ms.delete("/auth/api-keys/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:we.id}).from(we).where(wN(Ju(we.id,n),Ju(we.userId,t),vN(we.revokedAt)));return r?(await d.update(we).set({revokedAt:new Date}).where(Ju(we.id,n)),e.json({revoked:!0})):e.json({error:"API key not found"},404)});import{Hono as SN}from"hono";import{z as yr}from"zod";import{eq as It,and as wr,isNull as AN,sql as Em}from"drizzle-orm";import{randomUUID as Tm}from"node:crypto";var vr=new SN;vr.post("/eval-targets/:id/conversations",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:k.id}).from(k).where(wr(It(k.id,n),It(k.userId,t)));if(!r)return e.json({error:"Target not found"},404);let[o]=await d.select().from(ke).where(wr(It(ke.evalTargetId,n),It(ke.userId,t),It(ke.status,"active")));if(o)return e.json(o);let[s]=await d.insert(ke).values({evalTargetId:n,userId:t}).returning();return e.json(s,201)});vr.get("/eval-targets/:id/conversations",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(ke).where(wr(It(ke.evalTargetId,n),It(ke.userId,t),It(ke.status,"active")));return r?e.json(r):e.json(null)});var xN=yr.object({content:yr.string().min(1).max(5e3)});vr.post("/eval-conversations/:id/messages",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=xN.parse(await e.req.json()),[o]=await d.select().from(ke).where(wr(It(ke.id,n),It(ke.userId,t)));if(!o)return e.json({error:"Conversation not found"},404);let s=Tm(),i={id:s,role:"user",content:r.content,createdAt:new Date().toISOString()};await d.update(ke).set({messages:Em`${ke.messages} || ${JSON.stringify([i])}::jsonb`,updatedAt:new Date}).where(It(ke.id,n));let c={type:"conversation",conversationId:n,messageId:s,messageContent:r.content},{id:a,noLiveWorker:l}=await kt({taskName:"process_conversation",payload:{evalTargetId:o.evalTargetId,config:c},userId:t,mirror:{userId:t,evalTargetId:o.evalTargetId,config:c}});return e.json({message:i,jobId:a,noLiveWorker:l},201)});var EN=yr.object({content:yr.string(),type:yr.enum(["text","status","results","proposal","applied","generated","comparison"]).default("text"),data:yr.record(yr.unknown()).optional()});vr.post("/eval-conversations/:id/messages/assistant",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=EN.parse(await e.req.json()),o={id:Tm(),role:"assistant",content:r.content,type:r.type,data:r.data,createdAt:new Date().toISOString()};return await d.update(ke).set({messages:Em`${ke.messages} || ${JSON.stringify([o])}::jsonb`,updatedAt:new Date}).where(wr(It(ke.id,n),It(ke.userId,t))),e.json(o,201)});vr.get("/eval-conversations/:id/messages",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=e.req.query("after"),[o]=await d.select().from(ke).where(wr(It(ke.id,n),It(ke.userId,t)));if(!o)return e.json({error:"Conversation not found"},404);let s=o.messages;if(r){let i=s.filter(c=>c.createdAt>r);return e.json(i)}return e.json(s)});var TN=yr.object({messageId:yr.string().uuid()});vr.post("/eval-conversations/:id/apply-proposal",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=TN.parse(await e.req.json()),[o]=await d.select().from(ke).where(wr(It(ke.id,n),It(ke.userId,t)));if(!o)return e.json({error:"Conversation not found"},404);let i=o.messages.find(m=>m.id===r.messageId&&m.type==="proposal");if(!i?.data?.proposedContent)return e.json({error:"Proposal message not found or has no content"},400);let[c]=await d.select().from(k).where(wr(It(k.id,o.evalTargetId),It(k.userId,t)));if(!c)return e.json({error:"Target not found"},404);let[a]=await d.insert(k).values({userId:t,name:c.name,type:c.type,content:i.data.proposedContent,description:c.description,metadata:c.metadata,version:c.version+1,parentId:c.id}).returning(),l=await d.select().from(_e).where(wr(It(_e.evalTargetId,c.id),AN(_e.retiredAt)));l.length>0&&await d.insert(_e).values(l.map(m=>({evalTargetId:a.id,name:m.name,prompt:m.prompt,expectedOutput:m.expectedOutput,files:m.files,expectations:m.expectations})));let p={id:Tm(),role:"assistant",content:`Applied changes \u2014 created v${a.version}`,type:"applied",data:{newVersion:a.version,evalTargetId:a.id},createdAt:new Date().toISOString()};return await d.update(ke).set({evalTargetId:a.id,messages:Em`${ke.messages} || ${JSON.stringify([p])}::jsonb`,updatedAt:new Date}).where(It(ke.id,n)),e.json({newTarget:a,message:p})});import*as Ls from"node:fs";import*as Oo from"node:path";import{createHash as RN}from"node:crypto";import{fileURLToPath as kN}from"node:url";import{createRequire as jN}from"node:module";import{Hono as NN}from"hono";import{z as gt}from"zod";import{eq as Po,desc as CN,and as PN,sql as ON}from"drizzle-orm";var DN=Oo.dirname(kN(import.meta.url)),Jr=new NN,Gu=null,Ku=null;function MN(){let e=process.env.RULEMETRIC_SKILLS_REGISTRY_PATH;if(e&&Ls.existsSync(e))return e;try{let n=jN(import.meta.url),r=Oo.dirname(n.resolve("@rulemetric/skills-registry/package.json")),o=Oo.join(r,"registry.json");if(Ls.existsSync(o))return o}catch{}let t=Oo.resolve(DN,"../../../../packages/skills-registry/registry.json");return Ls.existsSync(t)?t:null}u(MN,"resolveRegistryPath");function fv(){if(Gu)return Gu;let e=MN();return e?(Gu=JSON.parse(Ls.readFileSync(e,"utf-8")),Gu):null}u(fv,"loadRegistry");function LN(){if(Ku)return Ku;let e=fv();return e?(Ku={version:e.version,generatedAt:e.generatedAt,skills:e.skills.map(({content:t,...n})=>n)},Ku):null}u(LN,"loadRegistryIndex");Jr.get("/skills",e=>{let t=LN();return t?e.json(t):e.json({error:"Skills registry not found"},404)});Jr.post("/skills/publish",async e=>{let t=e.get("userId"),n=await e.req.json();if(!n.id||!n.name||!n.content)return e.json({error:"Missing required fields: id, name, content"},400);if(n.content.trim().length<20)return e.json({error:"Content too short (minimum 20 characters)"},400);let[r]=await d.insert(jr).values({skillId:n.id,name:n.name,description:n.description,category:n.category,tools:n.tools,tags:n.tags,content:n.content,submittedBy:t}).returning({id:jr.id});return e.json({id:r.id,skillId:n.id,message:`Skill "${n.name}" submitted for review. It will appear in the registry after approval.`},201)});Jr.get("/skills/submissions/approved",async e=>{let n=(await d.select().from(jr).where(Po(jr.status,"approved")).orderBy(CN(jr.createdAt))).map(r=>({id:r.skillId,name:r.name,description:r.description,category:r.category,tags:r.tags??[],tools:r.tools,source:{repo:"community",path:`published/${r.skillId}.md`,url:"",license:"MIT"},content:r.content,popularity:{installs:0},updatedAt:r.updatedAt?.toISOString()??new Date().toISOString()}));return e.json(n)});var gv=gt.object({id:gt.string().min(1),name:gt.string().min(1),description:gt.string(),content:gt.string().min(1),source:gt.object({repo:gt.string(),path:gt.string(),url:gt.string(),license:gt.string().optional()}),tags:gt.array(gt.string()).optional(),category:gt.string().optional(),updatedAt:gt.string().optional(),sourceUpdatedAt:gt.string().optional(),popularity:gt.object({stars:gt.number().int().nonnegative().optional(),installs:gt.number().int().nonnegative().optional()}).optional()}),i6=gt.object({skills:gt.array(gv).max(5e3)});Jr.post("/skills/sync-public",async e=>{let t=process.env.RULEMETRIC_REGISTRY_BOT_TOKEN;if(!t)return e.json({error:"Registry bot token not configured"},503);let n=e.req.header("authorization")??"";if((n.startsWith("Bearer ")?n.slice(7):"")!==t)return e.json({error:"Invalid bot token"},401);let o=await e.req.json(),s=gt.object({skills:gt.array(gt.unknown()).max(5e3)}).safeParse(o);if(!s.success)return e.json({error:"Invalid request body",issues:s.error.issues},400);let i=s.data.skills,c=0,a=0,l=0,p=0,m=0;for(let y of i){let v=gv.safeParse(y);if(!v.success){console.warn("[sync-public] Skipping invalid skill entry:",JSON.stringify(v.error.issues)),m++;continue}let g=v.data,h=RN("sha256").update(g.content).digest("hex"),w=`public_skill::${g.source.repo}::${g.id}`,b=g.updatedAt??"1.0.0",[I]=await d.select({id:_.id,contentHash:_.contentHash,popularityScore:_.popularityScore,sourceUpdatedAt:_.sourceUpdatedAt}).from(_).where(PN(Po(_.name,g.id),Po(_.scope,"public"))),S=g.popularity&&Math.max(g.popularity.stars??0,g.popularity.installs??0)||null,A=g.sourceUpdatedAt?new Date(g.sourceUpdatedAt):null,x=A&&!Number.isNaN(A.getTime())?A:null;if(I)if(I.contentHash!==h){let P=!1;for(let E=0;E<=4;E++)try{await d.transaction(async j=>{await j.select({id:_.id}).from(_).where(Po(_.id,I.id)).for("update"),await j.update(_).set({description:g.description||g.name,content:g.content,contentHash:h,version:b,upstreamVersion:b,popularityScore:S,sourceUpdatedAt:x,frontmatter:{name:g.name,source:g.source,category:g.category??null,popularity:g.popularity??null},updatedAt:new Date}).where(Po(_.id,I.id));let[O]=await j.select({max:ON`coalesce(max(${fe.versionNumber}), 0)`}).from(fe).where(Po(fe.instructionId,I.id));await j.insert(fe).values({instructionId:I.id,versionNumber:(O?.max??0)+1,content:g.content,frontmatter:{name:g.name,source:g.source,category:g.category??null},changeSummary:`Synced from registry (${b})`})}),P=!0;break}catch(j){if(j.cause?.code==="23505"){if(E<4)continue;break}throw j}if(!P)continue;a++,p++}else{let T=I.sourceUpdatedAt?.getTime()??null,P=x?.getTime()??null,E=I.popularityScore!==S,j=x!==null&&T!==P;(E||j)&&await d.update(_).set({...E?{popularityScore:S}:{},...j?{sourceUpdatedAt:x}:{}}).where(Po(_.id,I.id)),l++}else{let[T]=await d.insert(_).values({name:g.id,description:g.description||g.name,type:"skill",scope:"public",scopeRef:null,version:b,content:g.content,frontmatter:{name:g.name,source:g.source,category:g.category??null,popularity:g.popularity??null},tags:g.tags??null,contentHash:h,contextIdentity:w,upstreamVersion:b,popularityScore:S,sourceUpdatedAt:x}).returning({id:_.id});T&&(c++,await d.insert(fe).values({instructionId:T.id,versionNumber:1,content:g.content,frontmatter:{name:g.name,source:g.source,category:g.category??null},changeSummary:"Initial sync from public registry"}),p++)}}return e.json({inserted:c,updated:a,unchanged:l,versionsCreated:p,skipped:m})});Jr.get("/skills/:id",e=>{let t=fv();if(!t?.skills)return e.json({error:"Skills registry not found"},404);let n=t.skills.find(r=>r.id===e.req.param("id"));return n?e.json(n):e.json({error:"Skill not found"},404)});import{Hono as KN}from"hono";import{desc as YN,eq as XN}from"drizzle-orm";import{eq as _v,and as JN}from"drizzle-orm";var $N=/pricing|rate.?limit|rate.?cap|messages.?per|tokens.?per|RPM|TPM|TPD|cache.?write|cache.?read|context.?window|5.?hour|five.?hour|7.?day|seven.?day|weekly.?limit/i,qN="claude-haiku-4-5-20251001",UN=1e3,BN=.7,FN=`You extract pricing and rate-limit changes from AI provider release notes.
|
|
946
946
|
Return a JSON object: {
|
|
947
947
|
"observations": [
|
|
948
948
|
{
|
|
@@ -957,66 +957,66 @@ Return a JSON object: {
|
|
|
957
957
|
}
|
|
958
958
|
Only emit observations if the release notes EXPLICITLY state a numeric value.
|
|
959
959
|
Do NOT speculate. Do NOT emit observations for "increased by X%" without an absolute number.
|
|
960
|
-
Return { "observations": [] } if nothing concrete.`;function
|
|
960
|
+
Return { "observations": [] } if nothing concrete.`;function HN(){let e=process.env.ANTHROPIC_API_KEY;if(!e)return null;let t=Wi("anthropic",e);return async n=>{let r=await t.complete(n,{model:qN,maxTokens:UN,temperature:0});return{text:r.text,usage:{inputTokens:r.usage?.inputTokens??0,outputTokens:r.usage?.outputTokens??0}}}}u(HN,"defaultLlm");async function WN(e){await d.insert(pe).values({provider:"anthropic",plan:e.plan,limitType:e.limitType,value:String(e.value),unit:e.unit,comparator:e.comparator,sourceType:e.sourceType,sourceUrl:e.sourceUrl,sourceEvidence:e.sourceEvidence,confidence:String(e.confidence)})}u(WN,"defaultObserve");function zN(e){return`${FN}
|
|
961
961
|
|
|
962
962
|
Release notes (harness=${e.harness}, version=${e.version}):
|
|
963
963
|
|
|
964
|
-
${e.body??""}`}u(
|
|
965
|
-
`);for(let s of o){let i=s.trim();if(!i.startsWith("- ")&&!i.startsWith("* "))continue;let c=i.replace(/^[-*]\s+/,"").trim();if(!c)continue;let a=c.toLowerCase();a.startsWith("security:")||a.includes("security fix")||a.includes("cve-")?r.push(c):a.startsWith("fixed ")||a.startsWith("fix ")||a.startsWith("fixed:")?n.push(c):t.push(c)}return{features:t,fixes:n,security:r}}u(JN,"parseReleaseBody");async function Gu(e){let t=e?hv.filter(o=>o.harness===e):hv,n=0,r=0;for(let o of t){let s=`https://api.github.com/repos/${o.repo}/releases?per_page=100`,i={Accept:"application/vnd.github+json"};process.env.GITHUB_TOKEN&&(i.Authorization=`Bearer ${process.env.GITHUB_TOKEN}`);let c=await fetch(s,{headers:i});if(!c.ok)continue;let a=await c.json();r+=a.length;for(let l of a){let p=JN(l.body??"");if((await d.select({id:Tt.id}).from(Tt).where(VN(gv(Tt.harness,o.harness),gv(Tt.version,l.tag_name)))).length===0){await d.insert(Tt).values({harness:o.harness,version:l.tag_name,publishedAt:new Date(l.published_at),title:l.name,body:l.body,categories:p,url:l.html_url}),n++;try{await fv({harness:o.harness,version:l.tag_name,url:l.html_url,publishedAt:new Date(l.published_at),body:l.body})}catch(_){console.warn("release notes extraction failed:",_)}}}}return{synced:n,total:r}}u(Gu,"syncHarnessReleases");var xa=new GN;xa.get("/harness-releases",async e=>{let t=e.req.query("harness"),n=Math.min(Number(e.req.query("limit")??50),100),r=t?YN(Tt.harness,t):void 0,o=await d.select({id:Tt.id,harness:Tt.harness,version:Tt.version,publishedAt:Tt.publishedAt,title:Tt.title,categories:Tt.categories,url:Tt.url}).from(Tt).where(r).orderBy(KN(Tt.publishedAt)).limit(n);return e.json(o)});xa.post("/harness-releases/sync",async e=>{let t=await e.req.json().catch(()=>({})),n=await Gu(t.harness);return e.json(n)});import{Hono as XN}from"hono";import{and as Ku,desc as QN,eq as Ls,isNull as Em,sql as ZN}from"drizzle-orm";var $s=new XN;$s.get("/notifications",async e=>{let t=e.get("userId"),n=Math.min(parseInt(e.req.query("limit")??"20",10),100),r=parseInt(e.req.query("offset")??"0",10),s=e.req.query("unread")==="true"?Ku(Ls(ft.userId,t),Em(ft.readAt)):Ls(ft.userId,t),i=await d.select().from(ft).where(s).orderBy(QN(ft.createdAt)).limit(n).offset(r),[{count:c}]=await d.select({count:ZN`count(*)::int`}).from(ft).where(Ku(Ls(ft.userId,t),Em(ft.readAt)));return e.json({items:i,unreadCount:c})});$s.post("/notifications/:id/read",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.update(ft).set({readAt:new Date}).where(Ku(Ls(ft.id,t),Ls(ft.userId,n))).returning();return r?e.json(r):e.json({error:"Not found"},404)});$s.post("/notifications/read-all",async e=>{let t=e.get("userId");return await d.update(ft).set({readAt:new Date}).where(Ku(Ls(ft.userId,t),Em(ft.readAt))),e.json({success:!0})});import{Hono as eC}from"hono";import{z as Gt}from"zod";import{eq as Xn,and as Yu,desc as tC,ne as nC}from"drizzle-orm";var Jr=new eC;function rC(e){let t=e.terminalTarget;if(!t||typeof t!="object")return null;let n=t;return n.kind!=="tmux"||typeof n.target!="string"||typeof n.attachCommand!="string"?null:{sessionId:typeof e.sessionId=="string"?e.sessionId:void 0,terminalTarget:{kind:"tmux",target:n.target,attachCommand:n.attachCommand,live:typeof n.live=="boolean"?n.live:void 0}}}u(rC,"parseTerminalTargetResult");async function oC(e){let t=rC(e.result);if(!t?.terminalTarget)return;let n=e.config&&typeof e.config=="object"?e.config:{},r=typeof n.projectPath=="string"?n.projectPath:null,o=typeof n.resumeSessionId=="string"?n.resumeSessionId:null,[s]=o?await d.select({id:f.id}).from(f).where(Yu(Xn(f.userId,e.userId),Xn(f.externalSessionId,o))).limit(1):[];await d.insert(We).values({userId:e.userId,sessionId:s?.id??null,externalSessionId:o,kind:"tmux",target:t.terminalTarget.target,status:t.terminalTarget.live===!1?"unknown":"active",attachCommand:t.terminalTarget.attachCommand,projectPath:r,metadata:{launchJobId:e.jobId,launcherSessionId:t.sessionId}}).onConflictDoUpdate({target:[We.userId,We.target],set:{sessionId:s?.id??null,externalSessionId:o,status:t.terminalTarget.live===!1?"unknown":"active",attachCommand:t.terminalTarget.attachCommand,projectPath:r,metadata:{launchJobId:e.jobId,launcherSessionId:t.sessionId},lastSeenAt:new Date,updatedAt:new Date}})}u(oC,"upsertTerminalTargetFromLaunchResult");var sC=Gt.object({tool:Gt.string().min(1),config:Gt.object({projectPath:Gt.string().min(1),prompt:Gt.string().optional(),systemPrompt:Gt.string().optional(),model:Gt.string().optional(),mode:Gt.enum(["headless","interactive"]).default("interactive"),timeout:Gt.number().int().positive().optional(),resumeSessionId:Gt.string().optional()})});Jr.post("/launch-jobs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=sC.parse(n),{id:o,noLiveWorker:s}=await kt({taskName:"process_launch",payload:{tool:r.tool,config:r.config},userId:t,mirror:{userId:t,tool:r.tool,config:r.config}}),[i]=await d.select().from(re).where(Xn(re.id,o));return e.json({...i,noLiveWorker:s},201)});Jr.get("/launch-jobs",async e=>{let t=e.get("userId"),n=Number(e.req.query("limit")??50),r=await d.select().from(re).where(Xn(re.userId,t)).orderBy(tC(re.createdAt)).limit(n);return e.json(r)});var iC=Gt.object({status:Gt.enum(["running","completed","failed"]).optional(),attempts:Gt.number().int().nonnegative().optional(),error:Gt.string().optional(),result:Gt.record(Gt.unknown()).optional()});Jr.patch("/launch-jobs/:id/state",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=iC.parse(await e.req.json()),o={updatedAt:new Date};r.attempts!==void 0&&(o.attempts=r.attempts),r.status&&(o.status=r.status),r.error&&(o.error=r.error),r.result!==void 0&&(o.result=r.result),(r.status==="completed"||r.status==="failed")&&(o.completedAt=new Date);let[s]=await d.update(re).set(o).where(Yu(Xn(re.id,n),Xn(re.userId,t),nC(re.status,"cancelled"))).returning();if(!s){let[i]=await d.select().from(re).where(Yu(Xn(re.id,n),Xn(re.userId,t)));return i?e.json(i):e.json({error:"Job not found"},404)}return r.result!==void 0&&await oC({userId:t,jobId:n,config:s.config,result:r.result}),e.json(s)});Jr.post("/launch-jobs/:id/cancel",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.update(re).set({status:"cancelled",updatedAt:new Date}).where(Yu(Xn(re.id,n),Xn(re.userId,t))).returning();return r?e.json(r):e.json({error:"Job not found"},404)});Jr.get("/launchers",async e=>{let{getAvailableLaunchers:t}=await Promise.resolve().then(()=>(uu(),Ly));return e.json(t())});import{Hono as aC}from"hono";import{z as An}from"zod";import{eq as ve,and as Mt,desc as Qu,inArray as Xu,isNull as cC,ne as uC}from"drizzle-orm";uu();var Qn=new aC,dC=An.object({tool:An.string().min(1),model:An.string().optional(),label:An.string().optional()}),lC=An.object({title:An.string().optional(),projectPath:An.string().min(1),gitRemote:An.string().optional(),baseBranch:An.string().optional(),prompt:An.string().optional(),autoWorktree:An.boolean().optional(),sessions:An.array(dC).min(1).max(8)});function pC(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/(^-|-$)/g,"")||"tool"}u(pC,"sanitizeTool");var mC=new Set(["pending","claimed","running"]);var fC=1800*1e3;function _v(e,t){if(e==="cancelled")return!0;if(e!=="completed"&&e!=="failed"||t==null)return!1;let n=t instanceof Date?t.getTime():Date.parse(t);return Number.isFinite(n)?Date.now()-n>fC:!1}u(_v,"canSkipRollup");function yv(e,t,n){if(e==="cancelled")return"cancelled";let r=t.length>0,o=t.some(c=>c.endedAt==null),s=n.some(c=>mC.has(c.status));return n.length>0&&n.every(c=>c.status==="failed")&&!r?"failed":o||s&&r?"running":r&&!o&&!s?"completed":"pending"}u(yv,"rollupRunStatus");async function wv(e){if(e.rolled===e.stored)return;let t=e.rolled==="completed"||e.rolled==="failed"||e.rolled==="cancelled",n={status:e.rolled,updatedAt:new Date};t&&!e.hadCompletedAt&&(n.completedAt=new Date);try{await d.update(W).set(n).where(Mt(ve(W.id,e.runId),ve(W.userId,e.userId),uC(W.status,"cancelled")))}catch{}}u(wv,"persistRolledUpStatus");function gC(e){return Array.isArray(e)?e.length:e&&typeof e=="object"?Object.values(e).reduce((t,n)=>t+(typeof n=="number"&&n>0?n:0),0):0}u(gC,"frictionCount");async function hC(e,t){if(!e||typeof e!="object")return null;let n=e,r="claude-sonnet-4-6",o=Wr(r),s={input_tokens:n.input_tokens??0,output_tokens:n.output_tokens??0,cache_read_input_tokens:n.cache_read_input_tokens??0,cache_creation_5m:n.cache_creation_5m??0,cache_creation_1h:n.cache_creation_1h??0,cache_creation_input_tokens:n.cache_creation_input_tokens??0},i=await mr(d,s,r,t,o);return i?{...i,estimated:!0}:null}u(hC,"deriveSessionCost");async function vv(e,t){let[n]=await d.select({id:W.id,autoWorktree:W.autoWorktree}).from(W).where(Mt(ve(W.id,e),ve(W.userId,t))).limit(1);if(!n||!n.autoWorktree)return{linked:0};let r=await d.select({config:re.config,result:re.result}).from(re).where(Mt(ve(re.runId,e),ve(re.userId,t))),o=new Set;for(let i of r){let c=i.result??{};typeof c.worktreePath=="string"&&c.worktreePath&&o.add(c.worktreePath);let a=i.config??{};a.worktree?.create&&typeof a.worktree.branch=="string"&&typeof a.projectPath=="string"&&o.add(cu({repoRoot:a.projectPath,branch:a.worktree.branch}))}return o.size===0?{linked:0}:{linked:(await d.update(f).set({runId:e}).where(Mt(ve(f.userId,t),cC(f.runId),Xu(f.projectPath,[...o]))).returning({id:f.id})).length}}u(vv,"linkRunSessions");Qn.post("/runs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=lC.parse(n),o=await vu(t,null),s=r.autoWorktree??!0,i=r.baseBranch??"HEAD",c=null;if(r.projectPath){let[m]=await d.select({projectId:ce.projectId}).from(ce).where(ve(ce.path,r.projectPath)).orderBy(Qu(ce.lastSeen)).limit(1);c=m?.projectId??null}if(!c&&r.gitRemote){let[m]=await d.select({id:O.id}).from(O).where(ve(O.gitRemoteUrl,r.gitRemote)).limit(1);c=m?.id??null}let[a]=await d.insert(W).values({userId:t,orgId:o,projectPath:r.projectPath,projectId:c,gitRemote:r.gitRemote??null,baseBranch:r.baseBranch??null,title:r.title??null,prompt:r.prompt??null,toolSpec:r.sessions,autoWorktree:s,status:"pending",sessionCount:r.sessions.length}).returning(),l=a.id.slice(0,8),p=!1;try{for(let m=0;m<r.sessions.length;m++){let _=r.sessions[m],v=`rm/run-${l}/s${m}-${pC(_.tool)}`,g={projectPath:r.projectPath,prompt:r.prompt,systemPrompt:void 0,model:_.model,mode:"interactive",worktree:{create:s,branch:v,baseRef:i},runId:a.id},h=await kt({taskName:"process_launch",userId:t,payload:{tool:_.tool,config:g},mirror:{userId:t,tool:_.tool,config:g},runId:a.id});p=p||h.noLiveWorker}}catch(m){return await d.update(W).set({status:"failed",updatedAt:new Date}).where(ve(W.id,a.id)),await d.update(re).set({status:"cancelled",updatedAt:new Date}).where(Mt(ve(re.runId,a.id),ve(re.status,"pending"))),e.json({error:"Failed to enqueue all launch jobs",detail:m instanceof Error?m.message:String(m),run:{...a,status:"failed"}},500)}return e.json({run:a,noLiveWorker:p},201)});Qn.get("/runs",async e=>{let t=e.get("userId"),n=Number(e.req.query("limit")),r=Math.min(Math.max(Number.isFinite(n)?n:50,1),100),o=Number(e.req.query("offset")),s=Math.max(Number.isFinite(o)?o:0,0),i=e.req.query("projectId"),c=i?Mt(ve(W.userId,t),ve(W.projectId,i)):ve(W.userId,t),a=await d.select({id:W.id,userId:W.userId,orgId:W.orgId,projectId:W.projectId,projectPath:W.projectPath,gitRemote:W.gitRemote,baseBranch:W.baseBranch,title:W.title,toolSpec:W.toolSpec,autoWorktree:W.autoWorktree,status:W.status,sessionCount:W.sessionCount,createdAt:W.createdAt,updatedAt:W.updatedAt,completedAt:W.completedAt}).from(W).where(c).orderBy(Qu(W.createdAt)).limit(r).offset(s),l=a.filter(m=>!_v(m.status,m.completedAt)),p=l.map(m=>m.id);if(p.length>0){let[m,_]=await Promise.all([d.select({runId:f.runId,endedAt:f.endedAt}).from(f).where(Mt(ve(f.userId,t),Xu(f.runId,p))),d.select({runId:re.runId,status:re.status}).from(re).where(Mt(ve(re.userId,t),Xu(re.runId,p)))]),v=new Map;for(let h of m){if(!h.runId)continue;let w=v.get(h.runId)??[];w.push({endedAt:h.endedAt}),v.set(h.runId,w)}let g=new Map;for(let h of _){if(!h.runId)continue;let w=g.get(h.runId)??[];w.push({status:h.status}),g.set(h.runId,w)}await Promise.all(l.map(async h=>{let w=yv(h.status,v.get(h.id)??[],g.get(h.id)??[]);w!==h.status&&(await wv({runId:h.id,userId:t,stored:h.status,rolled:w,hadCompletedAt:h.completedAt!=null}),h.status=w,h.completedAt==null&&(w==="completed"||w==="failed"||w==="cancelled")&&(h.completedAt=new Date))}))}return e.json({runs:a})});Qn.get("/runs/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(W).where(Mt(ve(W.id,n),ve(W.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);try{await vv(n,t)}catch{}let o=await d.select({id:f.id,tool:f.tool,gitBranch:f.gitBranch,projectPath:f.projectPath,startedAt:f.startedAt,endedAt:f.endedAt,eventCount:f.eventCount,tokenUsage:f.tokenUsage,analysis:f.analysis}).from(f).where(Mt(ve(f.runId,n),ve(f.userId,t))).orderBy(Qu(f.startedAt)),s=o.map(w=>w.id);if(!_v(r.status,r.completedAt)){let w=await d.select({status:re.status}).from(re).where(Mt(ve(re.runId,n),ve(re.userId,t))),I=yv(r.status,o.map(b=>({endedAt:b.endedAt})),w);I!==r.status&&(await wv({runId:n,userId:t,stored:r.status,rolled:I,hadCompletedAt:r.completedAt!=null}),r.status=I,r.completedAt==null&&(I==="completed"||I==="failed"||I==="cancelled")&&(r.completedAt=new Date))}let i=s.length>0?await d.select({sessionId:te.sessionId,instructionId:y.id,name:y.name}).from(te).innerJoin(y,ve(y.id,te.instructionId)).where(Xu(te.sessionId,s)):[],c=new Map;for(let w of s)c.set(w,[]);for(let w of i)c.get(w.sessionId)?.push({id:w.instructionId,name:w.name});let a=await Promise.all(o.map(async w=>{let I=w.analysis??{},b=typeof I.goalSummary=="string"?I.goalSummary:null,S=typeof I.outcome=="string"?I.outcome:null,A=I.friction??null,x=await hC(w.tokenUsage,w.startedAt??new Date);return{id:w.id,tool:w.tool,gitBranch:w.gitBranch,projectPath:w.projectPath,startedAt:w.startedAt,endedAt:w.endedAt,eventCount:w.eventCount,tokenUsage:w.tokenUsage,goalSummary:b,outcome:S,friction:A,cost:x,instructions:c.get(w.id)??[]}})),l=a.map(w=>({sessionId:w.id,score:w.outcome!=null?vs[w.outcome]??-1:-1,costUsd:w.cost?.totalUsd??Number.POSITIVE_INFINITY,frictionCount:gC(w.friction)})).sort((w,I)=>I.score!==w.score?I.score-w.score:w.costUsd!==I.costUsd?w.costUsd-I.costUsd:w.frictionCount-I.frictionCount).map((w,I)=>({sessionId:w.sessionId,rank:I+1,isWinner:I===0&&w.score>=0,score:w.score,costUsd:Number.isFinite(w.costUsd)?w.costUsd:null,frictionCount:w.frictionCount})),p=new Map,m=new Map;for(let w of i)p.set(w.instructionId,w.name),m.has(w.instructionId)||m.set(w.instructionId,new Set),m.get(w.instructionId).add(w.sessionId);let _=s.length,v=[],g=[];for(let[w,I]of m){let b=p.get(w)??"Unknown";_>0&&I.size===_?v.push({id:w,name:b}):g.push({id:w,name:b,sessionIds:[...I]})}let h=null;return r.autoWorktree?r.sessionCount>0&&a.length<r.sessionCount&&(h=`Only ${a.length} of ${r.sessionCount} expected sessions are attributed to this run so far \u2014 the comparison may be incomplete while sessions are still launching or being linked.`):h="This run did not auto-create per-session worktrees, so sessions are attributed only via the launch hook. Sessions from tools that do not run RuleMetric hooks may be missing from this comparison.",e.json({run:r,sessions:a,comparison:{ranking:l,instructionDiff:{shared:v,differing:g}},attributionCaveat:h})});Qn.post("/runs/:id/link-sessions",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:W.id}).from(W).where(Mt(ve(W.id,n),ve(W.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);let{linked:o}=await vv(n,t);return e.json({linked:o})});Qn.get("/runs/:id/jobs",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:W.id}).from(W).where(Mt(ve(W.id,n),ve(W.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);let o=await d.select({id:re.id,runId:re.runId,status:re.status,tool:re.tool}).from(re).where(Mt(ve(re.runId,n),ve(re.userId,t))).orderBy(Qu(re.createdAt));return e.json(o)});Qn.post("/runs/:id/cancel",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:W.id}).from(W).where(Mt(ve(W.id,n),ve(W.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);await d.update(re).set({status:"cancelled",updatedAt:new Date}).where(Mt(ve(re.runId,n),ve(re.userId,t),ve(re.status,"pending")));let[o]=await d.update(W).set({status:"cancelled",updatedAt:new Date}).where(Mt(ve(W.id,n),ve(W.userId,t))).returning();return e.json({run:o})});Qn.post("/runs/:id/cleanup",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:W.id}).from(W).where(Mt(ve(W.id,n),ve(W.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);let{noLiveWorker:o}=await By({runId:n,userId:t});return e.json({enqueued:!0,noLiveWorker:o})});import{Hono as _C}from"hono";import{z as Co}from"zod";import{and as qs,desc as Tm,eq as Ut,or as Iv}from"drizzle-orm";var Po=new _C;function yC(e,t){return{liveSend:e?.kind==="tmux"&&e.status==="active"&&t,fallbackResume:!0,tmuxAvailable:e?.kind==="tmux"&&e.status!=="fallback_only",workerOnline:t}}u(yC,"capabilitiesFor");Po.get("/sessions/:id/terminal-target",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:f.id,externalSessionId:f.externalSessionId}).from(f).where(qs(Ut(f.id,n),Ut(f.userId,t))).limit(1);if(!r)return e.json({error:"Session not found"},404);let o=r.externalSessionId?Iv(Ut(We.sessionId,r.id),Ut(We.externalSessionId,r.externalSessionId)):Ut(We.sessionId,r.id),[s]=await d.select().from(We).where(qs(Ut(We.userId,t),o)).orderBy(Tm(We.lastSeenAt)).limit(1),i=await ho(t);return e.json({target:s??null,capabilities:yC(s??null,i),...s?{}:{reason:"no_target"}})});var bv=Co.enum(["active","missing","unknown","fallback_only"]),wC=Co.object({message:Co.string().min(1).max(16*1024),delivery:Co.enum(["live","fallback"]).default("live"),submit:Co.boolean().optional().default(!0)});Po.post("/sessions/:id/send",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=wC.parse(await e.req.json()),[o]=await d.select({id:f.id,externalSessionId:f.externalSessionId,projectPath:f.projectPath}).from(f).where(qs(Ut(f.id,n),Ut(f.userId,t))).limit(1);if(!o)return e.json({error:"Session not found"},404);let s=o.externalSessionId?Iv(Ut(We.sessionId,o.id),Ut(We.externalSessionId,o.externalSessionId)):Ut(We.sessionId,o.id),[i]=await d.select().from(We).where(qs(Ut(We.userId,t),Ut(We.status,"active"),s)).orderBy(Tm(We.lastSeenAt)).limit(1);if(!i){if(r.delivery==="fallback"){if(!o.externalSessionId||!o.projectPath)return e.json({error:"Live target unavailable",code:"LIVE_TARGET_UNAVAILABLE"},409);let p={projectPath:o.projectPath,mode:"interactive",resumeSessionId:o.externalSessionId,prompt:r.message},m={tool:"claude_code",config:p},{id:_,noLiveWorker:v}=await kt({taskName:"process_launch",payload:m,userId:t,mirror:{userId:t,tool:"claude_code",config:p}});return e.json({delivery:"fallback",job:{id:_,kind:"process_launch"},noLiveWorker:v},202)}return e.json({error:"Live target unavailable",code:"LIVE_TARGET_UNAVAILABLE",fallback:{available:!!(o.externalSessionId&&o.projectPath),action:"resume_terminal"}},409)}if(!await ho(t))return e.json({error:"Worker offline",code:"WORKER_OFFLINE"},409);let a={sessionId:o.id,terminalTargetId:i.id,target:i.target,message:r.message,submit:r.submit},{id:l}=await kt({taskName:"process_send_message",payload:a,userId:t,mirror:{userId:t,sessionId:o.id,terminalTargetId:i.id,target:i.target,message:r.message,submit:r.submit,delivery:"live"}});return e.json({delivery:"live",job:{id:l,kind:"process_send_message"},target:i},202)});var vC=Co.object({status:bv,lastSeenAt:Co.string().datetime().optional()});Po.patch("/terminal-targets/:id/status",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=vC.parse(await e.req.json()),o=r.lastSeenAt?new Date(r.lastSeenAt):new Date,s=new Date,[i]=await d.update(We).set({status:r.status,lastSeenAt:o,updatedAt:s}).where(qs(Ut(We.id,n),Ut(We.userId,t))).returning();return i?e.json({target:i}):e.json({error:"Terminal target not found"},404)});Po.get("/terminal-targets",async e=>{let t=e.get("userId"),n=e.req.query("status"),r=n?bv.parse(n):null,o=await d.select().from(We).where(qs(Ut(We.userId,t),...r?[Ut(We.status,r)]:[])).orderBy(Tm(We.lastSeenAt)).limit(100);return e.json({targets:o})});import{Hono as DC}from"hono";import{z as _t}from"zod";import{randomBytes as MC}from"node:crypto";import{eq as fe,and as Mn,asc as nd,desc as LC,sql as Ta,max as $C,inArray as Ea,isNull as Bs,gt as qC,gte as Cv}from"drizzle-orm";import{randomBytes as IC}from"node:crypto";async function Rm(e){let t=e.idempotencyKey?` idempotencyKey=${e.idempotencyKey}`:"";return process.stderr.write(`[email:noop] would send to=${e.to} subject=${JSON.stringify(e.subject)}${t}
|
|
966
|
-
`),{id:`noop-${
|
|
967
|
-
`)}return"onboarding@resend.dev"}u(
|
|
964
|
+
${e.body??""}`}u(zN,"buildPrompt");function VN(e){let t=e.trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/i,"").trim(),n=t.indexOf("{"),r=t.lastIndexOf("}"),o=n>=0&&r>n?t.slice(n,r+1):t,s=JSON.parse(o);if(!s.observations||!Array.isArray(s.observations))return{observations:[]};let i=[];for(let c of s.observations){if(!c||typeof c!="object")continue;let a=c;if(typeof a.limitType!="string"||typeof a.plan!="string"||typeof a.value!="number"||!Number.isFinite(a.value)||typeof a.unit!="string")continue;let l=a.comparator===">="||a.comparator==="<="?a.comparator:"=";i.push({limitType:a.limitType,plan:a.plan,value:a.value,unit:a.unit,comparator:l,evidence_quote:typeof a.evidence_quote=="string"?a.evidence_quote:""})}return{observations:i}}u(VN,"parseLlmJson");async function hv(e,t={}){let n=e.body??"";if(!$N.test(n))return{observations:[],llm_called:!1,reason:"no keywords matched"};let r=t.llm===void 0?HN():t.llm;if(!r)return console.warn("[harness-release-extractor] ANTHROPIC_API_KEY missing; skipping extraction"),{observations:[],llm_called:!1,reason:"no LLM available"};let o,s;try{let a=await r(zN(e));o=a.text,s=a.usage}catch(a){return{observations:[],llm_called:!0,error:`LLM call failed: ${a instanceof Error?a.message:String(a)}`}}let i;try{i=VN(o).observations}catch(a){return{observations:[],llm_called:!0,llm_tokens:{input:s.inputTokens,output:s.outputTokens},error:`failed to parse LLM JSON: ${a instanceof Error?a.message:String(a)}`}}if(i.length===0)return{observations:[],llm_called:!0,llm_tokens:{input:s.inputTokens,output:s.outputTokens},reason:"LLM returned no observations"};let c=t.observe??WN;for(let a of i)await c({plan:a.plan,limitType:a.limitType,value:a.value,unit:a.unit,comparator:a.comparator,sourceType:"release_notes",sourceUrl:e.url,sourceEvidence:{harness:e.harness,version:e.version,publishedAt:e.publishedAt.toISOString(),quote:a.evidence_quote,fullBody:n},confidence:BN,provider:"anthropic"});return{observations:i,llm_called:!0,llm_tokens:{input:s.inputTokens,output:s.outputTokens}}}u(hv,"extractAndPostObservationsFromRelease");var yv=[{harness:"claude_code",repo:"anthropics/claude-code"}];function GN(e){let t=[],n=[],r=[],o=e.split(`
|
|
965
|
+
`);for(let s of o){let i=s.trim();if(!i.startsWith("- ")&&!i.startsWith("* "))continue;let c=i.replace(/^[-*]\s+/,"").trim();if(!c)continue;let a=c.toLowerCase();a.startsWith("security:")||a.includes("security fix")||a.includes("cve-")?r.push(c):a.startsWith("fixed ")||a.startsWith("fix ")||a.startsWith("fixed:")?n.push(c):t.push(c)}return{features:t,fixes:n,security:r}}u(GN,"parseReleaseBody");async function Yu(e){let t=e?yv.filter(o=>o.harness===e):yv,n=0,r=0;for(let o of t){let s=`https://api.github.com/repos/${o.repo}/releases?per_page=100`,i={Accept:"application/vnd.github+json"};process.env.GITHUB_TOKEN&&(i.Authorization=`Bearer ${process.env.GITHUB_TOKEN}`);let c=await fetch(s,{headers:i});if(!c.ok)continue;let a=await c.json();r+=a.length;for(let l of a){let p=GN(l.body??"");if((await d.select({id:Rt.id}).from(Rt).where(JN(_v(Rt.harness,o.harness),_v(Rt.version,l.tag_name)))).length===0){await d.insert(Rt).values({harness:o.harness,version:l.tag_name,publishedAt:new Date(l.published_at),title:l.name,body:l.body,categories:p,url:l.html_url}),n++;try{await hv({harness:o.harness,version:l.tag_name,url:l.html_url,publishedAt:new Date(l.published_at),body:l.body})}catch(y){console.warn("release notes extraction failed:",y)}}}}return{synced:n,total:r}}u(Yu,"syncHarnessReleases");var xa=new KN;xa.get("/harness-releases",async e=>{let t=e.req.query("harness"),n=Math.min(Number(e.req.query("limit")??50),100),r=t?XN(Rt.harness,t):void 0,o=await d.select({id:Rt.id,harness:Rt.harness,version:Rt.version,publishedAt:Rt.publishedAt,title:Rt.title,categories:Rt.categories,url:Rt.url}).from(Rt).where(r).orderBy(YN(Rt.publishedAt)).limit(n);return e.json(o)});xa.post("/harness-releases/sync",async e=>{let t=await e.req.json().catch(()=>({})),n=await Yu(t.harness);return e.json(n)});import{Hono as QN}from"hono";import{and as Xu,desc as ZN,eq as $s,isNull as Rm,sql as eC}from"drizzle-orm";var qs=new QN;qs.get("/notifications",async e=>{let t=e.get("userId"),n=Math.min(parseInt(e.req.query("limit")??"20",10),100),r=parseInt(e.req.query("offset")??"0",10),s=e.req.query("unread")==="true"?Xu($s(ht.userId,t),Rm(ht.readAt)):$s(ht.userId,t),i=await d.select().from(ht).where(s).orderBy(ZN(ht.createdAt)).limit(n).offset(r),[{count:c}]=await d.select({count:eC`count(*)::int`}).from(ht).where(Xu($s(ht.userId,t),Rm(ht.readAt)));return e.json({items:i,unreadCount:c})});qs.post("/notifications/:id/read",async e=>{let t=e.req.param("id"),n=e.get("userId"),[r]=await d.update(ht).set({readAt:new Date}).where(Xu($s(ht.id,t),$s(ht.userId,n))).returning();return r?e.json(r):e.json({error:"Not found"},404)});qs.post("/notifications/read-all",async e=>{let t=e.get("userId");return await d.update(ht).set({readAt:new Date}).where(Xu($s(ht.userId,t),Rm(ht.readAt))),e.json({success:!0})});import{Hono as tC}from"hono";import{z as Gt}from"zod";import{eq as Xn,and as Qu,desc as nC,ne as rC}from"drizzle-orm";var Gr=new tC;function oC(e){let t=e.terminalTarget;if(!t||typeof t!="object")return null;let n=t;return n.kind!=="tmux"||typeof n.target!="string"||typeof n.attachCommand!="string"?null:{sessionId:typeof e.sessionId=="string"?e.sessionId:void 0,terminalTarget:{kind:"tmux",target:n.target,attachCommand:n.attachCommand,live:typeof n.live=="boolean"?n.live:void 0}}}u(oC,"parseTerminalTargetResult");async function sC(e){let t=oC(e.result);if(!t?.terminalTarget)return;let n=e.config&&typeof e.config=="object"?e.config:{},r=typeof n.projectPath=="string"?n.projectPath:null,o=typeof n.resumeSessionId=="string"?n.resumeSessionId:null,[s]=o?await d.select({id:f.id}).from(f).where(Qu(Xn(f.userId,e.userId),Xn(f.externalSessionId,o))).limit(1):[];await d.insert(We).values({userId:e.userId,sessionId:s?.id??null,externalSessionId:o,kind:"tmux",target:t.terminalTarget.target,status:t.terminalTarget.live===!1?"unknown":"active",attachCommand:t.terminalTarget.attachCommand,projectPath:r,metadata:{launchJobId:e.jobId,launcherSessionId:t.sessionId}}).onConflictDoUpdate({target:[We.userId,We.target],set:{sessionId:s?.id??null,externalSessionId:o,status:t.terminalTarget.live===!1?"unknown":"active",attachCommand:t.terminalTarget.attachCommand,projectPath:r,metadata:{launchJobId:e.jobId,launcherSessionId:t.sessionId},lastSeenAt:new Date,updatedAt:new Date}})}u(sC,"upsertTerminalTargetFromLaunchResult");var iC=Gt.object({tool:Gt.string().min(1),config:Gt.object({projectPath:Gt.string().min(1),prompt:Gt.string().optional(),systemPrompt:Gt.string().optional(),model:Gt.string().optional(),mode:Gt.enum(["headless","interactive"]).default("interactive"),timeout:Gt.number().int().positive().optional(),resumeSessionId:Gt.string().optional()})});Gr.post("/launch-jobs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=iC.parse(n),{id:o,noLiveWorker:s}=await kt({taskName:"process_launch",payload:{tool:r.tool,config:r.config},userId:t,mirror:{userId:t,tool:r.tool,config:r.config}}),[i]=await d.select().from(oe).where(Xn(oe.id,o));return e.json({...i,noLiveWorker:s},201)});Gr.get("/launch-jobs",async e=>{let t=e.get("userId"),n=Number(e.req.query("limit")??50),r=await d.select().from(oe).where(Xn(oe.userId,t)).orderBy(nC(oe.createdAt)).limit(n);return e.json(r)});var aC=Gt.object({status:Gt.enum(["running","completed","failed"]).optional(),attempts:Gt.number().int().nonnegative().optional(),error:Gt.string().optional(),result:Gt.record(Gt.unknown()).optional()});Gr.patch("/launch-jobs/:id/state",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=aC.parse(await e.req.json()),o={updatedAt:new Date};r.attempts!==void 0&&(o.attempts=r.attempts),r.status&&(o.status=r.status),r.error&&(o.error=r.error),r.result!==void 0&&(o.result=r.result),(r.status==="completed"||r.status==="failed")&&(o.completedAt=new Date);let[s]=await d.update(oe).set(o).where(Qu(Xn(oe.id,n),Xn(oe.userId,t),rC(oe.status,"cancelled"))).returning();if(!s){let[i]=await d.select().from(oe).where(Qu(Xn(oe.id,n),Xn(oe.userId,t)));return i?e.json(i):e.json({error:"Job not found"},404)}return r.result!==void 0&&await sC({userId:t,jobId:n,config:s.config,result:r.result}),e.json(s)});Gr.post("/launch-jobs/:id/cancel",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.update(oe).set({status:"cancelled",updatedAt:new Date}).where(Qu(Xn(oe.id,n),Xn(oe.userId,t))).returning();return r?e.json(r):e.json({error:"Job not found"},404)});Gr.get("/launchers",async e=>{let{getAvailableLaunchers:t}=await Promise.resolve().then(()=>(lu(),Uy));return e.json(t())});import{Hono as cC}from"hono";import{z as xn}from"zod";import{eq as Ie,and as Mt,desc as ed,inArray as Zu,isNull as uC,ne as dC}from"drizzle-orm";lu();var Qn=new cC,lC=xn.object({tool:xn.string().min(1),model:xn.string().optional(),label:xn.string().optional()}),pC=xn.object({title:xn.string().optional(),projectPath:xn.string().min(1),gitRemote:xn.string().optional(),baseBranch:xn.string().optional(),prompt:xn.string().optional(),autoWorktree:xn.boolean().optional(),sessions:xn.array(lC).min(1).max(8)});function mC(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/(^-|-$)/g,"")||"tool"}u(mC,"sanitizeTool");var fC=new Set(["pending","claimed","running"]);var gC=1800*1e3;function wv(e,t){if(e==="cancelled")return!0;if(e!=="completed"&&e!=="failed"||t==null)return!1;let n=t instanceof Date?t.getTime():Date.parse(t);return Number.isFinite(n)?Date.now()-n>gC:!1}u(wv,"canSkipRollup");function vv(e,t,n){if(e==="cancelled")return"cancelled";let r=t.length>0,o=t.some(c=>c.endedAt==null),s=n.some(c=>fC.has(c.status));return n.length>0&&n.every(c=>c.status==="failed")&&!r?"failed":o||s&&r?"running":r&&!o&&!s?"completed":"pending"}u(vv,"rollupRunStatus");async function Iv(e){if(e.rolled===e.stored)return;let t=e.rolled==="completed"||e.rolled==="failed"||e.rolled==="cancelled",n={status:e.rolled,updatedAt:new Date};t&&!e.hadCompletedAt&&(n.completedAt=new Date);try{await d.update(J).set(n).where(Mt(Ie(J.id,e.runId),Ie(J.userId,e.userId),dC(J.status,"cancelled")))}catch{}}u(Iv,"persistRolledUpStatus");function hC(e){return Array.isArray(e)?e.length:e&&typeof e=="object"?Object.values(e).reduce((t,n)=>t+(typeof n=="number"&&n>0?n:0),0):0}u(hC,"frictionCount");async function _C(e,t){if(!e||typeof e!="object")return null;let n=e,r="claude-sonnet-4-6",o=zr(r),s={input_tokens:n.input_tokens??0,output_tokens:n.output_tokens??0,cache_read_input_tokens:n.cache_read_input_tokens??0,cache_creation_5m:n.cache_creation_5m??0,cache_creation_1h:n.cache_creation_1h??0,cache_creation_input_tokens:n.cache_creation_input_tokens??0},i=await fr(d,s,r,t,o);return i?{...i,estimated:!0}:null}u(_C,"deriveSessionCost");async function bv(e,t){let[n]=await d.select({id:J.id,autoWorktree:J.autoWorktree}).from(J).where(Mt(Ie(J.id,e),Ie(J.userId,t))).limit(1);if(!n||!n.autoWorktree)return{linked:0};let r=await d.select({config:oe.config,result:oe.result}).from(oe).where(Mt(Ie(oe.runId,e),Ie(oe.userId,t))),o=new Set;for(let i of r){let c=i.result??{};typeof c.worktreePath=="string"&&c.worktreePath&&o.add(c.worktreePath);let a=i.config??{};a.worktree?.create&&typeof a.worktree.branch=="string"&&typeof a.projectPath=="string"&&o.add(du({repoRoot:a.projectPath,branch:a.worktree.branch}))}return o.size===0?{linked:0}:{linked:(await d.update(f).set({runId:e}).where(Mt(Ie(f.userId,t),uC(f.runId),Zu(f.projectPath,[...o]))).returning({id:f.id})).length}}u(bv,"linkRunSessions");Qn.post("/runs",async e=>{let t=e.get("userId"),n=await e.req.json(),r=pC.parse(n),o=await bu(t,null),s=r.autoWorktree??!0,i=r.baseBranch??"HEAD",c=null;if(r.projectPath){let[m]=await d.select({projectId:ue.projectId}).from(ue).where(Ie(ue.path,r.projectPath)).orderBy(ed(ue.lastSeen)).limit(1);c=m?.projectId??null}if(!c&&r.gitRemote){let[m]=await d.select({id:D.id}).from(D).where(Ie(D.gitRemoteUrl,r.gitRemote)).limit(1);c=m?.id??null}let[a]=await d.insert(J).values({userId:t,orgId:o,projectPath:r.projectPath,projectId:c,gitRemote:r.gitRemote??null,baseBranch:r.baseBranch??null,title:r.title??null,prompt:r.prompt??null,toolSpec:r.sessions,autoWorktree:s,status:"pending",sessionCount:r.sessions.length}).returning(),l=a.id.slice(0,8),p=!1;try{for(let m=0;m<r.sessions.length;m++){let y=r.sessions[m],v=`rm/run-${l}/s${m}-${mC(y.tool)}`,g={projectPath:r.projectPath,prompt:r.prompt,systemPrompt:void 0,model:y.model,mode:"interactive",worktree:{create:s,branch:v,baseRef:i},runId:a.id},h=await kt({taskName:"process_launch",userId:t,payload:{tool:y.tool,config:g},mirror:{userId:t,tool:y.tool,config:g},runId:a.id});p=p||h.noLiveWorker}}catch(m){return await d.update(J).set({status:"failed",updatedAt:new Date}).where(Ie(J.id,a.id)),await d.update(oe).set({status:"cancelled",updatedAt:new Date}).where(Mt(Ie(oe.runId,a.id),Ie(oe.status,"pending"))),e.json({error:"Failed to enqueue all launch jobs",detail:m instanceof Error?m.message:String(m),run:{...a,status:"failed"}},500)}return e.json({run:a,noLiveWorker:p},201)});Qn.get("/runs",async e=>{let t=e.get("userId"),n=Number(e.req.query("limit")),r=Math.min(Math.max(Number.isFinite(n)?n:50,1),100),o=Number(e.req.query("offset")),s=Math.max(Number.isFinite(o)?o:0,0),i=e.req.query("projectId"),c=i?Mt(Ie(J.userId,t),Ie(J.projectId,i)):Ie(J.userId,t),a=await d.select({id:J.id,userId:J.userId,orgId:J.orgId,projectId:J.projectId,projectPath:J.projectPath,gitRemote:J.gitRemote,baseBranch:J.baseBranch,title:J.title,toolSpec:J.toolSpec,autoWorktree:J.autoWorktree,status:J.status,sessionCount:J.sessionCount,createdAt:J.createdAt,updatedAt:J.updatedAt,completedAt:J.completedAt}).from(J).where(c).orderBy(ed(J.createdAt)).limit(r).offset(s),l=a.filter(m=>!wv(m.status,m.completedAt)),p=l.map(m=>m.id);if(p.length>0){let[m,y]=await Promise.all([d.select({runId:f.runId,endedAt:f.endedAt}).from(f).where(Mt(Ie(f.userId,t),Zu(f.runId,p))),d.select({runId:oe.runId,status:oe.status}).from(oe).where(Mt(Ie(oe.userId,t),Zu(oe.runId,p)))]),v=new Map;for(let h of m){if(!h.runId)continue;let w=v.get(h.runId)??[];w.push({endedAt:h.endedAt}),v.set(h.runId,w)}let g=new Map;for(let h of y){if(!h.runId)continue;let w=g.get(h.runId)??[];w.push({status:h.status}),g.set(h.runId,w)}await Promise.all(l.map(async h=>{let w=vv(h.status,v.get(h.id)??[],g.get(h.id)??[]);w!==h.status&&(await Iv({runId:h.id,userId:t,stored:h.status,rolled:w,hadCompletedAt:h.completedAt!=null}),h.status=w,h.completedAt==null&&(w==="completed"||w==="failed"||w==="cancelled")&&(h.completedAt=new Date))}))}return e.json({runs:a})});Qn.get("/runs/:id",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select().from(J).where(Mt(Ie(J.id,n),Ie(J.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);try{await bv(n,t)}catch{}let o=await d.select({id:f.id,tool:f.tool,gitBranch:f.gitBranch,projectPath:f.projectPath,startedAt:f.startedAt,endedAt:f.endedAt,eventCount:f.eventCount,tokenUsage:f.tokenUsage,analysis:f.analysis}).from(f).where(Mt(Ie(f.runId,n),Ie(f.userId,t))).orderBy(ed(f.startedAt)),s=o.map(w=>w.id);if(!wv(r.status,r.completedAt)){let w=await d.select({status:oe.status}).from(oe).where(Mt(Ie(oe.runId,n),Ie(oe.userId,t))),b=vv(r.status,o.map(I=>({endedAt:I.endedAt})),w);b!==r.status&&(await Iv({runId:n,userId:t,stored:r.status,rolled:b,hadCompletedAt:r.completedAt!=null}),r.status=b,r.completedAt==null&&(b==="completed"||b==="failed"||b==="cancelled")&&(r.completedAt=new Date))}let i=s.length>0?await d.select({sessionId:ne.sessionId,instructionId:_.id,name:_.name}).from(ne).innerJoin(_,Ie(_.id,ne.instructionId)).where(Zu(ne.sessionId,s)):[],c=new Map;for(let w of s)c.set(w,[]);for(let w of i)c.get(w.sessionId)?.push({id:w.instructionId,name:w.name});let a=await Promise.all(o.map(async w=>{let b=w.analysis??{},I=typeof b.goalSummary=="string"?b.goalSummary:null,S=typeof b.outcome=="string"?b.outcome:null,A=b.friction??null,x=await _C(w.tokenUsage,w.startedAt??new Date);return{id:w.id,tool:w.tool,gitBranch:w.gitBranch,projectPath:w.projectPath,startedAt:w.startedAt,endedAt:w.endedAt,eventCount:w.eventCount,tokenUsage:w.tokenUsage,goalSummary:I,outcome:S,friction:A,cost:x,instructions:c.get(w.id)??[]}})),l=a.map(w=>({sessionId:w.id,score:w.outcome!=null?bs[w.outcome]??-1:-1,costUsd:w.cost?.totalUsd??Number.POSITIVE_INFINITY,frictionCount:hC(w.friction)})).sort((w,b)=>b.score!==w.score?b.score-w.score:w.costUsd!==b.costUsd?w.costUsd-b.costUsd:w.frictionCount-b.frictionCount).map((w,b)=>({sessionId:w.sessionId,rank:b+1,isWinner:b===0&&w.score>=0,score:w.score,costUsd:Number.isFinite(w.costUsd)?w.costUsd:null,frictionCount:w.frictionCount})),p=new Map,m=new Map;for(let w of i)p.set(w.instructionId,w.name),m.has(w.instructionId)||m.set(w.instructionId,new Set),m.get(w.instructionId).add(w.sessionId);let y=s.length,v=[],g=[];for(let[w,b]of m){let I=p.get(w)??"Unknown";y>0&&b.size===y?v.push({id:w,name:I}):g.push({id:w,name:I,sessionIds:[...b]})}let h=null;return r.autoWorktree?r.sessionCount>0&&a.length<r.sessionCount&&(h=`Only ${a.length} of ${r.sessionCount} expected sessions are attributed to this run so far \u2014 the comparison may be incomplete while sessions are still launching or being linked.`):h="This run did not auto-create per-session worktrees, so sessions are attributed only via the launch hook. Sessions from tools that do not run RuleMetric hooks may be missing from this comparison.",e.json({run:r,sessions:a,comparison:{ranking:l,instructionDiff:{shared:v,differing:g}},attributionCaveat:h})});Qn.post("/runs/:id/link-sessions",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:J.id}).from(J).where(Mt(Ie(J.id,n),Ie(J.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);let{linked:o}=await bv(n,t);return e.json({linked:o})});Qn.get("/runs/:id/jobs",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:J.id}).from(J).where(Mt(Ie(J.id,n),Ie(J.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);let o=await d.select({id:oe.id,runId:oe.runId,status:oe.status,tool:oe.tool}).from(oe).where(Mt(Ie(oe.runId,n),Ie(oe.userId,t))).orderBy(ed(oe.createdAt));return e.json(o)});Qn.post("/runs/:id/cancel",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:J.id}).from(J).where(Mt(Ie(J.id,n),Ie(J.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);await d.update(oe).set({status:"cancelled",updatedAt:new Date}).where(Mt(Ie(oe.runId,n),Ie(oe.userId,t),Ie(oe.status,"pending")));let[o]=await d.update(J).set({status:"cancelled",updatedAt:new Date}).where(Mt(Ie(J.id,n),Ie(J.userId,t))).returning();return e.json({run:o})});Qn.post("/runs/:id/cleanup",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:J.id}).from(J).where(Mt(Ie(J.id,n),Ie(J.userId,t))).limit(1);if(!r)return e.json({error:"Run not found"},404);let{noLiveWorker:o}=await Wy({runId:n,userId:t});return e.json({enqueued:!0,noLiveWorker:o})});import{Hono as yC}from"hono";import{z as Do}from"zod";import{and as Us,desc as km,eq as Ut,or as Sv}from"drizzle-orm";var Mo=new yC;function wC(e,t){return{liveSend:e?.kind==="tmux"&&e.status==="active"&&t,fallbackResume:!0,tmuxAvailable:e?.kind==="tmux"&&e.status!=="fallback_only",workerOnline:t}}u(wC,"capabilitiesFor");Mo.get("/sessions/:id/terminal-target",async e=>{let t=e.get("userId"),n=e.req.param("id"),[r]=await d.select({id:f.id,externalSessionId:f.externalSessionId}).from(f).where(Us(Ut(f.id,n),Ut(f.userId,t))).limit(1);if(!r)return e.json({error:"Session not found"},404);let o=r.externalSessionId?Sv(Ut(We.sessionId,r.id),Ut(We.externalSessionId,r.externalSessionId)):Ut(We.sessionId,r.id),[s]=await d.select().from(We).where(Us(Ut(We.userId,t),o)).orderBy(km(We.lastSeenAt)).limit(1),i=await yo(t);return e.json({target:s??null,capabilities:wC(s??null,i),...s?{}:{reason:"no_target"}})});var Av=Do.enum(["active","missing","unknown","fallback_only"]),vC=Do.object({message:Do.string().min(1).max(16*1024),delivery:Do.enum(["live","fallback"]).default("live"),submit:Do.boolean().optional().default(!0)});Mo.post("/sessions/:id/send",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=vC.parse(await e.req.json()),[o]=await d.select({id:f.id,externalSessionId:f.externalSessionId,projectPath:f.projectPath}).from(f).where(Us(Ut(f.id,n),Ut(f.userId,t))).limit(1);if(!o)return e.json({error:"Session not found"},404);let s=o.externalSessionId?Sv(Ut(We.sessionId,o.id),Ut(We.externalSessionId,o.externalSessionId)):Ut(We.sessionId,o.id),[i]=await d.select().from(We).where(Us(Ut(We.userId,t),Ut(We.status,"active"),s)).orderBy(km(We.lastSeenAt)).limit(1);if(!i){if(r.delivery==="fallback"){if(!o.externalSessionId||!o.projectPath)return e.json({error:"Live target unavailable",code:"LIVE_TARGET_UNAVAILABLE"},409);let p={projectPath:o.projectPath,mode:"interactive",resumeSessionId:o.externalSessionId,prompt:r.message},m={tool:"claude_code",config:p},{id:y,noLiveWorker:v}=await kt({taskName:"process_launch",payload:m,userId:t,mirror:{userId:t,tool:"claude_code",config:p}});return e.json({delivery:"fallback",job:{id:y,kind:"process_launch"},noLiveWorker:v},202)}return e.json({error:"Live target unavailable",code:"LIVE_TARGET_UNAVAILABLE",fallback:{available:!!(o.externalSessionId&&o.projectPath),action:"resume_terminal"}},409)}if(!await yo(t))return e.json({error:"Worker offline",code:"WORKER_OFFLINE"},409);let a={sessionId:o.id,terminalTargetId:i.id,target:i.target,message:r.message,submit:r.submit},{id:l}=await kt({taskName:"process_send_message",payload:a,userId:t,mirror:{userId:t,sessionId:o.id,terminalTargetId:i.id,target:i.target,message:r.message,submit:r.submit,delivery:"live"}});return e.json({delivery:"live",job:{id:l,kind:"process_send_message"},target:i},202)});var IC=Do.object({status:Av,lastSeenAt:Do.string().datetime().optional()});Mo.patch("/terminal-targets/:id/status",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=IC.parse(await e.req.json()),o=r.lastSeenAt?new Date(r.lastSeenAt):new Date,s=new Date,[i]=await d.update(We).set({status:r.status,lastSeenAt:o,updatedAt:s}).where(Us(Ut(We.id,n),Ut(We.userId,t))).returning();return i?e.json({target:i}):e.json({error:"Terminal target not found"},404)});Mo.get("/terminal-targets",async e=>{let t=e.get("userId"),n=e.req.query("status"),r=n?Av.parse(n):null,o=await d.select().from(We).where(Us(Ut(We.userId,t),...r?[Ut(We.status,r)]:[])).orderBy(km(We.lastSeenAt)).limit(100);return e.json({targets:o})});import{Hono as MC}from"hono";import{z as wt}from"zod";import{randomBytes as LC}from"node:crypto";import{eq as ge,and as Ln,asc as od,desc as $C,sql as Ta,max as qC,inArray as Ea,isNull as Fs,gt as UC,gte as Ov}from"drizzle-orm";import{randomBytes as bC}from"node:crypto";async function jm(e){let t=e.idempotencyKey?` idempotencyKey=${e.idempotencyKey}`:"";return process.stderr.write(`[email:noop] would send to=${e.to} subject=${JSON.stringify(e.subject)}${t}
|
|
966
|
+
`),{id:`noop-${bC(8).toString("hex")}`,provider:"noop"}}u(jm,"sendNoopEmail");var td=null;async function SC(){if(td)return td;let e=process.env.RESEND_API_KEY;if(!e)throw new Error("RESEND_API_KEY is not set");let{Resend:t}=await import("resend");return td=new t(e),td}u(SC,"getClient");var xv=!1;function AC(){let e=process.env.RESEND_FROM_EMAIL;if(e)return e;if(!xv){xv=!0;let t=process.env.NODE_ENV==="production"?"PRODUCTION":"dev";process.stderr.write(`[email:resend] ${t}: RESEND_FROM_EMAIL not set \u2014 sending from the shared sandbox sender onboarding@resend.dev, which Gmail spam-filters. Set RESEND_FROM_EMAIL to an address on a verified domain.
|
|
967
|
+
`)}return"onboarding@resend.dev"}u(AC,"resolveFromEmail");async function Ev(e){let t=e.fromName??"RuleMetric",n=AC(),r=`${t} <${n}>`,o=await SC(),s=e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:void 0,i=await o.emails.send({from:r,to:e.to,subject:e.subject,html:e.html,text:e.text,...e.headers?{headers:e.headers}:{}},s);if(i.error)throw new Error(`Resend send failed: ${i.error.message}`);if(!i.data)throw new Error("Resend send returned no data and no error");return{id:i.data.id,provider:"resend"}}u(Ev,"sendResendEmail");async function Tv(e){throw new Error("SMTP provider not implemented. Set RESEND_API_KEY to use Resend, or unset RULEMETRIC_EMAIL_PROVIDER to fall back to noop.")}u(Tv,"sendSmtpEmail");var xC="#2DD4BF",EC="#0d9488",TC="#0A0C12",nd="#1a1a1a",rd="#666666",Rv="#f5f5f7",RC="#ffffff",kv="#e5e5e9";function kC(e){let n=["January","February","March","April","May","June","July","August","September","October","November","December"][e.getUTCMonth()],r=e.getUTCDate(),o=e.getUTCFullYear();return`${n} ${r}, ${o}`}u(kC,"formatExpiresAt");function Bs(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}u(Bs,"escapeHtml");function jC(e){return e==="admin"?{article:"an admin",description:"As an admin, you can manage members, teams, and invitations for the organization."}:{article:"a member",description:"As a member, you can view organization activity and participate in shared sessions."}}u(jC,"roleCopy");function Nm(e){let{orgName:t,inviterName:n,role:r,acceptUrl:o,expiresAt:s}=e,i=`${n} invited you to ${t} on RuleMetric`,c=kC(s),{article:a,description:l}=jC(r),p=`<!doctype html>
|
|
968
968
|
<html lang="en">
|
|
969
969
|
<head>
|
|
970
970
|
<meta charset="utf-8" />
|
|
971
971
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
972
|
-
<title>${
|
|
972
|
+
<title>${Bs(i)}</title>
|
|
973
973
|
</head>
|
|
974
|
-
<body style="margin:0;padding:0;background:${
|
|
975
|
-
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="background:${
|
|
974
|
+
<body style="margin:0;padding:0;background:${Rv};font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;color:${nd};">
|
|
975
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="background:${Rv};padding:32px 16px;">
|
|
976
976
|
<tr>
|
|
977
977
|
<td align="center">
|
|
978
|
-
<table role="presentation" width="560" cellspacing="0" cellpadding="0" border="0" style="max-width:560px;background:${
|
|
978
|
+
<table role="presentation" width="560" cellspacing="0" cellpadding="0" border="0" style="max-width:560px;background:${RC};border:1px solid ${kv};border-radius:8px;overflow:hidden;">
|
|
979
979
|
<tr>
|
|
980
980
|
<td style="padding:32px 32px 8px 32px;">
|
|
981
|
-
<h1 style="margin:0 0 16px 0;font-size:22px;line-height:1.3;font-weight:600;color:${
|
|
982
|
-
You've been invited to ${
|
|
981
|
+
<h1 style="margin:0 0 16px 0;font-size:22px;line-height:1.3;font-weight:600;color:${nd};">
|
|
982
|
+
You've been invited to ${Bs(t)}
|
|
983
983
|
</h1>
|
|
984
|
-
<p style="margin:0 0 16px 0;font-size:15px;line-height:1.5;color:${
|
|
984
|
+
<p style="margin:0 0 16px 0;font-size:15px;line-height:1.5;color:${nd};">
|
|
985
985
|
Hi there,
|
|
986
986
|
</p>
|
|
987
|
-
<p style="margin:0 0 16px 0;font-size:15px;line-height:1.5;color:${
|
|
988
|
-
<strong>${
|
|
989
|
-
<strong>${
|
|
987
|
+
<p style="margin:0 0 16px 0;font-size:15px;line-height:1.5;color:${nd};">
|
|
988
|
+
<strong>${Bs(n)}</strong> invited you to join
|
|
989
|
+
<strong>${Bs(t)}</strong> on RuleMetric as ${a}.
|
|
990
990
|
</p>
|
|
991
|
-
<p style="margin:0 0 24px 0;font-size:15px;line-height:1.5;color:${
|
|
991
|
+
<p style="margin:0 0 24px 0;font-size:15px;line-height:1.5;color:${rd};">
|
|
992
992
|
${l}
|
|
993
993
|
</p>
|
|
994
994
|
</td>
|
|
995
995
|
</tr>
|
|
996
996
|
<tr>
|
|
997
997
|
<td align="center" style="padding:0 32px 8px 32px;">
|
|
998
|
-
<a href="${
|
|
999
|
-
style="display:inline-block;padding:12px 24px;background:${
|
|
998
|
+
<a href="${Bs(o)}"
|
|
999
|
+
style="display:inline-block;padding:12px 24px;background:${xC};color:${TC};text-decoration:none;border-radius:6px;font-size:15px;font-weight:600;">
|
|
1000
1000
|
Accept invitation
|
|
1001
1001
|
</a>
|
|
1002
1002
|
</td>
|
|
1003
1003
|
</tr>
|
|
1004
1004
|
<tr>
|
|
1005
1005
|
<td style="padding:16px 32px 8px 32px;">
|
|
1006
|
-
<p style="margin:0 0 8px 0;font-size:13px;line-height:1.5;color:${
|
|
1006
|
+
<p style="margin:0 0 8px 0;font-size:13px;line-height:1.5;color:${rd};">
|
|
1007
1007
|
Or copy and paste this link into your browser:
|
|
1008
1008
|
</p>
|
|
1009
|
-
<p style="margin:0 0 24px 0;font-size:13px;line-height:1.5;color:${
|
|
1010
|
-
${
|
|
1009
|
+
<p style="margin:0 0 24px 0;font-size:13px;line-height:1.5;color:${EC};word-break:break-all;">
|
|
1010
|
+
${Bs(o)}
|
|
1011
1011
|
</p>
|
|
1012
|
-
<p style="margin:0 0 24px 0;font-size:13px;line-height:1.5;color:${
|
|
1012
|
+
<p style="margin:0 0 24px 0;font-size:13px;line-height:1.5;color:${rd};">
|
|
1013
1013
|
This invitation expires on <strong>${c}</strong>.
|
|
1014
1014
|
</p>
|
|
1015
1015
|
</td>
|
|
1016
1016
|
</tr>
|
|
1017
1017
|
<tr>
|
|
1018
|
-
<td style="padding:16px 32px 32px 32px;border-top:1px solid ${
|
|
1019
|
-
<p style="margin:0;font-size:12px;line-height:1.5;color:${
|
|
1018
|
+
<td style="padding:16px 32px 32px 32px;border-top:1px solid ${kv};">
|
|
1019
|
+
<p style="margin:0;font-size:12px;line-height:1.5;color:${rd};">
|
|
1020
1020
|
If you didn't expect this email, you can safely ignore it. The link will expire on its own.
|
|
1021
1021
|
</p>
|
|
1022
1022
|
</td>
|
|
@@ -1027,16 +1027,16 @@ ${e.body??""}`}u(WN,"buildPrompt");function zN(e){let t=e.trim().replace(/^```(?
|
|
|
1027
1027
|
</table>
|
|
1028
1028
|
</body>
|
|
1029
1029
|
</html>`,m=[`You've been invited to ${t}`,"","Hi there,","",`${n} invited you to join ${t} on RuleMetric as ${a}.`,"",l,"","Accept the invitation:",o,"",`This invitation expires on ${c}.`,"","--","If you didn't expect this email, you can safely ignore it. The link will expire on its own."].join(`
|
|
1030
|
-
`);return{subject:i,html:p,text:m}}u(
|
|
1031
|
-
`)),t){case"resend":return
|
|
1032
|
-
`),
|
|
1030
|
+
`);return{subject:i,html:p,text:m}}u(Nm,"renderInvitation");function NC(){let e=process.env.RULEMETRIC_EMAIL_PROVIDER;return e==="resend"||e==="smtp"||e==="noop"?e:process.env.RESEND_API_KEY?"resend":"noop"}u(NC,"selectEmailProvider");var CC=new Set(["test","example","invalid","localhost"]),PC=/^example\.(com|net|org)$/;function OC(e){let t=e.trim().toLowerCase(),n=t.lastIndexOf("@");if(n<0)return!1;let r=t.slice(n+1);if(!r)return!1;let o=r.slice(r.lastIndexOf(".")+1);return!!(CC.has(o)||PC.test(r))}u(OC,"isUndeliverableRecipient");var jv=!1;async function Nv(e){let t=NC();switch(jv||(jv=!0,process.stderr.write(`[email] active provider: ${t}
|
|
1031
|
+
`)),t){case"resend":return OC(e.to)?(process.stderr.write(`[email] skipping real send to reserved/undeliverable address ${e.to} (RFC 2606/6761) \u2014 routed to noop to protect sender reputation
|
|
1032
|
+
`),jm(e)):Ev(e);case"smtp":return Tv(e);case"noop":if(process.env.NODE_ENV==="production"&&process.env.RULEMETRIC_EMAIL_PROVIDER!=="noop")throw new Error("email provider unconfigured in production: RESEND_API_KEY is not set (set it, or force RULEMETRIC_EMAIL_PROVIDER=noop to intentionally disable email)");return jm(e)}}u(Nv,"sendEmail");import{eq as Cm,and as DC}from"drizzle-orm";function xt(e){return async(t,n)=>{let r=t.get("userId");if(!r)return t.json({error:"Unauthenticated",code:"UNAUTHENTICATED"},401);let o=t.req.param("slug");if(!o)return t.json({error:"Missing org slug",code:"BAD_REQUEST"},400);let[s]=await d.select({id:V.id,slug:V.slug}).from(V).where(Cm(V.slug,o));if(!s)return t.json({error:"Organization not found",code:"ORG_NOT_FOUND"},404);let[i]=await d.select({role:Y.role}).from(Y).where(DC(Cm(Y.orgId,s.id),Cm(Y.userId,r)));if(!i||!e.includes(i.role))return t.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403);t.set("orgId",s.id),t.set("orgSlug",o),t.set("orgRole",i.role),await n()}}u(xt,"requireOrgRole");var Hs=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,lt=new MC,id=/^(?=.{3,40}$)[a-z0-9]+(?:-[a-z0-9]+)*$/,ad="Slug must be 3-40 chars, lowercase alphanumerics with single dashes only \u2014 no leading, trailing, or consecutive dashes",BC=wt.object({name:wt.string().min(1).max(100),slug:wt.string().regex(id,{message:ad})}),FC=wt.object({name:wt.string().min(1).max(100).optional(),slug:wt.string().regex(id,{message:ad}).optional()});lt.post("/orgs",async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=BC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{name:o,slug:s}=r.data,{data:i,error:c}=await t.rpc("create_organization",{p_name:o,p_slug:s});if(c){let l=nn(c),p=wo(c);if(l==="23505")return e.json({error:"Slug already taken",code:"ORG_SLUG_TAKEN"},409);if(l==="P0001"&&/unauthenticated/i.test(p))return e.json({error:"Unauthenticated",code:"UNAUTHENTICATED"},401);throw c}let a=i;return e.json({id:a.id,name:a.name,slug:a.slug,role:"owner"},201)});lt.get("/orgs",async e=>{let t=e.get("userId"),n=await d.select({id:V.id,name:V.name,slug:V.slug,role:Y.role,createdAt:V.createdAt}).from(Y).innerJoin(V,ge(Y.orgId,V.id)).where(ge(Y.userId,t)).orderBy(V.createdAt);return e.json(n.map(r=>({id:r.id,name:r.name,slug:r.slug,role:r.role})))});var Dv=Ta`case ${Y.role}
|
|
1033
1033
|
when 'owner' then 0
|
|
1034
1034
|
when 'admin' then 1
|
|
1035
1035
|
when 'member' then 2
|
|
1036
1036
|
else 3
|
|
1037
|
-
end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("orgId"),[n]=await d.select({id:H.id,name:H.name,slug:H.slug,createdAt:H.createdAt}).from(H).where(fe(H.id,t)),r=await d.select({userId:K.userId,role:K.role,joinedAt:K.createdAt,email:T.email,displayName:T.displayName}).from(K).leftJoin(T,fe(K.userId,T.id)).where(fe(K.orgId,t)).orderBy(Pv,nd(K.createdAt)),o=await d.select({id:G.id,name:G.name,slug:G.slug,memberCount:Ta`count(${ge.userId})::int`}).from(G).leftJoin(ge,fe(ge.teamId,G.id)).where(fe(G.orgId,t)).groupBy(G.id,G.name,G.slug).orderBy(nd(G.name));return e.json({id:n.id,name:n.name,slug:n.slug,createdAt:n.createdAt,members:r.map(s=>({userId:s.userId,email:s.email,displayName:s.displayName,role:s.role,joinedAt:s.joinedAt})),teams:o.map(s=>({id:s.id,name:s.name,slug:s.slug,memberCount:Number(s.memberCount)}))})});ct.patch("/orgs/:slug",At(["owner","admin"]),async e=>{let t=e.get("orgId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=BC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{name:o,slug:s}=r.data;if(o===void 0&&s===void 0)return e.json({error:"At least one of `name` or `slug` is required",code:"BAD_REQUEST"},400);let i={};o!==void 0&&(i.name=o),s!==void 0&&(i.slug=s);try{let[c]=await d.update(H).set(i).where(fe(H.id,t)).returning({id:H.id,name:H.name,slug:H.slug});return e.json({id:c.id,name:c.name,slug:c.slug})}catch(c){if(nn(c)==="23505")return e.json({error:"Slug already taken",code:"ORG_SLUG_TAKEN"},409);throw c}});ct.delete("/orgs/:slug",At(["owner"]),async e=>{let t=e.get("orgId");return await d.delete(H).where(fe(H.id,t)),e.body(null,204)});var FC=_t.object({newOwnerId:_t.string().uuid()});ct.post("/orgs/:slug/transfer",At(["owner"]),async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=FC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{newOwnerId:o}=r.data,s=e.get("orgId"),{data:i,error:c}=await t.rpc("transfer_ownership",{p_org:s,p_new_owner_id:o});if(c){let l=nn(c),p=_o(c);if(l==="P0001"){if(/same_user/i.test(p))return e.json({error:"Cannot transfer ownership to yourself",code:"SAME_USER"},400);if(/not_a_member/i.test(p))return e.json({error:"Target user is not a member of this organization",code:"NOT_A_MEMBER"},404);if(/forbidden/i.test(p))return e.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403)}throw c}let a=i;return e.json({orgId:a.orgId,newOwnerId:a.newOwnerId,oldOwnerId:a.oldOwnerId})});ct.get("/orgs/:slug/members",At(["owner","admin"]),async e=>{let t=e.get("orgId"),n=await d.select({userId:K.userId,role:K.role,joinedAt:K.createdAt,email:T.email,displayName:T.displayName}).from(K).leftJoin(T,fe(K.userId,T.id)).where(fe(K.orgId,t)).orderBy(Pv,nd(K.createdAt)),r=n.map(a=>a.userId),o=r.length?await d.select({userId:ge.userId,teamId:G.id,teamName:G.name,teamSlug:G.slug}).from(ge).innerJoin(G,fe(ge.teamId,G.id)).where(Mn(fe(G.orgId,t),Ea(ge.userId,r))):[],s=new Map;for(let a of o){let l=s.get(a.userId)??[];l.push({id:a.teamId,name:a.teamName,slug:a.teamSlug}),s.set(a.userId,l)}let i=r.length?await d.select({userId:f.userId,lastActiveAt:$C(f.startedAt)}).from(f).where(Mn(fe(f.orgId,t),Ea(f.userId,r))).groupBy(f.userId):[],c=new Map;for(let a of i)c.set(a.userId,a.lastActiveAt);return e.json(n.map(a=>{let l=c.get(a.userId)??null;return{userId:a.userId,email:a.email,displayName:a.displayName,role:a.role,joinedAt:a.joinedAt,teams:s.get(a.userId)??[],lastActiveAt:l?new Date(l).toISOString():null}}))});var HC=_t.object({role:_t.enum(["owner","admin","member"])});ct.patch("/orgs/:slug/members/:userId",At(["owner","admin"]),async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n=e.req.param("userId");if(!n||!Fs.test(n))return e.json({error:"Invalid userId path param",code:"BAD_REQUEST"},400);let r;try{r=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let o=HC.safeParse(r);if(!o.success)return e.json({error:o.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let s=e.get("orgId"),{data:i,error:c}=await t.rpc("change_member_role",{p_org:s,p_user:n,p_new_role:o.data.role});if(c){let l=nn(c),p=_o(c);if(l==="P0001"){if(/invalid_role/i.test(p))return e.json({error:"Invalid role",code:"INVALID_ROLE"},400);if(/not_a_member/i.test(p))return e.json({error:"Target user is not a member of this organization",code:"NOT_A_MEMBER"},404);if(/last_owner_violation/i.test(p))return e.json({error:"Cannot demote the last owner of this organization",code:"LAST_OWNER"},409);if(/forbidden/i.test(p))return e.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403)}throw c}let a=i;return e.json({userId:a.userId,orgId:a.orgId,role:a.role})});ct.delete("/orgs/:slug/members/:userId",At(["owner","admin","member"]),async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n=e.req.param("userId");if(!n||!Fs.test(n))return e.json({error:"Invalid userId path param",code:"BAD_REQUEST"},400);let r=e.get("orgRole"),o=e.get("userId");if(!(n===o)&&!(r==="owner"||r==="admin"))return e.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403);let c=e.get("orgId"),{error:a}=await t.rpc("remove_member",{p_org:c,p_user:n});if(a){let l=nn(a),p=_o(a);if(l==="P0001"){if(/not_a_member/i.test(p))return e.json({error:"Target user is not a member of this organization",code:"NOT_A_MEMBER"},404);if(/last_owner_violation/i.test(p))return e.json({error:"Cannot remove the last owner of this organization",code:"LAST_OWNER"},409);if(/forbidden/i.test(p))return e.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403)}throw a}return e.body(null,204)});var WC=_t.object({name:_t.string().min(1).max(100),slug:_t.string().regex(od,{message:sd})}),zC=_t.object({name:_t.string().min(1).max(100).optional(),slug:_t.string().regex(od,{message:sd}).optional()}),VC=_t.object({userId:_t.string().uuid()});async function Ra(e){let t=e.req.param("teamId");if(!t||!Fs.test(t))return{ok:!1,response:e.json({error:"Invalid teamId path param",code:"BAD_REQUEST"},400)};let n=e.get("orgId"),[r]=await d.select({id:G.id,orgId:G.orgId,name:G.name,slug:G.slug,createdAt:G.createdAt}).from(G).where(Mn(fe(G.id,t),fe(G.orgId,n)));return r?{ok:!0,team:{id:r.id,orgId:r.orgId,name:r.name,slug:r.slug,createdAt:r.createdAt}}:{ok:!1,response:e.json({error:"Team not found",code:"TEAM_NOT_FOUND"},404)}}u(Ra,"loadTeamInOrg");ct.get("/orgs/:slug/teams",At(["owner","admin","member"]),async e=>{let t=e.get("orgId"),n=await d.select({id:G.id,name:G.name,slug:G.slug,createdAt:G.createdAt,memberCount:Ta`count(${ge.userId})::int`}).from(G).leftJoin(ge,fe(ge.teamId,G.id)).where(fe(G.orgId,t)).groupBy(G.id,G.name,G.slug,G.createdAt).orderBy(nd(G.name));return e.json(n.map(r=>({id:r.id,name:r.name,slug:r.slug,memberCount:Number(r.memberCount),createdAt:r.createdAt})))});ct.post("/orgs/:slug/teams",At(["owner","admin"]),async e=>{let t;try{t=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let n=WC.safeParse(t);if(!n.success)return e.json({error:n.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let r=e.get("orgId"),{name:o,slug:s}=n.data;try{let[i]=await d.insert(G).values({orgId:r,name:o,slug:s}).returning({id:G.id,orgId:G.orgId,name:G.name,slug:G.slug,createdAt:G.createdAt});return e.json({id:i.id,orgId:i.orgId,name:i.name,slug:i.slug,createdAt:i.createdAt,memberCount:0},201)}catch(i){if(nn(i)==="23505")return e.json({error:"Slug already taken",code:"TEAM_SLUG_TAKEN"},409);throw i}});ct.patch("/orgs/:slug/teams/:teamId",At(["owner","admin"]),async e=>{let t=await Ra(e);if(!t.ok)return t.response;let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=zC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{name:o,slug:s}=r.data;if(o===void 0&&s===void 0)return e.json({error:"At least one of `name` or `slug` is required",code:"BAD_REQUEST"},400);let i={};o!==void 0&&(i.name=o),s!==void 0&&(i.slug=s);try{let[c]=await d.update(G).set(i).where(fe(G.id,t.team.id)).returning({id:G.id,orgId:G.orgId,name:G.name,slug:G.slug,createdAt:G.createdAt});return e.json({id:c.id,orgId:c.orgId,name:c.name,slug:c.slug,createdAt:c.createdAt})}catch(c){if(nn(c)==="23505")return e.json({error:"Slug already taken",code:"TEAM_SLUG_TAKEN"},409);throw c}});ct.delete("/orgs/:slug/teams/:teamId",At(["owner","admin"]),async e=>{let t=await Ra(e);return t.ok?(await d.delete(G).where(fe(G.id,t.team.id)),e.body(null,204)):t.response});ct.post("/orgs/:slug/teams/:teamId/members",At(["owner","admin"]),async e=>{let t=await Ra(e);if(!t.ok)return t.response;let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=VC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{userId:o}=r.data,s=e.get("orgId"),[i]=await d.select({userId:K.userId}).from(K).where(Mn(fe(K.userId,o),fe(K.orgId,s)));if(!i)return e.json({error:"Target user is not a member of this organization",code:"NOT_ORG_MEMBER"},400);try{await d.insert(ge).values({userId:o,teamId:t.team.id})}catch(c){if(nn(c)==="23505")return e.json({error:"User is already a member of this team",code:"ALREADY_TEAM_MEMBER"},409);throw c}return e.json({userId:o,teamId:t.team.id},201)});ct.delete("/orgs/:slug/teams/:teamId/members/:userId",At(["owner","admin"]),async e=>{let t=await Ra(e);if(!t.ok)return t.response;let n=e.req.param("userId");return!n||!Fs.test(n)?e.json({error:"Invalid userId path param",code:"BAD_REQUEST"},400):(await d.delete(ge).where(Mn(fe(ge.teamId,t.team.id),fe(ge.userId,n))).returning({userId:ge.userId})).length===0?e.json({error:"User is not a member of this team",code:"NOT_TEAM_MEMBER"},404):e.body(null,204)});function Ov(){return MC(32).toString("base64url")}u(Ov,"generateInviteToken");var jv=!1;function Dv(e){let t=process.env.WEB_URL??process.env.RULEMETRIC_WEB_URL;return t||(process.env.NODE_ENV==="production"?(jv||(jv=!0,process.stderr.write(`[invite] WEB_URL / RULEMETRIC_WEB_URL is not set in production \u2014 falling back to https://rulemetric.com for invite accept links
|
|
1038
|
-
`)),t="https://rulemetric.com"):t="http://localhost:5174"),`${t.replace(/\/$/,"")}/invite/${e}`}u(
|
|
1039
|
-
`),qn(t,{tags:{source:"invite-email"},extra:{to:e.to,orgName:e.orgName}}),{sent:!1,reason:n}}}u(Lv,"sendInvitationEmail");var JC=_t.enum(["admin","member"]),GC=_t.object({email:_t.string().email().max(254),role:JC.optional(),teamId:_t.string().uuid().optional()});ct.post("/orgs/:slug/invitations",At(["owner","admin"]),async e=>{let t;try{t=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let n=GC.safeParse(t);if(!n.success)return e.json({error:n.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let r=e.get("orgId"),o=e.get("userId"),s=n.data.email.toLowerCase(),i=n.data.role??"member",c=n.data.teamId;if(c){let[h]=await d.select({id:G.id}).from(G).where(Mn(fe(G.id,c),fe(G.orgId,r)));if(!h)return e.json({error:"Team not found in this organization",code:"INVALID_TEAM"},400)}let a=Ov(),l;try{let[h]=await d.insert(ne).values({orgId:r,email:s,role:i,teamId:c??null,invitedBy:o,token:a,expiresAt:new Date(Date.now()+6048e5)}).returning({id:ne.id,email:ne.email,role:ne.role,teamId:ne.teamId,expiresAt:ne.expiresAt});l=h}catch(h){if(nn(h)==="23505")return e.json({error:"A pending invitation for this email already exists",code:"INVITE_ALREADY_PENDING"},409);throw h}let p=Dv(a),[m]=await d.select({name:H.name}).from(H).where(fe(H.id,r)),_=await Mv(o),v=await Lv({to:s,orgName:m?.name??"your organization",inviterName:_,role:l.role,acceptUrl:p,expiresAt:l.expiresAt}),g=process.env.NODE_ENV==="test";return e.json({id:l.id,email:l.email,role:l.role,teamId:l.teamId,expiresAt:l.expiresAt,acceptUrl:p,emailSent:v.sent,...v.sent?{}:{emailError:v.reason},...g?{token:a}:{}},201)});ct.get("/orgs/:slug/invitations",At(["owner","admin"]),async e=>{let t=e.get("orgId"),n=await d.select({id:ne.id,email:ne.email,role:ne.role,teamId:ne.teamId,teamName:G.name,invitedById:ne.invitedBy,invitedByDisplayName:T.displayName,invitedByEmail:T.email,createdAt:ne.createdAt,expiresAt:ne.expiresAt}).from(ne).leftJoin(G,fe(ne.teamId,G.id)).leftJoin(T,fe(ne.invitedBy,T.id)).where(Mn(fe(ne.orgId,t),Bs(ne.acceptedAt),Bs(ne.revokedAt),qC(ne.expiresAt,Ta`now()`))).orderBy(LC(ne.createdAt));return e.json(n.map(r=>({id:r.id,email:r.email,role:r.role,teamId:r.teamId,teamName:r.teamName,invitedById:r.invitedById,invitedByName:r.invitedByDisplayName??r.invitedByEmail??null,createdAt:r.createdAt,expiresAt:r.expiresAt})))});ct.post("/orgs/:slug/invitations/:id/revoke",At(["owner","admin"]),async e=>{let t=e.req.param("id");if(!t||!Fs.test(t))return e.json({error:"Invalid invitation id",code:"BAD_REQUEST"},400);let n=e.get("orgId");return(await d.update(ne).set({revokedAt:new Date}).where(Mn(fe(ne.id,t),fe(ne.orgId,n),Bs(ne.acceptedAt),Bs(ne.revokedAt))).returning({id:ne.id})).length===0?e.json({error:"Invitation not found",code:"INVITE_NOT_FOUND"},404):e.body(null,204)});ct.post("/orgs/:slug/invitations/:id/resend",At(["owner","admin"]),async e=>{let t=e.req.param("id");if(!t||!Fs.test(t))return e.json({error:"Invalid invitation id",code:"BAD_REQUEST"},400);let n=e.get("orgId"),r=Ov(),o=new Date(Date.now()+10080*60*1e3),s=await d.update(ne).set({token:r,expiresAt:o}).where(Mn(fe(ne.id,t),fe(ne.orgId,n),Bs(ne.acceptedAt),Bs(ne.revokedAt))).returning({id:ne.id,email:ne.email,role:ne.role,expiresAt:ne.expiresAt});if(s.length===0)return e.json({error:"Invitation not found",code:"INVITE_NOT_FOUND"},404);let i=s[0],c=Dv(r),a=e.get("userId"),[l]=await d.select({name:H.name}).from(H).where(fe(H.id,n)),p=await Mv(a),m=await Lv({to:i.email,orgName:l?.name??"your organization",inviterName:p,role:i.role,acceptUrl:c,expiresAt:i.expiresAt}),_=process.env.NODE_ENV==="test";return e.json({id:i.id,email:i.email,expiresAt:i.expiresAt,acceptUrl:c,emailSent:m.sent,...m.sent?{}:{emailError:m.reason},..._?{token:r}:{}})});var rd={"7d":7,"30d":30},Nv={fully_achieved:1,mostly_achieved:.75,partially_achieved:.5,unclear_from_transcript:.25,not_achieved:0};async function Nm(e,t,n,r,o,s){let i=new Map;for(let A of e)i.set(A.tool,(i.get(A.tool)??0)+1);let c=[...i.entries()].sort((A,x)=>x[1]-A[1]).slice(0,5).map(([A,x])=>({tool:A,count:x})),a=new Map;for(let A of e)a.set(A.userId,(a.get(A.userId)??0)+1);let l=[...a.entries()].sort((A,x)=>x[1]-A[1]).slice(0,5).map(([A])=>A),p=l.length?await d.select({id:T.id,displayName:T.displayName,email:T.email}).from(T).where(Ea(T.id,l)):[],m=new Map(p.map(A=>[A.id,A])),_=l.map(A=>{let x=m.get(A);return{userId:A,displayName:x?.displayName??null,email:x?.email??null,count:a.get(A)??0}}),v=new Map;for(let A of e){let x=A.analysis;if(!x)continue;let E=x.friction;if(!E)continue;let P=Object.values(E).reduce((z,B)=>z+(typeof B=="number"?B:0),0),N=A.startedAt.toISOString().split("T")[0]??"",C=v.get(N)??{sum:0,count:0};C.sum+=P,C.count+=1,v.set(N,C)}let g=[...v.entries()].sort(([A],[x])=>A<x?-1:1).map(([A,{sum:x,count:E}])=>({day:A,avgFriction:Math.round(x/E*100)/100})),h=e.map(A=>A.id),w=h.length?await d.select({sessionId:te.sessionId,instructionId:te.instructionId,name:y.name}).from(te).innerJoin(y,fe(y.id,te.instructionId)).where(Ea(te.sessionId,h)):[],I=new Map;for(let A of w){let x=I.get(A.instructionId);x?x.sessions.add(A.sessionId):I.set(A.instructionId,{name:A.name,sessions:new Set([A.sessionId])})}let b=new Map;for(let A of e){let x=A.analysis;if(!x)continue;let E=x.outcome;E&&E in Nv&&b.set(A.id,Nv[E])}let S=[];for(let[A,{name:x,sessions:E}]of I){let P=[],N=[];for(let oe of e){let V=b.get(oe.id);V!==void 0&&(E.has(oe.id)?P.push(V):N.push(V))}let C=u(oe=>oe.length===0?null:oe.reduce((V,le)=>V+le,0)/oe.length,"avg"),z=C(P),B=C(N),q=z!==null&&B!==null?Math.round((z-B)*1e3)/10:null;S.push({instructionId:A,name:x,withSessions:E.size,withoutSessions:e.length-E.size,deltaPct:q})}return{range:t,sessionCount:e.length,memberCount:n,topTools:c,topMembers:_,frictionTrend:g,instructionEffectiveness:S}}u(Nm,"buildActivityResponse");ct.get("/orgs/:slug/activity",At(["owner","admin","member"]),async e=>{let t=e.get("orgId"),n=e.req.query("range")??"7d";if(!(n in rd))return e.json({error:"Invalid range. Allowed: 7d, 30d",code:"BAD_REQUEST"},400);let r=new Date(Date.now()-rd[n]*24*60*60*1e3),o=await d.select({id:f.id,userId:f.userId,tool:f.tool,startedAt:f.startedAt,analysis:f.analysis}).from(f).where(Mn(fe(f.orgId,t),Cv(f.startedAt,r))),[{count:s}]=await d.select({count:Ta`count(*)::int`}).from(K).where(fe(K.orgId,t)),i=await Nm(o,n,Number(s),t,r,null);return e.json(i)});ct.get("/orgs/:slug/teams/:teamId/activity",At(["owner","admin","member"]),async e=>{let t=await Ra(e);if(!t.ok)return t.response;let n=t.team,r=e.req.query("range")??"7d";if(!(r in rd))return e.json({error:"Invalid range. Allowed: 7d, 30d",code:"BAD_REQUEST"},400);let o=new Date(Date.now()-rd[r]*24*60*60*1e3),s=e.get("orgId"),c=(await d.select({userId:ge.userId}).from(ge).where(fe(ge.teamId,n.id))).map(p=>p.userId);if(c.length===0){let p=await Nm([],r,0,s,o,[]);return e.json(p)}let a=await d.select({id:f.id,userId:f.userId,tool:f.tool,startedAt:f.startedAt,analysis:f.analysis}).from(f).where(Mn(fe(f.orgId,s),Cv(f.startedAt,o),Ea(f.userId,c))),l=await Nm(a,r,c.length,s,o,c);return e.json(l)});import{Hono as KC}from"hono";import{z as Cm}from"zod";import{createClient as YC}from"@supabase/supabase-js";import{eq as ka,and as $v,isNull as qv,sql as Uv}from"drizzle-orm";var ja=new KC;ja.get("/:token",async e=>{let t=e.req.param("token");if(!t||t.length<8)return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);let[n]=await d.select({orgName:H.name,role:ne.role,email:ne.email,acceptedAt:ne.acceptedAt,revokedAt:ne.revokedAt,expiresAt:ne.expiresAt,inviterDisplayName:T.displayName,inviterEmail:T.email}).from(ne).innerJoin(H,ka(ne.orgId,H.id)).leftJoin(T,ka(ne.invitedBy,T.id)).where(ka(ne.token,t));if(!n)return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);let r=Date.now(),o=new Date(n.expiresAt).getTime()<r;if(n.acceptedAt||n.revokedAt||o)return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);let s=null,i,c=e.req.header("Authorization");if(c?.startsWith("Bearer ")){let l=c.slice(7);if(l&&!l.startsWith("rm_"))try{let p=YC(process.env.SUPABASE_URL,process.env.SUPABASE_ANON_KEY,{global:{headers:{Authorization:`Bearer ${l}`}}}),{data:m,error:_}=await p.auth.getUser();!_&&m.user&&(s=m.user.id,i=m.user.email)}catch{}}let a=null;if(s&&i&&i.toLowerCase()===n.email.toLowerCase()){let[{cnt:l}]=await d.select({cnt:Uv`count(*)::int`}).from(f).where($v(ka(f.userId,s),qv(f.orgId)));a=Number(l)}return e.json({orgName:n.orgName,inviterName:n.inviterDisplayName??n.inviterEmail??null,role:n.role,sessionCount:a})});var XC=Cm.object({token:Cm.string().min(1),acknowledgedSessionCount:Cm.number().int().nonnegative()});ja.post("/accept",async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=XC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let o=e.get("userId");if(o){let[{cnt:a}]=await d.select({cnt:Uv`count(*)::int`}).from(f).where($v(ka(f.userId,o),qv(f.orgId))),l=Number(a);if(l>r.data.acknowledgedSessionCount)return e.json({error:"Session count changed since you reviewed the consent notice \u2014 please re-confirm",code:"SESSION_COUNT_CHANGED",currentSessionCount:l},409)}let{data:s,error:i}=await t.rpc("accept_invitation",{p_token:r.data.token});if(i){let a=nn(i),l=_o(i);if(a==="P0001"){if(/invitation_not_found/i.test(l))return e.json({error:"Invitation not found",code:"INVITE_NOT_FOUND"},404);if(/invitation_revoked/i.test(l))return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);if(/invitation_already_accepted/i.test(l))return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);if(/invitation_expired/i.test(l))return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);if(/invitation_email_mismatch/i.test(l))return e.json({error:"This invitation is for a different email address",code:"INVITE_EMAIL_MISMATCH"},403);if(/already_member/i.test(l))return e.json({error:"You are already a member of this organization",code:"ALREADY_MEMBER"},409);if(/already_team_member/i.test(l))return e.json({error:"You are already a member of this team",code:"ALREADY_TEAM_MEMBER"},409);if(/unauthenticated/i.test(l))return e.json({error:"Unauthenticated",code:"UNAUTHENTICATED"},401)}throw i}let c=s;return e.json({orgId:c.orgId,role:c.role})});import{Hono as QC}from"hono";import{z as Na}from"zod";import{eq as Ca,and as ZC}from"drizzle-orm";var Pa=new QC;Pa.get("/profile",async e=>{let t=e.get("userId"),[n]=await d.select({id:T.id,email:T.email,displayName:T.displayName,activeOrgId:T.activeOrgId,isSuperadmin:T.isSuperadmin,claudeCodePlan:T.claudeCodePlan,planSource:T.planSource,setupCompletedAt:T.setupCompletedAt,liveSendSkipped:T.liveSendSkipped}).from(T).where(Ca(T.id,t));return n?(e.header("Cache-Control","private, max-age=15"),e.json({id:n.id,email:n.email,displayName:n.displayName,activeOrgId:n.activeOrgId,isSuperadmin:n.isSuperadmin,claudeCodePlan:n.claudeCodePlan,planSource:n.planSource,setupCompletedAt:n.setupCompletedAt,liveSendSkipped:n.liveSendSkipped})):e.json({error:"Profile not found",code:"PROFILE_NOT_FOUND"},404)});var eP=["free","pro","max_5x","max_20x"],tP=Na.object({activeOrgId:Na.string().uuid().nullable().optional(),claudeCodePlan:Na.enum(eP).nullable().optional(),setupCompletedAt:Na.string().datetime().nullable().optional(),liveSendSkipped:Na.boolean().optional()});Pa.patch("/profile",async e=>{let t=e.get("userId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=tP.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let o=r.data;if("activeOrgId"in o&&o.activeOrgId!=null){let[c]=await d.select({orgId:K.orgId}).from(K).where(ZC(Ca(K.userId,t),Ca(K.orgId,o.activeOrgId)));if(!c)return e.json({error:"You are not a member of the requested organization",code:"NOT_A_MEMBER"},403)}let s={};"activeOrgId"in o&&(s.activeOrgId=o.activeOrgId??null),"claudeCodePlan"in o&&(s.claudeCodePlan=o.claudeCodePlan??null,s.planSource=o.claudeCodePlan==null?"detected":"manual"),"setupCompletedAt"in o&&(s.setupCompletedAt=o.setupCompletedAt?new Date(o.setupCompletedAt):null),"liveSendSkipped"in o&&(s.liveSendSkipped=o.liveSendSkipped),Object.keys(s).length>0&&await d.update(T).set(s).where(Ca(T.id,t));let[i]=await d.select({activeOrgId:T.activeOrgId,claudeCodePlan:T.claudeCodePlan,planSource:T.planSource,setupCompletedAt:T.setupCompletedAt,liveSendSkipped:T.liveSendSkipped}).from(T).where(Ca(T.id,t));return e.json({activeOrgId:i.activeOrgId,claudeCodePlan:i.claudeCodePlan,planSource:i.planSource,setupCompletedAt:i.setupCompletedAt,liveSendSkipped:i.liveSendSkipped})});import{Hono as rP}from"hono";import{z as ut}from"zod";import{asc as Bv,eq as Oo,sql as xn}from"drizzle-orm";import{eq as nP}from"drizzle-orm";function Oa(){return async(e,t)=>{let n=e.get("userId");if(!n)return e.json({error:"Unauthenticated",code:"UNAUTHENTICATED"},401);let[r]=await d.select({isSuperadmin:T.isSuperadmin}).from(T).where(nP(T.id,n));if(!r?.isSuperadmin)return e.json({error:"Forbidden",code:"NOT_SUPERADMIN"},403);await t()}}u(Oa,"requireSuperadmin");na();var sn=new rP;sn.use("/superadmin/*",Oa());var oP=ut.object({search:ut.string().trim().min(1).max(120).optional(),limit:ut.coerce.number().int().min(1).max(200).default(50),offset:ut.coerce.number().int().min(0).default(0)});sn.get("/superadmin/users",async e=>{let t=oP.safeParse({search:e.req.query("search"),limit:e.req.query("limit"),offset:e.req.query("offset")});if(!t.success)return e.json({error:t.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{search:n,limit:r,offset:o}=t.data,s=await d.execute(xn`
|
|
1037
|
+
end`;lt.get("/orgs/:slug",xt(["owner","admin","member"]),async e=>{let t=e.get("orgId"),[n]=await d.select({id:V.id,name:V.name,slug:V.slug,createdAt:V.createdAt}).from(V).where(ge(V.id,t)),r=await d.select({userId:Y.userId,role:Y.role,joinedAt:Y.createdAt,email:R.email,displayName:R.displayName}).from(Y).leftJoin(R,ge(Y.userId,R.id)).where(ge(Y.orgId,t)).orderBy(Dv,od(Y.createdAt)),o=await d.select({id:K.id,name:K.name,slug:K.slug,memberCount:Ta`count(${he.userId})::int`}).from(K).leftJoin(he,ge(he.teamId,K.id)).where(ge(K.orgId,t)).groupBy(K.id,K.name,K.slug).orderBy(od(K.name));return e.json({id:n.id,name:n.name,slug:n.slug,createdAt:n.createdAt,members:r.map(s=>({userId:s.userId,email:s.email,displayName:s.displayName,role:s.role,joinedAt:s.joinedAt})),teams:o.map(s=>({id:s.id,name:s.name,slug:s.slug,memberCount:Number(s.memberCount)}))})});lt.patch("/orgs/:slug",xt(["owner","admin"]),async e=>{let t=e.get("orgId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=FC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{name:o,slug:s}=r.data;if(o===void 0&&s===void 0)return e.json({error:"At least one of `name` or `slug` is required",code:"BAD_REQUEST"},400);let i={};o!==void 0&&(i.name=o),s!==void 0&&(i.slug=s);try{let[c]=await d.update(V).set(i).where(ge(V.id,t)).returning({id:V.id,name:V.name,slug:V.slug});return e.json({id:c.id,name:c.name,slug:c.slug})}catch(c){if(nn(c)==="23505")return e.json({error:"Slug already taken",code:"ORG_SLUG_TAKEN"},409);throw c}});lt.delete("/orgs/:slug",xt(["owner"]),async e=>{let t=e.get("orgId");return await d.delete(V).where(ge(V.id,t)),e.body(null,204)});var HC=wt.object({newOwnerId:wt.string().uuid()});lt.post("/orgs/:slug/transfer",xt(["owner"]),async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=HC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{newOwnerId:o}=r.data,s=e.get("orgId"),{data:i,error:c}=await t.rpc("transfer_ownership",{p_org:s,p_new_owner_id:o});if(c){let l=nn(c),p=wo(c);if(l==="P0001"){if(/same_user/i.test(p))return e.json({error:"Cannot transfer ownership to yourself",code:"SAME_USER"},400);if(/not_a_member/i.test(p))return e.json({error:"Target user is not a member of this organization",code:"NOT_A_MEMBER"},404);if(/forbidden/i.test(p))return e.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403)}throw c}let a=i;return e.json({orgId:a.orgId,newOwnerId:a.newOwnerId,oldOwnerId:a.oldOwnerId})});lt.get("/orgs/:slug/members",xt(["owner","admin"]),async e=>{let t=e.get("orgId"),n=await d.select({userId:Y.userId,role:Y.role,joinedAt:Y.createdAt,email:R.email,displayName:R.displayName}).from(Y).leftJoin(R,ge(Y.userId,R.id)).where(ge(Y.orgId,t)).orderBy(Dv,od(Y.createdAt)),r=n.map(a=>a.userId),o=r.length?await d.select({userId:he.userId,teamId:K.id,teamName:K.name,teamSlug:K.slug}).from(he).innerJoin(K,ge(he.teamId,K.id)).where(Ln(ge(K.orgId,t),Ea(he.userId,r))):[],s=new Map;for(let a of o){let l=s.get(a.userId)??[];l.push({id:a.teamId,name:a.teamName,slug:a.teamSlug}),s.set(a.userId,l)}let i=r.length?await d.select({userId:f.userId,lastActiveAt:qC(f.startedAt)}).from(f).where(Ln(ge(f.orgId,t),Ea(f.userId,r))).groupBy(f.userId):[],c=new Map;for(let a of i)c.set(a.userId,a.lastActiveAt);return e.json(n.map(a=>{let l=c.get(a.userId)??null;return{userId:a.userId,email:a.email,displayName:a.displayName,role:a.role,joinedAt:a.joinedAt,teams:s.get(a.userId)??[],lastActiveAt:l?new Date(l).toISOString():null}}))});var WC=wt.object({role:wt.enum(["owner","admin","member"])});lt.patch("/orgs/:slug/members/:userId",xt(["owner","admin"]),async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n=e.req.param("userId");if(!n||!Hs.test(n))return e.json({error:"Invalid userId path param",code:"BAD_REQUEST"},400);let r;try{r=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let o=WC.safeParse(r);if(!o.success)return e.json({error:o.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let s=e.get("orgId"),{data:i,error:c}=await t.rpc("change_member_role",{p_org:s,p_user:n,p_new_role:o.data.role});if(c){let l=nn(c),p=wo(c);if(l==="P0001"){if(/invalid_role/i.test(p))return e.json({error:"Invalid role",code:"INVALID_ROLE"},400);if(/not_a_member/i.test(p))return e.json({error:"Target user is not a member of this organization",code:"NOT_A_MEMBER"},404);if(/last_owner_violation/i.test(p))return e.json({error:"Cannot demote the last owner of this organization",code:"LAST_OWNER"},409);if(/forbidden/i.test(p))return e.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403)}throw c}let a=i;return e.json({userId:a.userId,orgId:a.orgId,role:a.role})});lt.delete("/orgs/:slug/members/:userId",xt(["owner","admin","member"]),async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n=e.req.param("userId");if(!n||!Hs.test(n))return e.json({error:"Invalid userId path param",code:"BAD_REQUEST"},400);let r=e.get("orgRole"),o=e.get("userId");if(!(n===o)&&!(r==="owner"||r==="admin"))return e.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403);let c=e.get("orgId"),{error:a}=await t.rpc("remove_member",{p_org:c,p_user:n});if(a){let l=nn(a),p=wo(a);if(l==="P0001"){if(/not_a_member/i.test(p))return e.json({error:"Target user is not a member of this organization",code:"NOT_A_MEMBER"},404);if(/last_owner_violation/i.test(p))return e.json({error:"Cannot remove the last owner of this organization",code:"LAST_OWNER"},409);if(/forbidden/i.test(p))return e.json({error:"Forbidden",code:"ORG_FORBIDDEN"},403)}throw a}return e.body(null,204)});var zC=wt.object({name:wt.string().min(1).max(100),slug:wt.string().regex(id,{message:ad})}),VC=wt.object({name:wt.string().min(1).max(100).optional(),slug:wt.string().regex(id,{message:ad}).optional()}),JC=wt.object({userId:wt.string().uuid()});async function Ra(e){let t=e.req.param("teamId");if(!t||!Hs.test(t))return{ok:!1,response:e.json({error:"Invalid teamId path param",code:"BAD_REQUEST"},400)};let n=e.get("orgId"),[r]=await d.select({id:K.id,orgId:K.orgId,name:K.name,slug:K.slug,createdAt:K.createdAt}).from(K).where(Ln(ge(K.id,t),ge(K.orgId,n)));return r?{ok:!0,team:{id:r.id,orgId:r.orgId,name:r.name,slug:r.slug,createdAt:r.createdAt}}:{ok:!1,response:e.json({error:"Team not found",code:"TEAM_NOT_FOUND"},404)}}u(Ra,"loadTeamInOrg");lt.get("/orgs/:slug/teams",xt(["owner","admin","member"]),async e=>{let t=e.get("orgId"),n=await d.select({id:K.id,name:K.name,slug:K.slug,createdAt:K.createdAt,memberCount:Ta`count(${he.userId})::int`}).from(K).leftJoin(he,ge(he.teamId,K.id)).where(ge(K.orgId,t)).groupBy(K.id,K.name,K.slug,K.createdAt).orderBy(od(K.name));return e.json(n.map(r=>({id:r.id,name:r.name,slug:r.slug,memberCount:Number(r.memberCount),createdAt:r.createdAt})))});lt.post("/orgs/:slug/teams",xt(["owner","admin"]),async e=>{let t;try{t=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let n=zC.safeParse(t);if(!n.success)return e.json({error:n.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let r=e.get("orgId"),{name:o,slug:s}=n.data;try{let[i]=await d.insert(K).values({orgId:r,name:o,slug:s}).returning({id:K.id,orgId:K.orgId,name:K.name,slug:K.slug,createdAt:K.createdAt});return e.json({id:i.id,orgId:i.orgId,name:i.name,slug:i.slug,createdAt:i.createdAt,memberCount:0},201)}catch(i){if(nn(i)==="23505")return e.json({error:"Slug already taken",code:"TEAM_SLUG_TAKEN"},409);throw i}});lt.patch("/orgs/:slug/teams/:teamId",xt(["owner","admin"]),async e=>{let t=await Ra(e);if(!t.ok)return t.response;let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=VC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{name:o,slug:s}=r.data;if(o===void 0&&s===void 0)return e.json({error:"At least one of `name` or `slug` is required",code:"BAD_REQUEST"},400);let i={};o!==void 0&&(i.name=o),s!==void 0&&(i.slug=s);try{let[c]=await d.update(K).set(i).where(ge(K.id,t.team.id)).returning({id:K.id,orgId:K.orgId,name:K.name,slug:K.slug,createdAt:K.createdAt});return e.json({id:c.id,orgId:c.orgId,name:c.name,slug:c.slug,createdAt:c.createdAt})}catch(c){if(nn(c)==="23505")return e.json({error:"Slug already taken",code:"TEAM_SLUG_TAKEN"},409);throw c}});lt.delete("/orgs/:slug/teams/:teamId",xt(["owner","admin"]),async e=>{let t=await Ra(e);return t.ok?(await d.delete(K).where(ge(K.id,t.team.id)),e.body(null,204)):t.response});lt.post("/orgs/:slug/teams/:teamId/members",xt(["owner","admin"]),async e=>{let t=await Ra(e);if(!t.ok)return t.response;let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=JC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{userId:o}=r.data,s=e.get("orgId"),[i]=await d.select({userId:Y.userId}).from(Y).where(Ln(ge(Y.userId,o),ge(Y.orgId,s)));if(!i)return e.json({error:"Target user is not a member of this organization",code:"NOT_ORG_MEMBER"},400);try{await d.insert(he).values({userId:o,teamId:t.team.id})}catch(c){if(nn(c)==="23505")return e.json({error:"User is already a member of this team",code:"ALREADY_TEAM_MEMBER"},409);throw c}return e.json({userId:o,teamId:t.team.id},201)});lt.delete("/orgs/:slug/teams/:teamId/members/:userId",xt(["owner","admin"]),async e=>{let t=await Ra(e);if(!t.ok)return t.response;let n=e.req.param("userId");return!n||!Hs.test(n)?e.json({error:"Invalid userId path param",code:"BAD_REQUEST"},400):(await d.delete(he).where(Ln(ge(he.teamId,t.team.id),ge(he.userId,n))).returning({userId:he.userId})).length===0?e.json({error:"User is not a member of this team",code:"NOT_TEAM_MEMBER"},404):e.body(null,204)});function Mv(){return LC(32).toString("base64url")}u(Mv,"generateInviteToken");var Cv=!1;function Lv(e){let t=process.env.WEB_URL??process.env.RULEMETRIC_WEB_URL;return t||(process.env.NODE_ENV==="production"?(Cv||(Cv=!0,process.stderr.write(`[invite] WEB_URL / RULEMETRIC_WEB_URL is not set in production \u2014 falling back to https://rulemetric.com for invite accept links
|
|
1038
|
+
`)),t="https://rulemetric.com"):t="http://localhost:5174"),`${t.replace(/\/$/,"")}/invite/${e}`}u(Lv,"buildAcceptUrl");async function $v(e){let[t]=await d.select({displayName:R.displayName,email:R.email}).from(R).where(ge(R.id,e));return t?.displayName?.trim()||t?.email||"A teammate"}u($v,"getInviterDisplayName");async function qv(e){try{let{subject:t,html:n,text:r}=Nm({orgName:e.orgName,inviterName:e.inviterName,role:e.role,acceptUrl:e.acceptUrl,expiresAt:e.expiresAt});return(await Nv({to:e.to,subject:t,html:n,text:r})).provider==="noop"?{sent:!1,reason:"email provider is noop \u2014 no email was delivered; share the accept link directly"}:{sent:!0}}catch(t){let n=t instanceof Error?t.message:String(t);return process.stderr.write(`[invite] email send failed for ${e.to}: ${n}
|
|
1039
|
+
`),Un(t,{tags:{source:"invite-email"},extra:{to:e.to,orgName:e.orgName}}),{sent:!1,reason:n}}}u(qv,"sendInvitationEmail");var GC=wt.enum(["admin","member"]),KC=wt.object({email:wt.string().email().max(254),role:GC.optional(),teamId:wt.string().uuid().optional()});lt.post("/orgs/:slug/invitations",xt(["owner","admin"]),async e=>{let t;try{t=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let n=KC.safeParse(t);if(!n.success)return e.json({error:n.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let r=e.get("orgId"),o=e.get("userId"),s=n.data.email.toLowerCase(),i=n.data.role??"member",c=n.data.teamId;if(c){let[h]=await d.select({id:K.id}).from(K).where(Ln(ge(K.id,c),ge(K.orgId,r)));if(!h)return e.json({error:"Team not found in this organization",code:"INVALID_TEAM"},400)}let a=Mv(),l;try{let[h]=await d.insert(re).values({orgId:r,email:s,role:i,teamId:c??null,invitedBy:o,token:a,expiresAt:new Date(Date.now()+6048e5)}).returning({id:re.id,email:re.email,role:re.role,teamId:re.teamId,expiresAt:re.expiresAt});l=h}catch(h){if(nn(h)==="23505")return e.json({error:"A pending invitation for this email already exists",code:"INVITE_ALREADY_PENDING"},409);throw h}let p=Lv(a),[m]=await d.select({name:V.name}).from(V).where(ge(V.id,r)),y=await $v(o),v=await qv({to:s,orgName:m?.name??"your organization",inviterName:y,role:l.role,acceptUrl:p,expiresAt:l.expiresAt}),g=process.env.NODE_ENV==="test";return e.json({id:l.id,email:l.email,role:l.role,teamId:l.teamId,expiresAt:l.expiresAt,acceptUrl:p,emailSent:v.sent,...v.sent?{}:{emailError:v.reason},...g?{token:a}:{}},201)});lt.get("/orgs/:slug/invitations",xt(["owner","admin"]),async e=>{let t=e.get("orgId"),n=await d.select({id:re.id,email:re.email,role:re.role,teamId:re.teamId,teamName:K.name,invitedById:re.invitedBy,invitedByDisplayName:R.displayName,invitedByEmail:R.email,createdAt:re.createdAt,expiresAt:re.expiresAt}).from(re).leftJoin(K,ge(re.teamId,K.id)).leftJoin(R,ge(re.invitedBy,R.id)).where(Ln(ge(re.orgId,t),Fs(re.acceptedAt),Fs(re.revokedAt),UC(re.expiresAt,Ta`now()`))).orderBy($C(re.createdAt));return e.json(n.map(r=>({id:r.id,email:r.email,role:r.role,teamId:r.teamId,teamName:r.teamName,invitedById:r.invitedById,invitedByName:r.invitedByDisplayName??r.invitedByEmail??null,createdAt:r.createdAt,expiresAt:r.expiresAt})))});lt.post("/orgs/:slug/invitations/:id/revoke",xt(["owner","admin"]),async e=>{let t=e.req.param("id");if(!t||!Hs.test(t))return e.json({error:"Invalid invitation id",code:"BAD_REQUEST"},400);let n=e.get("orgId");return(await d.update(re).set({revokedAt:new Date}).where(Ln(ge(re.id,t),ge(re.orgId,n),Fs(re.acceptedAt),Fs(re.revokedAt))).returning({id:re.id})).length===0?e.json({error:"Invitation not found",code:"INVITE_NOT_FOUND"},404):e.body(null,204)});lt.post("/orgs/:slug/invitations/:id/resend",xt(["owner","admin"]),async e=>{let t=e.req.param("id");if(!t||!Hs.test(t))return e.json({error:"Invalid invitation id",code:"BAD_REQUEST"},400);let n=e.get("orgId"),r=Mv(),o=new Date(Date.now()+10080*60*1e3),s=await d.update(re).set({token:r,expiresAt:o}).where(Ln(ge(re.id,t),ge(re.orgId,n),Fs(re.acceptedAt),Fs(re.revokedAt))).returning({id:re.id,email:re.email,role:re.role,expiresAt:re.expiresAt});if(s.length===0)return e.json({error:"Invitation not found",code:"INVITE_NOT_FOUND"},404);let i=s[0],c=Lv(r),a=e.get("userId"),[l]=await d.select({name:V.name}).from(V).where(ge(V.id,n)),p=await $v(a),m=await qv({to:i.email,orgName:l?.name??"your organization",inviterName:p,role:i.role,acceptUrl:c,expiresAt:i.expiresAt}),y=process.env.NODE_ENV==="test";return e.json({id:i.id,email:i.email,expiresAt:i.expiresAt,acceptUrl:c,emailSent:m.sent,...m.sent?{}:{emailError:m.reason},...y?{token:r}:{}})});var sd={"7d":7,"30d":30},Pv={fully_achieved:1,mostly_achieved:.75,partially_achieved:.5,unclear_from_transcript:.25,not_achieved:0};async function Pm(e,t,n,r,o,s){let i=new Map;for(let A of e)i.set(A.tool,(i.get(A.tool)??0)+1);let c=[...i.entries()].sort((A,x)=>x[1]-A[1]).slice(0,5).map(([A,x])=>({tool:A,count:x})),a=new Map;for(let A of e)a.set(A.userId,(a.get(A.userId)??0)+1);let l=[...a.entries()].sort((A,x)=>x[1]-A[1]).slice(0,5).map(([A])=>A),p=l.length?await d.select({id:R.id,displayName:R.displayName,email:R.email}).from(R).where(Ea(R.id,l)):[],m=new Map(p.map(A=>[A.id,A])),y=l.map(A=>{let x=m.get(A);return{userId:A,displayName:x?.displayName??null,email:x?.email??null,count:a.get(A)??0}}),v=new Map;for(let A of e){let x=A.analysis;if(!x)continue;let T=x.friction;if(!T)continue;let P=Object.values(T).reduce((O,F)=>O+(typeof F=="number"?F:0),0),E=A.startedAt.toISOString().split("T")[0]??"",j=v.get(E)??{sum:0,count:0};j.sum+=P,j.count+=1,v.set(E,j)}let g=[...v.entries()].sort(([A],[x])=>A<x?-1:1).map(([A,{sum:x,count:T}])=>({day:A,avgFriction:Math.round(x/T*100)/100})),h=e.map(A=>A.id),w=h.length?await d.select({sessionId:ne.sessionId,instructionId:ne.instructionId,name:_.name}).from(ne).innerJoin(_,ge(_.id,ne.instructionId)).where(Ea(ne.sessionId,h)):[],b=new Map;for(let A of w){let x=b.get(A.instructionId);x?x.sessions.add(A.sessionId):b.set(A.instructionId,{name:A.name,sessions:new Set([A.sessionId])})}let I=new Map;for(let A of e){let x=A.analysis;if(!x)continue;let T=x.outcome;T&&T in Pv&&I.set(A.id,Pv[T])}let S=[];for(let[A,{name:x,sessions:T}]of b){let P=[],E=[];for(let ee of e){let z=I.get(ee.id);z!==void 0&&(T.has(ee.id)?P.push(z):E.push(z))}let j=u(ee=>ee.length===0?null:ee.reduce((z,de)=>z+de,0)/ee.length,"avg"),O=j(P),F=j(E),U=O!==null&&F!==null?Math.round((O-F)*1e3)/10:null;S.push({instructionId:A,name:x,withSessions:T.size,withoutSessions:e.length-T.size,deltaPct:U})}return{range:t,sessionCount:e.length,memberCount:n,topTools:c,topMembers:y,frictionTrend:g,instructionEffectiveness:S}}u(Pm,"buildActivityResponse");lt.get("/orgs/:slug/activity",xt(["owner","admin","member"]),async e=>{let t=e.get("orgId"),n=e.req.query("range")??"7d";if(!(n in sd))return e.json({error:"Invalid range. Allowed: 7d, 30d",code:"BAD_REQUEST"},400);let r=new Date(Date.now()-sd[n]*24*60*60*1e3),o=await d.select({id:f.id,userId:f.userId,tool:f.tool,startedAt:f.startedAt,analysis:f.analysis}).from(f).where(Ln(ge(f.orgId,t),Ov(f.startedAt,r))),[{count:s}]=await d.select({count:Ta`count(*)::int`}).from(Y).where(ge(Y.orgId,t)),i=await Pm(o,n,Number(s),t,r,null);return e.json(i)});lt.get("/orgs/:slug/teams/:teamId/activity",xt(["owner","admin","member"]),async e=>{let t=await Ra(e);if(!t.ok)return t.response;let n=t.team,r=e.req.query("range")??"7d";if(!(r in sd))return e.json({error:"Invalid range. Allowed: 7d, 30d",code:"BAD_REQUEST"},400);let o=new Date(Date.now()-sd[r]*24*60*60*1e3),s=e.get("orgId"),c=(await d.select({userId:he.userId}).from(he).where(ge(he.teamId,n.id))).map(p=>p.userId);if(c.length===0){let p=await Pm([],r,0,s,o,[]);return e.json(p)}let a=await d.select({id:f.id,userId:f.userId,tool:f.tool,startedAt:f.startedAt,analysis:f.analysis}).from(f).where(Ln(ge(f.orgId,s),Ov(f.startedAt,o),Ea(f.userId,c))),l=await Pm(a,r,c.length,s,o,c);return e.json(l)});import{Hono as YC}from"hono";import{z as Om}from"zod";import{createClient as XC}from"@supabase/supabase-js";import{eq as ka,and as Uv,isNull as Bv,sql as Fv}from"drizzle-orm";var ja=new YC;ja.get("/:token",async e=>{let t=e.req.param("token");if(!t||t.length<8)return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);let[n]=await d.select({orgName:V.name,role:re.role,email:re.email,acceptedAt:re.acceptedAt,revokedAt:re.revokedAt,expiresAt:re.expiresAt,inviterDisplayName:R.displayName,inviterEmail:R.email}).from(re).innerJoin(V,ka(re.orgId,V.id)).leftJoin(R,ka(re.invitedBy,R.id)).where(ka(re.token,t));if(!n)return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);let r=Date.now(),o=new Date(n.expiresAt).getTime()<r;if(n.acceptedAt||n.revokedAt||o)return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);let s=null,i,c=e.req.header("Authorization");if(c?.startsWith("Bearer ")){let l=c.slice(7);if(l&&!l.startsWith("rm_"))try{let p=XC(process.env.SUPABASE_URL,process.env.SUPABASE_ANON_KEY,{global:{headers:{Authorization:`Bearer ${l}`}}}),{data:m,error:y}=await p.auth.getUser();!y&&m.user&&(s=m.user.id,i=m.user.email)}catch{}}let a=null;if(s&&i&&i.toLowerCase()===n.email.toLowerCase()){let[{cnt:l}]=await d.select({cnt:Fv`count(*)::int`}).from(f).where(Uv(ka(f.userId,s),Bv(f.orgId)));a=Number(l)}return e.json({orgName:n.orgName,inviterName:n.inviterDisplayName??n.inviterEmail??null,role:n.role,sessionCount:a})});var QC=Om.object({token:Om.string().min(1),acknowledgedSessionCount:Om.number().int().nonnegative()});ja.post("/accept",async e=>{let t=e.get("supabase");if(!t)return e.json({error:"JWT authentication required for this endpoint",code:"JWT_REQUIRED"},401);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=QC.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let o=e.get("userId");if(o){let[{cnt:a}]=await d.select({cnt:Fv`count(*)::int`}).from(f).where(Uv(ka(f.userId,o),Bv(f.orgId))),l=Number(a);if(l>r.data.acknowledgedSessionCount)return e.json({error:"Session count changed since you reviewed the consent notice \u2014 please re-confirm",code:"SESSION_COUNT_CHANGED",currentSessionCount:l},409)}let{data:s,error:i}=await t.rpc("accept_invitation",{p_token:r.data.token});if(i){let a=nn(i),l=wo(i);if(a==="P0001"){if(/invitation_not_found/i.test(l))return e.json({error:"Invitation not found",code:"INVITE_NOT_FOUND"},404);if(/invitation_revoked/i.test(l))return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);if(/invitation_already_accepted/i.test(l))return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);if(/invitation_expired/i.test(l))return e.json({error:"Invitation no longer valid",code:"INVITE_GONE"},410);if(/invitation_email_mismatch/i.test(l))return e.json({error:"This invitation is for a different email address",code:"INVITE_EMAIL_MISMATCH"},403);if(/already_member/i.test(l))return e.json({error:"You are already a member of this organization",code:"ALREADY_MEMBER"},409);if(/already_team_member/i.test(l))return e.json({error:"You are already a member of this team",code:"ALREADY_TEAM_MEMBER"},409);if(/unauthenticated/i.test(l))return e.json({error:"Unauthenticated",code:"UNAUTHENTICATED"},401)}throw i}let c=s;return e.json({orgId:c.orgId,role:c.role})});import{Hono as ZC}from"hono";import{z as Na}from"zod";import{eq as Ca,and as eP}from"drizzle-orm";var Pa=new ZC;Pa.get("/profile",async e=>{let t=e.get("userId"),[n]=await d.select({id:R.id,email:R.email,displayName:R.displayName,activeOrgId:R.activeOrgId,isSuperadmin:R.isSuperadmin,claudeCodePlan:R.claudeCodePlan,planSource:R.planSource,setupCompletedAt:R.setupCompletedAt,liveSendSkipped:R.liveSendSkipped}).from(R).where(Ca(R.id,t));return n?(e.header("Cache-Control","private, max-age=15"),e.json({id:n.id,email:n.email,displayName:n.displayName,activeOrgId:n.activeOrgId,isSuperadmin:n.isSuperadmin,claudeCodePlan:n.claudeCodePlan,planSource:n.planSource,setupCompletedAt:n.setupCompletedAt,liveSendSkipped:n.liveSendSkipped})):e.json({error:"Profile not found",code:"PROFILE_NOT_FOUND"},404)});var tP=["free","pro","max_5x","max_20x"],nP=Na.object({activeOrgId:Na.string().uuid().nullable().optional(),claudeCodePlan:Na.enum(tP).nullable().optional(),setupCompletedAt:Na.string().datetime().nullable().optional(),liveSendSkipped:Na.boolean().optional()});Pa.patch("/profile",async e=>{let t=e.get("userId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON body",code:"VALIDATION_ERROR"},400)}let r=nP.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let o=r.data;if("activeOrgId"in o&&o.activeOrgId!=null){let[c]=await d.select({orgId:Y.orgId}).from(Y).where(eP(Ca(Y.userId,t),Ca(Y.orgId,o.activeOrgId)));if(!c)return e.json({error:"You are not a member of the requested organization",code:"NOT_A_MEMBER"},403)}let s={};"activeOrgId"in o&&(s.activeOrgId=o.activeOrgId??null),"claudeCodePlan"in o&&(s.claudeCodePlan=o.claudeCodePlan??null,s.planSource=o.claudeCodePlan==null?"detected":"manual"),"setupCompletedAt"in o&&(s.setupCompletedAt=o.setupCompletedAt?new Date(o.setupCompletedAt):null),"liveSendSkipped"in o&&(s.liveSendSkipped=o.liveSendSkipped),Object.keys(s).length>0&&await d.update(R).set(s).where(Ca(R.id,t));let[i]=await d.select({activeOrgId:R.activeOrgId,claudeCodePlan:R.claudeCodePlan,planSource:R.planSource,setupCompletedAt:R.setupCompletedAt,liveSendSkipped:R.liveSendSkipped}).from(R).where(Ca(R.id,t));return e.json({activeOrgId:i.activeOrgId,claudeCodePlan:i.claudeCodePlan,planSource:i.planSource,setupCompletedAt:i.setupCompletedAt,liveSendSkipped:i.liveSendSkipped})});import{Hono as oP}from"hono";import{z as pt}from"zod";import{asc as Hv,eq as Lo,sql as En}from"drizzle-orm";import{eq as rP}from"drizzle-orm";function Oa(){return async(e,t)=>{let n=e.get("userId");if(!n)return e.json({error:"Unauthenticated",code:"UNAUTHENTICATED"},401);let[r]=await d.select({isSuperadmin:R.isSuperadmin}).from(R).where(rP(R.id,n));if(!r?.isSuperadmin)return e.json({error:"Forbidden",code:"NOT_SUPERADMIN"},403);await t()}}u(Oa,"requireSuperadmin");na();var sn=new oP;sn.use("/superadmin/*",Oa());var sP=pt.object({search:pt.string().trim().min(1).max(120).optional(),limit:pt.coerce.number().int().min(1).max(200).default(50),offset:pt.coerce.number().int().min(0).default(0)});sn.get("/superadmin/users",async e=>{let t=sP.safeParse({search:e.req.query("search"),limit:e.req.query("limit"),offset:e.req.query("offset")});if(!t.success)return e.json({error:t.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{search:n,limit:r,offset:o}=t.data,s=await d.execute(En`
|
|
1040
1040
|
select
|
|
1041
1041
|
p.id,
|
|
1042
1042
|
p.email,
|
|
@@ -1058,16 +1058,16 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1058
1058
|
count(*) filter (where org_id is null)::int as orphan
|
|
1059
1059
|
from sessions group by user_id
|
|
1060
1060
|
) s on s.user_id = p.id
|
|
1061
|
-
${n?
|
|
1061
|
+
${n?En`where p.email ilike ${"%"+et(n)+"%"}`:En``}
|
|
1062
1062
|
order by p.created_at desc
|
|
1063
1063
|
limit ${r} offset ${o}
|
|
1064
|
-
`),[{total:i}]=await d.execute(
|
|
1064
|
+
`),[{total:i}]=await d.execute(En`
|
|
1065
1065
|
select count(*)::int as total from profiles p
|
|
1066
|
-
${n?
|
|
1067
|
-
`);return e.json({users:s,total:i,limit:r,offset:o})});sn.get("/superadmin/users/:id",async e=>{let t=e.req.param("id");if(!
|
|
1066
|
+
${n?En`where p.email ilike ${"%"+et(n)+"%"}`:En``}
|
|
1067
|
+
`);return e.json({users:s,total:i,limit:r,offset:o})});sn.get("/superadmin/users/:id",async e=>{let t=e.req.param("id");if(!pt.string().uuid().safeParse(t).success)return e.json({error:"Invalid user id",code:"VALIDATION_ERROR"},400);let[n]=await d.select({id:R.id,email:R.email,displayName:R.displayName,isSuperadmin:R.isSuperadmin,activeOrgId:R.activeOrgId,createdAt:R.createdAt}).from(R).where(Lo(R.id,t));if(!n)return e.json({error:"User not found",code:"USER_NOT_FOUND"},404);let r=await d.select({orgId:V.id,orgName:V.name,orgSlug:V.slug,role:Y.role}).from(Y).innerJoin(V,Lo(V.id,Y.orgId)).where(Lo(Y.userId,t)).orderBy(Hv(V.name)),[o]=await d.select({total:En`count(*)::int`,orphan:En`count(*) filter (where org_id is null)::int`}).from(f).where(Lo(f.userId,t)),s={banned:!1,bannedUntil:null,lastSignInAt:null};try{let{data:i,error:c}=await vn().auth.admin.getUserById(t);!c&&i?.user&&(s={banned:i.user.banned_until?new Date(i.user.banned_until)>new Date:!1,bannedUntil:i.user.banned_until??null,lastSignInAt:i.user.last_sign_in_at??null})}catch{}return e.json({user:{...n,...s},memberships:r,sessionCounts:o??{total:0,orphan:0}})});async function Wv(e){let[t]=await d.execute(En`
|
|
1068
1068
|
select count(*)::int as n from profiles
|
|
1069
1069
|
where is_superadmin = true and id <> ${e}
|
|
1070
|
-
`);return t?.n??0}u(
|
|
1070
|
+
`);return t?.n??0}u(Wv,"countOtherSuperadmins");sn.post("/superadmin/users/:id/force-logout",async e=>{let t=e.req.param("id");if(!pt.string().uuid().safeParse(t).success)return e.json({error:"Invalid user id",code:"VALIDATION_ERROR"},400);if(t===e.get("userId"))return e.json({error:"Cannot force-logout yourself",code:"SELF_ACTION_FORBIDDEN"},400);try{await d.execute(En`update auth.refresh_tokens set revoked = true where user_id = ${t}`),await d.execute(En`delete from auth.sessions where user_id = ${t}`)}catch(n){return e.json({error:n.message,code:"AUTH_ADMIN_ERROR"},400)}return e.json({ok:!0})});sn.post("/superadmin/users/:id/reset-password",async e=>{let t=e.req.param("id");if(!pt.string().uuid().safeParse(t).success)return e.json({error:"Invalid user id",code:"VALIDATION_ERROR"},400);let[n]=await d.select({email:R.email}).from(R).where(Lo(R.id,t));if(!n?.email)return e.json({error:"User not found",code:"USER_NOT_FOUND"},404);let{data:r,error:o}=await vn().auth.admin.generateLink({type:"recovery",email:n.email});return o?e.json({error:o.message,code:"AUTH_ADMIN_ERROR"},400):e.json({actionLink:r.properties?.action_link??null,email:n.email})});var iP=pt.object({suspended:pt.boolean()});sn.patch("/superadmin/users/:id/suspend",async e=>{let t=e.req.param("id");if(!pt.string().uuid().safeParse(t).success)return e.json({error:"Invalid user id",code:"VALIDATION_ERROR"},400);if(t===e.get("userId"))return e.json({error:"Cannot suspend yourself",code:"SELF_ACTION_FORBIDDEN"},400);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON",code:"VALIDATION_ERROR"},400)}let r=iP.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);if(r.data.suspended){let[c]=await d.select({isSuperadmin:R.isSuperadmin}).from(R).where(Lo(R.id,t));if(c?.isSuperadmin&&await Wv(t)===0)return e.json({error:"Cannot suspend the last superadmin",code:"LAST_SUPERADMIN"},409)}let o=r.data.suspended?"876000h":"none",{data:s,error:i}=await vn().auth.admin.updateUserById(t,{ban_duration:o});return i?e.json({error:i.message,code:"AUTH_ADMIN_ERROR"},400):e.json({ok:!0,suspended:r.data.suspended,bannedUntil:s.user?.banned_until??null})});var aP=pt.object({confirmEmail:pt.string().email()});sn.delete("/superadmin/users/:id",async e=>{let t=e.req.param("id");if(!pt.string().uuid().safeParse(t).success)return e.json({error:"Invalid user id",code:"VALIDATION_ERROR"},400);if(t===e.get("userId"))return e.json({error:"Cannot delete yourself",code:"SELF_ACTION_FORBIDDEN"},400);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON",code:"VALIDATION_ERROR"},400)}let r=aP.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let[o]=await d.select({email:R.email,isSuperadmin:R.isSuperadmin}).from(R).where(Lo(R.id,t));if(!o)return e.json({error:"User not found",code:"USER_NOT_FOUND"},404);if(o.email?.toLowerCase()!==r.data.confirmEmail.toLowerCase())return e.json({error:"confirmEmail does not match",code:"CONFIRMATION_MISMATCH"},400);if(o.isSuperadmin&&await Wv(t)===0)return e.json({error:"Cannot delete the last superadmin",code:"LAST_SUPERADMIN"},409);let{error:s}=await vn().auth.admin.deleteUser(t);return s?e.json({error:s.message,code:"AUTH_ADMIN_ERROR"},400):e.json({ok:!0})});var cP=pt.object({email:pt.string().email(),orgId:pt.string().uuid().optional(),role:pt.enum(["owner","admin","member"]).optional()});sn.post("/superadmin/users/invite",async e=>{let t;try{t=await e.req.json()}catch{return e.json({error:"Invalid JSON",code:"VALIDATION_ERROR"},400)}let n=cP.safeParse(t);if(!n.success)return e.json({error:n.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{email:r,orgId:o,role:s}=n.data;if(o&&!s)return e.json({error:"role is required when orgId is set",code:"VALIDATION_ERROR"},400);let i=vn(),c=process.env.WEB_URL??"http://localhost:5174",{data:a,error:l}=await i.auth.admin.inviteUserByEmail(r,{redirectTo:`${c}/auth/confirm`});if(l)return e.json({error:l.message,code:"AUTH_ADMIN_ERROR"},400);let p=a.user?.id,m=null;if(p&&o&&s){let y=e.get("supabase");if(y){let{error:v}=await y.rpc("superadmin_assign_user_to_org",{p_user_id:p,p_org_id:o,p_role:s,p_claim_sessions:!1});v||(m={orgId:o,role:s})}}return e.json({ok:!0,userId:p??null,email:r,assigned:m})});var uP=pt.object({orgId:pt.string().uuid(),role:pt.enum(["owner","admin","member"]),claimSessions:pt.boolean().default(!0)});sn.post("/superadmin/users/:id/assign",async e=>{let t=e.req.param("id");if(!pt.string().uuid().safeParse(t).success)return e.json({error:"Invalid user id",code:"VALIDATION_ERROR"},400);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON",code:"VALIDATION_ERROR"},400)}let r=uP.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let{orgId:o,role:s,claimSessions:i}=r.data,c=e.get("supabase");if(!c)return e.json({error:"Internal: no auth client",code:"INTERNAL"},500);let{data:a,error:l}=await c.rpc("superadmin_assign_user_to_org",{p_user_id:t,p_org_id:o,p_role:s,p_claim_sessions:i});if(l){let p=l.message.includes("not_authorized")?403:l.message.includes("org_not_found")||l.message.includes("user_not_found")?404:400;return e.json({error:l.message,code:"RPC_ERROR"},p)}return e.json(a)});sn.delete("/superadmin/users/:id/orgs/:orgId",async e=>{let t=e.req.param("id"),n=e.req.param("orgId");if(!pt.string().uuid().safeParse(t).success||!pt.string().uuid().safeParse(n).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let r=e.get("supabase");if(!r)return e.json({error:"Internal: no auth client",code:"INTERNAL"},500);let{error:o}=await r.rpc("superadmin_remove_member",{p_user_id:t,p_org_id:n});if(o){let s=o.message.includes("last_owner_violation")?409:o.message.includes("not_authorized")?403:400;return e.json({error:o.message,code:"RPC_ERROR"},s)}return e.json({ok:!0})});sn.get("/superadmin/orgs",async e=>{let t=await d.select({id:V.id,name:V.name,slug:V.slug,memberCount:En`(select count(*)::int from user_organizations where org_id = organizations.id)`,createdAt:V.createdAt}).from(V).orderBy(Hv(V.name));return e.json({orgs:t})});import{Hono as dP}from"hono";import{z as Kr}from"zod";var cd=new dP,zv=Kr.object({type:Kr.string().min(1).max(64),payload:Kr.record(Kr.unknown()).optional(),timestamp:Kr.string().datetime().optional()}),lP=Kr.union([zv,Kr.object({events:Kr.array(zv).max(50)})]);cd.post("/telemetry/extension-events",async e=>{let t=e.get("userId"),n=await e.req.json().catch(()=>null),r=lP.safeParse(n);if(!r.success)return e.json({error:"invalid payload",details:r.error.flatten()},400);let o="events"in r.data?r.data.events:[r.data];for(let s of o)console.log(`[ext-telemetry] user=${t} type=${s.type} payload=${JSON.stringify(s.payload??{})}`);return e.body(null,204)});import{Hono as pP}from"hono";import{z as Zn}from"zod";import{sql as mP}from"drizzle-orm";var Da=new pP,Vv=Zn.object({event:Zn.string().min(1).max(64),deviceId:Zn.string().min(1).max(128),cliVersion:Zn.string().max(64).optional(),os:Zn.string().max(32).optional(),props:Zn.record(Zn.unknown()).optional()}),fP=Zn.union([Vv,Zn.object({events:Zn.array(Vv).max(50)})]);Da.post("/telemetry/cli-events",async e=>{let t=e.get("userId"),n=fP.safeParse(await e.req.json().catch(()=>null));if(!n.success)return e.json({error:"invalid payload",details:n.error.flatten()},400);let r="events"in n.data?n.data.events:[n.data];return r.length===0||await d.insert(_c).values(r.map(o=>({userId:t,deviceId:o.deviceId,event:o.event,cliVersion:o.cliVersion??null,os:o.os??null,props:o.props??{}}))),e.body(null,204)});Da.get("/telemetry/deployments",async e=>{let t=e.get("userId"),n=await d.execute(mP`
|
|
1071
1071
|
select
|
|
1072
1072
|
device_id,
|
|
1073
1073
|
count(*)::int as event_count,
|
|
@@ -1084,7 +1084,7 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1084
1084
|
group by device_id
|
|
1085
1085
|
order by max(created_at) desc
|
|
1086
1086
|
limit 200
|
|
1087
|
-
`);return e.json({deployments:n})});import{Hono as fP}from"hono";import{z as En}from"zod";var ad=new fP,gP=En.object({event:En.string().min(1).max(64),deviceId:En.string().max(128).optional(),command:En.string().max(128).optional(),statusCode:En.number().int().optional(),message:En.string().max(1e3).optional(),cliVersion:En.string().max(64).optional(),os:En.string().max(32).optional(),nodeVersion:En.string().max(32).optional(),proxied:En.boolean().optional(),props:En.record(En.unknown()).optional()});ad.post("/telemetry/cli-error",async e=>{let t=gP.safeParse(await e.req.json().catch(()=>null));if(!t.success)return e.json({error:"invalid payload",details:t.error.flatten()},400);let n=t.data;console.warn(`[cli-error-beacon] event=${n.event} command=${n.command??""} status=${n.statusCode??""} proxied=${n.proxied??""} cli=${n.cliVersion??""} os=${n.os??""} node=${n.nodeVersion??""} device=${n.deviceId??""} msg=${JSON.stringify(n.message??"")}`);try{await d.insert(yc).values({deviceId:n.deviceId??null,event:n.event,command:n.command??null,statusCode:n.statusCode??null,message:n.message??null,cliVersion:n.cliVersion??null,os:n.os??null,nodeVersion:n.nodeVersion??null,proxied:n.proxied??null,props:n.props??{}})}catch{}return e.body(null,204)});import{Hono as Gv}from"hono";import{z as wr}from"zod";import{createHash as hP,randomBytes as Kv}from"node:crypto";import{and as zv,eq as Pm,gt as _P,isNull as yP,lt as wP}from"drizzle-orm";var vP={vscode:"VS Code extension","vscode-insiders":"VS Code Insiders extension",cursor:"Cursor extension",windsurf:"Windsurf extension"},Vv="VS Code extension";function IP(e){return e?vP[e]??Vv:Vv}u(IP,"editorKeyName");var Jv=6e4;async function bP(){try{await d.delete(gn).where(wP(gn.expiresAt,new Date))}catch{}}u(bP,"sweepExpiredCodes");setInterval(()=>void bP(),5*6e4).unref?.();var Ma=new Gv,SP=wr.object({code:wr.string().min(1).max(256)}),AP=wr.object({refreshToken:wr.string().min(1).max(2048)});Ma.post("/auth/extension/refresh",async e=>{let t=await e.req.json().catch(()=>null),n=AP.safeParse(t);if(!n.success)return e.json({error:"invalid request"},400);let r=await Uc(n.data.refreshToken);return r.ok?e.json(r.session):e.json({error:r.error},r.status)});Ma.post("/auth/extension/exchange",async e=>{let t=await e.req.json().catch(()=>null),n=SP.safeParse(t);if(!n.success)return e.json({error:"invalid request"},400);let[r]=await d.delete(gn).where(zv(Pm(gn.code,n.data.code),_P(gn.expiresAt,new Date))).returning({userId:gn.userId,editor:gn.editor,email:gn.email});if(!r)return e.json({error:"code not found or expired"},404);let o=IP(r.editor),{plaintext:s,hash:i,prefix:c}=EP();try{await d.transaction(async a=>{await a.update(ye).set({revokedAt:new Date}).where(zv(Pm(ye.userId,r.userId),Pm(ye.name,o),yP(ye.revokedAt))),await a.insert(ye).values({userId:r.userId,name:o,keyHash:i,keyPrefix:c})})}catch(a){return console.log(`[auth] extension/exchange mint failed userId=${r.userId} err=${a.message}`),e.json({error:"could not mint session"},500)}return e.json({accessToken:s,expiresAt:null,email:r.email})});var cd=new Gv,xP=wr.object({refreshToken:wr.string().min(1).nullish(),expiresAt:wr.string().nullish(),email:wr.string().email().nullish(),editor:wr.enum(["vscode","vscode-insiders","cursor","windsurf"]).nullish()});function EP(){let e=`rm_${Kv(32).toString("base64url")}`;return{plaintext:e,hash:hP("sha256").update(e).digest("hex"),prefix:e.slice(0,11)}}u(EP,"generateApiKey");cd.post("/auth/extension/code",async e=>{let t=e.get("userId");if(!t)return e.json({error:"unauthenticated"},401);let n=await e.req.json().catch(()=>null),r=xP.safeParse(n);if(!r.success)return e.json({error:"invalid request"},400);let o=Kv(32).toString("base64url");try{await d.insert(gn).values({code:o,userId:t,editor:r.data.editor??null,email:r.data.email??null,expiresAt:new Date(Date.now()+Jv)})}catch(s){return console.log(`[auth] extension/code intent insert failed userId=${t} err=${s.message}`),e.json({error:"could not start sign-in"},500)}return e.json({code:o,expiresInSeconds:Math.floor(Jv/1e3),sessionStrategy:"api_key"})});na();import{Hono as TP}from"hono";var ud=new TP;function RP(e,t){let n=e.record??{};return e.schema==="auth"&&e.table==="users"&&e.type==="INSERT"?{title:"\u{1F389} New signup",color:2278750,fields:[{name:"Email",value:n.email??t??"unknown",inline:!0},{name:"User ID",value:String(n.id??"unknown"),inline:!0}],timestamp:new Date().toISOString()}:e.schema==="auth"&&e.table==="sessions"&&e.type==="INSERT"?{title:"\u{1F44B} Login",color:3900150,fields:[{name:"Email",value:t??"unknown",inline:!0},{name:"User ID",value:String(n.user_id??"unknown"),inline:!0}],timestamp:new Date().toISOString()}:null}u(RP,"formatEmbed");async function kP(e){if(!e)return null;try{let t=wn(),{data:n}=await t.auth.admin.getUserById(e);return n.user?.email??null}catch{return null}}u(kP,"lookupEmail");async function jP(e,t){let n=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({embeds:[t]})});n.ok||console.error("[webhooks] Discord post failed",n.status,await n.text().catch(()=>""))}u(jP,"postToDiscord");ud.post("/webhooks/supabase-auth",async e=>{let t=process.env.SUPABASE_WEBHOOK_SECRET,n=process.env.DISCORD_WEBHOOK_URL;if(!t||!n)return e.json({error:"webhook not configured"},503);if(e.req.header("x-webhook-secret")!==t)return e.json({error:"unauthorized"},401);let o;try{o=await e.req.json()}catch{return e.json({error:"invalid json"},400)}let i=o.schema==="auth"&&o.table==="sessions"&&o.type==="INSERT"?await kP(o.record?.user_id):null,c=RP(o,i);return c?(await jP(n,c),e.json({ok:!0})):e.json({ok:!0,skipped:!0})});import{Hono as HP}from"hono";import{z as Le}from"zod";import{and as qa,desc as md,eq as er,gte as Gm,isNull as WP,sql as zP}from"drizzle-orm";var Dm="anthropic",NP=[{limitType:"five_hour_percent",unit:"percentage",displayName:"5-hour window"}],Om=[{limitType:"five_hour_percent",unit:"percentage",displayName:"5-hour window"},{limitType:"seven_day_percent",unit:"percentage",displayName:"Weekly window"}];function CP(e){return typeof e=="object"&&e!==null}u(CP,"isOAuthUsageResponse");function Yv(e,t,n,r,o,s){if(!e||typeof e.used_percentage!="number")return null;let i=typeof e.resets_at=="number"?new Date(e.resets_at*1e3):null;return{provider:Dm,plan:n,limitType:t,value:e.used_percentage,unit:"percentage",comparator:"=",resetsAt:i,sourceType:"oauth_usage",sourceUrl:r,sourceEvidence:o,confidence:1,observedAt:s}}u(Yv,"parseWindow");function PP(e,t){let n=e.match(/reset(?:s|\s+at)?\s+(?:at\s+)?(\d{1,2}):(\d{2})\s*(am|pm)?\s*(?:\(([^)]+)\))?/i);if(!n)return null;let r=parseInt(n[1],10),o=parseInt(n[2],10),s=n[3]?.toLowerCase();if(s==="pm"&&r<12&&(r+=12),s==="am"&&r===12&&(r=0),isNaN(r)||isNaN(o)||r>23||o>59)return null;let i=new Date(t);return i.setHours(r,o,0,0),i.getTime()<=t.getTime()&&i.setDate(i.getDate()+1),i}u(PP,"parseResetTime");var Mm={id:Dm,displayName:"Anthropic (Claude Code)",plans:["unknown","pro","max_5x","max_20x"],limits:{unknown:Om,pro:NP,max_5x:Om,max_20x:Om},docs:[{url:"https://docs.claude.com/en/docs/claude-code/setup#usage-limits",parse(e){let t=[],n=e.replace(/<script[\s\S]*?<\/script>/gi," ").replace(/<style[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim(),r=n.match(/(\d{1,4})\s+messages?\s+(?:every|per)\s+5[-\s]?hours?/i);r&&t.push({plan:"unknown",limitType:"five_hour_messages",value:parseInt(r[1],10),unit:"messages",comparator:"="});let o=n.match(/(\d{1,5})\s+messages?\s+(?:per|every)\s+(?:week|7[-\s]?days?)/i);return o&&t.push({plan:"unknown",limitType:"seven_day_messages",value:parseInt(o[1],10),unit:"messages",comparator:"="}),t}}],liveSource:{matches(e,t){return e==="api.anthropic.com"&&t==="/api/oauth/usage"},parse(e,t){if(!CP(e))return null;let n=e.rate_limits;if(!n||typeof n!="object")return[];let r=t.observedAt??new Date,o=t.plan??"unknown",s=`https://${t.host}${t.path}`,i={rawResponse:e},c=[],a=Yv(n.five_hour,"five_hour_percent",o,s,i,r);a&&c.push(a);let l=Yv(n.seven_day,"seven_day_percent",o,s,i,r);return l&&c.push(l),c}},observe429(e){if(e.statusCode!==429||e.host!=="api.anthropic.com")return null;let t="",n=e.responseBody;if(typeof n=="string")t=n;else if(n&&typeof n=="object"){let o=n,s=o.error;if(s&&typeof s.message=="string")t=s.message;else if(typeof o.message=="string")t=o.message;else try{t=JSON.stringify(n)}catch{return null}}if(!t)return null;let r=PP(t,e.observedAt);return[{provider:Dm,plan:e.plan??"unknown",limitType:"five_hour_percent",value:100,unit:"percentage",comparator:">=",resetsAt:r,sourceType:"self_observed_429",sourceUrl:`https://${e.host}${e.path}`,sourceEvidence:{responseBody:n,parsedText:t},confidence:.9,userId:e.userId??null,observedAt:e.observedAt}]}};var Lm="codex",$m="chatgpt.com",Xv="/backend-api/codex/responses",OP="codex.rate_limits",Qv=["primary","secondary"];function DP(e,t){return t!=null?t>=1440?"seven_day_percent":"five_hour_percent":e==="secondary"?"seven_day_percent":"five_hour_percent"}u(DP,"limitTypeForWindow");var Hs=[{limitType:"five_hour_percent",unit:"percentage",displayName:"5-hour usage"},{limitType:"seven_day_percent",unit:"percentage",displayName:"7-day usage"}],qm={id:Lm,displayName:"Codex CLI (OpenAI)",plans:["unknown","free","plus","pro","team","enterprise"],limits:{unknown:Hs,free:Hs,plus:Hs,pro:Hs,team:Hs,enterprise:Hs},docs:[{url:"https://platform.openai.com/docs/guides/rate-limits",parse(e){return[]}}],liveSource:{matches(e,t){return!1},parse(e,t){return null},streamFrame:{matches(e,t){return e===$m&&t.startsWith(Xv)},parse(e,t){let n;try{n=JSON.parse(e)}catch{return null}if(typeof n!="object"||n===null||n.type!==OP)return null;let r=n.rate_limits;if(typeof r!="object"||r===null)return null;let o=t.observedAt??new Date,s=t.plan??"unknown",i=[];for(let c of Qv){let a=r[c];if(typeof a!="object"||a===null)continue;let l=a,p=l.used_percent??l.used_percentage;if(typeof p!="number"||!isFinite(p))continue;let m=p,_=l.window_minutes,v=typeof _=="number"&&isFinite(_)?_:null,g=DP(c,v),h=null,w=l.reset_at??l.resets_at;if(typeof w=="string"){let I=new Date(w);isNaN(I.getTime())||(h=I)}else typeof w=="number"&&isFinite(w)&&(h=new Date(w*1e3));i.push({provider:Lm,plan:s,limitType:g,value:m,unit:"percentage",comparator:"=",resetsAt:h,sourceType:"live_stream",sourceUrl:`wss://${$m}${Xv}`,sourceEvidence:{wireKey:c,frame:n},confidence:1,observedAt:o})}return i.length===0&&Qv.some(a=>{let l=r[a];return typeof l=="object"&&l!==null})&&console.warn(`[codex] rate_limits windows present but none parsed \u2014 field drift? sample=${JSON.stringify(r).slice(0,300)}`),i.length>0?i:null}}},observe429(e){return e.statusCode!==429||e.host!==$m?null:[{provider:Lm,plan:e.plan??"unknown",limitType:"five_hour_percent",value:100,unit:"percentage",comparator:">=",resetsAt:null,sourceType:"self_observed_429",sourceUrl:`https://${e.host}${e.path}`,sourceEvidence:{responseBody:e.responseBody},confidence:.9,userId:e.userId??null,observedAt:e.observedAt}]}};var La={anthropic:Mm,codex:qm};function Um(e){for(let t of Object.values(La))if(t.liveSource?.headers?.matchesHost(e))return t}u(Um,"matchLiveHeaders");function Bm(e,t){for(let n of Object.values(La))if(n.liveSource?.streamFrame?.matches(e,t))return n}u(Bm,"matchStreamFrame");var C9=1440*60*1e3;import{and as eI,desc as tI,eq as $a,gte as qP,sql as UP}from"drizzle-orm";function Fm(e){let{used_percentage:t,burnRateEtaSeconds:n,secondsUntilReset:r,hadObserved429:o}=e;return t>=100||o?"hit":t>=95||t>=80&&n!==null&&n<900?"imminent":t>=80&&n!==null&&n<r?"approaching":t>=80?"soft":"none"}u(Fm,"classifySeverity");function Ws(e){switch(e){case"none":return 0;case"soft":return 1;case"approaching":return 2;case"imminent":return 3;case"hit":return 4}}u(Ws,"severityRank");var dd={soft:"soft warning",approaching:"approaching limit",imminent:"imminent limit",hit:"limit reached"};function MP(e,t){if(!e)return"soon";let n=new Date(e).getTime()-t;if(n<=0)return"now";let r=Math.round(n/6e4);if(r<60)return`in ${r} min`;let o=Math.floor(r/60),s=r%60;return s>0?`in ${o}h ${s}m`:`in ${o}h`}u(MP,"formatTimeLeft");function Hm(e,t,n,r,o=Date.now()){let s=MP(r,o);if(e==="hit")return`Claude ${t} reached 100% \u2014 requests will fail. Resets ${s}.`;let i=n!=null?`${n.toFixed(0)}%`:"limit";return`Claude ${t} at ${i} \u2014 ${dd[e]}. Resets ${s}.`}u(Hm,"formatAlertMessage");function Wm(e,t=new Date){if(e.length<2)return null;let n=300*1e3,r=t.getTime()-n,o=e.filter(b=>b.observedAt.getTime()>=r).sort((b,S)=>b.observedAt.getTime()-S.observedAt.getTime());if(o.length<2)return null;let s=o[o.length-1];if(s.value>=100)return null;let i=o[0].observedAt.getTime(),c=o.map(b=>(b.observedAt.getTime()-i)/1e3),a=o.map(b=>b.value),l=c.length,p=c.reduce((b,S)=>b+S,0),m=a.reduce((b,S)=>b+S,0),_=c.reduce((b,S,A)=>b+S*a[A],0),v=c.reduce((b,S)=>b+S*S,0),g=l*v-p*p;if(g===0)return null;let h=(l*_-p*m)/g;return h<=0?null:(100-s.value)/h}u(Wm,"projectExhaustion");var LP=300*1e3,$P=70;function zm(e){let{proposedSeverity:t,lastDispatch:n,currentUsedPercentage:r,now:o,isFirstTime429:s}=e;if(s)return!0;if(!n)return Ws(t)>0;let i=Ws(t),c=Ws(n.severity);return i>c?!0:o.getTime()-n.lastDispatchedAt.getTime()>=LP?c>=Ws("approaching")&&i===c?!(r>=$P):i>0:!1}u(zm,"shouldDispatch");function Vm(e){let t=Wm(e.observations,e.now),n=Math.max(0,Math.floor((e.currentResetsAt.getTime()-e.now.getTime())/1e3)),r=Fm({used_percentage:e.currentUsedPercentage,burnRateEtaSeconds:t,secondsUntilReset:n,hadObserved429:e.hadObserved429}),o={alertKey:e.alertKey,severity:r,usedPercentage:e.currentUsedPercentage,resetsAt:e.currentResetsAt.toISOString(),burnRateEtaSeconds:t};if(r==="none")return{shouldDispatch:!1,severity:"none",reason:"below threshold",payload:o};let s=e.hadObserved429&&(e.lastDispatch===null||e.lastDispatch.severity!=="hit"),i=zm({proposedSeverity:r,lastDispatch:e.lastDispatch,currentResetsAt:e.currentResetsAt,currentUsedPercentage:e.currentUsedPercentage,now:e.now,isFirstTime429:s});return{shouldDispatch:i,severity:r,reason:i?"dispatch":"suppressed by cooldown/hysteresis",payload:o}}u(Vm,"evaluate");function Zv(e,t,n){return`${e}:${t}:${n}`}u(Zv,"deriveAlertKey");async function zs(e){await en({userId:e.userId,type:`usage_${e.severity}`,title:e.title??`Usage limit \u2014 ${dd[e.severity]}`,body:e.message,url:"/usage",sourceTable:"alert_dispatches",sourceId:e.dispatchId})}u(zs,"notifyFromDispatch");var BP=30*6e4;async function ld(e,t){let n=new Date((t.observedAt??new Date).getTime()-BP);try{let o=await d.execute(UP`
|
|
1087
|
+
`);return e.json({deployments:n})});import{Hono as gP}from"hono";import{z as Tn}from"zod";var ud=new gP,hP=Tn.object({event:Tn.string().min(1).max(64),deviceId:Tn.string().max(128).optional(),command:Tn.string().max(128).optional(),statusCode:Tn.number().int().optional(),message:Tn.string().max(1e3).optional(),cliVersion:Tn.string().max(64).optional(),os:Tn.string().max(32).optional(),nodeVersion:Tn.string().max(32).optional(),proxied:Tn.boolean().optional(),props:Tn.record(Tn.unknown()).optional()});ud.post("/telemetry/cli-error",async e=>{let t=hP.safeParse(await e.req.json().catch(()=>null));if(!t.success)return e.json({error:"invalid payload",details:t.error.flatten()},400);let n=t.data;console.warn(`[cli-error-beacon] event=${n.event} command=${n.command??""} status=${n.statusCode??""} proxied=${n.proxied??""} cli=${n.cliVersion??""} os=${n.os??""} node=${n.nodeVersion??""} device=${n.deviceId??""} msg=${JSON.stringify(n.message??"")}`);try{await d.insert(yc).values({deviceId:n.deviceId??null,event:n.event,command:n.command??null,statusCode:n.statusCode??null,message:n.message??null,cliVersion:n.cliVersion??null,os:n.os??null,nodeVersion:n.nodeVersion??null,proxied:n.proxied??null,props:n.props??{}})}catch{}return e.body(null,204)});import{Hono as Yv}from"hono";import{z as Ir}from"zod";import{createHash as _P,randomBytes as Xv}from"node:crypto";import{and as Jv,eq as Dm,gt as yP,isNull as wP,lt as vP}from"drizzle-orm";var IP={vscode:"VS Code extension","vscode-insiders":"VS Code Insiders extension",cursor:"Cursor extension",windsurf:"Windsurf extension"},Gv="VS Code extension";function bP(e){return e?IP[e]??Gv:Gv}u(bP,"editorKeyName");var Kv=6e4;async function SP(){try{await d.delete(_n).where(vP(_n.expiresAt,new Date))}catch{}}u(SP,"sweepExpiredCodes");setInterval(()=>void SP(),5*6e4).unref?.();var Ma=new Yv,AP=Ir.object({code:Ir.string().min(1).max(256)}),xP=Ir.object({refreshToken:Ir.string().min(1).max(2048)});Ma.post("/auth/extension/refresh",async e=>{let t=await e.req.json().catch(()=>null),n=xP.safeParse(t);if(!n.success)return e.json({error:"invalid request"},400);let r=await Bc(n.data.refreshToken);return r.ok?e.json(r.session):e.json({error:r.error},r.status)});Ma.post("/auth/extension/exchange",async e=>{let t=await e.req.json().catch(()=>null),n=AP.safeParse(t);if(!n.success)return e.json({error:"invalid request"},400);let[r]=await d.delete(_n).where(Jv(Dm(_n.code,n.data.code),yP(_n.expiresAt,new Date))).returning({userId:_n.userId,editor:_n.editor,email:_n.email});if(!r)return e.json({error:"code not found or expired"},404);let o=bP(r.editor),{plaintext:s,hash:i,prefix:c}=TP();try{await d.transaction(async a=>{await a.update(we).set({revokedAt:new Date}).where(Jv(Dm(we.userId,r.userId),Dm(we.name,o),wP(we.revokedAt))),await a.insert(we).values({userId:r.userId,name:o,keyHash:i,keyPrefix:c})})}catch(a){return console.log(`[auth] extension/exchange mint failed userId=${r.userId} err=${a.message}`),e.json({error:"could not mint session"},500)}return e.json({accessToken:s,expiresAt:null,email:r.email})});var dd=new Yv,EP=Ir.object({refreshToken:Ir.string().min(1).nullish(),expiresAt:Ir.string().nullish(),email:Ir.string().email().nullish(),editor:Ir.enum(["vscode","vscode-insiders","cursor","windsurf"]).nullish()});function TP(){let e=`rm_${Xv(32).toString("base64url")}`;return{plaintext:e,hash:_P("sha256").update(e).digest("hex"),prefix:e.slice(0,11)}}u(TP,"generateApiKey");dd.post("/auth/extension/code",async e=>{let t=e.get("userId");if(!t)return e.json({error:"unauthenticated"},401);let n=await e.req.json().catch(()=>null),r=EP.safeParse(n);if(!r.success)return e.json({error:"invalid request"},400);let o=Xv(32).toString("base64url");try{await d.insert(_n).values({code:o,userId:t,editor:r.data.editor??null,email:r.data.email??null,expiresAt:new Date(Date.now()+Kv)})}catch(s){return console.log(`[auth] extension/code intent insert failed userId=${t} err=${s.message}`),e.json({error:"could not start sign-in"},500)}return e.json({code:o,expiresInSeconds:Math.floor(Kv/1e3),sessionStrategy:"api_key"})});na();import{Hono as RP}from"hono";var ld=new RP;function kP(e,t){let n=e.record??{};return e.schema==="auth"&&e.table==="users"&&e.type==="INSERT"?{title:"\u{1F389} New signup",color:2278750,fields:[{name:"Email",value:n.email??t??"unknown",inline:!0},{name:"User ID",value:String(n.id??"unknown"),inline:!0}],timestamp:new Date().toISOString()}:e.schema==="auth"&&e.table==="sessions"&&e.type==="INSERT"?{title:"\u{1F44B} Login",color:3900150,fields:[{name:"Email",value:t??"unknown",inline:!0},{name:"User ID",value:String(n.user_id??"unknown"),inline:!0}],timestamp:new Date().toISOString()}:null}u(kP,"formatEmbed");async function jP(e){if(!e)return null;try{let t=vn(),{data:n}=await t.auth.admin.getUserById(e);return n.user?.email??null}catch{return null}}u(jP,"lookupEmail");async function NP(e,t){let n=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({embeds:[t]})});n.ok||console.error("[webhooks] Discord post failed",n.status,await n.text().catch(()=>""))}u(NP,"postToDiscord");ld.post("/webhooks/supabase-auth",async e=>{let t=process.env.SUPABASE_WEBHOOK_SECRET,n=process.env.DISCORD_WEBHOOK_URL;if(!t||!n)return e.json({error:"webhook not configured"},503);if(e.req.header("x-webhook-secret")!==t)return e.json({error:"unauthorized"},401);let o;try{o=await e.req.json()}catch{return e.json({error:"invalid json"},400)}let i=o.schema==="auth"&&o.table==="sessions"&&o.type==="INSERT"?await jP(o.record?.user_id):null,c=kP(o,i);return c?(await NP(n,c),e.json({ok:!0})):e.json({ok:!0,skipped:!0})});import{Hono as WP}from"hono";import{z as $e}from"zod";import{and as qa,desc as gd,eq as er,gte as Ym,isNull as zP,sql as VP}from"drizzle-orm";var Lm="anthropic",CP=[{limitType:"five_hour_percent",unit:"percentage",displayName:"5-hour window"}],Mm=[{limitType:"five_hour_percent",unit:"percentage",displayName:"5-hour window"},{limitType:"seven_day_percent",unit:"percentage",displayName:"Weekly window"}];function PP(e){return typeof e=="object"&&e!==null}u(PP,"isOAuthUsageResponse");function Qv(e,t,n,r,o,s){if(!e||typeof e.used_percentage!="number")return null;let i=typeof e.resets_at=="number"?new Date(e.resets_at*1e3):null;return{provider:Lm,plan:n,limitType:t,value:e.used_percentage,unit:"percentage",comparator:"=",resetsAt:i,sourceType:"oauth_usage",sourceUrl:r,sourceEvidence:o,confidence:1,observedAt:s}}u(Qv,"parseWindow");function OP(e,t){let n=e.match(/reset(?:s|\s+at)?\s+(?:at\s+)?(\d{1,2}):(\d{2})\s*(am|pm)?\s*(?:\(([^)]+)\))?/i);if(!n)return null;let r=parseInt(n[1],10),o=parseInt(n[2],10),s=n[3]?.toLowerCase();if(s==="pm"&&r<12&&(r+=12),s==="am"&&r===12&&(r=0),isNaN(r)||isNaN(o)||r>23||o>59)return null;let i=new Date(t);return i.setHours(r,o,0,0),i.getTime()<=t.getTime()&&i.setDate(i.getDate()+1),i}u(OP,"parseResetTime");var $m={id:Lm,displayName:"Anthropic (Claude Code)",plans:["unknown","pro","max_5x","max_20x"],limits:{unknown:Mm,pro:CP,max_5x:Mm,max_20x:Mm},docs:[{url:"https://docs.claude.com/en/docs/claude-code/setup#usage-limits",parse(e){let t=[],n=e.replace(/<script[\s\S]*?<\/script>/gi," ").replace(/<style[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim(),r=n.match(/(\d{1,4})\s+messages?\s+(?:every|per)\s+5[-\s]?hours?/i);r&&t.push({plan:"unknown",limitType:"five_hour_messages",value:parseInt(r[1],10),unit:"messages",comparator:"="});let o=n.match(/(\d{1,5})\s+messages?\s+(?:per|every)\s+(?:week|7[-\s]?days?)/i);return o&&t.push({plan:"unknown",limitType:"seven_day_messages",value:parseInt(o[1],10),unit:"messages",comparator:"="}),t}}],liveSource:{matches(e,t){return e==="api.anthropic.com"&&t==="/api/oauth/usage"},parse(e,t){if(!PP(e))return null;let n=e.rate_limits;if(!n||typeof n!="object")return[];let r=t.observedAt??new Date,o=t.plan??"unknown",s=`https://${t.host}${t.path}`,i={rawResponse:e},c=[],a=Qv(n.five_hour,"five_hour_percent",o,s,i,r);a&&c.push(a);let l=Qv(n.seven_day,"seven_day_percent",o,s,i,r);return l&&c.push(l),c}},observe429(e){if(e.statusCode!==429||e.host!=="api.anthropic.com")return null;let t="",n=e.responseBody;if(typeof n=="string")t=n;else if(n&&typeof n=="object"){let o=n,s=o.error;if(s&&typeof s.message=="string")t=s.message;else if(typeof o.message=="string")t=o.message;else try{t=JSON.stringify(n)}catch{return null}}if(!t)return null;let r=OP(t,e.observedAt);return[{provider:Lm,plan:e.plan??"unknown",limitType:"five_hour_percent",value:100,unit:"percentage",comparator:">=",resetsAt:r,sourceType:"self_observed_429",sourceUrl:`https://${e.host}${e.path}`,sourceEvidence:{responseBody:n,parsedText:t},confidence:.9,userId:e.userId??null,observedAt:e.observedAt}]}};var qm="codex",Um="chatgpt.com",Zv="/backend-api/codex/responses",DP="codex.rate_limits",eI=["primary","secondary"];function MP(e,t){return t!=null?t>=1440?"seven_day_percent":"five_hour_percent":e==="secondary"?"seven_day_percent":"five_hour_percent"}u(MP,"limitTypeForWindow");var Ws=[{limitType:"five_hour_percent",unit:"percentage",displayName:"5-hour usage"},{limitType:"seven_day_percent",unit:"percentage",displayName:"7-day usage"}],Bm={id:qm,displayName:"Codex CLI (OpenAI)",plans:["unknown","free","plus","pro","team","enterprise"],limits:{unknown:Ws,free:Ws,plus:Ws,pro:Ws,team:Ws,enterprise:Ws},docs:[{url:"https://platform.openai.com/docs/guides/rate-limits",parse(e){return[]}}],liveSource:{matches(e,t){return!1},parse(e,t){return null},streamFrame:{matches(e,t){return e===Um&&t.startsWith(Zv)},parse(e,t){let n;try{n=JSON.parse(e)}catch{return null}if(typeof n!="object"||n===null||n.type!==DP)return null;let r=n.rate_limits;if(typeof r!="object"||r===null)return null;let o=t.observedAt??new Date,s=t.plan??"unknown",i=[];for(let c of eI){let a=r[c];if(typeof a!="object"||a===null)continue;let l=a,p=l.used_percent??l.used_percentage;if(typeof p!="number"||!isFinite(p))continue;let m=p,y=l.window_minutes,v=typeof y=="number"&&isFinite(y)?y:null,g=MP(c,v),h=null,w=l.reset_at??l.resets_at;if(typeof w=="string"){let b=new Date(w);isNaN(b.getTime())||(h=b)}else typeof w=="number"&&isFinite(w)&&(h=new Date(w*1e3));i.push({provider:qm,plan:s,limitType:g,value:m,unit:"percentage",comparator:"=",resetsAt:h,sourceType:"live_stream",sourceUrl:`wss://${Um}${Zv}`,sourceEvidence:{wireKey:c,frame:n},confidence:1,observedAt:o})}return i.length===0&&eI.some(a=>{let l=r[a];return typeof l=="object"&&l!==null})&&console.warn(`[codex] rate_limits windows present but none parsed \u2014 field drift? sample=${JSON.stringify(r).slice(0,300)}`),i.length>0?i:null}}},observe429(e){return e.statusCode!==429||e.host!==Um?null:[{provider:qm,plan:e.plan??"unknown",limitType:"five_hour_percent",value:100,unit:"percentage",comparator:">=",resetsAt:null,sourceType:"self_observed_429",sourceUrl:`https://${e.host}${e.path}`,sourceEvidence:{responseBody:e.responseBody},confidence:.9,userId:e.userId??null,observedAt:e.observedAt}]}};var La={anthropic:$m,codex:Bm};function Fm(e){for(let t of Object.values(La))if(t.liveSource?.headers?.matchesHost(e))return t}u(Fm,"matchLiveHeaders");function Hm(e,t){for(let n of Object.values(La))if(n.liveSource?.streamFrame?.matches(e,t))return n}u(Hm,"matchStreamFrame");var D9=1440*60*1e3;import{and as nI,desc as rI,eq as $a,gte as UP,sql as BP}from"drizzle-orm";function Wm(e){let{used_percentage:t,burnRateEtaSeconds:n,secondsUntilReset:r,hadObserved429:o}=e;return t>=100||o?"hit":t>=95||t>=80&&n!==null&&n<900?"imminent":t>=80&&n!==null&&n<r?"approaching":t>=80?"soft":"none"}u(Wm,"classifySeverity");function zs(e){switch(e){case"none":return 0;case"soft":return 1;case"approaching":return 2;case"imminent":return 3;case"hit":return 4}}u(zs,"severityRank");var pd={soft:"soft warning",approaching:"approaching limit",imminent:"imminent limit",hit:"limit reached"};function LP(e,t){if(!e)return"soon";let n=new Date(e).getTime()-t;if(n<=0)return"now";let r=Math.round(n/6e4);if(r<60)return`in ${r} min`;let o=Math.floor(r/60),s=r%60;return s>0?`in ${o}h ${s}m`:`in ${o}h`}u(LP,"formatTimeLeft");function zm(e,t,n,r,o=Date.now()){let s=LP(r,o);if(e==="hit")return`Claude ${t} reached 100% \u2014 requests will fail. Resets ${s}.`;let i=n!=null?`${n.toFixed(0)}%`:"limit";return`Claude ${t} at ${i} \u2014 ${pd[e]}. Resets ${s}.`}u(zm,"formatAlertMessage");function Vm(e,t=new Date){if(e.length<2)return null;let n=300*1e3,r=t.getTime()-n,o=e.filter(I=>I.observedAt.getTime()>=r).sort((I,S)=>I.observedAt.getTime()-S.observedAt.getTime());if(o.length<2)return null;let s=o[o.length-1];if(s.value>=100)return null;let i=o[0].observedAt.getTime(),c=o.map(I=>(I.observedAt.getTime()-i)/1e3),a=o.map(I=>I.value),l=c.length,p=c.reduce((I,S)=>I+S,0),m=a.reduce((I,S)=>I+S,0),y=c.reduce((I,S,A)=>I+S*a[A],0),v=c.reduce((I,S)=>I+S*S,0),g=l*v-p*p;if(g===0)return null;let h=(l*y-p*m)/g;return h<=0?null:(100-s.value)/h}u(Vm,"projectExhaustion");var $P=300*1e3,qP=70;function Jm(e){let{proposedSeverity:t,lastDispatch:n,currentUsedPercentage:r,now:o,isFirstTime429:s}=e;if(s)return!0;if(!n)return zs(t)>0;let i=zs(t),c=zs(n.severity);return i>c?!0:o.getTime()-n.lastDispatchedAt.getTime()>=$P?c>=zs("approaching")&&i===c?!(r>=qP):i>0:!1}u(Jm,"shouldDispatch");function Gm(e){let t=Vm(e.observations,e.now),n=Math.max(0,Math.floor((e.currentResetsAt.getTime()-e.now.getTime())/1e3)),r=Wm({used_percentage:e.currentUsedPercentage,burnRateEtaSeconds:t,secondsUntilReset:n,hadObserved429:e.hadObserved429}),o={alertKey:e.alertKey,severity:r,usedPercentage:e.currentUsedPercentage,resetsAt:e.currentResetsAt.toISOString(),burnRateEtaSeconds:t};if(r==="none")return{shouldDispatch:!1,severity:"none",reason:"below threshold",payload:o};let s=e.hadObserved429&&(e.lastDispatch===null||e.lastDispatch.severity!=="hit"),i=Jm({proposedSeverity:r,lastDispatch:e.lastDispatch,currentResetsAt:e.currentResetsAt,currentUsedPercentage:e.currentUsedPercentage,now:e.now,isFirstTime429:s});return{shouldDispatch:i,severity:r,reason:i?"dispatch":"suppressed by cooldown/hysteresis",payload:o}}u(Gm,"evaluate");function tI(e,t,n){return`${e}:${t}:${n}`}u(tI,"deriveAlertKey");async function Vs(e){await tn({userId:e.userId,type:`usage_${e.severity}`,title:e.title??`Usage limit \u2014 ${pd[e.severity]}`,body:e.message,url:"/usage",sourceTable:"alert_dispatches",sourceId:e.dispatchId})}u(Vs,"notifyFromDispatch");var FP=30*6e4;async function md(e,t){let n=new Date((t.observedAt??new Date).getTime()-FP);try{let o=await d.execute(BP`
|
|
1088
1088
|
SELECT id, observed_at
|
|
1089
1089
|
FROM limit_observations
|
|
1090
1090
|
WHERE user_id = ${e}
|
|
@@ -1097,40 +1097,40 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1097
1097
|
AND observed_at >= ${n.toISOString()}::timestamptz
|
|
1098
1098
|
ORDER BY observed_at DESC
|
|
1099
1099
|
LIMIT 1
|
|
1100
|
-
`);if(o.length>0){let s=o[0];return{id:s.id,observedAt:new Date(s.observed_at).toISOString(),deduped:!0}}}catch(o){console.warn("[observe] dedup probe failed; proceeding to insert",o)}let[r]=await d.insert(pe).values({provider:t.provider,plan:t.plan,limitType:t.limitType,value:String(t.value),unit:t.unit,comparator:t.comparator,resetsAt:t.resetsAt??null,sourceType:t.sourceType,sourceUrl:t.sourceUrl??null,sourceEvidence:t.sourceEvidence??null,confidence:String(t.confidence),userId:e,...t.observedAt?{observedAt:t.observedAt}:{}}).returning({id:pe.id,observedAt:pe.observedAt});if(t.sourceType==="oauth_usage"||t.sourceType==="self_observed_429")try{let o=Zv(t.provider,t.plan,t.limitType),s=new Date,i=new Date(s.getTime()-600*1e3),c=await d.select({observedAt:pe.observedAt,value:pe.value}).from(pe).where(eI($a(pe.userId,e),$a(pe.provider,t.provider),$a(pe.limitType,t.limitType),qP(pe.observedAt,i))).orderBy(tI(pe.observedAt)).limit(50),a=await d.select().from(un).where(eI($a(un.userId,e),$a(un.alertKey,o))).orderBy(tI(un.lastDispatchedAt)).limit(1),l=Vm({alertKey:o,observations:c.map(p=>({observedAt:p.observedAt,value:Number(p.value)})),currentUsedPercentage:t.value,currentResetsAt:t.resetsAt??new Date(s.getTime()+300*60*1e3),hadObserved429:t.sourceType==="self_observed_429",lastDispatch:a[0]?{severity:a[0].severity,lastDispatchedAt:a[0].lastDispatchedAt,lastState:a[0].lastState}:null,now:s});if(l.shouldDispatch&&l.severity!=="none"){let p=l.severity,[m]=await d.insert(un).values({userId:e,alertKey:o,severity:p,lastState:l.payload,channel:"banner"}).returning({id:un.id});m&&await zs({userId:e,dispatchId:m.id,severity:p,message:Hm(p,t.limitType,l.payload.usedPercentage,l.payload.resetsAt)})}}catch(o){console.error("alert evaluation failed",o)}return{id:r.id,observedAt:new Date(r.observedAt).toISOString(),deduped:!1}}u(ld,"processObservation");function nI(e,t){return`${e}::${t.provider}::${t.sourceType}::${t.limitType}`}u(nI,"observationKey");function pd(){return process.env.OBSERVE_BATCHING!=="0"}u(pd,"observeBatchingEnabled");function rI(){let e=Number(process.env.OBSERVE_BATCH_BUFFER_MAX);return Number.isFinite(e)&&e>0?Math.floor(e):5e3}u(rI,"observeBufferMax");function oI(){let e=Number(process.env.PG_POOL_MAX)||3;return Math.max(1,e-1)}u(oI,"defaultConcurrency");function FP(e={}){let t=e.process??((I,b)=>ld(I,b)),n=e.maxBuffered??rI(),r=Math.max(1,e.concurrency??oI()),o=new Map,s=0,i=new Set,c=0,a=!1,l=[];function p(){let I=l;l=[];for(let b of I)b()}u(p,"notifyProgress");function m(){for(;c<r;){let I=null,b=null;for(let[S,A]of o)if(!(i.has(S)||A.length===0)){b=A,o.delete(S),I=S;break}if(I==null||b==null)return;s-=b.length,i.add(I),c++,_(I,b)}}u(m,"tick");async function _(I,b){try{for(let S of b)try{await t(S.userId,S.obs)}catch(A){console.warn("[observe-batcher] drain failed for one observation; dropping it:",A instanceof Error?A.message:A)}}finally{c--,i.delete(I),p(),m()}}u(_,"runDrain");function v(I){if(a||s>=n)return!1;let b=nI(I.userId,I.obs),S=o.get(b);return S?S.push(I):o.set(b,[I]),s++,m(),!0}u(v,"push");function g(I){return new Promise(b=>{let S=!1,A=u(()=>{S||(S=!0,clearTimeout(x),b())},"finish"),x=setTimeout(A,I);x.unref?.(),l.push(A)})}u(g,"waitForProgress");async function h(I){let b=I!=null?Date.now()+I:Number.POSITIVE_INFINITY;for(;;){if(m(),s===0&&c===0)return;let S=b-Date.now();if(S<=0)return;await g(Math.min(S,50))}}u(h,"flush");function w(){a=!0}return u(w,"stop"),{push:v,flush:h,stop:w,size:u(()=>s,"size"),inFlight:u(()=>c,"inFlight")}}u(FP,"createObserveBatcher");var Kr=null;function Jm(){return Kr==null&&(Kr=FP()),Kr}u(Jm,"getObserveBatcher");function sI(){Jm(),console.log(`[observe-batcher] batched observe ingest ON (bufferMax=${rI()} drainConcurrency=${oI()}; OBSERVE_BATCHING=0 to disable)`)}u(sI,"initObserveBatcher");async function iI(e=5e3){if(Kr==null)return;Kr.stop(),await Kr.flush(e);let t=Kr.size()+Kr.inFlight();t>0&&console.warn(`[observe-batcher] shutdown flush deadline (${e}ms) hit; dropping ~${t} buffered observation(s)`)}u(iI,"shutdownObserveBatcher");var Ln=new HP,VP=Le.object({provider:Le.string().min(1).max(64),plan:Le.string().min(1).max(64),limitType:Le.string().min(1).max(128),value:Le.number().finite(),unit:Le.string().min(1).max(32),comparator:Le.enum(["=",">=","<="]).default("="),resetsAt:Le.union([Le.string(),Le.date(),Le.null()]).optional().transform(e=>{if(e==null)return null;if(e instanceof Date)return e;let t=new Date(e);return isNaN(t.getTime())?null:t}),sourceType:Le.enum(["oauth_usage","self_observed_429","official_docs","self_observed_lower_bound","community","llm_research","release_notes","live_headers","live_stream"]),sourceUrl:Le.string().url().optional().nullable(),sourceEvidence:Le.unknown().optional(),confidence:Le.number().min(0).max(1),observedAt:Le.union([Le.string(),Le.date()]).optional().transform(e=>{if(e==null)return;if(e instanceof Date)return e;let t=new Date(e);return isNaN(t.getTime())?void 0:t})});Ln.post("/internal/research/match-headers",async e=>{let t=e.get("userId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON"},400)}let o=Le.object({host:Le.string(),path:Le.string().default("/"),responseHeaders:Le.record(Le.string()),observedAt:Le.string().optional(),plan:Le.string().optional()}).safeParse(n);if(!o.success)return e.json({error:"Invalid request body",issues:o.error.issues},400);let{host:s,path:i,responseHeaders:c,observedAt:a,plan:l}=o.data,p=Um(s);if(!p?.liveSource?.headers)return e.json({observations:[]});let m={host:s,path:i,plan:l??null,observedAt:a?new Date(a):new Date,userId:t},_=p.liveSource.headers.parse(c,m);if(!_||_.length===0)return e.json({observations:[]});let v=[];for(let g of _)try{let h=g.observedAt instanceof Date?g.observedAt:typeof g.observedAt=="string"?new Date(g.observedAt):void 0,[w]=await d.insert(pe).values({provider:g.provider,plan:g.plan,limitType:g.limitType,value:String(g.value),unit:g.unit,comparator:g.comparator??"=",resetsAt:g.resetsAt instanceof Date?g.resetsAt:null,sourceType:g.sourceType,sourceUrl:g.sourceUrl??null,sourceEvidence:g.sourceEvidence??null,confidence:String(g.confidence),userId:t,...h?{observedAt:h}:{}}).returning({id:pe.id});v.push({...g,id:w.id})}catch{}return e.json({observations:v})});Ln.post("/internal/research/match-stream-frame",async e=>{let t=e.get("userId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON"},400)}let o=Le.object({host:Le.string(),path:Le.string().default("/"),frameText:Le.string(),observedAt:Le.string().optional(),plan:Le.string().optional()}).safeParse(n);if(!o.success)return e.json({error:"Invalid request body",issues:o.error.issues},400);let{host:s,path:i,frameText:c,observedAt:a,plan:l}=o.data,p=Bm(s,i);if(!p?.liveSource?.streamFrame)return e.json({observations:[]});let m={host:s,path:i,plan:l??null,observedAt:a?new Date(a):new Date,userId:t},_=p.liveSource.streamFrame.parse(c,m);if(!_||_.length===0)return e.json({observations:[]});let v=[];for(let g of _)try{let h=g.observedAt instanceof Date?g.observedAt:typeof g.observedAt=="string"?new Date(g.observedAt):void 0,[w]=await d.insert(pe).values({provider:g.provider,plan:g.plan,limitType:g.limitType,value:String(g.value),unit:g.unit,comparator:g.comparator??"=",resetsAt:g.resetsAt instanceof Date?g.resetsAt:null,sourceType:g.sourceType,sourceUrl:g.sourceUrl??null,sourceEvidence:g.sourceEvidence??null,confidence:String(g.confidence),userId:t,...h?{observedAt:h}:{}}).returning({id:pe.id});v.push({...g,id:w.id})}catch{}return e.json({observations:v})});Ln.post("/internal/research/observe",async e=>{let t=e.get("userId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON"},400)}let r=VP.safeParse(n);if(!r.success)return e.json({error:"Invalid observation",issues:r.error.issues},400);let o=r.data;if(pd())return Jm().push({userId:t,obs:o})?e.json({buffered:!0,durable:!1},202):(e.header("Retry-After","2"),e.json({error:"Observe buffer full; retry shortly.",durable:!1},429));let s=await ld(t,o);return e.json({id:s.id,observedAt:s.observedAt,...s.deduped?{deduped:!0}:{}},s.deduped?200:201)});Ln.get("/research/active-limits",async e=>{let t=e.req.query("provider"),n=e.req.query("plan"),r=[WP(Ve.effectiveUntil)];t&&r.push(er(Ve.provider,t)),n&&r.push(er(Ve.plan,n));let o=await d.select().from(Ve).where(qa(...r)).orderBy(Ve.provider,Ve.plan,Ve.limitType,md(Ve.effectiveFrom));return e.json({items:o})});Ln.get("/research/doc-changes",async e=>{let t=e.req.query("since"),n=t?new Date(t):new Date(Date.now()-7*864e5);if(isNaN(n.getTime()))return e.json({error:"Invalid since parameter"},400);let r=await d.select({id:It.id,fetchedAt:It.fetchedAt,provider:It.provider,docUrl:It.docUrl,contentHash:It.contentHash,parseSuccess:It.parseSuccess}).from(It).where(Gm(It.fetchedAt,n)).orderBy(It.provider,It.docUrl,md(It.fetchedAt)),o=new Map;for(let s of r){let i=`${s.provider}::${s.docUrl}`,c=o.get(i);c?(c.previousHash===null&&s.contentHash!==c.latestHash&&(c.previousHash=s.contentHash,c.changed=!0),c.snapshots.push(s)):o.set(i,{provider:s.provider,docUrl:s.docUrl,latestFetchedAt:s.fetchedAt,latestHash:s.contentHash,previousHash:null,parseSuccess:s.parseSuccess,changed:!1,snapshots:[s]})}return e.json({items:Array.from(o.values())})});Ln.get("/research/disagreements",async e=>{let t=e.get("userId"),n=Math.min(parseInt(e.req.query("since_days")??"14",10)||14,90),r=new Date(Date.now()-n*864e5),o=await d.select().from(pe).where(qa(er(pe.userId,t),Gm(pe.observedAt,r))).orderBy(md(pe.observedAt)),s=new Map;for(let c of o){let a=`${c.provider}::${c.plan}::${c.limitType}`,l=s.get(a);l||(l={provider:c.provider,plan:c.plan,limitType:c.limitType,observations:[]},s.set(a,l)),l.observations.push({id:c.id,value:Number(c.value),unit:c.unit,sourceType:c.sourceType,confidence:Number(c.confidence),observedAt:c.observedAt})}let i=[];for(let c of s.values()){if(c.observations.length<2)continue;let a=c.observations.map(_=>_.value).filter(_=>_>0);if(a.length<2)continue;let l=Math.min(...a),p=Math.max(...a);if(l===0)continue;let m=(p-l)/l*100;m>20&&i.push({provider:c.provider,plan:c.plan,limitType:c.limitType,minValue:l,maxValue:p,spreadPct:m,observations:c.observations})}return i.sort((c,a)=>a.spreadPct-c.spreadPct),e.json({items:i.slice(0,100)})});Ln.get("/research/confidence-history",async e=>{let t=e.req.query("provider"),n=e.req.query("plan"),r=e.req.query("limit_type"),o=Math.min(parseInt(e.req.query("days")??"90",10)||90,365);if(!t||!n||!r)return e.json({error:"provider, plan, limit_type required"},400);let s=new Date(Date.now()-o*864e5),i=await d.select({effectiveFrom:Ve.effectiveFrom,effectiveUntil:Ve.effectiveUntil,confidence:Ve.confidence,value:Ve.value}).from(Ve).where(qa(er(Ve.provider,t),er(Ve.plan,n),er(Ve.limitType,r),Gm(Ve.effectiveFrom,s))).orderBy(Ve.effectiveFrom);return e.json({items:i.map(c=>({effectiveFrom:c.effectiveFrom,effectiveUntil:c.effectiveUntil,confidence:Number(c.confidence),value:Number(c.value)}))})});Ln.get("/research/observations",async e=>{let t=e.get("userId"),n=e.req.query("provider"),r=e.req.query("plan"),o=e.req.query("limit_type"),s=Math.min(parseInt(e.req.query("limit")??"50",10)||50,200),i=Math.max(parseInt(e.req.query("offset")??"0",10)||0,0),c=[er(pe.userId,t)];n&&c.push(er(pe.provider,n)),r&&c.push(er(pe.plan,r)),o&&c.push(er(pe.limitType,o));let a=await d.select().from(pe).where(qa(...c)).orderBy(md(pe.observedAt)).limit(s).offset(i),[{total:l}]=await d.select({total:zP`count(*)::int`}).from(pe).where(qa(...c));return e.json({items:a,total:l,limit:s,offset:i})});import{Hono as JP}from"hono";import{and as dI,desc as GP,eq as Vs,isNull as KP,ne as YP,sql as Do}from"drizzle-orm";var aI={free:.2,pro:1,max_5x:5,max_20x:20},Ym=new Set(["free","pro","max_5x","max_20x"]),Km={fiveHourMessages:20,sevenDaySonnetHours:14,sevenDayOpusHours:1.65};function cI(e){let t=aI[e]??aI.max_20x;return{fiveHourMessages:Math.round(Km.fiveHourMessages*t),sevenDaySonnetHours:Math.round(Km.sevenDaySonnetHours*t),sevenDayOpusHours:Math.round(Km.sevenDayOpusHours*t)}}u(cI,"planDefaultCaps");var Ua=new JP,XP=60*1e3,Xm=new Map;function QP(e,t){let n=`${e}::${t}`,r=Xm.get(n);if(r&&Date.now()-r.at<XP)return r.rows;let o=d.select({limitType:Ve.limitType,value:Ve.value,unit:Ve.unit}).from(Ve).where(dI(Vs(Ve.provider,e),Vs(Ve.plan,t),KP(Ve.effectiveUntil)));return o.catch(()=>Xm.delete(n)),Xm.set(n,{at:Date.now(),rows:o}),o}u(QP,"getActivePlanLimits");var uI=["five_hour_percent","seven_day_percent","seven_day_opus_percent"],ZP={anthropic:["oauth_usage"],codex:["live_stream","self_observed_429"]};function eO(e){return ZP[e]??["oauth_usage"]}u(eO,"sourceTypesFor");Ua.get("/usage/current-limits",async e=>{let t=e.get("userId"),n=e.req.query("provider")??"anthropic",r=eO(n),o=await d.execute(Do`
|
|
1100
|
+
`);if(o.length>0){let s=o[0];return{id:s.id,observedAt:new Date(s.observed_at).toISOString(),deduped:!0}}}catch(o){console.warn("[observe] dedup probe failed; proceeding to insert",o)}let[r]=await d.insert(pe).values({provider:t.provider,plan:t.plan,limitType:t.limitType,value:String(t.value),unit:t.unit,comparator:t.comparator,resetsAt:t.resetsAt??null,sourceType:t.sourceType,sourceUrl:t.sourceUrl??null,sourceEvidence:t.sourceEvidence??null,confidence:String(t.confidence),userId:e,...t.observedAt?{observedAt:t.observedAt}:{}}).returning({id:pe.id,observedAt:pe.observedAt});if(t.sourceType==="oauth_usage"||t.sourceType==="self_observed_429")try{let o=tI(t.provider,t.plan,t.limitType),s=new Date,i=new Date(s.getTime()-600*1e3),c=await d.select({observedAt:pe.observedAt,value:pe.value}).from(pe).where(nI($a(pe.userId,e),$a(pe.provider,t.provider),$a(pe.limitType,t.limitType),UP(pe.observedAt,i))).orderBy(rI(pe.observedAt)).limit(50),a=await d.select().from(un).where(nI($a(un.userId,e),$a(un.alertKey,o))).orderBy(rI(un.lastDispatchedAt)).limit(1),l=Gm({alertKey:o,observations:c.map(p=>({observedAt:p.observedAt,value:Number(p.value)})),currentUsedPercentage:t.value,currentResetsAt:t.resetsAt??new Date(s.getTime()+300*60*1e3),hadObserved429:t.sourceType==="self_observed_429",lastDispatch:a[0]?{severity:a[0].severity,lastDispatchedAt:a[0].lastDispatchedAt,lastState:a[0].lastState}:null,now:s});if(l.shouldDispatch&&l.severity!=="none"){let p=l.severity,[m]=await d.insert(un).values({userId:e,alertKey:o,severity:p,lastState:l.payload,channel:"banner"}).returning({id:un.id});m&&await Vs({userId:e,dispatchId:m.id,severity:p,message:zm(p,t.limitType,l.payload.usedPercentage,l.payload.resetsAt)})}}catch(o){console.error("alert evaluation failed",o)}return{id:r.id,observedAt:new Date(r.observedAt).toISOString(),deduped:!1}}u(md,"processObservation");function oI(e,t){return`${e}::${t.provider}::${t.sourceType}::${t.limitType}`}u(oI,"observationKey");function fd(){return process.env.OBSERVE_BATCHING!=="0"}u(fd,"observeBatchingEnabled");function sI(){let e=Number(process.env.OBSERVE_BATCH_BUFFER_MAX);return Number.isFinite(e)&&e>0?Math.floor(e):5e3}u(sI,"observeBufferMax");function iI(){let e=Number(process.env.PG_POOL_MAX)||3;return Math.max(1,e-1)}u(iI,"defaultConcurrency");function HP(e={}){let t=e.process??((b,I)=>md(b,I)),n=e.maxBuffered??sI(),r=Math.max(1,e.concurrency??iI()),o=new Map,s=0,i=new Set,c=0,a=!1,l=[];function p(){let b=l;l=[];for(let I of b)I()}u(p,"notifyProgress");function m(){for(;c<r;){let b=null,I=null;for(let[S,A]of o)if(!(i.has(S)||A.length===0)){I=A,o.delete(S),b=S;break}if(b==null||I==null)return;s-=I.length,i.add(b),c++,y(b,I)}}u(m,"tick");async function y(b,I){try{for(let S of I)try{await t(S.userId,S.obs)}catch(A){console.warn("[observe-batcher] drain failed for one observation; dropping it:",A instanceof Error?A.message:A)}}finally{c--,i.delete(b),p(),m()}}u(y,"runDrain");function v(b){if(a||s>=n)return!1;let I=oI(b.userId,b.obs),S=o.get(I);return S?S.push(b):o.set(I,[b]),s++,m(),!0}u(v,"push");function g(b){return new Promise(I=>{let S=!1,A=u(()=>{S||(S=!0,clearTimeout(x),I())},"finish"),x=setTimeout(A,b);x.unref?.(),l.push(A)})}u(g,"waitForProgress");async function h(b){let I=b!=null?Date.now()+b:Number.POSITIVE_INFINITY;for(;;){if(m(),s===0&&c===0)return;let S=I-Date.now();if(S<=0)return;await g(Math.min(S,50))}}u(h,"flush");function w(){a=!0}return u(w,"stop"),{push:v,flush:h,stop:w,size:u(()=>s,"size"),inFlight:u(()=>c,"inFlight")}}u(HP,"createObserveBatcher");var Yr=null;function Km(){return Yr==null&&(Yr=HP()),Yr}u(Km,"getObserveBatcher");function aI(){Km(),console.log(`[observe-batcher] batched observe ingest ON (bufferMax=${sI()} drainConcurrency=${iI()}; OBSERVE_BATCHING=0 to disable)`)}u(aI,"initObserveBatcher");async function cI(e=5e3){if(Yr==null)return;Yr.stop(),await Yr.flush(e);let t=Yr.size()+Yr.inFlight();t>0&&console.warn(`[observe-batcher] shutdown flush deadline (${e}ms) hit; dropping ~${t} buffered observation(s)`)}u(cI,"shutdownObserveBatcher");var $n=new WP,JP=$e.object({provider:$e.string().min(1).max(64),plan:$e.string().min(1).max(64),limitType:$e.string().min(1).max(128),value:$e.number().finite(),unit:$e.string().min(1).max(32),comparator:$e.enum(["=",">=","<="]).default("="),resetsAt:$e.union([$e.string(),$e.date(),$e.null()]).optional().transform(e=>{if(e==null)return null;if(e instanceof Date)return e;let t=new Date(e);return isNaN(t.getTime())?null:t}),sourceType:$e.enum(["oauth_usage","self_observed_429","official_docs","self_observed_lower_bound","community","llm_research","release_notes","live_headers","live_stream"]),sourceUrl:$e.string().url().optional().nullable(),sourceEvidence:$e.unknown().optional(),confidence:$e.number().min(0).max(1),observedAt:$e.union([$e.string(),$e.date()]).optional().transform(e=>{if(e==null)return;if(e instanceof Date)return e;let t=new Date(e);return isNaN(t.getTime())?void 0:t})});$n.post("/internal/research/match-headers",async e=>{let t=e.get("userId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON"},400)}let o=$e.object({host:$e.string(),path:$e.string().default("/"),responseHeaders:$e.record($e.string()),observedAt:$e.string().optional(),plan:$e.string().optional()}).safeParse(n);if(!o.success)return e.json({error:"Invalid request body",issues:o.error.issues},400);let{host:s,path:i,responseHeaders:c,observedAt:a,plan:l}=o.data,p=Fm(s);if(!p?.liveSource?.headers)return e.json({observations:[]});let m={host:s,path:i,plan:l??null,observedAt:a?new Date(a):new Date,userId:t},y=p.liveSource.headers.parse(c,m);if(!y||y.length===0)return e.json({observations:[]});let v=[];for(let g of y)try{let h=g.observedAt instanceof Date?g.observedAt:typeof g.observedAt=="string"?new Date(g.observedAt):void 0,[w]=await d.insert(pe).values({provider:g.provider,plan:g.plan,limitType:g.limitType,value:String(g.value),unit:g.unit,comparator:g.comparator??"=",resetsAt:g.resetsAt instanceof Date?g.resetsAt:null,sourceType:g.sourceType,sourceUrl:g.sourceUrl??null,sourceEvidence:g.sourceEvidence??null,confidence:String(g.confidence),userId:t,...h?{observedAt:h}:{}}).returning({id:pe.id});v.push({...g,id:w.id})}catch{}return e.json({observations:v})});$n.post("/internal/research/match-stream-frame",async e=>{let t=e.get("userId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON"},400)}let o=$e.object({host:$e.string(),path:$e.string().default("/"),frameText:$e.string(),observedAt:$e.string().optional(),plan:$e.string().optional()}).safeParse(n);if(!o.success)return e.json({error:"Invalid request body",issues:o.error.issues},400);let{host:s,path:i,frameText:c,observedAt:a,plan:l}=o.data,p=Hm(s,i);if(!p?.liveSource?.streamFrame)return e.json({observations:[]});let m={host:s,path:i,plan:l??null,observedAt:a?new Date(a):new Date,userId:t},y=p.liveSource.streamFrame.parse(c,m);if(!y||y.length===0)return e.json({observations:[]});let v=[];for(let g of y)try{let h=g.observedAt instanceof Date?g.observedAt:typeof g.observedAt=="string"?new Date(g.observedAt):void 0,[w]=await d.insert(pe).values({provider:g.provider,plan:g.plan,limitType:g.limitType,value:String(g.value),unit:g.unit,comparator:g.comparator??"=",resetsAt:g.resetsAt instanceof Date?g.resetsAt:null,sourceType:g.sourceType,sourceUrl:g.sourceUrl??null,sourceEvidence:g.sourceEvidence??null,confidence:String(g.confidence),userId:t,...h?{observedAt:h}:{}}).returning({id:pe.id});v.push({...g,id:w.id})}catch{}return e.json({observations:v})});$n.post("/internal/research/observe",async e=>{let t=e.get("userId"),n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON"},400)}let r=JP.safeParse(n);if(!r.success)return e.json({error:"Invalid observation",issues:r.error.issues},400);let o=r.data;if(fd())return Km().push({userId:t,obs:o})?e.json({buffered:!0,durable:!1},202):(e.header("Retry-After","2"),e.json({error:"Observe buffer full; retry shortly.",durable:!1},429));let s=await md(t,o);return e.json({id:s.id,observedAt:s.observedAt,...s.deduped?{deduped:!0}:{}},s.deduped?200:201)});$n.get("/research/active-limits",async e=>{let t=e.req.query("provider"),n=e.req.query("plan"),r=[zP(Ve.effectiveUntil)];t&&r.push(er(Ve.provider,t)),n&&r.push(er(Ve.plan,n));let o=await d.select().from(Ve).where(qa(...r)).orderBy(Ve.provider,Ve.plan,Ve.limitType,gd(Ve.effectiveFrom));return e.json({items:o})});$n.get("/research/doc-changes",async e=>{let t=e.req.query("since"),n=t?new Date(t):new Date(Date.now()-7*864e5);if(isNaN(n.getTime()))return e.json({error:"Invalid since parameter"},400);let r=await d.select({id:bt.id,fetchedAt:bt.fetchedAt,provider:bt.provider,docUrl:bt.docUrl,contentHash:bt.contentHash,parseSuccess:bt.parseSuccess}).from(bt).where(Ym(bt.fetchedAt,n)).orderBy(bt.provider,bt.docUrl,gd(bt.fetchedAt)),o=new Map;for(let s of r){let i=`${s.provider}::${s.docUrl}`,c=o.get(i);c?(c.previousHash===null&&s.contentHash!==c.latestHash&&(c.previousHash=s.contentHash,c.changed=!0),c.snapshots.push(s)):o.set(i,{provider:s.provider,docUrl:s.docUrl,latestFetchedAt:s.fetchedAt,latestHash:s.contentHash,previousHash:null,parseSuccess:s.parseSuccess,changed:!1,snapshots:[s]})}return e.json({items:Array.from(o.values())})});$n.get("/research/disagreements",async e=>{let t=e.get("userId"),n=Math.min(parseInt(e.req.query("since_days")??"14",10)||14,90),r=new Date(Date.now()-n*864e5),o=await d.select().from(pe).where(qa(er(pe.userId,t),Ym(pe.observedAt,r))).orderBy(gd(pe.observedAt)),s=new Map;for(let c of o){let a=`${c.provider}::${c.plan}::${c.limitType}`,l=s.get(a);l||(l={provider:c.provider,plan:c.plan,limitType:c.limitType,observations:[]},s.set(a,l)),l.observations.push({id:c.id,value:Number(c.value),unit:c.unit,sourceType:c.sourceType,confidence:Number(c.confidence),observedAt:c.observedAt})}let i=[];for(let c of s.values()){if(c.observations.length<2)continue;let a=c.observations.map(y=>y.value).filter(y=>y>0);if(a.length<2)continue;let l=Math.min(...a),p=Math.max(...a);if(l===0)continue;let m=(p-l)/l*100;m>20&&i.push({provider:c.provider,plan:c.plan,limitType:c.limitType,minValue:l,maxValue:p,spreadPct:m,observations:c.observations})}return i.sort((c,a)=>a.spreadPct-c.spreadPct),e.json({items:i.slice(0,100)})});$n.get("/research/confidence-history",async e=>{let t=e.req.query("provider"),n=e.req.query("plan"),r=e.req.query("limit_type"),o=Math.min(parseInt(e.req.query("days")??"90",10)||90,365);if(!t||!n||!r)return e.json({error:"provider, plan, limit_type required"},400);let s=new Date(Date.now()-o*864e5),i=await d.select({effectiveFrom:Ve.effectiveFrom,effectiveUntil:Ve.effectiveUntil,confidence:Ve.confidence,value:Ve.value}).from(Ve).where(qa(er(Ve.provider,t),er(Ve.plan,n),er(Ve.limitType,r),Ym(Ve.effectiveFrom,s))).orderBy(Ve.effectiveFrom);return e.json({items:i.map(c=>({effectiveFrom:c.effectiveFrom,effectiveUntil:c.effectiveUntil,confidence:Number(c.confidence),value:Number(c.value)}))})});$n.get("/research/observations",async e=>{let t=e.get("userId"),n=e.req.query("provider"),r=e.req.query("plan"),o=e.req.query("limit_type"),s=Math.min(parseInt(e.req.query("limit")??"50",10)||50,200),i=Math.max(parseInt(e.req.query("offset")??"0",10)||0,0),c=[er(pe.userId,t)];n&&c.push(er(pe.provider,n)),r&&c.push(er(pe.plan,r)),o&&c.push(er(pe.limitType,o));let a=await d.select().from(pe).where(qa(...c)).orderBy(gd(pe.observedAt)).limit(s).offset(i),[{total:l}]=await d.select({total:VP`count(*)::int`}).from(pe).where(qa(...c));return e.json({items:a,total:l,limit:s,offset:i})});import{Hono as GP}from"hono";import{and as pI,desc as KP,eq as Js,isNull as YP,ne as XP,sql as $o}from"drizzle-orm";var uI={free:.2,pro:1,max_5x:5,max_20x:20},Qm=new Set(["free","pro","max_5x","max_20x"]),Xm={fiveHourMessages:20,sevenDaySonnetHours:14,sevenDayOpusHours:1.65};function dI(e){let t=uI[e]??uI.max_20x;return{fiveHourMessages:Math.round(Xm.fiveHourMessages*t),sevenDaySonnetHours:Math.round(Xm.sevenDaySonnetHours*t),sevenDayOpusHours:Math.round(Xm.sevenDayOpusHours*t)}}u(dI,"planDefaultCaps");var Ua=new GP,QP=60*1e3,Zm=new Map;function ZP(e,t){let n=`${e}::${t}`,r=Zm.get(n);if(r&&Date.now()-r.at<QP)return r.rows;let o=d.select({limitType:Ve.limitType,value:Ve.value,unit:Ve.unit}).from(Ve).where(pI(Js(Ve.provider,e),Js(Ve.plan,t),YP(Ve.effectiveUntil)));return o.catch(()=>Zm.delete(n)),Zm.set(n,{at:Date.now(),rows:o}),o}u(ZP,"getActivePlanLimits");var lI=["five_hour_percent","seven_day_percent","seven_day_opus_percent"],eO={anthropic:["oauth_usage"],codex:["live_stream","self_observed_429"]};function tO(e){return eO[e]??["oauth_usage"]}u(tO,"sourceTypesFor");Ua.get("/usage/current-limits",async e=>{let t=e.get("userId"),n=e.req.query("provider")??"anthropic",r=tO(n),o=await d.execute($o`
|
|
1101
1101
|
SELECT lt.limit_type AS limit_type, o.value AS value, o.resets_at AS resets_at, o.observed_at AS observed_at
|
|
1102
|
-
FROM (VALUES ${
|
|
1102
|
+
FROM (VALUES ${$o.join(lI.map(i=>$o`(${i})`),$o`, `)}) AS lt(limit_type)
|
|
1103
1103
|
LEFT JOIN LATERAL (
|
|
1104
1104
|
SELECT value, resets_at, observed_at
|
|
1105
1105
|
FROM limit_observations
|
|
1106
1106
|
WHERE user_id = ${t}
|
|
1107
1107
|
AND provider = ${n}
|
|
1108
|
-
AND source_type IN (${
|
|
1108
|
+
AND source_type IN (${$o.join(r.map(i=>$o`${i}`),$o`, `)})
|
|
1109
1109
|
AND limit_type = lt.limit_type
|
|
1110
1110
|
ORDER BY observed_at DESC, value DESC
|
|
1111
1111
|
LIMIT 1
|
|
1112
1112
|
) o ON true
|
|
1113
|
-
`),s=new Map;for(let i of o)i.value==null||i.observed_at==null||
|
|
1113
|
+
`),s=new Map;for(let i of o)i.value==null||i.observed_at==null||lI.includes(i.limit_type)&&s.set(i.limit_type,{used_percentage:Number(i.value),resets_at:i.resets_at?new Date(i.resets_at).toISOString():null,observed_at:new Date(i.observed_at).toISOString()});return e.header("Cache-Control","private, max-age=15"),e.json({provider:n,five_hour:s.get("five_hour_percent")??null,seven_day:s.get("seven_day_percent")??null,seven_day_opus:s.get("seven_day_opus_percent")??null})});Ua.get("/usage/inferred-caps",async e=>{let t=e.get("userId"),n=e.req.query("provider")??"anthropic",[r]=await d.select({plan:R.claudeCodePlan,source:R.planSource}).from(R).where(Js(R.id,t)),o=r?.source==="manual"&&r.plan&&Qm.has(r.plan)?r.plan:null,s=await d.select({plan:pe.plan}).from(pe).where(pI(Js(pe.userId,t),Js(pe.provider,n),Js(pe.sourceType,"oauth_usage"),XP(pe.plan,"unknown"))).orderBy(KP(pe.observedAt)).limit(1),i=s[0]?.plan&&Qm.has(s[0].plan)?s[0].plan:null,c=o??i??"max_20x",a=o===null&&i===null,l=dI(c),p=await ZP(n,c);function m(h,w,b){let I=p.filter(S=>S.limitType===h&&w.test(S.unit));return I.length===0?b:Math.max(...I.map(S=>Number(S.value)))}u(m,"bestCap");let y=m("five_hour_messages",/msg|message/i,l.fiveHourMessages),v=m("seven_day_sonnet_hours",/hour|hr/i,l.sevenDaySonnetHours),g=m("seven_day_opus_hours",/hour|hr/i,l.sevenDayOpusHours);return e.header("Cache-Control","private, max-age=15"),e.json({plan:c,assumed:a,five_hour_percent:{inferred_cap:y,unit:"messages",confidence_band_pct:20},seven_day_percent:{inferred_cap:v,unit:"hours",confidence_band_pct:20},seven_day_opus_percent:{inferred_cap:g,unit:"hours",confidence_band_pct:20}})});import{Hono as nO}from"hono";import{z as qn}from"zod";import{and as mI,desc as hI,eq as Ba,sql as rO}from"drizzle-orm";var Ha=new nO,fI=30,oO=30,sO=0,ef=1e3,gI=2e3,tf=2;function Fa(e){return e==null?0:typeof e=="number"?e:Number(e)}u(Fa,"toNum");function iO(e){if(!e)return null;let t=typeof e=="string"?Date.parse(e):e.getTime();return Number.isNaN(t)?null:(Date.now()-t)/864e5}u(iO,"ageDays");async function aO(){let e=await d.select({provider:Ye.provider,modelId:Ye.modelId,inputPerM:Ye.inputPerM,outputPerM:Ye.outputPerM,effectiveFrom:Ye.effectiveFrom,verifiedAt:Ye.verifiedAt}).from(Ye).orderBy(hI(Ye.effectiveFrom)),t=new Map;for(let n of e){let r=`${n.provider}::${n.modelId}`;t.has(r)||t.set(r,n)}return t}u(aO,"loadActiveRows");Ha.get("/pricing/coverage",async e=>{if(!e.get("userId"))return e.json({error:"unauthorized"},401);let n=await d.execute(rO`
|
|
1114
1114
|
SELECT model,
|
|
1115
1115
|
COUNT(*)::int AS events,
|
|
1116
1116
|
MAX(timestamp) AS last_seen
|
|
1117
1117
|
FROM session_events
|
|
1118
1118
|
WHERE model IS NOT NULL
|
|
1119
1119
|
AND model NOT IN ('unknown', '(null)')
|
|
1120
|
-
AND timestamp > now() - (${
|
|
1120
|
+
AND timestamp > now() - (${oO} || ' days')::interval
|
|
1121
1121
|
GROUP BY model
|
|
1122
1122
|
ORDER BY events DESC
|
|
1123
|
-
`),r=await
|
|
1124
|
-
UPDATE ${
|
|
1123
|
+
`),r=await aO(),o=[],s=[],i=0;for(let c of n){let a=c.model,l=zr(a),p=r.get(`${l}::${a}`);if(!p){o.push({provider:l,modelId:a,events:c.events,lastSeen:String(c.last_seen)});continue}let m=iO(p.verifiedAt??p.effectiveFrom);m===null||m>fI?s.push({provider:l,modelId:a,events:c.events,verifiedAt:p.verifiedAt?String(p.verifiedAt):null,ageDays:m===null?null:Math.round(m),currentInput:Fa(p.inputPerM),currentOutput:Fa(p.outputPerM)}):i+=1}return e.json({staleDays:fI,capturedModels:n.length,pricedFresh:i,unpriced:o,stale:s})});var cO=qn.object({provider:qn.string().min(1).optional(),modelId:qn.string().min(1),inputPerM:qn.number(),outputPerM:qn.number(),cacheReadPerM:qn.number().optional(),cacheWrite5mPerM:qn.number().optional(),cacheWrite1hPerM:qn.number().optional(),contextWindow:qn.number().int().positive().nullable().optional(),sourceUrl:qn.string().url(),effectiveFrom:qn.string().datetime().optional()});Ha.post("/pricing/rates",async e=>{if(!e.get("userId"))return e.json({error:"unauthorized"},401);let n=cO.safeParse(await e.req.json().catch(()=>null));if(!n.success)return e.json({status:"rejected",reason:"invalid body",detail:n.error.flatten()},400);let r=n.data,o=r.provider??zr(r.modelId),s=u((g,h)=>g>sO&&g<=h,"inRange");if(!s(r.inputPerM,ef)||!s(r.outputPerM,ef))return e.json({status:"rejected",reason:`input/output out of range (0, ${ef}]`},422);let i=r.cacheReadPerM??0,c=r.cacheWrite5mPerM??0,a=r.cacheWrite1hPerM??0;for(let[g,h]of[["cacheReadPerM",i],["cacheWrite5mPerM",c],["cacheWrite1hPerM",a]])if(h<0||h>gI)return e.json({status:"rejected",reason:`${g} out of range [0, ${gI}]`},422);let p=(await d.select().from(Ye).where(mI(Ba(Ye.provider,o),Ba(Ye.modelId,r.modelId))).orderBy(hI(Ye.effectiveFrom)).limit(1))[0],m=1e-9;if(p){let g=Fa(p.inputPerM),h=Fa(p.outputPerM),w=u((A,x)=>x<=0?1/0:A/x,"ratio"),b=Math.max(w(r.inputPerM,g),w(g,r.inputPerM)),I=Math.max(w(r.outputPerM,h),w(h,r.outputPerM));if(b>tf||I>tf)return e.json({status:"flagged",reason:`new rate differs from current by more than ${tf}x \u2014 needs human review`,current:{inputPerM:g,outputPerM:h},proposed:{inputPerM:r.inputPerM,outputPerM:r.outputPerM},sourceUrl:r.sourceUrl});if(Math.abs(g-r.inputPerM)<m&&Math.abs(h-r.outputPerM)<m&&Math.abs(Fa(p.cacheReadPerM)-i)<m)return await d.update(Ye).set({verifiedAt:new Date}).where(mI(Ba(Ye.provider,o),Ba(Ye.modelId,r.modelId),Ba(Ye.effectiveFrom,p.effectiveFrom))),e.json({status:"unchanged",modelId:r.modelId})}let y=r.effectiveFrom?new Date(r.effectiveFrom):new Date,v=new Date().toISOString().slice(0,10);return await d.insert(Ye).values({provider:o,modelId:r.modelId,inputPerM:String(r.inputPerM),outputPerM:String(r.outputPerM),cacheReadPerM:String(i),cacheWrite5mPerM:String(c),cacheWrite1hPerM:String(a),contextWindow:r.contextWindow??null,effectiveFrom:y,verifiedAt:new Date,source:`auto-refresh-${v}`}).onConflictDoNothing(),e.json({status:"written",modelId:r.modelId,provider:o,effectiveFrom:y.toISOString()})});import{Hono as uO}from"hono";import{desc as dO,eq as lO}from"drizzle-orm";var hd=new uO;hd.get("/alerts/recent",async e=>{let t=e.get("userId"),n=await d.select().from(un).where(lO(un.userId,t)).orderBy(dO(un.lastDispatchedAt)).limit(20);return e.json({items:n})});import{Hono as pO}from"hono";import{randomUUID as mO}from"node:crypto";import{sql as Gs}from"drizzle-orm";var _d=new pO,wI=300,_I=3e4,fO=6e4,gO=1e3,nf={process_send_message:"session_send_jobs",process_launch:"launch_jobs",process_eval:"eval_jobs",process_conversation:"eval_jobs",process_insights:"insights_jobs",process_announcement:"agent_jobs",process_session_goal:"agent_jobs",distill_memories:"agent_jobs",memory_ab:"agent_jobs",process_run_cleanup:"agent_jobs",cron_suggest_instructions:"agent_jobs",cron_refresh_skills:"agent_jobs",cron_refresh_pricing:"agent_jobs",cron_eval_autorun:"agent_jobs",cron_instruction_evolution:"agent_jobs",process_judge_review:"agent_jobs"},hO=["session_send_jobs","launch_jobs","eval_jobs","insights_jobs","agent_jobs"];async function _O(e,t,n,r){if(n.length===0)return null;let o=Gs.join(n.map(i=>Gs`${i}`),Gs`, `),s=await d.execute(Gs`
|
|
1124
|
+
UPDATE ${Gs.raw(e)} AS m
|
|
1125
1125
|
SET status = 'claimed',
|
|
1126
1126
|
claimed_by = ${r},
|
|
1127
1127
|
claimed_at = now(),
|
|
1128
|
-
lease_expires_at = now() + (${
|
|
1128
|
+
lease_expires_at = now() + (${wI}::int * interval '1 second'),
|
|
1129
1129
|
attempts = m.attempts + 1,
|
|
1130
1130
|
updated_at = now()
|
|
1131
1131
|
FROM (
|
|
1132
1132
|
SELECT id
|
|
1133
|
-
FROM ${
|
|
1133
|
+
FROM ${Gs.raw(e)}
|
|
1134
1134
|
WHERE user_id = ${t}
|
|
1135
1135
|
AND status = 'pending'
|
|
1136
1136
|
AND task_kind IN (${o})
|
|
@@ -1141,23 +1141,23 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1141
1141
|
) AS picked
|
|
1142
1142
|
WHERE m.id = picked.id
|
|
1143
1143
|
RETURNING m.id, m.task_kind, m.payload, m.attempts
|
|
1144
|
-
`);return s.length>0?s[0]:null}u(
|
|
1144
|
+
`);return s.length>0?s[0]:null}u(_O,"claimOne");async function yO(e,t,n){let r={};for(let o of t){let s=nf[o];s&&(r[s]??=[]).push(o)}for(let o of hO){let s=r[o];if(!s)continue;let i=await _O(o,e,s,n);if(i)return{job:i,table:o}}return null}u(yO,"tryClaimAcrossTables");var wO={cron_suggest_instructions:[0,7,37]};function vO(e){let t=/rulemetric-cli\/(\d+)\.(\d+)\.(\d+)/.exec(e??"");return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}u(vO,"parseCliVersion");function IO(e,t){return e[0]!==t[0]?e[0]>t[0]:e[1]!==t[1]?e[1]>t[1]:e[2]>=t[2]}u(IO,"versionAtLeast");function bO(e,t){let n=vO(t),r=[],o=[];for(let s of e){let i=wO[s];i&&(!n||!IO(n,i))?o.push(s):r.push(s)}return{allowed:r,fenced:o}}u(bO,"fenceCapabilities");var yI=new Set;_d.get("/work/next",async e=>{let t=e.get("userId"),r=(e.req.query("capabilities")??"").split(",").map(p=>p.trim()).filter(p=>p.length>0&&p in nf),{allowed:o,fenced:s}=bO(r,e.req.header("user-agent"));if(s.length>0&&!yI.has(t)&&(yI.add(t),console.warn(`[work] version fence: user=${t} ua=${e.req.header("user-agent")??"none"} withheld kinds: ${s.join(", ")} \u2014 worker below minimum CLI version; jobs stay pending until upgrade`)),r.length===0)return e.json({error:"capabilities must list one or more of: "+Object.keys(nf).join(", ")},400);if(o.length===0)return e.body(null,204);let i=Number.parseInt(e.req.query("waitMs")??`${_I}`,10),c=Number.isFinite(i)?Math.max(0,Math.min(i,fO)):_I,a=mO(),l=Date.now()+c;for(;;){let p=await yO(t,o,a);if(p)return e.json({id:p.job.id,kind:p.job.task_kind,payload:p.job.payload,attempts:p.job.attempts,leaseToken:a,leaseDurationSeconds:wI,table:p.table});if(Date.now()>=l)break;await new Promise(m=>setTimeout(m,gO))}return e.body(null,204)});import{Hono as SO}from"hono";import{z as Wa}from"zod";import{sql as br}from"drizzle-orm";import{eq as qo,and as vI}from"drizzle-orm";async function II(e,t,n,r){try{let[o]=await d.select({evalTargetId:Se.evalTargetId,config:Se.config}).from(Se).where(vI(qo(Se.id,t),qo(Se.userId,e)));if(!o||o.config?.type==="conversation")return;let[s]=await d.select({name:k.name}).from(k).where(qo(k.id,o.evalTargetId)),i=s?.name??"eval target";n==="failed"?await tn({userId:e,type:"eval_failed",title:"Eval run failed",body:`${i}: ${String(r??"").slice(0,200)}`,url:`/eval-targets/${o.evalTargetId}`,sourceTable:"eval_jobs",sourceId:t}):(await tn({userId:e,type:"eval_completed",title:"Eval run complete",body:`${i} finished`,url:`/eval-targets/${o.evalTargetId}`,sourceTable:"eval_jobs",sourceId:t}),await ga(e,o.evalTargetId))}catch(o){console.error("[job-notifications] eval notify failed:",o instanceof Error?o.stack:o)}}u(II,"notifyEvalTerminal");async function bI(e,t,n,r){try{let[o]=await d.select({projectPath:W.projectPath}).from(W).where(vI(qo(W.id,t),qo(W.userId,e)));if(!o)return;let s=null,i;if(o.projectPath){let[p]=await d.select({id:D.id,name:D.name}).from(ue).innerJoin(D,qo(D.id,ue.projectId)).where(qo(ue.path,o.projectPath)).limit(1);p?(s=p.id,i=p.name):i=`${o.projectPath.split("/").pop()||"Unknown"} (unregistered)`}else i="All Projects";let c=new Date().toISOString().slice(0,10),a=`${s??"unmatched"}-${c}`,l=o.projectPath?`/insights/computed?projectPath=${encodeURIComponent(o.projectPath)}&tab=recommendations`:"/insights";n==="failed"?await tn({userId:e,type:"insights_failed",title:"Insights generation failed",body:`${i}: ${String(r??"").slice(0,200)}`,url:l,sourceTable:"insights_jobs",sourceId:a}):await tn({userId:e,type:"insights_ready",title:`Insights ready: ${i}`,body:"New recommendations are available",url:l,sourceTable:"insights_jobs",sourceId:a})}catch(o){console.error("[job-notifications] insights notify failed:",o instanceof Error?o.stack:o)}}u(bI,"notifyInsightsTerminal");async function AI(e,t,n,r,o){e==="process_eval"?await II(t,n,r,o):e==="process_insights"&&await bI(t,n,r,o)}u(AI,"notifyTerminal");var Ks=new SO,SI=300,rf={process_eval:3,process_insights:3,process_launch:3,process_send_message:1,process_conversation:1,process_announcement:3,process_session_goal:1,distill_memories:1,memory_ab:1,process_run_cleanup:1,cron_suggest_instructions:1,cron_refresh_skills:1,cron_refresh_pricing:1,cron_eval_autorun:1,process_judge_review:1,cron_instruction_evolution:1},AO=["session_send_jobs","launch_jobs","eval_jobs","insights_jobs","agent_jobs"];async function of(e,t,n){for(let r of AO){let o=await d.execute(br`
|
|
1145
1145
|
SELECT status, attempts, task_kind
|
|
1146
|
-
FROM ${
|
|
1146
|
+
FROM ${br.raw(r)}
|
|
1147
1147
|
WHERE id = ${e}
|
|
1148
1148
|
AND user_id = ${t}
|
|
1149
1149
|
AND claimed_by = ${n}
|
|
1150
1150
|
AND status IN ('claimed', 'running')
|
|
1151
1151
|
LIMIT 1
|
|
1152
|
-
`);if(o.length>0)return{table:r,status:o[0].status,attempts:o[0].attempts,taskKind:o[0].task_kind}}return null}u(
|
|
1153
|
-
UPDATE ${
|
|
1154
|
-
SET lease_expires_at = now() + (${
|
|
1152
|
+
`);if(o.length>0)return{table:r,status:o[0].status,attempts:o[0].attempts,taskKind:o[0].task_kind}}return null}u(of,"locateRow");var xO=Wa.object({result:Wa.unknown().optional()}),EO=Wa.object({error:Wa.string().min(1).max(8192),terminal:Wa.boolean().optional().default(!1)});Ks.post("/work/:id/heartbeat",async e=>{let t=e.get("userId"),n=e.req.param("id"),o=(await e.req.json().catch(()=>({}))).leaseToken;if(!o)return e.json({error:"leaseToken required"},400);let s=await of(n,t,o);return s?(await d.execute(br`
|
|
1153
|
+
UPDATE ${br.raw(s.table)}
|
|
1154
|
+
SET lease_expires_at = now() + (${SI}::int * interval '1 second'),
|
|
1155
1155
|
updated_at = now()
|
|
1156
1156
|
WHERE id = ${n}
|
|
1157
1157
|
AND claimed_by = ${o}
|
|
1158
1158
|
AND status IN ('claimed', 'running')
|
|
1159
|
-
`),e.json({ok:!0,leaseDurationSeconds:
|
|
1160
|
-
UPDATE ${
|
|
1159
|
+
`),e.json({ok:!0,leaseDurationSeconds:SI})):e.json({error:"job not found or lease lost"},404)});Ks.post("/work/:id/complete",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json().catch(()=>({})),o=r.leaseToken;if(!o)return e.json({error:"leaseToken required"},400);let s=xO.safeParse(r);if(!s.success)return e.json({error:s.error.format()},400);let i=await of(n,t,o);if(!i)return e.json({error:"job not found or lease lost"},404);let c=JSON.stringify(s.data.result??null);return await d.execute(br`
|
|
1160
|
+
UPDATE ${br.raw(i.table)}
|
|
1161
1161
|
SET status = 'completed',
|
|
1162
1162
|
result = ${c}::jsonb,
|
|
1163
1163
|
error = NULL,
|
|
@@ -1168,22 +1168,22 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1168
1168
|
WHERE id = ${n}
|
|
1169
1169
|
AND claimed_by = ${o}
|
|
1170
1170
|
AND status IN ('claimed', 'running')
|
|
1171
|
-
`),await
|
|
1172
|
-
UPDATE ${
|
|
1171
|
+
`),await AI(i.taskKind,t,n,"completed"),e.json({ok:!0})});Ks.post("/work/:id/fail",async e=>{let t=e.get("userId"),n=e.req.param("id"),r=await e.req.json().catch(()=>({})),o=r.leaseToken;if(!o)return e.json({error:"leaseToken required"},400);let s=EO.safeParse(r);if(!s.success)return e.json({error:s.error.format()},400);let i=await of(n,t,o);if(!i)return e.json({error:"job not found or lease lost"},404);let c=rf[i.taskKind]??3,a=s.data.terminal||i.attempts>=c,l=a?"failed":"pending";return await d.execute(br`
|
|
1172
|
+
UPDATE ${br.raw(i.table)}
|
|
1173
1173
|
SET status = ${l},
|
|
1174
1174
|
error = ${s.data.error},
|
|
1175
1175
|
updated_at = now(),
|
|
1176
|
-
${
|
|
1176
|
+
${br.raw(a?"completed_at = now(),":"")}
|
|
1177
1177
|
claimed_by = NULL,
|
|
1178
1178
|
claimed_at = NULL,
|
|
1179
1179
|
lease_expires_at = NULL
|
|
1180
1180
|
WHERE id = ${n}
|
|
1181
1181
|
AND claimed_by = ${o}
|
|
1182
1182
|
AND status IN ('claimed', 'running')
|
|
1183
|
-
`),a&&await bI(i.taskKind,t,n,"failed",s.data.error),e.json({ok:!0,requeued:!a,attempts:i.attempts})});import{Hono as EO}from"hono";import{z as Yr}from"zod";import{and as AI,desc as TO,eq as tr,isNotNull as RO,sql as xI}from"drizzle-orm";var nr=new EO;nr.use("/announcements/*",Oa());nr.use("/announcements",Oa());nr.get("/announcements",async e=>{let t=await d.select({id:Je.id,version:Je.version,releaseDate:Je.releaseDate,subject:Je.subject,status:Je.status,recipientCount:Je.recipientCount,sentAt:Je.sentAt,sentBy:Je.sentBy,error:Je.error,createdAt:Je.createdAt,updatedAt:Je.updatedAt}).from(Je).orderBy(TO(Je.createdAt));return e.json({announcements:t})});nr.get("/announcements/:id",async e=>{let t=e.req.param("id");if(!Yr.string().uuid().safeParse(t).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let[n]=await d.select().from(Je).where(tr(Je.id,t));if(!n)return e.json({error:"Announcement not found",code:"NOT_FOUND"},404);let r=await d.select({status:po.status,count:xI`count(*)::int`}).from(po).where(tr(po.announcementId,t)).groupBy(po.status),o={};for(let s of r)o[s.status]=s.count;return e.json({...n,deliveryCounts:o})});nr.get("/announcements/:id/recipients/count",async e=>{let t=e.req.param("id");if(!Yr.string().uuid().safeParse(t).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let n=await kO();return e.json({count:n})});async function kO(){let[e]=await d.select({count:xI`count(*)::int`}).from(Zt).innerJoin(T,tr(T.id,Zt.userId)).where(AI(tr(Zt.productAnnouncements,!0),RO(T.email)));return e?.count??0}u(kO,"countOptedInRecipients");var SI=u(e=>e.includes("{{unsubscribe_url}}"),"hasUnsubscribePlaceholder"),jO=Yr.object({subject:Yr.string().min(1).max(500).optional(),htmlBody:Yr.string().min(1).refine(SI,{message:"htmlBody must contain the {{unsubscribe_url}} placeholder"}).optional(),textBody:Yr.string().min(1).refine(SI,{message:"textBody must contain the {{unsubscribe_url}} placeholder"}).optional()});nr.patch("/announcements/:id",async e=>{let t=e.req.param("id");if(!Yr.string().uuid().safeParse(t).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON",code:"VALIDATION_ERROR"},400)}let r=jO.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let o=r.data;if(Object.keys(o).length===0)return e.json({error:"No fields to update",code:"VALIDATION_ERROR"},400);let[s]=await d.select().from(Je).where(tr(Je.id,t));if(!s)return e.json({error:"Announcement not found",code:"NOT_FOUND"},404);if(s.status!=="draft")return e.json({error:"Can only edit draft announcements",code:"INVALID_STATE",status:s.status},409);let[i]=await d.update(Je).set({...o.subject!==void 0?{subject:o.subject}:{},...o.htmlBody!==void 0?{htmlBody:o.htmlBody}:{},...o.textBody!==void 0?{textBody:o.textBody}:{},updatedAt:new Date}).where(tr(Je.id,t)).returning();return e.json(i)});nr.post("/announcements/:id/send",async e=>{let t=e.get("userId");if(!t)return e.json({error:"Unauthenticated",code:"UNAUTHENTICATED"},401);let n=e.req.param("id");if(!Yr.string().uuid().safeParse(n).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let r=await d.update(Je).set({status:"queued",sentBy:t,updatedAt:new Date}).where(AI(tr(Je.id,n),tr(Je.status,"draft"))).returning();if(r.length===0){let[o]=await d.select().from(Je).where(tr(Je.id,n));return o?e.json({error:`Cannot send from status='${o.status}' (must be 'draft')`,code:"INVALID_STATE",status:o.status},409):e.json({error:"Announcement not found",code:"NOT_FOUND"},404)}try{let{jobId:o,noLiveWorker:s}=await qy({announcementId:n,userId:t});return e.json({jobId:o,noLiveWorker:s,announcement:r[0]})}catch(o){return await d.update(Je).set({status:"draft",sentBy:null,updatedAt:new Date}).where(tr(Je.id,n)).catch(()=>{}),e.json({error:o.message??"Failed to enqueue announcement",code:"ENQUEUE_FAILED"},500)}});import{Hono as NO}from"hono";import{inArray as TI,sql as EI}from"drizzle-orm";var za=new NO;function RI(e){let t;try{t=decodeURIComponent(e)}catch{return[]}let n=t.replace(/=+$/,"").replaceAll("+","-").replaceAll("/","_");return t===n?[t]:[t,n]}u(RI,"tokenCandidates");za.get("/:token",async e=>{let t=e.req.param("token");if(!t||t.length<8)return e.json({error:"invalid_token"},404);let n=RI(t);if(n.length===0)return e.json({error:"invalid_token"},404);let[r]=await d.select({productAnnouncements:Zt.productAnnouncements,unsubscribedAt:Zt.unsubscribedAt}).from(Zt).where(TI(Zt.unsubscribeToken,n)).limit(1);return r?e.json({valid:!0,alreadyUnsubscribed:r.productAnnouncements===!1}):e.json({error:"invalid_token"},404)});za.post("/:token",async e=>{let t=e.req.param("token");if(!t||t.length<8)return e.json({error:"invalid_token"},404);let n=RI(t);return n.length===0?e.json({error:"invalid_token"},404):(await d.update(Zt).set({productAnnouncements:!1,unsubscribedAt:EI`now()`,updatedAt:EI`now()`}).where(TI(Zt.unsubscribeToken,n)).returning({userId:Zt.userId})).length===0?e.json({error:"invalid_token"},404):e.json({ok:!0})});import{createHash as CO}from"node:crypto";async function kI(){let e=[],t=0,n=0,r=0;for(let[o,s]of Object.entries(La)){t++;for(let i of s.docs)try{let c=await fetch(i.url,{headers:{"User-Agent":"RuleMetric-Research/1.0"}});if(!c.ok){e.push({provider:o,url:i.url,message:`HTTP ${c.status}`});continue}let a=await c.text(),l=CO("sha256").update(a).digest("hex"),p=!0,m=[],_=null;try{m=i.parse(a)}catch(h){p=!1,_=h instanceof Error?h.message:String(h)}if((await d.insert(It).values({provider:o,docUrl:i.url,contentHash:l,content:a,parseSuccess:p,parseErrors:_?[_]:null}).onConflictDoNothing({target:[It.provider,It.docUrl,It.contentHash]}).returning({id:It.id})).length===1&&p){for(let h of m)await d.insert(pe).values({provider:o,plan:h.plan,limitType:h.limitType,value:String(h.value),unit:h.unit,comparator:h.comparator??"=",resetsAt:null,sourceType:"official_docs",sourceUrl:i.url,sourceEvidence:{snapshotHash:l},confidence:"0.85",userId:null}),r++;n++}}catch(c){e.push({provider:o,url:i.url,message:c instanceof Error?c.message:String(c)})}}return{providers_scraped:t,snapshots_inserted:n,observations_inserted:r,errors:e}}u(kI,"scrapeProviderDocs");var PO=360*60*1e3,jI=!1;function NI(){if(jI)return{stop:u(()=>{},"stop")};jI=!0;let e=setTimeout(()=>{kI().then(n=>{n.errors.length>0?console.warn("[research] scrape completed with errors:",n):console.log(`[research] scrape ok: providers=${n.providers_scraped}, snapshots+=${n.snapshots_inserted}, observations+=${n.observations_inserted}`)}).catch(n=>console.warn("[research] scrape failed:",n))},3e4),t=setInterval(()=>{kI().then(n=>{n.errors.length>0&&console.warn("[research] scrape completed with errors:",n)}).catch(n=>console.warn("[research] scrape failed:",n))},PO);return{stop:u(()=>{clearTimeout(e),clearInterval(t)},"stop")}}u(NI,"startScrapeInterval");var $=new MO,UO=process.env.ALLOWED_ORIGINS?.split(",")??["http://localhost:5174","http://localhost:5175"];$.use("*",LO({origin:u(e=>e?UO.includes(e)?e:"":"*","origin"),allowMethods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowHeaders:["Authorization","Content-Type"],credentials:!0}));$.use("*",jd());$.use("*",nh());$.use("/api/*",$O({maxSize:10*1024*1024}));$.use("*",th);$.use("/auth/login",$i(900*1e3,10));var DI=$i(60*1e3,10);$.use("/api/auth/api-keys",DI);$.use("/api/auth/api-keys/*",DI);$.use("/api/invitations/*",$i(60*1e3,30));$.use("/api/telemetry/cli-error",$i(60*1e3,60));$.route("/",rs);$.route("/api",Fc);$.route("/",ts);$.route("/",Ma);$.route("/api",Bc);$.route("/api",ad);$.route("/",ud);$.use("/api/*",Xg);$.use("/api/*",Zg);$.use("/api/sessions/:id/context-snapshots",Ui);$.use("/api/sessions/:id/events",Ui);$.use("/api/sessions/import",Ui);$.use("/api/internal/research/observe",Ui);$.use("/api/*",async(e,t)=>{let n=e.req.path,r=e.req.method,o=r==="GET"&&n.startsWith("/api/invitations/")&&n!=="/api/invitations/accept",s=r==="GET"&&n==="/api/cli/latest-version",i=r==="POST"&&n==="/api/skills/sync-public",c=(r==="GET"||r==="POST")&&n.startsWith("/api/unsubscribe/");return o||s||i||c?t():Gg(e,t)});$.route("/api",_n);$.route("/api",Jc);$.route("/api",Gc);$.route("/api",Kc);$.route("/api",Ji);$.route("/api",Gi);$.route("/api",Ki);$.route("/api",Xi);$.route("/api",Qc);$.route("/api",zn);$.route("/api",St);$.route("/api",aa);$.route("/api",Vn);$.route("/api",Iu);$.route("/api",_s);$.route("/api",Au);$.route("/api",bo);$.route("/api",ys);$.route("/api",Ss);$.route("/api",So);$.route("/api",As);$.route("/api",pr);$.route("/api",xo);$.route("/api",ks);$.route("/api",_a);$.route("/api",Ns);$.route("/api",Hr);$.route("/api",qu);$.route("/api",fr);$.route("/api",Sn);$.route("/api",Ds);$.route("/api",yr);$.route("/api",Vr);$.route("/api",xa);$.route("/api",$s);$.route("/api",Jr);$.route("/api",Qn);$.route("/api",Po);$.route("/api",ct);$.route("/api/invitations",ja);$.route("/api",Pa);$.route("/api",sn);$.route("/api",id);$.route("/api",Da);$.route("/api",Ln);$.route("/api",Ua);$.route("/api",Ha);$.route("/api",fd);$.route("/api",gd);$.route("/api",Gs);$.route("/api",nr);$.route("/api/unsubscribe",za);$.route("/api",cd);var BO=setTimeout(()=>{Gu().catch(()=>{})},5e3),FO=NI(),MI=[{stop:u(()=>clearTimeout(BO),"stop")},FO],HO=Ks.dirname(DO(import.meta.url)),rf=process.env.WEB_DIST_PATH??Ks.resolve(HO,"../../../apps/web/dist");if(Va.existsSync(rf)){let e=u(async t=>{let n=Ks.join(rf,"index.html");if(!Va.existsSync(n))return t.notFound();let{stampRuntimeConfig:r}=await Promise.resolve().then(()=>(OI(),PI));return t.html(r(Va.readFileSync(n,"utf-8")))},"serveIndex");$.get("/",e),$.get("/index.html",e),$.use("/*",qO({root:rf,rewriteRequestPath:u(t=>t,"rewriteRequestPath")})),$.get("*",e)}$.onError(Kg);import{sql as rr}from"drizzle-orm";var WO=300*1e3,zO="reconciler: lease expired with attempts exhausted \u2014 agent likely crashed mid-run",VO="reconciler: in-flight row had no lease and attempts were exhausted \u2014 unclaimable and unswept until recovered",Ys=1,JO=["eval_jobs","insights_jobs","launch_jobs","session_send_jobs","agent_jobs"];function Xs(){return rr.join(Object.entries(tf).map(([e,t])=>rr`WHEN ${e} THEN ${t}::int`),rr` `)}u(Xs,"maxAttemptsCase");async function GO(e){let t=await d.execute(rr`
|
|
1183
|
+
`),a&&await AI(i.taskKind,t,n,"failed",s.data.error),e.json({ok:!0,requeued:!a,attempts:i.attempts})});import{Hono as TO}from"hono";import{z as Xr}from"zod";import{and as EI,desc as RO,eq as tr,isNotNull as kO,sql as TI}from"drizzle-orm";var nr=new TO;nr.use("/announcements/*",Oa());nr.use("/announcements",Oa());nr.get("/announcements",async e=>{let t=await d.select({id:Je.id,version:Je.version,releaseDate:Je.releaseDate,subject:Je.subject,status:Je.status,recipientCount:Je.recipientCount,sentAt:Je.sentAt,sentBy:Je.sentBy,error:Je.error,createdAt:Je.createdAt,updatedAt:Je.updatedAt}).from(Je).orderBy(RO(Je.createdAt));return e.json({announcements:t})});nr.get("/announcements/:id",async e=>{let t=e.req.param("id");if(!Xr.string().uuid().safeParse(t).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let[n]=await d.select().from(Je).where(tr(Je.id,t));if(!n)return e.json({error:"Announcement not found",code:"NOT_FOUND"},404);let r=await d.select({status:mo.status,count:TI`count(*)::int`}).from(mo).where(tr(mo.announcementId,t)).groupBy(mo.status),o={};for(let s of r)o[s.status]=s.count;return e.json({...n,deliveryCounts:o})});nr.get("/announcements/:id/recipients/count",async e=>{let t=e.req.param("id");if(!Xr.string().uuid().safeParse(t).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let n=await jO();return e.json({count:n})});async function jO(){let[e]=await d.select({count:TI`count(*)::int`}).from(en).innerJoin(R,tr(R.id,en.userId)).where(EI(tr(en.productAnnouncements,!0),kO(R.email)));return e?.count??0}u(jO,"countOptedInRecipients");var xI=u(e=>e.includes("{{unsubscribe_url}}"),"hasUnsubscribePlaceholder"),NO=Xr.object({subject:Xr.string().min(1).max(500).optional(),htmlBody:Xr.string().min(1).refine(xI,{message:"htmlBody must contain the {{unsubscribe_url}} placeholder"}).optional(),textBody:Xr.string().min(1).refine(xI,{message:"textBody must contain the {{unsubscribe_url}} placeholder"}).optional()});nr.patch("/announcements/:id",async e=>{let t=e.req.param("id");if(!Xr.string().uuid().safeParse(t).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let n;try{n=await e.req.json()}catch{return e.json({error:"Invalid JSON",code:"VALIDATION_ERROR"},400)}let r=NO.safeParse(n);if(!r.success)return e.json({error:r.error.flatten().fieldErrors,code:"VALIDATION_ERROR"},400);let o=r.data;if(Object.keys(o).length===0)return e.json({error:"No fields to update",code:"VALIDATION_ERROR"},400);let[s]=await d.select().from(Je).where(tr(Je.id,t));if(!s)return e.json({error:"Announcement not found",code:"NOT_FOUND"},404);if(s.status!=="draft")return e.json({error:"Can only edit draft announcements",code:"INVALID_STATE",status:s.status},409);let[i]=await d.update(Je).set({...o.subject!==void 0?{subject:o.subject}:{},...o.htmlBody!==void 0?{htmlBody:o.htmlBody}:{},...o.textBody!==void 0?{textBody:o.textBody}:{},updatedAt:new Date}).where(tr(Je.id,t)).returning();return e.json(i)});nr.post("/announcements/:id/send",async e=>{let t=e.get("userId");if(!t)return e.json({error:"Unauthenticated",code:"UNAUTHENTICATED"},401);let n=e.req.param("id");if(!Xr.string().uuid().safeParse(n).success)return e.json({error:"Invalid id",code:"VALIDATION_ERROR"},400);let r=await d.update(Je).set({status:"queued",sentBy:t,updatedAt:new Date}).where(EI(tr(Je.id,n),tr(Je.status,"draft"))).returning();if(r.length===0){let[o]=await d.select().from(Je).where(tr(Je.id,n));return o?e.json({error:`Cannot send from status='${o.status}' (must be 'draft')`,code:"INVALID_STATE",status:o.status},409):e.json({error:"Announcement not found",code:"NOT_FOUND"},404)}try{let{jobId:o,noLiveWorker:s}=await Fy({announcementId:n,userId:t});return e.json({jobId:o,noLiveWorker:s,announcement:r[0]})}catch(o){return await d.update(Je).set({status:"draft",sentBy:null,updatedAt:new Date}).where(tr(Je.id,n)).catch(()=>{}),e.json({error:o.message??"Failed to enqueue announcement",code:"ENQUEUE_FAILED"},500)}});import{Hono as CO}from"hono";import{inArray as kI,sql as RI}from"drizzle-orm";var za=new CO;function jI(e){let t;try{t=decodeURIComponent(e)}catch{return[]}let n=t.replace(/=+$/,"").replaceAll("+","-").replaceAll("/","_");return t===n?[t]:[t,n]}u(jI,"tokenCandidates");za.get("/:token",async e=>{let t=e.req.param("token");if(!t||t.length<8)return e.json({error:"invalid_token"},404);let n=jI(t);if(n.length===0)return e.json({error:"invalid_token"},404);let[r]=await d.select({productAnnouncements:en.productAnnouncements,unsubscribedAt:en.unsubscribedAt}).from(en).where(kI(en.unsubscribeToken,n)).limit(1);return r?e.json({valid:!0,alreadyUnsubscribed:r.productAnnouncements===!1}):e.json({error:"invalid_token"},404)});za.post("/:token",async e=>{let t=e.req.param("token");if(!t||t.length<8)return e.json({error:"invalid_token"},404);let n=jI(t);return n.length===0?e.json({error:"invalid_token"},404):(await d.update(en).set({productAnnouncements:!1,unsubscribedAt:RI`now()`,updatedAt:RI`now()`}).where(kI(en.unsubscribeToken,n)).returning({userId:en.userId})).length===0?e.json({error:"invalid_token"},404):e.json({ok:!0})});import{createHash as PO}from"node:crypto";async function NI(){let e=[],t=0,n=0,r=0;for(let[o,s]of Object.entries(La)){t++;for(let i of s.docs)try{let c=await fetch(i.url,{headers:{"User-Agent":"RuleMetric-Research/1.0"}});if(!c.ok){e.push({provider:o,url:i.url,message:`HTTP ${c.status}`});continue}let a=await c.text(),l=PO("sha256").update(a).digest("hex"),p=!0,m=[],y=null;try{m=i.parse(a)}catch(h){p=!1,y=h instanceof Error?h.message:String(h)}if((await d.insert(bt).values({provider:o,docUrl:i.url,contentHash:l,content:a,parseSuccess:p,parseErrors:y?[y]:null}).onConflictDoNothing({target:[bt.provider,bt.docUrl,bt.contentHash]}).returning({id:bt.id})).length===1&&p){for(let h of m)await d.insert(pe).values({provider:o,plan:h.plan,limitType:h.limitType,value:String(h.value),unit:h.unit,comparator:h.comparator??"=",resetsAt:null,sourceType:"official_docs",sourceUrl:i.url,sourceEvidence:{snapshotHash:l},confidence:"0.85",userId:null}),r++;n++}}catch(c){e.push({provider:o,url:i.url,message:c instanceof Error?c.message:String(c)})}}return{providers_scraped:t,snapshots_inserted:n,observations_inserted:r,errors:e}}u(NI,"scrapeProviderDocs");var OO=360*60*1e3,CI=!1;function PI(){if(CI)return{stop:u(()=>{},"stop")};CI=!0;let e=setTimeout(()=>{NI().then(n=>{n.errors.length>0?console.warn("[research] scrape completed with errors:",n):console.log(`[research] scrape ok: providers=${n.providers_scraped}, snapshots+=${n.snapshots_inserted}, observations+=${n.observations_inserted}`)}).catch(n=>console.warn("[research] scrape failed:",n))},3e4),t=setInterval(()=>{NI().then(n=>{n.errors.length>0&&console.warn("[research] scrape completed with errors:",n)}).catch(n=>console.warn("[research] scrape failed:",n))},OO);return{stop:u(()=>{clearTimeout(e),clearInterval(t)},"stop")}}u(PI,"startScrapeInterval");var B=new LO,BO=process.env.ALLOWED_ORIGINS?.split(",")??["http://localhost:5174","http://localhost:5175"];B.use("*",$O({origin:u(e=>e?BO.includes(e)?e:"":"*","origin"),allowMethods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowHeaders:["Authorization","Content-Type"],credentials:!0}));B.use("*",Cd());B.use("*",oh());B.use("/api/*",qO({maxSize:10*1024*1024}));B.use("*",rh);B.use("/auth/login",$i(900*1e3,10));var LI=$i(60*1e3,10);B.use("/api/auth/api-keys",LI);B.use("/api/auth/api-keys/*",LI);B.use("/api/invitations/*",$i(60*1e3,30));B.use("/api/telemetry/cli-error",$i(60*1e3,60));B.route("/",as);B.route("/api",Hc);B.route("/",ss);B.route("/",Ma);B.route("/api",Fc);B.route("/api",ud);B.route("/",ld);B.use("/api/*",Zg);B.use("/api/*",th);B.use("/api/sessions/:id/context-snapshots",Ui);B.use("/api/sessions/:id/events",Ui);B.use("/api/sessions/import",Ui);B.use("/api/internal/research/observe",Ui);B.use("/api/*",async(e,t)=>{let n=e.req.path,r=e.req.method,o=r==="GET"&&n.startsWith("/api/invitations/")&&n!=="/api/invitations/accept",s=r==="GET"&&n==="/api/cli/latest-version",i=r==="POST"&&n==="/api/skills/sync-public",c=(r==="GET"||r==="POST")&&n.startsWith("/api/unsubscribe/");return o||s||i||c?t():Yg(e,t)});B.route("/api",dn);B.route("/api",Gc);B.route("/api",Kc);B.route("/api",Yc);B.route("/api",Ji);B.route("/api",Gi);B.route("/api",Ki);B.route("/api",Xi);B.route("/api",Zc);B.route("/api",Vn);B.route("/api",At);B.route("/api",aa);B.route("/api",Jn);B.route("/api",Su);B.route("/api",vs);B.route("/api",Eu);B.route("/api",Ao);B.route("/api",Is);B.route("/api",xs);B.route("/api",Eo);B.route("/api",Es);B.route("/api",mr);B.route("/api",Ro);B.route("/api",Ns);B.route("/api",_a);B.route("/api",Ps);B.route("/api",Wr);B.route("/api",Bu);B.route("/api",hr);B.route("/api",An);B.route("/api",Ms);B.route("/api",vr);B.route("/api",Jr);B.route("/api",xa);B.route("/api",qs);B.route("/api",Gr);B.route("/api",Qn);B.route("/api",Mo);B.route("/api",lt);B.route("/api/invitations",ja);B.route("/api",Pa);B.route("/api",sn);B.route("/api",cd);B.route("/api",Da);B.route("/api",$n);B.route("/api",Ua);B.route("/api",Ha);B.route("/api",hd);B.route("/api",_d);B.route("/api",Ks);B.route("/api",nr);B.route("/api/unsubscribe",za);B.route("/api",dd);var FO=setTimeout(()=>{Yu().catch(()=>{})},5e3),HO=PI(),$I=[{stop:u(()=>clearTimeout(FO),"stop")},HO],WO=Ys.dirname(MO(import.meta.url)),sf=process.env.WEB_DIST_PATH??Ys.resolve(WO,"../../../apps/web/dist");if(Va.existsSync(sf)){let e=u(async t=>{let n=Ys.join(sf,"index.html");if(!Va.existsSync(n))return t.notFound();let{stampRuntimeConfig:r}=await Promise.resolve().then(()=>(MI(),DI));return t.html(r(Va.readFileSync(n,"utf-8")))},"serveIndex");B.get("/",e),B.get("/index.html",e),B.use("/*",UO({root:sf,rewriteRequestPath:u(t=>t,"rewriteRequestPath")})),B.get("*",e)}B.onError(Xg);import{sql as rr}from"drizzle-orm";var zO=300*1e3,VO="reconciler: lease expired with attempts exhausted \u2014 agent likely crashed mid-run",JO="reconciler: in-flight row had no lease and attempts were exhausted \u2014 unclaimable and unswept until recovered",Xs=1,GO=["eval_jobs","insights_jobs","launch_jobs","session_send_jobs","agent_jobs"];function Qs(){return rr.join(Object.entries(rf).map(([e,t])=>rr`WHEN ${e} THEN ${t}::int`),rr` `)}u(Qs,"maxAttemptsCase");async function KO(e){let t=await d.execute(rr`
|
|
1184
1184
|
UPDATE ${rr.raw(e)}
|
|
1185
1185
|
SET status = 'failed',
|
|
1186
|
-
error = ${
|
|
1186
|
+
error = ${VO},
|
|
1187
1187
|
completed_at = now(),
|
|
1188
1188
|
claimed_by = NULL,
|
|
1189
1189
|
claimed_at = NULL,
|
|
@@ -1192,8 +1192,8 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1192
1192
|
WHERE status IN ('claimed', 'running')
|
|
1193
1193
|
AND claimed_by IS NOT NULL
|
|
1194
1194
|
AND lease_expires_at < now()
|
|
1195
|
-
AND attempts >= (CASE task_kind ${
|
|
1196
|
-
AND lease_recoveries >= ${
|
|
1195
|
+
AND attempts >= (CASE task_kind ${Qs()} ELSE 3 END)
|
|
1196
|
+
AND lease_recoveries >= ${Xs}
|
|
1197
1197
|
RETURNING id
|
|
1198
1198
|
`),n=await d.execute(rr`
|
|
1199
1199
|
UPDATE ${rr.raw(e)}
|
|
@@ -1211,28 +1211,28 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1211
1211
|
`),r=await d.execute(rr`
|
|
1212
1212
|
UPDATE ${rr.raw(e)}
|
|
1213
1213
|
SET status = CASE
|
|
1214
|
-
WHEN attempts >= (CASE task_kind ${
|
|
1215
|
-
AND lease_recoveries >= ${
|
|
1214
|
+
WHEN attempts >= (CASE task_kind ${Qs()} ELSE 3 END)
|
|
1215
|
+
AND lease_recoveries >= ${Xs} THEN 'failed'
|
|
1216
1216
|
ELSE 'pending'
|
|
1217
1217
|
END,
|
|
1218
1218
|
attempts = CASE
|
|
1219
|
-
WHEN attempts >= (CASE task_kind ${
|
|
1220
|
-
AND lease_recoveries >= ${
|
|
1219
|
+
WHEN attempts >= (CASE task_kind ${Qs()} ELSE 3 END)
|
|
1220
|
+
AND lease_recoveries >= ${Xs} THEN attempts
|
|
1221
1221
|
ELSE GREATEST(attempts - 1, 0)
|
|
1222
1222
|
END,
|
|
1223
1223
|
lease_recoveries = CASE
|
|
1224
|
-
WHEN attempts >= (CASE task_kind ${
|
|
1225
|
-
AND lease_recoveries >= ${
|
|
1224
|
+
WHEN attempts >= (CASE task_kind ${Qs()} ELSE 3 END)
|
|
1225
|
+
AND lease_recoveries >= ${Xs} THEN lease_recoveries
|
|
1226
1226
|
ELSE lease_recoveries + 1
|
|
1227
1227
|
END,
|
|
1228
1228
|
error = CASE
|
|
1229
|
-
WHEN attempts >= (CASE task_kind ${
|
|
1230
|
-
AND lease_recoveries >= ${
|
|
1229
|
+
WHEN attempts >= (CASE task_kind ${Qs()} ELSE 3 END)
|
|
1230
|
+
AND lease_recoveries >= ${Xs} THEN ${JO}
|
|
1231
1231
|
ELSE error
|
|
1232
1232
|
END,
|
|
1233
1233
|
completed_at = CASE
|
|
1234
|
-
WHEN attempts >= (CASE task_kind ${
|
|
1235
|
-
AND lease_recoveries >= ${
|
|
1234
|
+
WHEN attempts >= (CASE task_kind ${Qs()} ELSE 3 END)
|
|
1235
|
+
AND lease_recoveries >= ${Xs} THEN now()
|
|
1236
1236
|
ELSE completed_at
|
|
1237
1237
|
END,
|
|
1238
1238
|
claimed_at = NULL,
|
|
@@ -1242,7 +1242,7 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1242
1242
|
AND claimed_by IS NULL
|
|
1243
1243
|
AND updated_at < now() - interval '15 minutes'
|
|
1244
1244
|
RETURNING id
|
|
1245
|
-
`);return t.length+n.length+r.length}u(
|
|
1245
|
+
`);return t.length+n.length+r.length}u(KO,"reclaimExpiredLeases");async function YO(){return(await d.execute(rr`
|
|
1246
1246
|
UPDATE memory_experiments me
|
|
1247
1247
|
SET status = 'failed',
|
|
1248
1248
|
error = 'reconciler: worker died mid-experiment (backing job terminal, row left running)',
|
|
@@ -1255,12 +1255,12 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1255
1255
|
AND aj.status IN ('failed', 'completed')
|
|
1256
1256
|
)
|
|
1257
1257
|
RETURNING me.id
|
|
1258
|
-
`)).length}u(
|
|
1258
|
+
`)).length}u(YO,"failStrandedMemoryExperiments");function qI(){let e=setTimeout(()=>{n()},3e4),t=setInterval(()=>{n()},zO);async function n(){try{let r=[];for(let o of GO)try{let s=await KO(o);s>0&&r.push({table:o,count:s})}catch(s){console.error(`[reconciler] ${o} lease sweep failed:`,s instanceof Error?s.stack:s)}if(r.length>0){let o=r.map(s=>`${s.table}=${s.count}`).join(" ");console.log(`[reconciler] reclaimed expired leases: ${o}`)}try{let o=await YO();o>0&&console.log(`[reconciler] failed ${o} stranded memory experiment(s)`)}catch(o){console.error("[reconciler] memory-experiment sweep failed:",o instanceof Error?o.stack:o)}}catch(r){console.error("[reconciler] unexpected error:",r instanceof Error?r.stack:r)}}return u(n,"runOnce"),{stop(){clearTimeout(e),clearInterval(t)}}}u(qI,"startReconciler");import{and as QO,eq as cf,sql as yd}from"drizzle-orm";import{and as UI,eq as af,inArray as XO,sql as BI}from"drizzle-orm";async function FI(e,t){let n=new Map;if(t.length===0)return n;let r=t.map(m=>m.id),o=new Map(t.map(m=>[m.id,m.version])),i=(await d.select({id:f.id,projectId:f.projectId,outcome:BI`${f.analysis}->>'outcome'`}).from(f).where(UI(af(f.userId,e),BI`${f.analysis} is not null`)).orderBy(f.id)).map(m=>({id:m.id,key:m.projectId??"(no-project)",score:la(m.outcome)})).filter(m=>m.score!=null),c=await d.select({sessionId:X.sessionId,treatmentId:X.treatmentId,treatmentVersion:X.treatmentVersion}).from(X).where(UI(af(X.userId,e),af(X.treatmentType,"memory"),XO(X.treatmentId,r))),a=new Map,l=new Map;for(let m of c){let y=m.treatmentVersion===o.get(m.treatmentId)?a:l,v=y.get(m.treatmentId);v||(v=new Set,y.set(m.treatmentId,v)),v.add(m.sessionId)}let p=u(m=>{let y=a.get(m);if(!y||y.size===0)return"insufficient";let v=l.get(m),g=new Map;for(let h of i){if(v?.has(h.id)&&!y.has(h.id))continue;let w=g.get(h.key);w||(w={key:h.key,withScores:[],withoutScores:[]},g.set(h.key,w)),(y.has(h.id)?w.withScores:w.withoutScores).push(h.score)}return xo(mn([...g.values()],{iterations:1e3}))},"effectOf");for(let m of t)n.set(m.id,p(m.id));return n}u(FI,"computeTrustClasses");var ZO=1800*1e3;async function eD(e,t){if(t.length===0)return;let n=yd.join(t.map(r=>yd`(${r.id}::uuid, ${r.trustClass}::text, ${r.version}::int)`),yd`, `);await d.execute(yd`
|
|
1259
1259
|
update memories m
|
|
1260
1260
|
set trust_class = v.cls, trust_version = v.ver, trust_computed_at = now()
|
|
1261
1261
|
from (values ${n}) as v(id, cls, ver)
|
|
1262
1262
|
where m.id = v.id and m.user_id = ${e}
|
|
1263
|
-
`)}u(
|
|
1263
|
+
`)}u(eD,"applyMaterializedTrust");async function tD(e){let t=await d.select({id:$.id,version:$.version}).from($).where(QO(cf($.userId,e),cf($.status,"active")));if(t.length===0)return 0;let n=await FI(e,t),r=t.map(o=>({id:o.id,trustClass:n.get(o.id)??"insufficient",version:o.version}));return await eD(e,r),r.length}u(tD,"refreshMemoryTrustForUser");async function nD(){let e=await d.selectDistinct({userId:$.userId}).from($).where(cf($.status,"active")),t=0;for(let{userId:n}of e)try{t+=await tD(n)}catch(r){console.error(`[memory-trust-refresh] user ${n} failed:`,r instanceof Error?r.stack:r)}return{users:e.length,memories:t}}u(nD,"refreshAllMemoryTrust");function HI(){let e=setTimeout(()=>void n(),45e3),t=setInterval(()=>void n(),ZO);async function n(){try{let{users:r,memories:o}=await nD();o>0&&console.log(`[memory-trust-refresh] materialized ${o} memory class(es) across ${r} user(s)`)}catch(r){console.error("[memory-trust-refresh] sweep failed:",r instanceof Error?r.stack:r)}}return u(n,"runOnce"),{stop(){clearTimeout(e),clearInterval(t)}}}u(HI,"startMemoryTrustRefresh");import{sql as rD}from"drizzle-orm";var oD=30*6e4,WI=24,sD=6,zI="pipeline:usage_observations_stale";async function iD(){let e=await d.execute(rD`
|
|
1264
1264
|
WITH active_users AS (
|
|
1265
1265
|
SELECT user_id, count(*) AS sessions_24h
|
|
1266
1266
|
FROM sessions
|
|
@@ -1291,13 +1291,13 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1291
1291
|
LEFT JOIN latest_obs o ON o.user_id = a.user_id
|
|
1292
1292
|
LEFT JOIN first_seen f ON f.user_id = a.user_id
|
|
1293
1293
|
WHERE (o.last_observed IS NULL
|
|
1294
|
-
AND f.first_session < now() - make_interval(hours => ${
|
|
1295
|
-
OR o.last_observed < now() - make_interval(hours => ${
|
|
1294
|
+
AND f.first_session < now() - make_interval(hours => ${WI}))
|
|
1295
|
+
OR o.last_observed < now() - make_interval(hours => ${WI})
|
|
1296
1296
|
)
|
|
1297
1297
|
INSERT INTO alert_dispatches (user_id, alert_key, severity, channel, last_state)
|
|
1298
1298
|
SELECT
|
|
1299
1299
|
s.user_id,
|
|
1300
|
-
${
|
|
1300
|
+
${zI},
|
|
1301
1301
|
'soft',
|
|
1302
1302
|
'in_app',
|
|
1303
1303
|
jsonb_build_object(
|
|
@@ -1314,11 +1314,11 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1314
1314
|
WHERE NOT EXISTS (
|
|
1315
1315
|
SELECT 1 FROM alert_dispatches d
|
|
1316
1316
|
WHERE d.user_id = s.user_id
|
|
1317
|
-
AND d.alert_key = ${
|
|
1318
|
-
AND d.last_dispatched_at > now() - make_interval(hours => ${
|
|
1317
|
+
AND d.alert_key = ${zI}
|
|
1318
|
+
AND d.last_dispatched_at > now() - make_interval(hours => ${sD})
|
|
1319
1319
|
)
|
|
1320
1320
|
RETURNING user_id, id, last_state->>'message' AS message
|
|
1321
|
-
`);e.length>0&&console.log(`[usage-staleness] dispatched stale-pipeline alert for ${e.length} user(s)`);for(let t of e)try{await
|
|
1321
|
+
`);e.length>0&&console.log(`[usage-staleness] dispatched stale-pipeline alert for ${e.length} user(s)`);for(let t of e)try{await Vs({userId:t.user_id,dispatchId:t.id,severity:"soft",message:t.message??"Usage tracking looks broken \u2014 open /usage.",title:"Usage tracking issue"})}catch(n){console.error("[usage-staleness] bell mirror failed:",n instanceof Error?n.message:n)}return e.length}u(iD,"checkUsageStalenessOnce");function VI(){let e=setTimeout(()=>{n()},6e4),t=setInterval(()=>{n()},oD);async function n(){try{await iD()}catch(r){console.error("[usage-staleness] check failed:",r instanceof Error?r.stack:r)}}return u(n,"runOnce"),{stop:u(()=>{clearTimeout(e),clearInterval(t)},"stop")}}u(VI,"startUsageStalenessChecker");import{sql as aD}from"drizzle-orm";var cD=30*6e4,wd=24,uD=6,JI="pipeline:session_capture_stale";async function dD(){let e=await d.execute(aD`
|
|
1322
1322
|
WITH active_users AS (
|
|
1323
1323
|
SELECT user_id, max(last_seen) AS last_observed,
|
|
1324
1324
|
array_agg(DISTINCT signal) AS signals
|
|
@@ -1328,13 +1328,13 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1328
1328
|
FROM limit_observations
|
|
1329
1329
|
WHERE source_type = 'oauth_usage'
|
|
1330
1330
|
AND user_id IS NOT NULL
|
|
1331
|
-
AND observed_at > now() - make_interval(hours => ${
|
|
1331
|
+
AND observed_at > now() - make_interval(hours => ${wd})
|
|
1332
1332
|
GROUP BY user_id
|
|
1333
1333
|
UNION ALL
|
|
1334
1334
|
SELECT user_id, max(last_heartbeat), 'worker heartbeat'
|
|
1335
1335
|
FROM worker_connections
|
|
1336
1336
|
WHERE worker_type = 'cli-worker'
|
|
1337
|
-
AND last_heartbeat > now() - make_interval(hours => ${
|
|
1337
|
+
AND last_heartbeat > now() - make_interval(hours => ${wd})
|
|
1338
1338
|
GROUP BY user_id
|
|
1339
1339
|
UNION ALL
|
|
1340
1340
|
-- Beacons are unauthenticated (no user_id); attribute via the most
|
|
@@ -1350,7 +1350,7 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1350
1350
|
) owner ON true
|
|
1351
1351
|
WHERE e.event = 'hook_capture_failed'
|
|
1352
1352
|
AND e.device_id IS NOT NULL
|
|
1353
|
-
AND e.created_at > now() - make_interval(hours => ${
|
|
1353
|
+
AND e.created_at > now() - make_interval(hours => ${wd})
|
|
1354
1354
|
GROUP BY owner.user_id
|
|
1355
1355
|
) signal_union
|
|
1356
1356
|
GROUP BY user_id
|
|
@@ -1369,12 +1369,12 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1369
1369
|
FROM active_users a
|
|
1370
1370
|
LEFT JOIN latest_session s ON s.user_id = a.user_id
|
|
1371
1371
|
WHERE s.last_session IS NULL
|
|
1372
|
-
OR s.last_session < now() - make_interval(hours => ${
|
|
1372
|
+
OR s.last_session < now() - make_interval(hours => ${wd})
|
|
1373
1373
|
)
|
|
1374
1374
|
INSERT INTO alert_dispatches (user_id, alert_key, severity, channel, last_state)
|
|
1375
1375
|
SELECT
|
|
1376
1376
|
s.user_id,
|
|
1377
|
-
${
|
|
1377
|
+
${JI},
|
|
1378
1378
|
'soft',
|
|
1379
1379
|
'in_app',
|
|
1380
1380
|
jsonb_build_object(
|
|
@@ -1393,11 +1393,11 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1393
1393
|
WHERE NOT EXISTS (
|
|
1394
1394
|
SELECT 1 FROM alert_dispatches d
|
|
1395
1395
|
WHERE d.user_id = s.user_id
|
|
1396
|
-
AND d.alert_key = ${
|
|
1397
|
-
AND d.last_dispatched_at > now() - make_interval(hours => ${
|
|
1396
|
+
AND d.alert_key = ${JI}
|
|
1397
|
+
AND d.last_dispatched_at > now() - make_interval(hours => ${uD})
|
|
1398
1398
|
)
|
|
1399
1399
|
RETURNING user_id, id, last_state->>'message' AS message
|
|
1400
|
-
`);e.length>0&&console.log(`[capture-staleness] dispatched stale-capture alert for ${e.length} user(s)`);for(let t of e)try{await
|
|
1400
|
+
`);e.length>0&&console.log(`[capture-staleness] dispatched stale-capture alert for ${e.length} user(s)`);for(let t of e)try{await Vs({userId:t.user_id,dispatchId:t.id,severity:"soft",message:t.message??"Session capture looks broken \u2014 check the proxy.",title:"Session capture issue"})}catch(n){console.error("[capture-staleness] bell mirror failed:",n instanceof Error?n.message:n)}return e.length}u(dD,"checkCaptureStalenessOnce");function GI(){let e=setTimeout(()=>{n()},9e4),t=setInterval(()=>{n()},cD);async function n(){try{await dD()}catch(r){console.error("[capture-staleness] check failed:",r instanceof Error?r.stack:r)}}return u(n,"runOnce"),{stop:u(()=>{clearTimeout(e),clearInterval(t)},"stop")}}u(GI,"startCaptureStalenessChecker");import{sql as KI}from"drizzle-orm";var lD=900*1e3,YI=6,XI=60,pD=KI`array['user_message','tool_call','tool_result']`;async function mD(){return[...await d.execute(KI`
|
|
1401
1401
|
WITH session_stats AS (
|
|
1402
1402
|
SELECT s.id,
|
|
1403
1403
|
s.external_session_id,
|
|
@@ -1405,10 +1405,10 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1405
1405
|
(
|
|
1406
1406
|
SELECT MAX(timestamp) FROM session_events e
|
|
1407
1407
|
WHERE e.session_id = s.id
|
|
1408
|
-
AND e.event_type = ANY(${
|
|
1408
|
+
AND e.event_type = ANY(${pD})
|
|
1409
1409
|
) AS last_hook_event
|
|
1410
1410
|
FROM sessions s
|
|
1411
|
-
WHERE s.started_at > now() - (${
|
|
1411
|
+
WHERE s.started_at > now() - (${YI}::int * interval '1 hour')
|
|
1412
1412
|
)
|
|
1413
1413
|
SELECT ss.id AS "sessionId",
|
|
1414
1414
|
ss.external_session_id AS "externalSessionId",
|
|
@@ -1419,8 +1419,8 @@ end`;ct.get("/orgs/:slug",At(["owner","admin","member"]),async e=>{let t=e.get("
|
|
|
1419
1419
|
FROM session_stats ss
|
|
1420
1420
|
JOIN context_snapshots cs ON cs.session_id = ss.id
|
|
1421
1421
|
WHERE ss.last_hook_event IS NOT NULL
|
|
1422
|
-
AND cs.captured_at > ss.last_hook_event + (${
|
|
1422
|
+
AND cs.captured_at > ss.last_hook_event + (${XI}::int * interval '1 second')
|
|
1423
1423
|
GROUP BY ss.id, ss.external_session_id, ss.tool
|
|
1424
1424
|
HAVING COUNT(cs.id) > 0
|
|
1425
|
-
`)]}u(
|
|
1426
|
-
`)){let t=e.trim();if(!t||t.startsWith("#"))continue;let n=t.indexOf("=");if(n===-1)continue;let r=t.slice(0,n),o=t.slice(n+1);process.env[r]||(process.env[r]=o)}process.env.PG_APPLICATION_NAME||="rulemetric-api";var
|
|
1425
|
+
`)]}u(mD,"auditPollutionOnce");function QI(){let e=setTimeout(()=>{n()},6e4),t=setInterval(()=>{n()},lD);async function n(){try{let r=await mD();if(r.length===0)return;for(let o of r)console.warn(`[pollution-auditor] suspected_pollution session_id=${o.sessionId} external_session_id=${o.externalSessionId??"(null)"} tool=${o.tool} polluted_snapshots=${o.pollutedSnapshots} first_polluted_at=${o.firstPollutedAt} last_polluted_at=${o.lastPollutedAt}`);console.warn(`[pollution-auditor] pass summary: ${r.length} sessions flagged (window=${YI}h, grace=${XI}s)`)}catch(r){console.error("[pollution-auditor] pass failed:",r instanceof Error?r.stack:r)}}return u(n,"runOnce"),{stop(){clearTimeout(e),clearInterval(t)}}}u(QI,"startPollutionAuditor");var hD=Id.dirname(fD(import.meta.url)),ZI=Id.resolve(hD,"../../../.env.local");if(vd.existsSync(ZI))for(let e of vd.readFileSync(ZI,"utf-8").split(`
|
|
1426
|
+
`)){let t=e.trim();if(!t||t.startsWith("#"))continue;let n=t.indexOf("=");if(n===-1)continue;let r=t.slice(0,n),o=t.slice(n+1);process.env[r]||(process.env[r]=o)}process.env.PG_APPLICATION_NAME||="rulemetric-api";var _D=Od({serviceName:"rulemetric-api"});_D?console.log("[sentry] error capture enabled"):process.env.NODE_ENV==="production"&&console.log("[sentry] no SENTRY_DSN \u2014 error capture disabled");var uf=Rd({serviceName:"rulemetric-api"});console.log(uf==="otlp"?`[otel] traces exporting to ${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}`:uf==="console"?"[otel] traces printing to stdout (set OTEL_EXPORTER_OTLP_ENDPOINT to ship to a backend)":uf==="silent"?"[otel] traces enabled, span export OFF (OTEL_SPAN_EXPORT=none \u2014 no stdout span dump)":"[otel] disabled (TELEMETRY_ENABLED=false)");var yD=new Set(["CONNECT_TIMEOUT","ETIMEDOUT","ENOTFOUND","ECONNRESET","ECONNREFUSED","EAI_AGAIN","EPIPE"]);process.on("unhandledRejection",e=>{let t=os(e);console.error(`[guard] unhandledRejection${t?` code=${t}`:""}: ${e instanceof Error?e.message:String(e)}`),Un(e,{tags:{source:"unhandledRejection",code:t??"unknown"}})});process.on("uncaughtException",e=>{let t=os(e);if(t&&yD.has(t)){console.error(`[guard] uncaughtException (transient net code=${t}) \u2014 surviving: ${e.message}`),Un(e,{tags:{source:"uncaughtException",code:t}});return}console.error("[guard] uncaughtException (fatal):",e),Un(e,{tags:{source:"uncaughtException",code:t??"unknown"}}),Promise.allSettled([ii(2e3),Di()]).finally(()=>process.exit(1))});var df=Number(process.env.API_PORT)||3e3;console.log(`RuleMetric API starting on port ${df}`);console.log(`[auth] JWT verification: ${process.env.SUPABASE_JWT_SECRET?"local (fast path)":"remote getUser (set SUPABASE_JWT_SECRET to enable fast path)"}`);{let e=Ql();e.error&&console.warn(`[deployment] ${e.error}`);let t=process.env.DATABASE_URL?.match(/:(\d+)\/[^/]*$/)?.[1];e.mode==="local"?console.log(`[db] deployment=local (${e.source}) \u2014 direct postgres :${t??"?"}, pooler heuristics disabled`):console.log(`[db] deployment=cloud \u2014 pooler port ${t??"?"} \u2014 ${t==="6543"?"transaction mode (correct)":t==="5432"?"SESSION mode \u2014 WRONG for the always-on API (15-slot cap!)":"unknown"}`)}var t0,Qr=[],e0=!1;async function wD(){let e=gD({fetch:B.fetch,hostname:"0.0.0.0",port:df});t0=e,e.keepAliveTimeout=65e3,e.headersTimeout=66e3,console.log(`RuleMetric API running at http://localhost:${df} (keepAliveTimeout=65s)`),Jg().then(t=>console.log(`[auth] JWKS prime ${t?"ok":"deferred (will fetch on first auth)"}`)),Qr.push(qI()),Qr.push(HI()),mu()&&Qy(),fd()&&aI(),Qr.push(VI()),Qr.push(GI()),Qr.push(ch()),Qr.push(QI()),Qr.push(...$I)}u(wD,"start");wD().catch(e=>{console.error("Failed to start API:",e),Un(e,{tags:{phase:"boot",source:"start"}}),Promise.allSettled([ii(2e3),Di()]).finally(()=>process.exit(1))});async function n0(){if(!e0){e0=!0;for(let e of Qr)try{e.stop()}catch{}try{t0?.close?.()}catch{}try{await Zy(5e3)}catch{}try{await cI(5e3)}catch{}await Promise.allSettled([kd(),ii(2e3),Di()]),process.exit(0)}}u(n0,"gracefulShutdown");process.on("SIGTERM",n0);process.on("SIGINT",n0);
|