@reddb-io/red-skills 2.55.6 → 2.56.0

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.
@@ -6523,7 +6523,7 @@ ${d.body}`))}));for(let d=0;d<i.length;d++)for(let b=d+1;b<i.length;b++){let h=i
6523
6523
  ${n.citationExcerpt}
6524
6524
  ${n.intent}`.toLowerCase();return/\b(user preference|personal fact|personal context|human-facing|biographical|identity context)\b/.test(a)?{risk:"high",reason:"risk_requires_evidence_review:personal_or_human_context"}:/\b(always|never|must|should|do not|don't|remember to|instruction|agent rule)\b/.test(a)?{risk:"high",reason:"risk_requires_evidence_review:instruction_like_memory"}:{risk:"low",reason:"low_risk_validation_evidence_stored"}}function jhn(n){return n==="medium"?"Medium blast-radius governed writes require Evidence review before promotion.":"High blast-radius governed writes require Evidence review before promotion."}var fre="memory.governance_tidy_review.v1",dwe="memory tidy-review";async function Est(n,a={}){let i=a.now??Date.now(),b=(await gce(n,a)).recommendations.map(Kct),h=await Oct(n,b,{now:i,operation:Ev});return{schema_version:fre,action:"refresh",refreshed_at:new Date(i).toISOString(),summary:{recommendations:h.artifacts.length,stale:h.stale.length},artifacts:h.artifacts.map(y=>({artifact_id:y.artifact_id,recommendation_id:y.recommendation_id,status:y.status,fingerprint:y.fingerprint})),stale_artifacts:h.stale.map(y=>({artifact_id:y.artifact_id,recommendation_id:y.recommendation_id,status:"stale",fingerprint:y.fingerprint}))}}async function _st(n,a){let i=kst(a.approver,"accept"),d=a.now??Date.now(),b=await Jst(n,a.id),h=Dhn(b),[y,w]=await Promise.all([n.getNode(h.from_rid),n.getNode(h.to_rid)]);if(!y)throw new Error(`tidy recommendation source node not found: ${h.from_rid}`);if(!w)throw new Error(`tidy recommendation target node not found: ${h.to_rid}`);let J=await n.upsertEdge({label:h.label,from_rid:h.from_rid,to_rid:h.to_rid,properties:{reason:a.reason??"accepted provider tidy recommendation",approved_by:i,approved_at:d,approval_source:`${dwe} accept`,provider_review_artifact_id:b.artifact_id,provider_review_recommendation_id:b.recommendation_id,provider_review_recommendation_key:b.recommendation_key,provider_review_fingerprint:b.fingerprint,schema_version:fre}}),B=await pfe(n,b.artifact_id,"accepted",{now:d,approver:i,reason:a.reason,source:`${dwe} accept`});return{schema_version:fre,action:"accept",recommendation_id:B.recommendation_id,artifact_id:B.artifact_id,accepted_by:i,accepted_at:new Date(d).toISOString(),edge:{edge_rid:J,label:h.label,from_rid:h.from_rid,to_rid:h.to_rid},artifact:{status:"accepted",fingerprint:B.fingerprint}}}async function Cst(n,a){let i=kst(a.approver,"dismiss"),d=a.now??Date.now(),b=await Jst(n,a.id),h=await pfe(n,b.artifact_id,"dismissed",{now:d,approver:i,reason:a.reason,source:`${dwe} dismiss`});return{schema_version:fre,action:"dismiss",recommendation_id:h.recommendation_id,artifact_id:h.artifact_id,dismissed_by:i,dismissed_at:new Date(d).toISOString(),artifact:{status:"dismissed",fingerprint:h.fingerprint}}}async function Jst(n,a){let i=a.trim();if(!i)throw new Error("memory tidy-review requires a recommendation id");let d=(await dj(n,{operation:Ev})).filter(h=>h.artifact_id===i||h.recommendation_id===i);if(d.length===0)throw new Error(`tidy recommendation not found: ${i}`);let b=d.filter(h=>h.status==="open");if(b.length===1)return b[0];throw b.length>1?new Error(`tidy recommendation id is ambiguous; use an artifact id: ${b.map(h=>h.artifact_id).join(", ")}`):d.some(h=>h.status==="stale")?new Error(`tidy recommendation is stale: ${i}; refresh provider review evidence before accepting or dismissing it`):new Error(`tidy recommendation is not open: ${i} (${d[0].status})`)}function Dhn(n){for(let a of n.pair_evidence)for(let i of a.evidence??[]){let d=Khn(i.proposed_edge_label??i.edge_label),b=Qst(i.duplicate_rid??i.from_rid??i.from),h=Qst(i.canonical_rid??i.to_rid??i.to);if(d&&b!=null&&h!=null)return{label:d,from_rid:b,to_rid:h}}throw new Error(`tidy recommendation has no supported Soft-merge edge: ${n.artifact_id}`)}function Khn(n){if(typeof n!="string")return null;let a=n.trim().toUpperCase();return a==="SAME_AS"||a==="MERGED_INTO"?a:null}function Qst(n){return typeof n=="number"&&Number.isFinite(n)?n:null}function kst(n,a){let i=n.trim();if(!i)throw new Error(`memory tidy-review ${a} requires --approver`);return i}pH();import{resolve as Tst}from"node:path";import{createHash as qhn,randomUUID as uwe}from"node:crypto";import{spawn as $hn}from"node:child_process";import{constants as Gwe}from"node:fs";import{readFileSync as eWn}from"node:fs";import{mkdir as Ost,open as tWn,readFile as nWn,rename as Ikn,rm as gj,stat as lkn,writeFile as akn}from"node:fs/promises";import{tmpdir as IWn}from"node:os";import{dirname as Fx,join as RV,resolve as Qre}from"node:path";import{fileURLToPath as lWn}from"node:url";import{createConnection as Phn}from"node:net";async function wre(n,a){let i=n.timeoutMs??1e3;return await new Promise((d,b)=>{let h=Phn(n.socketPath),y=!1,w="",J=setTimeout(()=>{B(()=>b(new Error("resident rsp server timed out"))),h.destroy()},i);function B(ne){y||(y=!0,clearTimeout(J),ne())}h.on("connect",()=>{h.write(`${JSON.stringify(a)}
6525
6525
  `)}),h.on("data",ne=>{w+=ne.toString("utf8");let Ze=w.indexOf(`
6526
- `);if(Ze<0)return;let D=w.slice(0,Ze);B(()=>{try{d(JSON.parse(D))}catch(qe){b(qe)}}),h.end()}),h.on("error",ne=>B(()=>b(ne))),h.on("close",()=>{y||B(()=>b(new Error("resident rsp server closed without response")))})})}var aWn=108,cWn=1,rWn=5e3;function Ust(n){let a=NWn(n)??Qre(n),i=WWn(a);return{rootDir:a,socketPath:RV(i,"rsp.sock"),pidPath:RV(i,"rsp.pid"),lockPath:RV(i,"rsp.lock"),wakeLockPath:RV(a,".red","tmp","rsp.wake.lock"),summaryPath:RV(a,".red","tmp","rsp-status-summary.json"),registryPath:RV(a,".red","tmp","rsp-resident.pid.json")}}var Hre=class{constructor(a,i){this.paths=a;this.config=i}async request(a){await iWn(this.paths,this.config);let i=await wre(this.paths,{...a,id:uwe()});if(!i.ok)throw new Error(i.error);return i.value}};async function iWn(n,a){if(await Ost(Fx(n.socketPath),{recursive:!0,mode:448}),await xst(n.socketPath,a))return;await Lst(n,a);let i=await GWn(n.lockPath);if(i)try{if(await xst(n.socketPath,a))return;await Lst(n,a),await dWn(n.socketPath);let d=mWn(n,a);await Ast(n.socketPath,d);return}finally{await i.close(),await gj(n.lockPath,{force:!0})}await Ast(n.socketPath)}async function pwe(n,a=200){try{return await Mst(n,a)!=null}catch{return!1}}async function Mst(n,a=200){let i=await wre({socketPath:n,timeoutMs:a},{id:uwe(),op:"ping"});return i.ok?Sst(i.value)?{version:yWn(i.value.version)}:{}:null}async function sWn(n){try{let a=JSON.parse(await nWn(n,"utf8"));return RWn(a)?a:null}catch{return null}}async function Ast(n,a){let i=Date.now()+oWn(),d;for(;Date.now()<i;){if(await pwe(n))return;if(a){let b=a.spawnError();if(b)throw new Error(mwe("resident rsp server spawn failed",a,b));if(a.child.exitCode!=null||a.child.signalCode!=null)throw new Error(mwe("resident rsp server exited before ready",a))}await new Promise(b=>setTimeout(b,50))}throw d instanceof Error?d:new Error(a?mwe("resident rsp server did not start",a):"resident rsp server did not start")}function oWn(){let n=Number(process.env.RSP_RESIDENT_READY_TIMEOUT_MS??"");return Number.isFinite(n)&&n>0?n:rWn}async function dWn(n){await gj(n,{force:!0})}async function GWn(n){await Ost(Fx(n),{recursive:!0,mode:448});try{return await tWn(n,Gwe.O_CREAT|Gwe.O_EXCL|Gwe.O_RDWR)}catch(a){if(a.code!=="EEXIST")throw a;return null}}function mWn(n,a){let[i,d]=hWn(a),b=process.env.RSP_DEBUG==="1",h,y="",w=$hn(i,[...d,"server","--socket",n.socketPath,"--pid-file",n.pidPath,"--store-uri",a.storeUri,"--ttl-days",String(a.ttlDays),"--byte-budget",String(a.byteBudget),"--telemetry-ttl-days",String(a.telemetryTtlDays??90),"--telemetry-byte-budget",String(a.telemetryByteBudget??a.byteBudget),"--telemetry-drain-interval-ms",String(a.telemetryDrainIntervalMs??3e4),"--telemetry-drain-timeout-ms",String(a.telemetryDrainTimeoutMs??2e3),"--idle-ms",String(a.idleMs??3e5),"--resident-version",a.clientVersion??"0.0.0-dev","--registry",n.registryPath],{cwd:n.rootDir,detached:!0,stdio:b?["ignore","ignore","pipe"]:"ignore",env:{...process.env,RSP_RESIDENT_SERVER:"1"}});return w.on("error",J=>{h=J}),b&&(w.stderr?.setEncoding("utf8"),w.stderr?.on("data",J=>{y=uWn(`${y}${J}`,bWn)})),w.unref(),{child:w,stderrTail:()=>y,spawnError:()=>h}}var bWn=8*1024;function mwe(n,a,i){let d=[n];i&&d.push(`error: ${i.message}`),a.child.exitCode!=null&&d.push(`exit code: ${a.child.exitCode}`),a.child.signalCode!=null&&d.push(`signal: ${a.child.signalCode}`);let b=a.stderrTail().trimEnd();return b&&d.push(`stderr tail:
6526
+ `);if(Ze<0)return;let D=w.slice(0,Ze);B(()=>{try{d(JSON.parse(D))}catch(qe){b(qe)}}),h.end()}),h.on("error",ne=>B(()=>b(ne))),h.on("close",()=>{y||B(()=>b(new Error("resident rsp server closed without response")))})})}var aWn=108,cWn=1,rWn=5e3;function Ust(n){let a=NWn(n)??Qre(n),i=WWn(a);return{rootDir:a,socketPath:RV(i,"rsp.sock"),pidPath:RV(i,"rsp.pid"),lockPath:RV(i,"rsp.lock"),wakeLockPath:RV(a,".red","tmp","rsp.wake.lock"),summaryPath:RV(a,".red","tmp","rsp-status-summary.json"),registryPath:RV(a,".red","tmp","rsp-resident.pid.json")}}var Hre=class{constructor(a,i){this.paths=a;this.config=i}async request(a){await iWn(this.paths,this.config);let i=await wre(this.paths,{...a,id:uwe()});if(!i.ok)throw new Error(i.error);return i.value}};async function iWn(n,a){if(await Ost(Fx(n.socketPath),{recursive:!0,mode:448}),await xst(n.socketPath,a))return;await Lst(n,a);let i=await GWn(n.lockPath);if(i)try{if(await xst(n.socketPath,a))return;await Lst(n,a),await dWn(n.socketPath);let d=mWn(n,a);await Ast(n.socketPath,d);return}finally{await i.close(),await gj(n.lockPath,{force:!0})}await Ast(n.socketPath)}async function pwe(n,a=200){try{return await Mst(n,a)!=null}catch{return!1}}async function Mst(n,a=200){let i=await wre({socketPath:n,timeoutMs:a},{id:uwe(),op:"ping"});return i.ok?Sst(i.value)?{version:yWn(i.value.version)}:{}:null}async function sWn(n){try{let a=JSON.parse(await nWn(n,"utf8"));return RWn(a)?a:null}catch{return null}}async function Ast(n,a){let i=Date.now()+oWn(),d;for(;Date.now()<i;){if(await pwe(n))return;if(a){let b=a.spawnError();if(b)throw new Error(mwe("resident rsp server spawn failed",a,b));if(a.child.exitCode!=null||a.child.signalCode!=null)throw new Error(mwe("resident rsp server exited before ready",a))}await new Promise(b=>setTimeout(b,50))}throw d instanceof Error?d:new Error(a?mwe("resident rsp server did not start",a):"resident rsp server did not start")}function oWn(){let n=Number(process.env.RSP_RESIDENT_READY_TIMEOUT_MS??"");return Number.isFinite(n)&&n>0?n:rWn}async function dWn(n){await gj(n,{force:!0})}async function GWn(n){await Ost(Fx(n),{recursive:!0,mode:448});try{return await tWn(n,Gwe.O_CREAT|Gwe.O_EXCL|Gwe.O_RDWR)}catch(a){if(a.code!=="EEXIST")throw a;return null}}function mWn(n,a){let[i,d]=hWn(a),b=process.env.RSP_DEBUG==="1",h,y="",w=$hn(i,[...d,"server","--socket",n.socketPath,"--pid-file",n.pidPath,"--store-uri",a.storeUri,"--ttl-days",String(a.ttlDays),"--ephemeral-ttl-hours",String(a.ephemeralTtlHours??6),"--byte-budget",String(a.byteBudget),"--telemetry-ttl-days",String(a.telemetryTtlDays??90),"--telemetry-byte-budget",String(a.telemetryByteBudget??a.byteBudget),"--telemetry-drain-interval-ms",String(a.telemetryDrainIntervalMs??3e4),"--telemetry-drain-timeout-ms",String(a.telemetryDrainTimeoutMs??2e3),"--idle-ms",String(a.idleMs??3e5),"--resident-version",a.clientVersion??"0.0.0-dev","--registry",n.registryPath],{cwd:n.rootDir,detached:!0,stdio:b?["ignore","ignore","pipe"]:"ignore",env:{...process.env,RSP_RESIDENT_SERVER:"1"}});return w.on("error",J=>{h=J}),b&&(w.stderr?.setEncoding("utf8"),w.stderr?.on("data",J=>{y=uWn(`${y}${J}`,bWn)})),w.unref(),{child:w,stderrTail:()=>y,spawnError:()=>h}}var bWn=8*1024;function mwe(n,a,i){let d=[n];i&&d.push(`error: ${i.message}`),a.child.exitCode!=null&&d.push(`exit code: ${a.child.exitCode}`),a.child.signalCode!=null&&d.push(`signal: ${a.child.signalCode}`);let b=a.stderrTail().trimEnd();return b&&d.push(`stderr tail:
6527
6527
  ${b}`),d.join(`
6528
6528
  `)}function uWn(n,a){let i=Buffer.byteLength(n,"utf8");return i<=a?n:Buffer.from(n,"utf8").subarray(i-a).toString("utf8").replace(/^\uFFFD+/,"")}async function Lst(n,a){try{let i=await sWn(n.registryPath);if(!i||i.socket_path!==n.socketPath||i.store_uri!==a.storeUri)return;if(!yj(i.pid)){await gj(n.registryPath,{force:!0});return}if(await pwe(i.socket_path,100))return;if(Bst(a.clientVersion,i.resident_version)&&(await ZWn(i.pid,1500),!yj(i.pid))){await gj(n.registryPath,{force:!0});return}await pWn(i.pid),await gj(n.registryPath,{force:!0})}catch{}}function yj(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch{return!1}}async function pWn(n){if(!yj(n))return;try{process.kill(n,"SIGTERM")}catch{return}let a=Date.now()+1e3;for(;Date.now()<a;){if(!yj(n))return;await new Promise(i=>setTimeout(i,50))}try{process.kill(n,"SIGKILL")}catch{}}async function ZWn(n,a){let i=Date.now()+a;for(;Date.now()<i;){if(!yj(n))return;await new Promise(d=>setTimeout(d,50))}}function hWn(n){if(n.serverCommand)return[n.serverCommand,n.serverArgs??[]];let a=process.argv[1]?Qre(process.argv[1]):lWn(import.meta.url);return[process.execPath,[...process.execArgv,a]]}function WWn(n){let a=qhn("sha256").update(n).digest("hex").slice(0,20),i=process.env.XDG_RUNTIME_DIR;if(i){let b=RV(i,"red-skills",a);if(RV(b,"rsp.sock").length<aWn)return b}let d=typeof process.getuid=="function"?process.getuid():"nouid";return RV(IWn(),`red-skills-${d}`,a)}function NWn(n){let a=Qre(n);for(let i=0;i<32;i++){try{let b=bwe(RV(a,".git"));if(b!=null)return YWn(a,b)??a;if(bwe(RV(a,".git","HEAD"))!=null||bwe(RV(a,".red","config.yaml"))!=null)return a}catch{}let d=Fx(a);if(d===a)return null;a=d}return null}function YWn(n,a){let i=/^gitdir:\s*(.+?)\s*$/m.exec(a);if(!i)return null;let d=Qre(n,i[1]);return/[/\\]worktrees[/\\][^/\\]+$/.test(d)?Fx(Fx(Fx(d))):null}function bwe(n){try{return eWn(n,"utf8")}catch{return null}}async function xst(n,a){let i=await Mst(n).catch(()=>null);return i?Bst(a.clientVersion,i.version)?(await VWn(n,a.clientVersion),await vWn(n),!1):!0:!1}async function VWn(n,a){try{await wre({socketPath:n,timeoutMs:200},{id:uwe(),op:"handover",clientVersion:a})}catch{}}function Bst(n,a){return!n||!a?!1:gWn(n,a)>0}function gWn(n,a){let i=zst(n),d=zst(a);return!i||!d?0:i.major-d.major||i.minor-d.minor||i.patch-d.patch}function zst(n){let a=/^(\d+)\.(\d+)\.(\d+)/.exec(String(n).trim());return a?{major:Number(a[1]),minor:Number(a[2]),patch:Number(a[3])}:null}function Sst(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function yWn(n){return typeof n=="string"&&n.length>0?n:void 0}function RWn(n){return Sst(n)&&n.version===cWn&&Number.isInteger(n.pid)&&typeof n.socket_path=="string"&&typeof n.store_uri=="string"&&typeof n.resident_version=="string"&&typeof n.started_at=="string"}async function vWn(n){let a=Date.now()+1e3;for(;Date.now()<a;){if(!await pwe(n,50))return;await new Promise(i=>setTimeout(i,50))}}var Zwe=".red/tmp/red-skills.rdb",FWn=7,XWn=64*1024*1024;function hwe(n,a){if(a.mode!=="graph")return!1;let i=a.storePath??"";return i===Zwe?!0:Tst(n,i).endsWith(`/${Zwe}`)}async function Wwe(n,a,i,d){let b=Ust(n);return await new Hre(b,{storeUri:`file://${Tst(n,Zwe)}`,ttlDays:FWn,byteBudget:XWn,serverCommand:process.env.RSP_BIN??"rsp"}).request({op:"memory",action:i,payload:d})}bT();N3();BZ();import{execFile as fWn}from"node:child_process";import{createHash as wWn}from"node:crypto";import{existsSync as jst}from"node:fs";import{dirname as Dst,join as HWn}from"node:path";import{fileURLToPath as qst}from"node:url";import{promisify as QWn}from"node:util";var EWn=QWn(fWn),Kst="vcs:last-meaningful-commit";async function $st(n,a,i={}){if(a.mode!=="graph")throw new Error(`memory commit needs graph mode \u2014 this project is "${a.mode}". Re-run \`memory init --mode graph\` first`);let d=i.message??"memory graph checkpoint",b=Ys(n,a),h=qst(b),y=await Js.open({uri:b}),w=[],J=[],B="",ne=null;try{let ye=await dre(y);w=ye.versioned,J=ye.skipped,B=await _Wn(y,w),ne=JWn(await y.kvGet(Kst))}finally{await y.close()}if(ne?.fingerprint===B)return{status:"unchanged",committed:!1,message:d,included:w,skipped:J,fingerprint:B,previousCommit:ne.hash};let Ze=await kWn(h,d,i),D={fingerprint:B,hash:Ze.hash},qe=await Js.open({uri:b});try{await qe.kvPut(Kst,D)}finally{await qe.close()}return{status:"committed",committed:!0,message:d,included:w,skipped:J,fingerprint:B,commit:Ze}}async function _Wn(n,a){let i={};for(let d of a)i[d]=await CWn(n,d);return wWn("sha256").update(Nwe(i)).digest("hex")}async function CWn(n,a){if(a===Hr.docs)try{let{items:d}=await n.raw.documents.list(Hr.docs,{limit:1e5});return Pst(d)}catch{return[]}let i=await n.raw.query(`SELECT * FROM ${a}`);return Pst(i.rows)}function Pst(n){return[...n].sort((a,i)=>Nwe(a).localeCompare(Nwe(i)))}function Nwe(n){return JSON.stringify(Ywe(n))}function JWn(n){let a;try{a=typeof n=="string"?JSON.parse(n):n}catch{return null}if(!a||typeof a!="object")return null;let i=a;return typeof i.fingerprint!="string"||typeof i.hash!="string"?null:{fingerprint:i.fingerprint,hash:i.hash}}function Ywe(n){if(Array.isArray(n))return n.map(Ywe);if(n&&typeof n=="object"){let a={};for(let i of Object.keys(n).sort())a[i]=Ywe(n[i]);return a}return n}async function kWn(n,a,i){let d=["vcs","commit","--path",n,"--message",a,"--json"];i.author&&d.push("--author",i.author),i.email&&d.push("--email",i.email);let{stdout:b}=await EWn(AWn(),d,{encoding:"utf8",maxBuffer:1024*1024}),h=JSON.parse(b);if(!h.ok||!h.data?.hash)throw new Error(`red vcs commit failed${h.error?`: ${h.error}`:""}`);return{hash:h.data.hash,height:Number(h.data.height??0),parents:h.data.parents??[]}}function AWn(){let n=process.env.REDDB_BIN;if(n&&jst(n))return n;let a=process.platform==="win32"?"red.exe":"red",i=Dst(Dst(qst(import.meta.url))),d=HWn(i,"node_modules","@reddb-io","sdk","bin",a);if(jst(d))return d;throw new Error(`red binary not found \u2014 set REDDB_BIN or install @reddb-io/sdk (looked at ${d})`)}async function eot(n,a){let i=LWn(a.issueBody),d=zWn(a.repository,a.issueNumber),b={label:d,node_type:"issue",properties:{title:a.issueTitle??d,repository:a.repository,issue_number:a.issueNumber,url:a.issueUrl,source:"github-issues",...i!=null?{parent_prd:i}:{},hash:li("issue",a.repository,String(a.issueNumber))}},h=await n.upsertNode(b),y,w;if(i!=null){let An=OWn(a.repository,i),Ia={label:An,node_type:"prd",properties:{title:An,repository:a.repository,prd_number:i,source:"github-issues",hash:li("prd",a.repository,String(i))}};y=await n.upsertNode(Ia),w=await n.upsertEdge({label:"CONTAINS",from_rid:y,to_rid:h})}let J=SWn(a.touchedFiles),B=TWn(a.hooks),ne=UWn(a.repository,a.issueNumber,a.attemptNumber,a.workerId),Ze={label:ne,node_type:"attempt",properties:{title:a.summary??ne,content:a.summary,repository:a.repository,issue_number:a.issueNumber,attempt_number:a.attemptNumber,worker_id:a.workerId,...i!=null?{parent_prd:i}:{},status:a.status,issue_type:a.issueType,model_tier:a.modelTier,outcome:a.outcome,branch:a.branch,duration_ms:a.durationMs,diffstat:a.diffstat,envelope_ref:a.envelopeRef,envelope_hash:a.envelopeHash,merge_commit:a.mergeCommit,failure_branch:a.failureBranch,touched_files:J,notes:a.notes,error_class:a.errorClass,validation_summary:a.validationSummary,...B.length>0?{hooks:B}:{},summary:a.summary,source:"afk",hash:li("attempt",a.repository,String(a.issueNumber),String(a.attemptNumber),a.workerId??"",a.envelopeHash??"")}},D=await n.upsertNode(Ze),qe=await n.upsertEdge({label:"CONTAINS",from_rid:h,to_rid:D}),ye=[],fe=[];for(let An of J){let Ia={label:MWn(An),node_type:"file",properties:{title:An,source:An,hash:li("file",An)}},$n=await n.upsertNode(Ia);ye.push($n),fe.push(await n.upsertEdge({label:"TOUCHED",from_rid:D,to_rid:$n}))}let ft=jWn(a.validationRecords),Zn=[],Tt=[];for(let An of ft){let Ia={label:BWn(a.repository,a.issueNumber,a.attemptNumber,An.name),node_type:"validation",properties:{title:An.name,repository:a.repository,issue_number:a.issueNumber,attempt_number:a.attemptNumber,worker_id:a.workerId,name:An.name,command:An.command,status:An.status,duration_ms:An.durationMs,summary:An.summary,source:"afk-validation-sidecar",hash:li("validation",a.repository,String(a.issueNumber),String(a.attemptNumber),a.workerId??"",a.envelopeHash??"",An.name)}},$n=await n.upsertNode(Ia);Zn.push($n),Tt.push(await n.upsertEdge({label:"TESTED_BY",from_rid:D,to_rid:$n}))}let aI=await xWn(n,a.repository,a.issueNumber);return{attemptRid:D,issueRid:h,prdRid:y,parentPrd:i??void 0,prdContainsIssueEdge:w,fileRids:ye,touchedEdges:fe,validationRids:Zn,testedByEdges:Tt,containsEdge:qe,precedesEdges:aI,touchedFiles:J}}function LWn(n){if(!n)return null;let a=n.match(/^[ \t]*parent-prd[ \t]*:[ \t]*#?(\d+)\b/im);if(a)return Number(a[1]);let i=n.match(/^[ \t]*prd[ \t]*:[ \t]*#?(\d+)\b/im);return i?Number(i[1]):null}async function xWn(n,a,i){let b=(await n.listNodes()).filter(y=>y.node_type==="attempt").filter(y=>y.properties.repository===a&&Number(y.properties.issue_number)===i).map(y=>({rid:y.rid,attemptNumber:Number(y.properties.attempt_number??0)})).filter(y=>Number.isFinite(y.attemptNumber));b.sort((y,w)=>y.attemptNumber!==w.attemptNumber?y.attemptNumber-w.attemptNumber:y.rid-w.rid);let h=[];for(let y=1;y<b.length;y++)h.push(await n.upsertEdge({label:"PRECEDES",from_rid:b[y-1].rid,to_rid:b[y].rid}));return h}function zWn(n,a){return`issue:${n}#${a}`}function OWn(n,a){return`prd:${n}#${a}`}function UWn(n,a,i,d){let b=`attempt:${n}#${a}/${i}`;return d?`${b}@${d}`:b}function MWn(n){return`file:${n}`}function BWn(n,a,i,d){return`validation:${n}#${a}/${i}/${d}`}function SWn(n){if(!n||n.length===0)return[];let a=new Set,i=[];for(let d of n){if(typeof d!="string")continue;let b=d.trim();b.length===0||a.has(b)||(a.add(b),i.push(b))}return i}function TWn(n){if(!Array.isArray(n))return[];let a=[];for(let i of n){if(i==null||typeof i!="object")continue;let d=i,b=typeof d.lifecycle=="string"?d.lifecycle.trim():"",h=typeof d.command=="string"?d.command.trim():"",y=d.exit_code,w=typeof y=="number"&&Number.isFinite(y)?Math.trunc(y):typeof y=="string"&&/^-?\d+$/.test(y.trim())?Number(y.trim()):NaN;!b||!h||!Number.isFinite(w)||a.push({lifecycle:b,command:h,exit_code:w})}return a}function jWn(n){if(!Array.isArray(n))return[];let a=[];for(let i of n){if(i==null||typeof i!="object")continue;let d=i,b=typeof d.name=="string"?d.name.trim():"",h=typeof d.status=="string"?d.status.trim():"";if(!b||!h)continue;let y=typeof d.command=="string"?d.command.trim():void 0,w=typeof d.summary=="string"?d.summary.trim():void 0,J=typeof d.durationMs=="number"&&Number.isFinite(d.durationMs)?d.durationMs:void 0;a.push({name:b,status:h,...y?{command:y}:{},...J!=null?{durationMs:J}:{},...w?{summary:w.slice(0,1e3)}:{}})}return a}import{mkdir as DWn,writeFile as KWn}from"node:fs/promises";import{join as tot,relative as PWn}from"node:path";async function rot(n){let a=await n.listNodes(),i=await n.listEdges(),d=a.filter(w=>w.node_type==="attempt").sort($Wn),b=a.filter(w=>w.node_type==="validation").sort((w,J)=>w.rid-J.rid),h=[],y=[];for(let w of d){let J=[eNn(w)],B=Ere(w,"summary")??Ere(w,"content")??"",ne=Ere(w,"notes")??"",Ze=not(ne||B,J);if(Ze&&y.push(Ze),nNn(w)){h.push(MJ({kind:"failure",title:`Failure: ${String(w.properties.status??"attempt failed")} on ${w.label}`,recommendation:lQ(B||`${w.label} ended with status ${String(w.properties.status??"unknown")}.`),targetNodeType:"problem",confidence:"EXTRACTED",evidence:J}));let D=lNn(w);D&&h.push(MJ({kind:"skill_improvement",title:`Skill improvement candidate: ${D}`,recommendation:lQ(`Review ${D} for missing prerequisites, validation guidance, or recovery steps related to ${String(w.properties.error_class??w.properties.status??"the failed attempt")}.`),targetNodeType:"workflow",confidence:"INFERRED",evidence:J}))}INn(B)&&h.push(MJ({kind:"durable_fact",title:`Durable fact from ${w.label}`,recommendation:lQ(B),targetNodeType:"decision",confidence:"INFERRED",evidence:J}))}for(let w of b){let J=[tNn(w)],B=cNn(w),ne=String(w.properties.summary??""),Ze=not(ne,J);if(Ze&&y.push(Ze),h.push(MJ({kind:"validation",title:`Validation ${String(w.properties.name??w.label)} ${String(w.properties.status??"recorded")}`,recommendation:lQ([w.properties.command?`Command \`${String(w.properties.command)}\``:`Validation ${String(w.properties.name??w.label)}`,`finished with status ${String(w.properties.status??"unknown")}.`,Ze?"":ne].join(" ")),targetNodeType:"validation",confidence:"EXTRACTED",evidence:J})),rNn(w)&&h.push(MJ({kind:"durable_fact",title:`Durable fact from validation ${String(w.properties.name??w.label)}`,recommendation:lQ(`Validation ${String(w.properties.name??w.label)} passed for issue ${String(w.properties.issue_number??"unknown")}.`),targetNodeType:"decision",confidence:"EXTRACTED",evidence:J})),B){h.push(MJ({kind:"failure",title:`Failure: validation ${String(w.properties.name??w.label)} failed`,recommendation:lQ(String(w.properties.summary??"")||`Validation ${String(w.properties.name??w.label)} failed.`),targetNodeType:"problem",confidence:"EXTRACTED",evidence:J}));let D=aNn(w,a,i);D&&h.push(MJ({kind:"skill_improvement",title:`Skill improvement candidate: ${D}`,recommendation:lQ(`Review ${D} for validation guidance related to failed check ${String(w.properties.name??w.label)}.`),targetNodeType:"workflow",confidence:"INFERRED",evidence:J}))}}return{proposals:qWn(h).sort((w,J)=>w.kind.localeCompare(J.kind)||w.title.localeCompare(J.title)),rejected:y}}async function iot(n,a){if(a.proposals.length===0)return null;let i=iNn(a),d=tot(n,".red","memory","proposals");await DWn(d,{recursive:!0});let b=`attempt-learning-${i.slice(0,12)}.md`,h=tot(d,b);return await KWn(h,sNn(a,i),"utf8"),oNn(PWn(n,h))}function sot(n){let a=n.match(/```json memory-learning-proposal\s*([\s\S]*?)```/);if(!a)throw new Error("proposal needs a structured memory-learning-proposal block");let i=JSON.parse(a[1]);if(!i||typeof i!="object"||Array.isArray(i))throw new Error("memory-learning-proposal must be a JSON object");let d=i;if(!Array.isArray(d.proposals))throw new Error("memory-learning-proposal.proposals is required");return{proposals:d.proposals,rejected:Array.isArray(d.rejected)?d.rejected:[]}}async function oot(n,a){let i=[],d=[];for(let b of a.proposals){let h={label:`learning:${b.kind}:${b.id.slice(0,16)}`,node_type:b.targetNodeType,properties:{title:b.title,content:b.recommendation,summary:b.evidenceSummary,source:"attempt-learning",confidence:b.confidence,tags:["attempt-learning",b.kind],hash:li("attempt-learning",b.id),provenance:{source_kind:"derived",writer:"memory attempt learn apply",command:"memory attempt learn apply",confidence:b.confidence,evidence:b.evidence.map(w=>w.description)}}},y=await n.upsertNode(h);i.push(y);for(let w of b.evidence)d.push(await n.upsertEdge({label:"LEARNED_FROM",from_rid:y,to_rid:w.rid,properties:{reason:b.kind,source:"attempt-learning"}}))}return{applied:a.proposals.length,nodeRids:i,edgeRids:d}}function MJ(n){let a=n.evidence.map(d=>d.description).join("; "),i=li("attempt-learning",n.kind,n.title,n.recommendation,a);return{...n,id:i,evidenceSummary:a}}function qWn(n){let a=new Set,i=[];for(let d of n)a.has(d.id)||(a.add(d.id),i.push(d));return i}function $Wn(n,a){let i=String(n.properties.repository??"").localeCompare(String(a.properties.repository??""));if(i!==0)return i;let d=Number(n.properties.issue_number??0)-Number(a.properties.issue_number??0);if(d!==0)return d;let b=Number(n.properties.attempt_number??0)-Number(a.properties.attempt_number??0);return b!==0?b:n.rid-a.rid}function eNn(n){let a=String(n.properties.status??"unknown"),i=lQ(String(n.properties.summary??n.properties.content??n.properties.title??""));return{rid:n.rid,label:n.label,nodeType:"attempt",description:`attempt rid=${n.rid} label=${n.label} status=${a}${i?` summary=${i}`:""}`}}function tNn(n){return{rid:n.rid,label:n.label,nodeType:"validation",description:`validation rid=${n.rid} label=${n.label} name=${String(n.properties.name??"")} status=${String(n.properties.status??"unknown")}`}}function not(n,a){return n?/\b(raw stdout|raw stderr|operational log|tail of .*log|bg-task|\/tmp\/)\b/i.test(n)?{kind:"raw_operational_log",action:"rejected",reason:"raw operational logs are not durable Memory facts",evidence:a}:/\b(wip|in progress|still running|trying|next step|todo|temporary)\b/i.test(n)?{kind:"temporary_progress",action:"downgraded",reason:"temporary progress is attempt evidence, not a durable learning",evidence:a}:null:null}function nNn(n){let a=String(n.properties.status??"").toLowerCase();return a!==""&&a!=="done"}function INn(n){return!n||n.length<24||/\b(wip|still running|trying|todo|raw stdout|raw stderr|operational log)\b/i.test(n)?!1:/\b(must|uses?|stores?|records?|creates?|links?|dedupes?|verifies?|rejects?|requires?|without|approval-gated)\b/i.test(n)}function lNn(n){let a=n.properties.touched_files;if(!Array.isArray(a))return null;for(let i of a)if(typeof i=="string"&&/((^|\/)skills\/.*\/SKILL\.md$)|(^|\/)SKILL\.md$/i.test(i))return i;return null}function aNn(n,a,i){let d=i.find(B=>Iot(B)==="TESTED_BY"&&aot(B)===n.rid),b=lot(d);if(!Number.isFinite(b))return null;let h=i.find(B=>Iot(B)==="TOUCHED"&&lot(B)===b),y=aot(h);if(!Number.isFinite(y))return null;let w=a.find(B=>B.rid===y),J=cot(w,"title")??cot(w,"source")??"";return/(^|\/)skills\/.*\/SKILL\.md$/i.test(J)?J:null}function Iot(n){return String(n?.label??n?.LABEL??"")}function lot(n){return Number(n?.from??n?.from_rid??n?.FROM??n?.FROM_RID)}function aot(n){return Number(n?.to??n?.to_rid??n?.TO??n?.TO_RID)}function cNn(n){let a=String(n.properties.status??"").toLowerCase();return a==="failed"||a==="error"||a==="timed-out"}function rNn(n){let a=String(n.properties.status??"").toLowerCase();return a==="passed"||a==="succeeded"||a==="success"}function Ere(n,a){let i=n.properties[a];return typeof i=="string"&&i.trim()?i.trim():null}function cot(n,a){return n?Ere(n,a):null}function lQ(n){return n.replace(/\s+/g," ").trim().slice(0,500)}function iNn(n){return li("attempt-learning-report",...n.proposals.map(a=>a.id))}function sNn(n,a){let i=[...new Set(n.proposals.map(d=>d.kind))].join(", ");return`# Attempt Learning Proposal
6529
6529
 
@@ -6565,7 +6565,7 @@ Usage:
6565
6565
  ${n} archive --candidate <json> [--root <dir>] [--archive-dir <rel>]
6566
6566
  ${n} restore <name> [--root <dir>] [--archive-dir <rel>]`}function fx(n){return UNn(typeof n.root=="string"?n.root:process.cwd())}function fot(n){return typeof n["archive-dir"]=="string"?n["archive-dir"]:void 0}async function vj(n){let a=await Co(n);return a?a.mode!=="graph"?{ok:!1,message:`curate: skill telemetry needs graph mode (this project is "${a.mode}") \u2014 run \`${Rwe}\``}:sZ(a)?{ok:!0}:{ok:!1,message:`curate: skill telemetry is not enabled here \u2014 run \`${Rwe}\``}:{ok:!1,message:`curate: memory is not initialized here \u2014 run \`${Rwe}\``}}function BNn(){let n=ONn(MNn(import.meta.url));return n.includes("dist/curate-skill")||n.endsWith("dist/curate-skill")?Fot(n,"..","cli.js"):Fot(n,"..","cli.ts")}async function SNn(n,a){let i=["curate","skills","--json"];a!==void 0&&i.push("--stale-days",String(a));let d=BNn(),h=d.endsWith(".ts")?vot(process.execPath,["--import","tsx",d,...i,"--root",n],{encoding:"utf8"}):vot(process.execPath,[d,...i,"--root",n],{encoding:"utf8"}),y=h.status??1;if(y!==0)throw new Error(`memory curate skills exited ${y}`);return got(h.stdout??"")}function TNn(n){return typeof n.flags["stale-days"]=="string"?Number(n.flags["stale-days"]):void 0}async function wot(n,a){return(a.loadCuratorReport??SNn)(fx(n.flags),TNn(n))}async function jNn(n){let a=fx(n.flags),i=await vj(a);return i.ok?(console.log("curate: skill telemetry is enabled \u2014 ready to curate"),0):(console.error(i.message),2)}async function DNn(n,a){let i=fx(n.flags),d=await vj(i);if(!d.ok)return console.error(d.message),2;let b;try{b=await wot(n,a)}catch(J){return console.error(`curate: ${J.message}`),1}let{candidates:h,byCategory:y,filtered:w}=gwe(b);return console.log(JSON.stringify({candidates:h,byCategory:y,filtered:w,totals:{totalSkills:b.totalSkills,curatableSkills:b.curatableSkills,readOnlySkills:b.readOnlySkills}},null,2)),0}async function KNn(n,a){let i=fx(n.flags),d=await vj(i);if(!d.ok)return console.error(d.message),2;let b;try{b=await wot(n,a)}catch(J){return console.error(`curate: ${J.message}`),1}let{byCategory:h}=gwe(b);if(ywe(h)===0)return console.error("curate: no candidates \u2014 no issue filed"),0;let y=typeof n.flags.label=="string"?n.flags.label:void 0,w=await Rot({byCategory:h,totals:{totalSkills:b.totalSkills,curatableSkills:b.curatableSkills,readOnlySkills:b.readOnlySkills},generatedAt:b.generatedAt},{cwd:i,label:y});return console.log(`curate: filed background issue \u2014 ${w.output||w.title}`),0}async function PNn(n){let a=fx(n.flags),i=await vj(a);if(!i.ok)return console.error(i.message),2;let d=n.flags.candidate;if(typeof d!="string")return console.error("curate archive: --candidate <json> is required"),2;let b;try{b=JSON.parse(d)}catch(y){return console.error(`curate archive: invalid --candidate JSON: ${y.message}`),2}let h=await Yot(b,{rootDir:a,archiveDir:fot(n.flags)});return h.ok?(console.log(`curate: archived "${h.receipt.name}" \u2192 ${h.receipt.archiveRoot} (${h.receipt.files.length} file(s), manifest at ${h.receipt.manifestPath})`),0):(console.error(`curate archive: refused \u2014 ${h.rejection.reason}: ${h.rejection.detail}`),3)}async function qNn(n){let a=fx(n.flags),i=await vj(a);if(!i.ok)return console.error(i.message),2;let d=n.positional[0];if(!d)return console.error("curate restore: skill name is required"),2;let b=await Vot(d,{rootDir:a,archiveDir:fot(n.flags)});return console.log(`curate: restored "${b.name}" \u2192 ${b.restoredRoot} (${b.files.length} file(s) hash-verified)`),0}async function Hot(n,a={}){switch(n.command){case"check":return jNn(n);case"list":return DNn(n,a);case"background":return KNn(n,a);case"archive":return PNn(n);case"restore":return qNn(n);case void 0:case"--help":case"-h":return console.log(Xot(a.usageCommand)),0;default:return console.error(`unknown curate subcommand: ${n.command}
6567
6567
 
6568
- ${Xot(a.usageCommand)}`),2}}function Qot(n){let a={app:n,version:$Nn(wx("__RED_BUILD_VERSION__",()=>"2.55.6")??"0.0.0-dev"),gitSha:wx("__RED_BUILD_GIT_SHA__",()=>"e2ee7701007c700297ce5326a0cfa799eeff0b17")??"unknown",buildTime:wx("__RED_BUILD_TIME__",()=>"2026-07-14T08:59:46-03:00")??"unknown",bundleAsset:wx("__RED_BUNDLE_ASSET__",()=>"memory.bundle.min.mjs")??"unknown"},i=wx("__REDDB_SDK_VERSION__",()=>"1.23.1"),d=wx("__REDDB_BINARY_TAG__",()=>"v1.23.1");return i&&(a.reddbSdkVersion=i),d&&(a.reddbBinaryTag=d),a}function $Nn(n){return n.startsWith("v")?n.slice(1):n}function Eot(n){return`${n.app} ${n.version} ${n.gitSha}`}function wx(n,a){try{let i=a();return typeof i=="string"&&i.length>0?i:void 0}catch{return process.env[n.replace(/^__|__$/g,"")]}}var _ot=`memory \u2014 governed operational memory for code agents
6568
+ ${Xot(a.usageCommand)}`),2}}function Qot(n){let a={app:n,version:$Nn(wx("__RED_BUILD_VERSION__",()=>"2.56.0")??"0.0.0-dev"),gitSha:wx("__RED_BUILD_GIT_SHA__",()=>"c2f4ab02c1e92164b21e5855e6e168615ba1e2c3")??"unknown",buildTime:wx("__RED_BUILD_TIME__",()=>"2026-07-14T11:25:37-03:00")??"unknown",bundleAsset:wx("__RED_BUNDLE_ASSET__",()=>"memory.bundle.min.mjs")??"unknown"},i=wx("__REDDB_SDK_VERSION__",()=>"1.23.1"),d=wx("__REDDB_BINARY_TAG__",()=>"v1.23.1");return i&&(a.reddbSdkVersion=i),d&&(a.reddbBinaryTag=d),a}function $Nn(n){return n.startsWith("v")?n.slice(1):n}function Eot(n){return`${n.app} ${n.version} ${n.gitSha}`}function wx(n,a){try{let i=a();return typeof i=="string"&&i.length>0?i:void 0}catch{return process.env[n.replace(/^__|__$/g,"")]}}var _ot=`memory \u2014 governed operational memory for code agents
6569
6569
 
6570
6570
  Common workflows:
6571
6571
  remember one fact memory store "Decision: ..."