opencode-prompt-recorder 1.8.1 → 1.8.3

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/index.js CHANGED
@@ -1,17 +1,15 @@
1
- import{mkdir as j,appendFile as ee,writeFile as q,readFile as te,rename as Q}from"fs/promises";import{join as l,dirname as ne,basename as Ee}from"path";import{fileURLToPath as Ae}from"url";import{readFile as ye,rm as we}from"fs/promises";import{basename as $,dirname as w,join as U}from"path";import{fileURLToPath as he}from"url";var ke="opencode-prompt-recorder",K=!1;function Y(s,e){if(!e||K)return;K=!0;let n=new AbortController,o=setTimeout(()=>n.abort(),1e4);$e(n.signal).then(i=>{i.updated&&setTimeout(()=>{s.client.tui.showToast({body:{title:"Prompt Recorder \u66F4\u65B0",message:`${i.name} \u5DF2\u4ECE ${i.current} \u66F4\u65B0\u5230 ${i.latest}\uFF0C\u91CD\u542F OpenCode \u5B8C\u6210\u66F4\u65B0`,variant:"info"}})},5e3)}).catch(i=>{console.error("[prompt-recorder] auto-update check failed:",i)}).finally(()=>clearTimeout(o))}async function $e(s){let e=await be(ke);if(!e)return{updated:!1};let n=await F(U(e,"package.json"));if(!n?.name||!n.version)return{updated:!1};let o=await Pe(n.name,s);if(!o||!ve(o,n.version))return{updated:!1};let i=await De(e,n.name);if(!i)return{updated:!1};try{await we(i,{recursive:!0,force:!0})}catch{return{updated:!1,error:"remove_failed",name:n.name,current:n.version,latest:o}}return{updated:!0,name:n.name,current:n.version,latest:o}}async function be(s){let e=w(he(import.meta.url));for(;;){if((await F(U(e,"package.json")))?.name===s)return $(e)==="dist"?w(e):e;let o=w(e);if(o===e)return;e=o}}async function De(s,e){let n=w(s),o=$(n).startsWith("@")?w(n):n;if($(o)!=="node_modules")return;let i=w(o),c=await F(U(i,"package.json")),u=Me(i,e)??c?.dependencies?.[e];if(!(!u||!Se(u)))return i}function Me(s,e){if(e.startsWith("@")){let[i,c]=e.split("/");if(!i||!c||$(w(s))!==i)return;let u=`${c}@`,g=$(s);return g.startsWith(u)?g.slice(u.length):void 0}let n=`${e}@`,o=$(s);return o.startsWith(n)?o.slice(n.length):void 0}function Se(s){let e=s.trim();return e?!!(e==="latest"||e==="*"||/^[~^]/.test(e)||/^(?:>=|>|<=|<)/.test(e)||/\s+(?:\|\||-|[<>=])\s+/.test(e)):!1}async function F(s){try{let e=JSON.parse(await ye(s,"utf-8"));return e&&typeof e=="object"?e:void 0}catch{return}}async function Pe(s,e){try{let n=await fetch(`https://registry.npmjs.org/${encodeURIComponent(s)}/latest`,{signal:e});if(!n.ok)return;let o=await n.json();if(!o||typeof o!="object")return;let i=o.version;return typeof i=="string"?i:void 0}catch{return}}function ve(s,e){let n=Z(s),o=Z(e);if(!n||!o)return!1;for(let i=0;i<3;i++)if(n.parts[i]!==o.parts[i])return n.parts[i]>o.parts[i];if(!n.pre.length&&o.pre.length)return!0;if(n.pre.length&&!o.pre.length)return!1;for(let i=0;i<Math.max(n.pre.length,o.pre.length);i++){let c=n.pre[i],u=o.pre[i];if(c===void 0)return!1;if(u===void 0)return!0;if(c===u)continue;let g=/^\d+$/.test(c)?Number(c):void 0,y=/^\d+$/.test(u)?Number(u):void 0;return g!==void 0&&y!==void 0?g>y:g!==void 0?!1:y!==void 0?!0:c>u}return!1}function Z(s){let e=s.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+.+)?$/);if(e)return{parts:[Number(e[1]),Number(e[2]),Number(e[3])],pre:e[4]?.split(".")??[]}}var _e=ne(Ae(import.meta.url));async function L(s,e){if(process.env.PROMPT_RECORDER_DEBUG!=="1"&&process.env.PROMPT_RECORDER_DEBUG!=="true")return;let o=`[${new Date().toISOString()}] ${e}
2
- `;try{let i=l(s,".agent","prompts-log");await j(i,{recursive:!0}),await ee(l(i,"log.txt"),o)}catch(i){console.error("debugLog failed:",i)}}var I="";async function Ie(){if(I)return I;try{return I=JSON.parse(await te(l(_e,"package.json"),"utf-8")).version||"unknown",I}catch{return"unknown"}}var Re=/[<>:"/\\|?*\x00-\x1f\u200B-\u200F\u2028-\u202E\uFEFF]/g;function N(s){return s.split(`
3
- `)[0].trim().replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim().replace(Re,"").substring(0,40).trim()||"untitled"}function Te(s){let e=s.trimStart();return e.startsWith("<system-reminder>")||e.startsWith("<system>")}function xe(s){let e=s.getFullYear().toString(),n=String(s.getMonth()+1).padStart(2,"0"),o=String(s.getDate()).padStart(2,"0"),i=String(s.getHours()).padStart(2,"0"),c=String(s.getMinutes()).padStart(2,"0"),u=String(s.getSeconds()).padStart(2,"0");return{yyyy:e,MM:n,dd:o,HH:i,mm:c,ss:u}}var Ce=async s=>{Y(s,!0);let{directory:e}=s;ue();let n=new Map,o=new Map,i=new Map,c=new Map,u=1440*60*1e3,g=200,y=2e3,M=1440*60*1e3,re=3600*1e3,m=new Map,h=new Map,R=".txt",T=new Map;function ie(){if(m.size<g)return;let a=Date.now();for(let[t,r]of m)a-r.time>u&&m.delete(t)}function se(){let a=Date.now();if(i.size>y)for(let[t,r]of i)a-r>M&&i.delete(t);if(o.size>y)for(let[t,r]of o)a-r.time>M&&o.delete(t);if(c.size>y)for(let[t,r]of c)a-r>M&&c.delete(t);if(n.size>y)for(let[t,r]of n)a-r.time>M&&n.delete(t);if(h.size>0)for(let[t,r]of h)a-r.time>re&&h.delete(t)}async function S(a,t){let r=ne(a.filepath),d=Ee(a.filepath).match(/^(\d{10})-/);if(!d)return;let f=l(r,`${d[1]}-${N(t)}${R}`);if(f!==a.filepath)try{await Q(a.filepath,f),a.filepath=f}catch{let P=crypto.randomUUID().slice(0,8),v=l(r,`${d[1]}-${N(t)}-${P}${R}`);try{await Q(a.filepath,v),a.filepath=v}catch(k){console.error(`[prompt-recorder] rename failed: ${a.filepath}`,k)}}}async function oe(a){let t=a.properties.info,r=t?.id,p=t?.role||t?.message?.role;r&&p==="user"&&o.set(r,{role:p,time:Date.now()})}async function ae(a){let t=a.properties.part;if(t?.type==="tool"&&t?.tool==="task"){let b=t.state?.metadata??t.metadata;if(b){let D=b.sessionId??b.sessionID;D&&(c.set(D,Date.now()),await L(e,`[prompt-recorder] tracked task session: ${D}`))}}if(t?.type!=="text"||!t?.text||t.synthetic||t.ignored)return;let r=t.sessionID,p=t.messageID,d=t.text,f=o.get(p)?.role;if(f||(f=t.message?.role),f||(f=a.properties.info?.role),f||(f=a.properties.info?.message?.role),f!=="user"||!d||!r)return;if(Te(d)){await L(e,`[prompt-recorder] filtered system-injected: sessionID=${r}`);return}let P=p?`${p}:${d}`:`${r}:${d}`;if(i.has(P))return;i.set(P,Date.now()),se(),await L(e,`[prompt-recorder] event=${a.type}, role=${f}, sessionID=${r}, textLength=${d.length}, textPreview=${d.substring(0,50)}`);let v=new Date,{yyyy:k,MM:E,dd:A,HH:O,mm:H,ss:pe}=xe(v),z=l(e,".agent","prompts"),J=c.has(r)?l(z,"task",k,E,A):l(z,k,E,A);await j(J,{recursive:!0});let fe=k.slice(-2),G=`============ ${k}-${E}-${A} ${O}:${H}:${pe} ============`,x=m.get(r);if(x)x.time=Date.now(),await ee(x.filepath,`
1
+ import{mkdir as q,appendFile as H,writeFile as ke,readFile as De,rename as Y,readdir as Me}from"fs/promises";import{join as g,dirname as Se,basename as Pe}from"path";import{readFile as fe,rm as de}from"fs/promises";import{basename as M,dirname as w,join as U}from"path";import{fileURLToPath as pe}from"url";var le="opencode-prompt-recorder",K=!1;function Z(s,e){if(!e||K)return;K=!0;let n=new AbortController,o=setTimeout(()=>n.abort(),1e4);ge(n.signal).then(r=>{r.updated&&setTimeout(()=>{s.client.tui.showToast({body:{title:"Prompt Recorder \u66F4\u65B0",message:`${r.name} \u5DF2\u4ECE ${r.current} \u66F4\u65B0\u5230 ${r.latest}\uFF0C\u91CD\u542F OpenCode \u5B8C\u6210\u66F4\u65B0`,variant:"info"}})},5e3)}).catch(r=>{console.error("[prompt-recorder] auto-update check failed:",r)}).finally(()=>clearTimeout(o))}async function ge(s){let e=await me(le);if(!e)return{updated:!1};let n=await L(U(e,"package.json"));if(!n?.name||!n.version)return{updated:!1};let o=await $e(n.name,s);if(!o||!be(o,n.version))return{updated:!1};let r=await ye(e,n.name);if(!r)return{updated:!1};try{await de(r,{recursive:!0,force:!0})}catch{return{updated:!1,error:"remove_failed",name:n.name,current:n.version,latest:o}}return{updated:!0,name:n.name,current:n.version,latest:o}}async function me(s){let e=w(pe(import.meta.url));for(;;){if((await L(U(e,"package.json")))?.name===s)return M(e)==="dist"?w(e):e;let o=w(e);if(o===e)return;e=o}}async function ye(s,e){let n=w(s),o=M(n).startsWith("@")?w(n):n;if(M(o)!=="node_modules")return;let r=w(o),c=await L(U(r,"package.json")),u=he(r,e)??c?.dependencies?.[e];if(!(!u||!we(u)))return r}function he(s,e){if(e.startsWith("@")){let[r,c]=e.split("/");if(!r||!c||M(w(s))!==r)return;let u=`${c}@`,m=M(s);return m.startsWith(u)?m.slice(u.length):void 0}let n=`${e}@`,o=M(s);return o.startsWith(n)?o.slice(n.length):void 0}function we(s){let e=s.trim();return e?!!(e==="latest"||e==="*"||/^[~^]/.test(e)||/^(?:>=|>|<=|<)/.test(e)||/\s+(?:\|\||-|[<>=])\s+/.test(e)):!1}async function L(s){try{let e=JSON.parse(await fe(s,"utf-8"));return e&&typeof e=="object"?e:void 0}catch{return}}async function $e(s,e){try{let n=await fetch(`https://registry.npmjs.org/${encodeURIComponent(s)}/latest`,{signal:e});if(!n.ok)return;let o=await n.json();if(!o||typeof o!="object")return;let r=o.version;return typeof r=="string"?r:void 0}catch{return}}function be(s,e){let n=V(s),o=V(e);if(!n||!o)return!1;for(let r=0;r<3;r++)if(n.parts[r]!==o.parts[r])return n.parts[r]>o.parts[r];if(!n.pre.length&&o.pre.length)return!0;if(n.pre.length&&!o.pre.length)return!1;for(let r=0;r<Math.max(n.pre.length,o.pre.length);r++){let c=n.pre[r],u=o.pre[r];if(c===void 0)return!1;if(u===void 0)return!0;if(c===u)continue;let m=/^\d+$/.test(c)?Number(c):void 0,y=/^\d+$/.test(u)?Number(u):void 0;return m!==void 0&&y!==void 0?m>y:m!==void 0?!1:y!==void 0?!0:c>u}return!1}function V(s){let e=s.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+.+)?$/);if(e)return{parts:[Number(e[1]),Number(e[2]),Number(e[3])],pre:e[4]?.split(".")??[]}}async function N(s,e){if(process.env.PROMPT_RECORDER_DEBUG!=="1"&&process.env.PROMPT_RECORDER_DEBUG!=="true")return;let o=`[${new Date().toISOString()}] ${e}
2
+ `;try{let r=g(s,".agent","prompts-log");await q(r,{recursive:!0}),await H(g(r,"log.txt"),o)}catch(r){console.error("debugLog failed:",r)}}var Ee=/[<>:"/\\|?*\x00-\x1f\u200B-\u200F\u2028-\u202E\uFEFF]/g;function j(s){return s.split(`
3
+ `)[0].trim().replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim().replace(Ee,"").substring(0,40).trim()||"untitled"}function Ae(s){let e=s.trimStart();return e.startsWith("<system-reminder>")||e.startsWith("<system>")}function Ie(s){let e=s.getFullYear().toString(),n=String(s.getMonth()+1).padStart(2,"0"),o=String(s.getDate()).padStart(2,"0"),r=String(s.getHours()).padStart(2,"0"),c=String(s.getMinutes()).padStart(2,"0"),u=String(s.getSeconds()).padStart(2,"0");return{yyyy:e,MM:n,dd:o,HH:r,mm:c,ss:u}}var T=".txt";async function _e(s,e){return Q(g(s,".agent","prompts"),e)}async function Q(s,e){let n;try{n=await Me(s)}catch{return}for(let o of n){let r=g(s,o);try{if((await De(r,"utf-8")).includes(`SessionID: ${e}`))return r}catch{if(o.endsWith(T))continue;let c=await Q(r,e);if(c)return c}}}var ve=async s=>{Z(s,!0);let{directory:e}=s,n=new Map,o=new Map,r=new Map,c=new Map,u=1440*60*1e3,m=200,y=2e3,S=1440*60*1e3,ee=3600*1e3,p=new Map,$=new Map,x=new Map;function te(){if(p.size<m)return;let a=Date.now();for(let[t,i]of p)a-i.time>u&&p.delete(t)}function ne(){let a=Date.now();if(r.size>y)for(let[t,i]of r)a-i>S&&r.delete(t);if(o.size>y)for(let[t,i]of o)a-i.time>S&&o.delete(t);if(c.size>y)for(let[t,i]of c)a-i>S&&c.delete(t);if(n.size>y)for(let[t,i]of n)a-i.time>S&&n.delete(t);if($.size>0)for(let[t,i]of $)a-i.time>ee&&$.delete(t)}async function P(a,t){let i=Se(a.filepath),f=Pe(a.filepath).match(/^(\d{10})-/);if(!f)return;let d=g(i,`${f[1]}-${j(t)}${T}`);if(d!==a.filepath)try{await Y(a.filepath,d),a.filepath=d}catch{let E=crypto.randomUUID().slice(0,8),A=g(i,`${f[1]}-${j(t)}-${E}${T}`);try{await Y(a.filepath,A),a.filepath=A}catch(b){console.error(`[prompt-recorder] rename failed: ${a.filepath}`,b)}}}async function re(a){let t=a.properties.info,i=t?.id,l=t?.role||t?.message?.role;i&&l==="user"&&o.set(i,{role:l,time:Date.now()})}async function ie(a){let t=a.properties.part;if(t?.type==="tool"&&t?.tool==="task"){let h=t.state?.metadata??t.metadata;if(h){let k=h.sessionId??h.sessionID;k&&(c.set(k,Date.now()),await N(e,`[prompt-recorder] tracked task session: ${k}`))}}if(t?.type!=="text"||!t?.text||t.synthetic||t.ignored)return;let i=t.sessionID,l=t.messageID,f=t.text,d=o.get(l)?.role;if(d||(d=t.message?.role),d||(d=a.properties.info?.role),d||(d=a.properties.info?.message?.role),d!=="user"||!f||!i)return;if(Ae(f)){await N(e,`[prompt-recorder] filtered system-injected: sessionID=${i}`);return}let E=l?`${l}:${f}`:`${i}:${f}`;if(r.has(E))return;r.set(E,Date.now()),ne(),await N(e,`[prompt-recorder] event=${a.type}, role=${d}, sessionID=${i}, textLength=${f.length}, textPreview=${f.substring(0,50)}`);let A=new Date,{yyyy:b,MM:I,dd:_,HH:z,mm:O,ss:ae}=Ie(A),W=g(e,".agent","prompts"),G=c.has(i)?g(W,"task",b,I,_):g(W,b,I,_);await q(G,{recursive:!0});let ce=b.slice(-2),F=`============ ${b}-${I}-${_} ${z}:${O}:${ae} ============`,C=p.get(i);if(C)C.time=Date.now(),await H(C.filepath,`
4
4
 
5
- ${G}
5
+ ${F}
6
6
 
7
- ${d}`);else{let b=N(n.get(r)?.title??d),D=`${fe}${E}${A}${O}${H}-${b}${R}`,W=l(J,D),le=`============ SessionID: ${r} ============`;await q(W,`${le}
7
+ ${f}`);else{let h=await _e(e,i);if(h)p.set(i,{filepath:h,time:Date.now()}),await H(h,`
8
8
 
9
- ${G}
9
+ ${F}
10
10
 
11
- ${d}`),m.set(r,{filepath:W,time:Date.now()}),ie();let V=h.get(r);if(V){h.delete(r);let C=m.get(r);C&&await S(C,V.title)}let X=T.get(r);X&&clearTimeout(X);let me=setTimeout(async()=>{T.delete(r);try{let _=(await s.client.session.get({path:{id:r}}))?.data?.title;if(!_)return;let ge=n.get(r)?.title;if(_===ge)return;n.set(r,{title:_,time:Date.now()});let B=m.get(r);B&&await S(B,_)}catch{}},5e3);T.set(r,me)}}async function ce(a){let t=a.properties.info;if(t?.id&&t?.title){n.set(t.id,{title:t.title,time:Date.now()});let r=m.get(t.id);r&&await S(r,t.title)}}async function ue(){try{let a=await Ie(),t=l(e,".agent"),r=l(t,"opencode-prompt-recorder-readme.txt"),p=`# OpenCode Prompt Recorder
11
+ ${f}`);else{let X=j(n.get(i)?.title??f),D=`${ce}${I}${_}${z}${O}-${X}${T}`,v=g(G,D),R=`============ SessionID: ${i} ============`;await ke(v,`${R}
12
12
 
13
- \u81EA\u52A8\u8BB0\u5F55\u7528\u6237\u63D0\u793A\u8BCD\u5230 .agent/prompts \u76EE\u5F55\u7684\u63D2\u4EF6\u3002
13
+ ${F}
14
14
 
15
- \u7248\u672C\uFF1A${a}
16
- \u4F5C\u8005\uFF1Aanarckk
17
- \u9879\u76EE\u5730\u5740\uFF1Ahttps://github.com/anarckk/opencode-prompt-recorder`;try{if(await te(r,"utf-8")===p)return}catch{}await j(t,{recursive:!0}),await q(r,p)}catch{}}async function de(a){let t=a.properties.info;if(t?.id&&t?.title){let r=n.get(t.id)?.title;if(n.set(t.id,{title:t.title,time:Date.now()}),r!==t.title){let p=m.get(t.id);p?await S(p,t.title):h.set(t.id,{title:t.title,time:Date.now()})}}}return{event:async({event:a})=>{switch(a.type){case"message.updated":await oe(a);break;case"message.part.updated":await ae(a);break;case"session.created":await ce(a);break;case"session.updated":await de(a);break}}}},Ge=Ce;export{Ge as default};
15
+ ${f}`),p.set(i,{filepath:v,time:Date.now()}),te();let J=$.get(i);if(J){$.delete(i);let B=p.get(i);B&&await P(B,J.title)}}let k=x.get(i);k&&clearTimeout(k);let ue=setTimeout(async()=>{x.delete(i);try{let D=(await s.client.session.get({path:{id:i}}))?.data?.title;if(!D)return;let v=n.get(i)?.title;if(D===v)return;n.set(i,{title:D,time:Date.now()});let R=p.get(i);R&&await P(R,D)}catch{}},5e3);x.set(i,ue)}}async function se(a){let t=a.properties.info;if(t?.id&&t?.title){n.set(t.id,{title:t.title,time:Date.now()});let i=p.get(t.id);i&&await P(i,t.title)}}async function oe(a){let t=a.properties.info;if(t?.id&&t?.title){let i=n.get(t.id)?.title;if(n.set(t.id,{title:t.title,time:Date.now()}),i!==t.title){let l=p.get(t.id);l?await P(l,t.title):$.set(t.id,{title:t.title,time:Date.now()})}}}return{event:async({event:a})=>{switch(a.type){case"message.updated":await re(a);break;case"message.part.updated":await ie(a);break;case"session.created":await se(a);break;case"session.updated":await oe(a);break}}}},je=ve;export{je as default};
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-prompt-recorder",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "OpenCode plugin for recording user prompts. Automatically saves user messages to a local file system with organized directory structure.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-prompt-recorder",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "OpenCode plugin for recording user prompts. Automatically saves user messages to a local file system with organized directory structure.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",