opencode-metis 0.1.4 → 0.1.5
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/plugin.cjs +4 -4
- package/package.json +1 -1
package/dist/plugin.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var T=Object.defineProperty;var
|
|
2
|
-
`)}async function k(e,t,o,n){if(a("Session idle"),!!
|
|
3
|
-
`)}async function
|
|
4
|
-
`)}function
|
|
1
|
+
"use strict";var T=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var H=Object.prototype.hasOwnProperty;var q=(e,t)=>{for(var o in t)T(e,o,{get:t[o],enumerable:!0})},J=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of G(t))!H.call(e,r)&&r!==o&&T(e,r,{get:()=>t[r],enumerable:!(n=B(t,r))||n.enumerable});return e};var K=e=>J(T({},"__esModule",{value:!0}),e);var Ne={};q(Ne,{default:()=>W});module.exports=K(Ne);var b=require("child_process");function a(e){let t=e.replace(/"/g,'\\"');(0,b.exec)(`osascript -e 'display notification "${t}" with title "opencode"'`)}var z=3e3;async function I(e,t,o,n){a("Session started!");let r=`${t}/api/context/inject?project=${encodeURIComponent(e.project.name)}`;try{let i=await fetch(r,{signal:AbortSignal.timeout(z)});if(!i.ok){e.client.app.log("warn","Failed to load memory context",{status:i.status});return}let s=await i.json();s.context&&(n.messages=n.messages??[],n.messages.push({role:"system",content:s.context}))}catch(i){e.client.app.log("warn","Memory context injection failed",{error:i instanceof Error?i.message:String(i)})}}var V=15e3,X=200;async function O(e,t,o,n){a(`Tool completed: ${o.tool}`),Y(e,t,o,n).catch(r=>{e.client.app.log("warn","Observation capture failed",{error:r instanceof Error?r.message:String(r)})})}async function Y(e,t,o,n){let r={text:`Tool ${o.tool}: ${Q(o,n)}`,title:`${o.tool} execution`,project:e.project.name};await fetch(`${t}/api/memory/save`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:AbortSignal.timeout(V)})}function Q(e,t){let o=t.output??t.error??"",n=Z(e.input),r=o.slice(0,X).trim();return n&&r?`${n} -> ${r}`:n||r||"(no details)"}function Z(e){let t=Object.entries(e);return t.length===0?"":t.map(([o,n])=>`${o}=${String(n).slice(0,80)}`).join(", ")}var f=require("fs");var x=require("os"),l=require("path"),_=41777,v="127.0.0.1",ee=(0,l.join)((0,x.homedir)(),".config","opencode"),qe=(0,l.join)(ee,"opencode.json"),p=(0,l.join)((0,x.homedir)(),".config","opencode","memory"),te="memory.db",oe="settings.json",Je=(0,l.join)(p,"worker.pid");var Ke=(0,l.join)(p,te),C=(0,l.join)(p,oe),ze=(0,l.join)(p,"logs"),Ve=(0,l.join)(p,"models"),Xe=(0,l.join)(p,"vector-db");var E={workerPort:_,workerBind:v,chromaDbUrl:"http://localhost:8000",recencyWindowDays:90,retentionDays:365,tddEnabled:!0,fileLengthWarn:300,fileLengthCritical:500,testFilePatterns:["*.test.ts","*.spec.ts","*_test.go","test_*.py"],toolRedirectRules:[]},m=null;function g(){if(m!==null)return m;if(!(0,f.existsSync)(C))return m={...E},m;try{let e=(0,f.readFileSync)(C,"utf-8"),t=JSON.parse(e);return m={...E,...t},m}catch{return m={...E},m}}function w(){let e=g();return`http://${e.workerBind}:${e.workerPort}`}function ne(){let e=process.env.MEMORY_TOOL_REDIRECT_RULES;if(e!==void 0)try{return JSON.parse(e)}catch{return[]}return g().toolRedirectRules}function re(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.tool=="string"&&(t.action==="deny"||t.action==="redirect")}function ie(e){return e.message??`Tool '${e.tool}' is blocked by project configuration.`}function se(e){let t=e.message??`Tool '${e.tool}' has been redirected.`;return e.alternative?`${t} Suggested alternative: ${e.alternative}.`:t}function ae(e,t){t.blocked=!0,t.messages=[{role:"user",content:ie(e)}]}function ce(e,t){t.messages=[{role:"user",content:se(e)}]}async function $(e,t,o,n){a(`Tool executing: ${o.tool}`);let r=ne();for(let i of r)try{if(!re(i))throw new Error("Invalid rule: tool must be a string and action must be 'deny' or 'redirect'");if(i.tool!==o.tool)continue;i.action==="deny"?ae(i,n):ce(i,n);return}catch(s){e.client.app.log("warn","Tool redirect rule evaluation failed",{error:s instanceof Error?s.message:String(s),rule:JSON.stringify(i)})}}var le=15e3;function ue(e){let{context:t}=e;return t?!!(t.requested||t.investigated||t.learned||t.completed):!1}function me(e){let t=e.context??{};return["Session Summary:",`Requested: ${t.requested??"Not specified"}`,`Investigated: ${t.investigated??"Not specified"}`,`Learned: ${t.learned??"Not specified"}`,`Completed: ${t.completed??"Not specified"}`].join(`
|
|
2
|
+
`)}async function k(e,t,o,n){if(a("Session idle"),!!ue(o))try{let r=await fetch(`${t}/api/memory/save`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:"session-summary",title:`Session Summary: ${o.sessionId}`,text:me(o),project:e.project.name}),signal:AbortSignal.timeout(le)});r.ok||e.client.app.log("warn","Failed to save session summary",{status:r.status})}catch(r){e.client.app.log("warn","Session summary save failed",{error:r instanceof Error?r.message:String(r)})}}var S=require("fs"),y=require("path"),j=require("os");var pe=5e3;function de(){return process.env.OPENCODE_SESSIONS_DIR??(0,y.join)((0,j.homedir)(),".config","opencode","sessions")}function ge(e){return{sessionId:e.sessionId,activePlan:e.context?.activePlan??null,currentTask:e.context?.currentTask??null,summary:e.context?.summary??null,timestamp:new Date().toISOString(),type:"compaction-state"}}async function fe(e,t){try{return(await fetch(`${e}/api/memory/save`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),signal:AbortSignal.timeout(pe)})).ok}catch{return!1}}function ye(e,t){let o=(0,y.join)(de(),"sessions",e);(0,S.mkdirSync)(o,{recursive:!0});let n=(0,y.join)(o,"pre-compact-state.json");(0,S.writeFileSync)(n,JSON.stringify(t,null,2),"utf-8")}async function F(e,t,o,n){a("Session compacting...");let r=ge(o);if(!await fe(t,r))try{ye(o.sessionId,r)}catch(s){e.client.app.log("warn","Failed to write compaction fallback file",{error:s instanceof Error?s.message:String(s),sessionId:o.sessionId})}}var d=require("fs"),R=require("path"),D=require("os");var Se=5e3;function he(){return process.env.OPENCODE_SESSIONS_DIR??(0,R.join)((0,D.homedir)(),".config","opencode","sessions")}function Te(e){return(0,R.join)(he(),"sessions",e,"pre-compact-state.json")}function xe(e){let t=["[Memory Context Restored After Compaction]"];return e.activePlan&&t.push(`Active plan: ${e.activePlan}`),e.currentTask&&t.push(`Current task: ${e.currentTask}`),e.status&&t.push(`Status: ${e.status}`),e.summary&&t.push(`Recent context: ${e.summary}`),t.join(`
|
|
3
|
+
`)}async function Ce(e,t){let o=`${e}/api/context/inject?project=${encodeURIComponent(t)}`,n=await fetch(o,{signal:AbortSignal.timeout(Se)});return n.ok?(await n.json()).context??null:null}function Ee(e){let t=Te(e);if(!(0,d.existsSync)(t))return null;try{let o=(0,d.readFileSync)(t,"utf-8"),n=JSON.parse(o);return(0,d.unlinkSync)(t),n}catch{return null}}function M(e,t){e.messages=e.messages??[],e.messages.push({role:"user",content:t})}async function A(e,t,o,n){a("Session compacted!");try{let r=null;try{r=await Ce(t,e.project.name)}catch(s){if(s instanceof TypeError)throw s}if(r){M(n,r);return}let i=Ee(o.sessionId);if(i){let s=xe(i);M(n,s)}}catch(r){e.client.app.log("warn","Compacted state restore failed",{error:r instanceof Error?r.message:String(r),sessionId:o.sessionId})}}var N=require("fs"),c=require("path");var Re=300,Pe=500,be=["*.test.ts","*.spec.ts","*_test.go","test_*.py"];function Ie(e,t){let o=t.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${o}$`).test(e)}function Oe(e,t){let o=(0,c.basename)(e);return t.some(n=>Ie(o,n))}function _e(e,t){let o=(0,c.dirname)(e),n=(0,c.extname)(e),r=(0,c.basename)(e,n),i=[];for(let s of t)if(s.startsWith("*.")){let u=s.slice(1);i.push((0,c.join)(o,`${r}${u}`))}else if(s.endsWith("*")){let u=s.slice(0,-1);i.push((0,c.join)(o,`${u}${r}${n}`))}return i}function P(e,t){e.messages=e.messages??[],e.messages.push({role:"system",content:t})}function ve(e,t,o,n){if(Oe(t,o))return;let r=_e(t,o),i=e.project.root;r.some(u=>{let h=u.startsWith("/")?u:(0,c.join)(i,u);return(0,N.existsSync)(h)})||P(n,`\u26A0\uFE0F TDD Warning: No test file found for ${t}. Consider writing tests first (Red-Green-Refactor).`)}function we(e,t,o,n,r){if(t>n){P(r,`\u{1F6A8} File Length Critical: ${e} has ${t} lines. This file should be refactored.`);return}t>o&&P(r,`\u26A0\uFE0F File Length Warning: ${e} has ${t} lines. Consider splitting this file.`)}async function L(e,t,o,n){try{a(`File edited: ${o.filePath}`);let r=g(),i=o.testFilePatterns??r.testFilePatterns??be,s=o.fileLengthWarn??r.fileLengthWarn??Re,u=o.fileLengthCritical??r.fileLengthCritical??Pe;ve(e,o.filePath,i,n);let h=o.lineCount??0;we(o.filePath,h,s,u,n)}catch(r){e.client.app.log("warn","File edited check failed",{error:r instanceof Error?r.message:String(r),filePath:o.filePath})}}function U(e,t){return[$e(e,t),ke(e,t)]}function $e(e,t){return{name:"memory_search",description:"Search memory observations by topic or keyword",parameters:{query:{type:"string",description:"The search query or topic to look up in memory",required:!0},limit:{type:"number",description:"Maximum number of results to return (default 20)"},project:{type:"string",description:"Filter results to a specific project name"}},execute:o=>je(e,t,o)}}function ke(e,t){return{name:"memory_save",description:"Save an observation to memory for future reference",parameters:{text:{type:"string",description:"The observation text to save to memory",required:!0},title:{type:"string",description:"Optional short title summarising the observation"}},execute:o=>Fe(e,t,o)}}async function je(e,t,o){try{let n=Me(t,o),r=await fetch(n,{signal:AbortSignal.timeout(1e4)});if(!r.ok)return{result:`Error: Worker returned status ${r.status}`};let i=await r.json();return{result:De(i.results??[])}}catch(n){return e.client.app.log("warn","memory_search failed",{error:n instanceof Error?n.message:String(n)}),{result:`Error: ${n instanceof Error?n.message:String(n)}`}}}async function Fe(e,t,o){try{let n={text:o.text};o.title!==void 0&&(n.title=o.title);let r=await fetch(`${t}/api/memory/save`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),signal:AbortSignal.timeout(1e4)});if(!r.ok)return{result:`Error: Worker returned status ${r.status}`};let i=await r.json();return{result:Ae(i)}}catch(n){return e.client.app.log("warn","memory_save failed",{error:n instanceof Error?n.message:String(n)}),{result:`Error: ${n instanceof Error?n.message:String(n)}`}}}function Me(e,t){let o=new URLSearchParams;return o.set("query",String(t.query??"")),t.limit!==void 0&&o.set("limit",String(t.limit)),t.project!==void 0&&o.set("project",String(t.project)),`${e}/api/search?${o.toString()}`}function De(e){return e.length===0?"No results found for the given query.":e.map(t=>`[${t.id}] ${t.title} (${t.type}, ${t.project}) \u2014 ${t.summary}`).join(`
|
|
4
|
+
`)}function Ae(e){let t=e.id??"unknown",o=e.title??"(untitled)";return`Saved observation #${t}: "${o}"`}async function W(e){let t=w();return U(e,t),{"session.created":(o,n)=>I(e,t,o,n),"tool.execute.after":(o,n)=>O(e,t,o,n),"tool.execute.before":(o,n)=>$(e,t,o,n),"session.idle":(o,n)=>k(e,t,o,n),"experimental.session.compacting":(o,n)=>F(e,t,o,n),"session.compacted":(o,n)=>A(e,t,o,n),"file.edited":(o,n)=>L(e,t,o,n)}}
|