@popmelt.com/core 0.8.11 → 0.8.12

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.
@@ -171,7 +171,7 @@ These are public collaboration signals, not private reasoning. Keep each field c
171
171
  `,"utf8"),await t.sync()}finally{await t.close()}try{await dc(n,o)}catch(r){throw await lc(n).catch(()=>{}),r}}function uc(o,e){return{version:1,projectId:o,createdAt:e,updatedAt:e,head:{sequence:0,hash:null},explanations:[],concrete:[],relations:[]}}function mc(o,e){let n=o.explanations.findIndex(t=>t.id===e.id);n>=0?o.explanations[n]=Ae(e):o.explanations.push(Ae(e))}function Eo(o,e){let n=Ae(o);for(let t of e)if(t.op==="add_explanation"){if(n.explanations.some(r=>r.id===t.explanation.id))throw new Error(`Imprint explanation already exists: ${t.explanation.id}`);n.explanations.push(Ae(t.explanation))}else if(t.op==="replace_explanation")mc(n,t.explanation);else if(t.op==="remove_explanation")n.explanations=n.explanations.filter(r=>r.id!==t.explanationId),n.relations=n.relations.filter(r=>r.fromId!==t.explanationId&&r.toId!==t.explanationId);else if(t.op==="add_concrete")n.concrete.some(r=>r.id===t.concrete.id)||n.concrete.push(Ae(t.concrete));else if(t.op==="remove_concrete")n.concrete=n.concrete.filter(r=>r.id!==t.concreteId),n.relations=n.relations.filter(r=>r.fromId!==t.concreteId&&r.toId!==t.concreteId);else if(t.op==="add_evidence"){let r=n.explanations.find(i=>i.id===t.explanationId);if(!r)throw new Error(`Unknown imprint explanation: ${t.explanationId}`);r.evidence.some(i=>i.id===t.evidence.id)||(r.evidence.push(Ae(t.evidence)),r.updatedAt=t.evidence.createdAt)}else if(t.op==="revise_explanation"){let r=n.explanations.find(i=>i.id===t.explanationId);if(!r)throw new Error(`Unknown imprint explanation: ${t.explanationId}`);Object.assign(r,Ae(t.patch),{updatedAt:t.updatedAt})}else if(t.op==="add_relation"){let r=n.explanations.some(s=>s.id===t.relation.fromId),i=n.explanations.some(s=>s.id===t.relation.toId)||n.concrete.some(s=>s.id===t.relation.toId);if(!r||!i)throw new Error(`Imprint relation references an unknown explanation: ${t.relation.id}`);n.relations.some(s=>s.id===t.relation.id)||n.relations.push(Ae(t.relation))}else t.op==="remove_relation"&&(n.relations=n.relations.filter(r=>r.id!==t.relationId));return n}function fc(o,e){let n=[],t=Ae(o);for(let r of e){if(r.op==="add_explanation")n.unshift({op:"remove_explanation",explanationId:r.explanation.id});else if(r.op==="remove_explanation"){let i=t.explanations.find(s=>s.id===r.explanationId);i&&n.unshift({op:"add_explanation",explanation:Ae(i)})}else if(r.op==="add_concrete")n.unshift({op:"remove_concrete",concreteId:r.concrete.id});else if(r.op==="remove_concrete"){let i=t.concrete.find(s=>s.id===r.concreteId);i&&n.unshift({op:"add_concrete",concrete:Ae(i)})}else if(r.op==="replace_explanation"||r.op==="revise_explanation"||r.op==="add_evidence"){let i=r.op==="replace_explanation"?r.explanation.id:r.explanationId,s=t.explanations.find(c=>c.id===i);s&&n.unshift({op:"replace_explanation",explanation:Ae(s)})}else if(r.op==="add_relation")n.unshift({op:"remove_relation",relationId:r.relation.id});else if(r.op==="remove_relation"){let i=t.relations.find(s=>s.id===r.relationId);i&&n.unshift({op:"add_relation",relation:Ae(i)})}t=Eo(t,[r])}return n}function Yr(o){return o.op==="add_explanation"||o.op==="replace_explanation"?[o.explanation.id]:o.op==="remove_explanation"||o.op==="add_evidence"||o.op==="revise_explanation"?[o.explanationId]:o.op==="add_relation"?[o.relation.fromId,o.relation.toId]:[]}var Ln=class{constructor(e,n){this.projectRoot=e;this.projectId=n;this.writeChain=Promise.resolve();this.imprintDir=At(e,".popmelt","imprint"),this.manifestPath=At(this.imprintDir,"manifest.json"),this.graphPath=At(this.imprintDir,"graph.json"),this.journalDir=At(this.imprintDir,"journal")}async readManifest(){try{let e=JSON.parse(await Qr(this.manifestPath,"utf8"));if(e.version!==1||e.projectId!==this.projectId)throw new Error("Imprint manifest does not match this project.");return e}catch(e){if(e.code!=="ENOENT")throw e;let n=new Date().toISOString();return{version:1,projectId:this.projectId,createdAt:n,updatedAt:n,head:{sequence:0,hash:null}}}}async load(){let e=await this.readManifest(),t=(await cc(this.journalDir).catch(c=>{if(c.code==="ENOENT")return[];throw c})).filter(c=>/^\d{12}-.+\.json$/.test(c)).sort(),r=uc(this.projectId,e.createdAt),i=[],s=null;for(let c=0;c<t.length;c++){let d=JSON.parse(await Qr(At(this.journalDir,t[c]),"utf8")),{hash:p,...x}=d;if(d.sequence!==c+1||d.previousHash!==s||p!==Xr(x))throw new Error(`Imprint journal hash mismatch at sequence ${d.sequence}.`);r=Eo(r,d.mutations),r.updatedAt=d.committedAt,r.head={sequence:d.sequence,hash:d.hash},i.push(d),s=d.hash}return{graph:r,transactions:i,recoveredTransactions:Math.max(0,i.length-e.head.sequence)}}async commit(e){let n;return this.writeChain=this.writeChain.then(async()=>{let t=await this.load();if(t.transactions.some(j=>j.transactionId===e.transactionId))throw new Error(`Imprint transaction already exists: ${e.transactionId}`);let r=t.graph.head.sequence+1,i=fc(t.graph,e.mutations),s={version:1,sequence:r,transactionId:e.transactionId,projectId:this.projectId,committedAt:e.committedAt,previousHash:t.graph.head.hash,source:e.source,summary:e.summary,mutations:Ae(e.mutations),inverseMutations:i,...e.undoesTransactionId?{undoesTransactionId:e.undoesTransactionId}:{}},c={...s,hash:Xr(s)},d=Eo(t.graph,c.mutations);d.updatedAt=e.committedAt,d.head={sequence:r,hash:c.hash};let p=`${String(r).padStart(12,"0")}-${e.transactionId}.json`;await Zt(At(this.journalDir,p),c);let x={version:1,projectId:this.projectId,createdAt:d.createdAt,updatedAt:e.committedAt,head:d.head};await Zt(this.graphPath,d),await Zt(this.manifestPath,x),n={graph:d,transaction:c}}),await this.writeChain,n}async undo(e,n,t,r){let i=await this.load(),s=i.transactions.find(p=>p.transactionId===e);if(!s)throw new Error("The imprint update is no longer available to undo.");if(i.transactions.some(p=>p.undoesTransactionId===e))throw new Error("This imprint update has already been undone.");let c=new Set(s.mutations.flatMap(Yr));if(i.transactions.filter(p=>p.sequence>s.sequence).some(p=>p.mutations.some(x=>Yr(x).some(j=>c.has(j)))))throw new Error("This imprint update has newer dependent changes and cannot be undone cleanly. Edit or challenge the current explanation instead.");return this.commit({transactionId:r,committedAt:t,source:n,summary:`Undo: ${s.summary}`,mutations:s.inverseMutations,undoesTransactionId:e})}async recover(){let e=await this.load();return await Zt(this.graphPath,e.graph),await Zt(this.manifestPath,{version:1,projectId:this.projectId,createdAt:e.graph.createdAt,updatedAt:e.graph.updatedAt,head:e.graph.head}),{...e,recoveredTransactions:0}}};var hc=new Set(["application_only","transient_state","concrete_without_model_path","duplicate","insufficient_evidence","task_specific_detail","no_shared_understanding_change"]),gc=new Set(["about","after","again","before","being","change","from","have","into","make","should","that","the","their","this","with","would","here","only"]);function yc(o){return o.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().replace(/[^a-z0-9]+/g," ").trim().replace(/\s+/g," ")}function Fn(o){return new Set(yc(o).split(" ").filter(e=>e.length>2&&!gc.has(e)))}function Un(o,e){if(!o.size||!e.size)return 0;let n=0;for(let t of o)e.has(t)&&(n+=1);return n/Math.min(o.size,e.size)}function _o(o){return!o||!Array.isArray(o.values)||o.values.length===0?{kind:"project",values:["*"]}:{kind:o.kind,values:[...new Set(o.values.map(e=>e.trim()).filter(Boolean))]}}function tt(o,e,n){return{id:Ke(),kind:e==="excepts"?"exception":e==="challenges"?"correction":"observation",stance:e,summary:n,threadId:o.threadId,jobId:o.jobId,createdAt:o.occurredAt??new Date().toISOString()}}function Te(o,e=800){return typeof o=="string"?o.trim().slice(0,e):""}function Zr(o){if(!o||typeof o!="object"||Array.isArray(o))return;let e=o;if(!["project","route","component","selector","file"].includes(String(e.kind))||!Array.isArray(e.values))return;let n=e.values.filter(t=>typeof t=="string"&&!!t.trim());return n.length?{kind:e.kind,values:n}:void 0}function ei(o,e){if(!o||!e.trim())return{found:!1};let n=o;for(let t of e.split(".").filter(Boolean))if(Array.isArray(n)){let r=Number(t);if(!Number.isInteger(r)||r<0||r>=n.length)return{found:!1};n=n[r]}else if(n&&typeof n=="object"&&Object.prototype.hasOwnProperty.call(n,t))n=n[t];else return{found:!1};return{found:!0,value:n}}function Co(o){let e=[...o.matchAll(/<imprint>([\s\S]*?)<\/imprint>/g)],n=o.replace(/<imprint>[\s\S]*?<\/imprint>/g,"").replace(/<imprint>[\s\S]*$/g,"").trim(),t=e.at(-1)?.[1];if(!t)return{visibleText:n};try{let r=JSON.parse(t);if(r.decision==="none"){let T=String(r.reason);if(!hc.has(T))throw new Error("imprint no-op reason is invalid");return{draft:{decision:"none",reason:T},visibleText:n}}if(r.decision!==void 0&&r.decision!=="mutate")throw new Error("imprint decision is invalid");let i=r.summary,s=i?.kind;if(!["added","strengthened","refined","challenged","exception","consolidated"].includes(String(s)))throw new Error("summary.kind is invalid");let c={kind:s,title:Te(i?.title,120),detail:Te(i?.detail,500)};if(!c.title||!c.detail)throw new Error("summary title and detail are required");let d=Array.isArray(r.appliedExplanationIds)?r.appliedExplanationIds.filter(T=>typeof T=="string"&&!!T.trim()):[],p=[];for(let T of Array.isArray(r.mutations)?r.mutations:[]){if(!T||typeof T!="object")continue;let b=T;if(b.op==="add"&&["intention","principle","pattern"].includes(String(b.kind))){let h=Te(b.statement),l=Te(b.rationale);if(!h||!l)continue;p.push({op:"add",clientId:Te(b.clientId,100)||void 0,kind:b.kind,statement:h,rationale:l,scope:Zr(b.scope),rootReason:Te(b.rootReason,300)||void 0})}else if(b.op==="revise"&&typeof b.explanationId=="string"){let h={op:"revise",explanationId:b.explanationId,statement:Te(b.statement)||void 0,rationale:Te(b.rationale)||void 0,scope:Zr(b.scope),reopenGrounding:b.reopenGrounding===!0};(h.statement||h.rationale||h.scope||h.reopenGrounding)&&p.push(h)}else if(b.op==="evidence"&&typeof b.explanationId=="string"&&["supports","challenges","excepts"].includes(String(b.stance))){let h=Te(b.summary);h&&p.push({op:"evidence",explanationId:b.explanationId,stance:b.stance,summary:h})}else if(b.op==="relation"&&typeof b.fromId=="string"&&typeof b.toId=="string"&&["operationalizes","refines","supports","contradicts","excepts","instantiates"].includes(String(b.type))){let h=Te(b.rationale);if(!h)continue;p.push({op:"relation",type:b.type,fromId:b.fromId,toId:b.toId,rationale:h})}else if(b.op==="supersede"&&typeof b.explanationId=="string"&&typeof b.replacementId=="string"){let h=Te(b.reason);h&&p.push({op:"supersede",explanationId:b.explanationId,replacementId:b.replacementId,reason:h})}else if(b.op==="bind_concrete"&&typeof b.explanationId=="string"){let h=Te(b.modelPath,300);h&&p.push({op:"bind_concrete",explanationId:b.explanationId,modelPath:h,rationale:Te(b.rationale)})}else b.op==="retire"&&typeof b.explanationId=="string"&&p.push({op:"retire",explanationId:b.explanationId,reason:Te(b.reason)})}let x=r.grounding,j=x&&typeof x.explanationId=="string"&&Te(x.question)?{explanationId:x.explanationId,question:Te(x.question,300)}:void 0;return{draft:{decision:"mutate",summary:c,appliedExplanationIds:d,mutations:p,grounding:j},visibleText:n}}catch(r){return{visibleText:n,error:r instanceof Error?r.message:String(r)}}}function $o(o){let e=o?.explanations??[],n=new Set(o?.pendingGroundingExplanationIds??[]);return["","## Continuous imprinting","","An imprint is provisional shared understanding learned through human-AI collaboration. It is advisory, not authoritative product truth. Accepted product decisions above always win when they conflict.",...e.length?["","Relevant explanations from the project imprint:",...e.map((t,r)=>[`${r+1}. [${t.state}; ${t.kind}] ${t.statement}`,` - Why: ${t.rationale}`,` - Scope: ${t.scope.kind} ${t.scope.values.join(", ")}`,` - Explanation: ${t.id}`,...n.has(t.id)?[" - Grounding: already pending; do not ask again"]:[],...t.concrete.map(i=>` - Concrete terminal: ${i.modelPath} = ${JSON.stringify(i.value)}`)].join(`
172
172
  `)),...o?.truncated?["Additional imprint context exists outside this bounded packet."]:[]]:[],...o?.relations?.length?["","Known explanation topology:",...o.relations.map(t=>`- ${t.fromId} --${t.type}--> ${t.toId}: ${t.rationale}`)]:[],"","Work normally and preserve developer agency. You may use an emerging or testing explanation as a hypothesis without asking permission first. Silence is not confirmation.","The default outcome is no imprint mutation. Completing work, applying an existing explanation, or making a successful design choice does not by itself constitute learning.","Mutate the imprint only when this collaboration changed reusable shared understanding: a future agent facing a meaningfully different task would behave differently because of what was learned here.","","Before proposing a mutation, apply every admission test:","1. Reusable: it guides a future decision beyond reproducing this exact edit.","2. Novel: it is not already expressed by an explanation or its evidence.","3. Durable: it is an intention, rationale, relationship, or recurring pattern, not temporary implementation state.","4. Atomic: it expresses one claim at one abstraction level.","5. Scoped: its applicability can be named without silently generalizing.","6. Supported: the human supplied evidence, correction, or confirmation, not merely acceptance of completed work.","If any test fails, return a decision of none.","","Usually not learning: exact copy substitutions, one-pixel adjustments, element reordering, implementation mechanics, keeping something hidden temporarily, applying an already-known pattern, or a stylistic choice made without human feedback. A task-specific edit becomes learning only if the human establishes a reusable dependency or rationale beyond that edit.","When a candidate overlaps an existing explanation, consolidate before adding. Same meaning plus a new observation means evidence only. A concrete application means bind_concrete, not a broader explanation. A scope correction means revise scope. A direct disagreement means add the replacement and supersede the contradicted explanation. A different abstraction level means a separate related explanation.","Keep correction identity explicit. If feedback refines an emerging or testing explanation without rejecting its underlying claim, revise it and set reopenGrounding true; do not also add challenging evidence to that same explanation. If feedback rejects the claim as written, preserve that rejected wording, add a distinct replacement, and supersede the old explanation. Never revise an explanation and mark that same identity challenged in one update.","Topology assessment is mandatory for every add mutation. Connect the new clientId with relation or supersede mutations whenever it overlaps, specializes, operationalizes, supports, contradicts, or excepts another surfaced or newly-added explanation. If it is genuinely a new root with no meaningful relative, include rootReason on the add mutation explaining why. Unmapped additions without rootReason are rejected.","Never append implementation facts to an intention merely because they occurred in the same component. Grounded explanations are append-only: add evidence for a compatible observation, but never revise or demote the grounded explanation. A material change in meaning, causal rationale, abstraction level, or applicability must be a new testing explanation linked to the grounded parent with a refines, operationalizes, or excepts relation.","Grounded explanations may support new higher-level theory. Emerging explanations must not be the sole basis for another durable explanation. Concrete project facts should remain concrete; do not turn a one-off value into a universal principle.","Request grounding only when an ungrounded explanation materially influenced the action, this application produced genuinely new evidence, and that explanation does not already have grounding pending. Ask at most one grounding question per thread.","","At the end, append exactly one machine-readable decision block after the normal response. It is hidden from the developer:",'<imprint>{"decision":"none","reason":"application_only|transient_state|concrete_without_model_path|duplicate|insufficient_evidence|task_specific_detail|no_shared_understanding_change"}</imprint>',"Or, only after every admission test passes:",'<imprint>{"decision":"mutate","summary":{"kind":"added|strengthened|refined|challenged|exception|consolidated","title":"<short expandable-summary title>","detail":"<what changed in shared understanding>"},"appliedExplanationIds":["<only an ungrounded explanation materially tested here>"],"mutations":[{"op":"add","clientId":"new-1","kind":"intention|principle|pattern","statement":"<one durable atomic explanation>","rationale":"<why the evidence supports it>","scope":{"kind":"project|route|component|selector|file","values":["<scope>"]},"rootReason":"<only when this is genuinely unrelated to every surfaced or new explanation>"},{"op":"revise","explanationId":"<only an emerging or testing id>","statement":"<optional>","rationale":"<optional>","scope":{"kind":"component","values":["CardTile"]},"reopenGrounding":false},{"op":"evidence","explanationId":"<id>","stance":"supports|challenges|excepts","summary":"<thread evidence>"},{"op":"relation","type":"operationalizes|refines|supports|contradicts|excepts|instantiates","fromId":"<id or clientId>","toId":"<id or clientId>","rationale":"<why>"},{"op":"supersede","explanationId":"<contradicted old id>","replacementId":"<new clientId or existing id>","reason":"<direct conflict>"},{"op":"bind_concrete","explanationId":"<id or clientId>","modelPath":"<exact existing model path>","rationale":"<how this fact operationalizes the explanation>"},{"op":"retire","explanationId":"<id>","reason":"<why>"}],"grounding":{"explanationId":"<one applied ungrounded id or clientId>","question":"<brief post-application confirmation question>"}}</imprint>',"Include only mutation objects actually needed. Applying a grounded explanation requires neither appliedExplanationIds nor a mutation. Omit grounding unless its three conditions pass. Never claim that a new explanation is grounded."].join(`
173
173
  `)}var en=class{constructor(e,n){this.noopCounts=new Map;this.store=new Ln(e,n)}recordNoop(e){this.noopCounts.set(e,(this.noopCounts.get(e)??0)+1)}diagnostics(){return{noopDecisions:Object.fromEntries(this.noopCounts)}}async contextualize(e){let n=Fn(e.text??""),t=Fn((e.subjectHints??[]).join(" ")),r=new Set(e.pendingGroundingExplanationIds??[]);if(!n.size&&!t.size&&!r.size)return;let{graph:i}=await this.store.load(),s=i.explanations.filter(h=>h.state!=="retired"&&h.state!=="challenged").map(h=>{let l=Fn([h.statement,h.rationale].join(" ")),v=Fn(h.scope.values.join(" ")),w=Un(l,n),m=Un(v,n),u=Un(v,t),P=Un(l,t),E=w+m*.2+u*.25+P*.1+(h.state==="grounded"?.08:0)+(r.has(h.id)?1:0),y=r.has(h.id)||(n.size?w>=.12||m>=.5:u>=.2||P>=.2);return{item:h,score:E,relevant:y}}).filter(h=>h.relevant&&h.score>=.18).sort((h,l)=>l.score-h.score||l.item.updatedAt.localeCompare(h.item.updatedAt)),c=Math.max(1,e.maxExplanations??6);if(!s.length)return;let d=s.slice(0,c).map(({item:h})=>h),p=new Set(d.map(h=>h.id)),x=new Set(i.relations.flatMap(h=>p.has(h.fromId)?[h.toId]:p.has(h.toId)?[h.fromId]:[])),j=new Set(i.explanations.flatMap(h=>x.has(h.id)&&h.state!=="retired"&&h.state!=="challenged"?[h.id]:[])),T=i.explanations.filter(h=>j.has(h.id)&&!p.has(h.id)).sort((h,l)=>l.updatedAt.localeCompare(h.updatedAt)).slice(0,4),b=[...d,...T];for(let h of T)p.add(h.id);return{explanations:b.map(h=>{let l=new Set(i.relations.filter(v=>v.fromId===h.id&&v.type==="instantiates").map(v=>v.toId));return{id:h.id,kind:h.kind,statement:h.statement,rationale:h.rationale,scope:h.scope,state:h.state,concrete:i.concrete.filter(v=>l.has(v.id)).map(v=>({id:v.id,modelPath:v.modelPath,value:v.value}))}}),truncated:s.length>d.length||T.length<j.size,...r.size?{pendingGroundingExplanationIds:[...r]}:{},relations:i.relations.filter(h=>p.has(h.fromId)&&p.has(h.toId)&&h.type!=="instantiates").map(h=>({id:h.id,type:h.type,fromId:h.fromId,toId:h.toId,rationale:h.rationale}))}}async capture(e,n){if(e.mutations.length===0&&e.appliedExplanationIds.length===0)return;let t=n.occurredAt??new Date().toISOString(),r=await this.store.load(),i=new Map(r.graph.explanations.map(f=>[f.id,f])),s=new Map,c=new Map,d=[],p=new Set,x=new Set(n.pendingGroundingExplanationIds??[]),j=new Set(e.mutations.flatMap(f=>f.op==="revise"&&e.mutations.some(M=>M.op==="evidence"&&M.stance==="challenges"&&M.explanationId===f.explanationId)?[f.explanationId]:[])),T=new Set(e.mutations.flatMap(f=>f.op==="add"&&f.clientId?[f.clientId]:[])),b=f=>i.has(f)||T.has(f),h=new Set;for(let f of e.mutations)f.op==="relation"&&f.fromId!==f.toId&&b(f.fromId)&&b(f.toId)?(h.add(f.fromId),h.add(f.toId)):f.op==="supersede"&&f.explanationId!==f.replacementId&&b(f.explanationId)&&b(f.replacementId)?(h.add(f.explanationId),h.add(f.replacementId)):f.op==="bind_concrete"&&b(f.explanationId)&&ei(n.concreteModel,f.modelPath).found&&h.add(f.explanationId);let l=r.graph.explanations.length===0;for(let f of e.mutations){if(f.op!=="add")continue;let M=!!(f.clientId&&h.has(f.clientId)),D=!!f.rootReason?.trim()||l;if(!M&&!D)continue;l&&(l=!1);let B=Ke();f.clientId&&s.set(f.clientId,B);let W=f.clientId?e.appliedExplanationIds.includes(f.clientId):!1,V={id:B,kind:f.kind,statement:f.statement,rationale:f.rationale,scope:_o(f.scope),state:W?"testing":"emerging",createdAt:t,updatedAt:t,evidence:[tt(n,"supports",e.summary.detail)]};i.set(B,V),p.add(B),d.push({op:"add_explanation",explanation:V})}let v=f=>s.get(f)??f;for(let f of e.mutations){if(f.op!=="revise")continue;let M=v(f.explanationId),D=i.get(M);if(D?.state!=="grounded")continue;let B=Ke(),W={id:B,kind:D.kind,statement:f.statement??D.statement,rationale:f.rationale??D.rationale,scope:f.scope?_o(f.scope):D.scope,state:"testing",createdAt:t,updatedAt:t,evidence:[tt(n,"supports",e.summary.detail)]};i.set(B,W),c.set(M,B),p.add(B),d.push({op:"add_explanation",explanation:W}),d.push({op:"add_relation",relation:{id:Ke(),type:"refines",fromId:B,toId:M,rationale:f.rationale??e.summary.detail,createdAt:t}})}let w=f=>{let M=v(f);return c.get(M)??M};for(let f of e.mutations){if(f.op==="add")continue;if(f.op==="bind_concrete"){let D=w(f.explanationId);if(!i.has(D))continue;let B=ei(n.concreteModel,f.modelPath);if(!B.found)continue;let W=r.graph.concrete.find(V=>V.modelPath===f.modelPath&&JSON.stringify(V.value)===JSON.stringify(B.value));W||(W={id:Ke(),modelPath:f.modelPath,value:structuredClone(B.value),createdAt:t,updatedAt:t},d.push({op:"add_concrete",concrete:W})),d.push({op:"add_relation",relation:{id:Ke(),type:"instantiates",fromId:D,toId:W.id,rationale:f.rationale,createdAt:t}}),p.add(D);continue}if(f.op==="relation"){let D=w(f.fromId),B=w(f.toId);if(!i.has(D)||!i.has(B)||D===B)continue;d.push({op:"add_relation",relation:{id:Ke(),type:f.type,fromId:D,toId:B,rationale:f.rationale,createdAt:t}}),p.add(D),p.add(B);continue}if(f.op==="supersede"){let D=w(f.explanationId),B=w(f.replacementId);if(!i.has(D)||!i.has(B)||D===B)continue;d.push({op:"add_evidence",explanationId:D,evidence:tt(n,"challenges",f.reason)}),d.push({op:"revise_explanation",explanationId:D,patch:{state:"challenged",supersededBy:B},updatedAt:t}),d.push({op:"add_relation",relation:{id:Ke(),type:"supersedes",fromId:B,toId:D,rationale:f.reason,createdAt:t}}),p.add(D),p.add(B);continue}let M=w(f.explanationId);if(i.has(M))if(p.add(M),f.op==="revise"){if(c.has(v(f.explanationId)))continue;let D=i.get(M);if(!D||D.state!=="emerging"&&D.state!=="testing")continue;let B={...f.statement?{statement:f.statement}:{},...f.rationale?{rationale:f.rationale}:{},...f.scope?{scope:_o(f.scope)}:{},...f.reopenGrounding||j.has(f.explanationId)?{state:"testing"}:{}};d.push({op:"revise_explanation",explanationId:M,patch:B,updatedAt:t})}else if(f.op==="evidence"){if(f.stance==="challenges"&&j.has(f.explanationId))continue;d.push({op:"add_evidence",explanationId:M,evidence:tt(n,f.stance,f.summary)}),f.stance==="challenges"&&d.push({op:"revise_explanation",explanationId:M,patch:{state:"challenged"},updatedAt:t})}else f.op==="retire"&&(d.push({op:"add_evidence",explanationId:M,evidence:tt(n,"challenges",f.reason||"Retired after contradictory collaboration evidence.")}),d.push({op:"revise_explanation",explanationId:M,patch:{state:"retired"},updatedAt:t}))}for(let f of e.appliedExplanationIds){let M=w(f),D=i.get(M);!D||D.state==="grounded"||D.state==="retired"||x.has(M)&&!p.has(M)||(p.has(M)||(p.add(M),d.push({op:"add_evidence",explanationId:M,evidence:{...tt(n,"supports",`Applied as an advisory hypothesis: ${e.summary.detail}`),kind:"application"}})),D.state==="emerging"&&d.push({op:"revise_explanation",explanationId:M,patch:{state:"testing"},updatedAt:t}))}if(!d.length)return;let m=Ke(),u=await this.store.commit({transactionId:m,committedAt:t,source:{kind:"automatic",threadId:n.threadId,jobId:n.jobId},summary:e.summary.title,mutations:d}),P=new Map(u.graph.explanations.map(f=>[f.id,f])),E=[...p].flatMap(f=>{let M=P.get(f);if(!M)return[];let D=!r.graph.explanations.some(W=>W.id===f),B=M.state==="challenged"||M.state==="retired";return[{explanationId:f,action:D?"added":B?"challenged":"revised",statement:M.statement,state:M.state}]}),y=e.grounding?w(e.grounding.explanationId):void 0,L=y?P.get(y):void 0,C=L?.state==="testing"&&!x.has(L.id)?{explanationId:L.id,question:e.grounding.question,state:"testing"}:void 0;return{transactionId:m,kind:e.summary.kind,title:e.summary.title,detail:e.summary.detail,changes:E,...C?{grounding:C}:{}}}async applyGroundingAction(e){let n=e.occurredAt??new Date().toISOString();if(e.action==="undo"||e.action==="dont_learn"){let p=[...new Set([e.summary.transactionId,...e.summary.coalescedTransactionIds??[]])].reverse();for(let x of p)await this.store.undo(x,{kind:"undo",threadId:e.threadId,jobId:e.jobId},n,Ke());return}let t=e.summary.grounding?.explanationId??e.summary.changes[0]?.explanationId;if(!t)throw new Error("This imprint summary has no explanation to update.");let i=(await this.store.load()).graph.explanations.find(p=>p.id===t);if(!i||i.state==="retired")throw new Error("This explanation is no longer active.");let s={kind:e.action==="confirm"?"grounding":"correction",threadId:e.threadId,jobId:e.jobId},c=[],d="";if(e.action==="confirm")c.push({op:"add_evidence",explanationId:t,evidence:{...tt(e,"supports","The developer confirmed that the applied reasoning matched their intent."),kind:"confirmation"}}),c.push({op:"revise_explanation",explanationId:t,patch:{state:"grounded"},updatedAt:n}),d=`Grounded: ${i.statement}`;else if(e.action==="reason_wrong")c.push({op:"add_evidence",explanationId:t,evidence:{...tt(e,"challenges",e.value?.trim()||"The result was right, but this explanation was not the reason."),kind:"correction"}}),c.push({op:"revise_explanation",explanationId:t,patch:{state:"challenged"},updatedAt:n}),d=`Challenged: ${i.statement}`;else if(e.action==="narrow"){let p=(e.value??"").split(",").map(x=>x.trim()).filter(Boolean);if(!p.length)throw new Error("A narrower scope is required.");c.push({op:"revise_explanation",explanationId:t,patch:{scope:{kind:i.scope.kind,values:p},state:"testing"},updatedAt:n}),d=`Narrowed scope: ${i.statement}`}else if(e.action==="exception")c.push({op:"add_evidence",explanationId:t,evidence:{...tt(e,"excepts",e.value?.trim()||"The developer marked this application as an exception."),kind:"exception"}}),d=`Exception recorded: ${i.statement}`;else if(e.action==="edit"){let p=e.value?.trim();if(!p)throw new Error("Edited explanation wording is required.");c.push({op:"revise_explanation",explanationId:t,patch:{statement:p,state:"testing"},updatedAt:n}),d=`Edited: ${p}`}if(!c.length)throw new Error("Unsupported imprint action.");await this.store.commit({transactionId:Ke(),committedAt:n,source:s,summary:d,mutations:c})}};function ti(o,e){return o?.projectId===e.projectId&&o.version===e.version&&o.restartMode===e.restartMode}function qn(o){return(Array.isArray(o)?o[0]:o)?.split(",")[0]?.trim()||void 0}function Oo(o){if(!o)return null;try{let e=new URL(o);return["localhost","127.0.0.1","::1"].includes(e.hostname)?e.origin:null}catch{return null}}function ni(o){let e=Oo(qn(o.origin));if(e)return e;let n=Oo(qn(o.referer));if(n)return n;let t=qn(o["x-forwarded-host"]);if(!t)return null;let r=qn(o["x-forwarded-proto"])==="https"?"https":"http";return Oo(`${r}://${t}`)}function oi(o,e,n=5){let t=(d,p)=>(p.completedAt??p.startedAt)-(d.completedAt??d.startedAt),r=[...o].sort(t).slice(0,n),i=o.filter(d=>d.status==="applied"||d.status==="failed").sort(t).slice(0,n),s=e.filter(d=>d.status==="pending"&&d.authorityStatus==="accepted").sort((d,p)=>p.updatedAt-d.updatedAt).slice(0,10),c=s.reduce((d,p)=>(d[p.status]=(d[p.status]??0)+1,d),{});return{recentRuns:r,recentAppliedRuns:i,actionableProposalCounts:c,actionableProposals:s}}import{createHash as zn}from"crypto";import{mkdir as tn,readFile as gt,unlink as Ic,writeFile as _t}from"fs/promises";import{dirname as Wn,extname as bc,join as Ee}from"path";var vc={capacity:{label:"At capacity",message:"The model provider is temporarily unavailable. Try again shortly."},rate_limited:{label:"Rate limited",message:"The model provider is receiving too many requests. Try again shortly."},timeout:{label:"Timed out",message:"The model took too long to respond. Try again."},connection:{label:"Connection lost",message:"The model provider disconnected before the run completed. Try again."},authentication:{label:"Sign-in required",message:"The model provider needs to be authenticated before this run can continue."},failed:{label:"Failed",message:"The model could not complete this run. Try again, or inspect the job diagnostics if the problem continues."}};function wc(o){let e=typeof o=="string"?o:(()=>{try{return JSON.stringify(o)}catch{return String(o??"")}})();return/\b(?:http\s*)?503\b|server at capacity|\bat capacity\b|resource[_\s-]?exhausted|temporarily unavailable/i.test(e)?"capacity":/\b(?:http\s*)?429\b|rate[_\s-]?limit|too many requests/i.test(e)?"rate_limited":/timed?\s*out|timeout/i.test(e)?"timeout":/auth(?:entication|orization)? required|oauth|not authenticated|sign[ -]?in required|unauthorized|\b401\b/i.test(e)?"authentication":/transport channel closed|connection (?:closed|lost|reset)|socket hang up|network error|disconnected/i.test(e)?"connection":"failed"}function ri(o,e){let n=e??wc(o);return{kind:n,...vc[n]}}function Et(o,e){return!o||e||o.attention!=="response_requested"?o:{...o,attention:"response_available"}}function ii(o){let e=Array.from(new Set((o.changedFiles??[]).filter(Boolean))),n=e.length>0?[{kind:"changes_applied",files:e}]:[{kind:"replied"}],t=o.decisionRequired?"decision_required":o.question||o.groundingRequired?"response_requested":o.reviewRequired||o.resolutions?.some(r=>r.status==="needs_review")?"review_required":"response_available";return o.imprintTransactionId&&n.push({kind:"imprint_updated",transactionId:o.imprintTransactionId}),{attention:t,outcomes:n}}var xc={version:1,threads:{}},si=["feedbackContext","annotationSnapshot","memoryReview","imprintContext","toolsUsed","editEvents","segments"],nn={version:2,updatedAt:0,files:{}};function Sc(o){return JSON.stringify(o,null,2)}function Pc(o){return Object.fromEntries(si.flatMap(e=>o[e]===void 0?[]:[[e,o[e]]]))}function kc(o){let e={...o};for(let n of si)delete e[n];return e}function Ct(o){let e=o;if(o.error){let n=ri(o.error,o.errorKind);(o.error!==n.message||o.errorKind!==n.kind||o.responseText!==void 0)&&(e={...o,error:n.message,errorKind:n.kind},delete e.responseText)}if(e.imprintSummary?.resolvedAction&&!e.question){let n=Et(e.result,!1),t=Et(e.turn?.result,!1);(n!==e.result||t!==e.turn?.result)&&(e={...e,...n?{result:n}:{},...e.turn?{turn:{...e.turn,...t?{result:t}:{}}}:{}})}return e}var Hn=class{constructor(e){this.cache=null;this.index=null;this.writeChain=Promise.resolve();let n=Ee(e,".popmelt");this.legacyFilePath=Ee(n,"threads.json"),this.threadsDir=Ee(n,"threads"),this.indexPath=Ee(this.threadsDir,"index.json"),this.artifactsDir=Ee(n,"artifacts","thread-messages"),this.mediaDir=Ee(n,"artifacts","thread-media")}async load(){if(this.cache)return this.cache;try{let e=JSON.parse(await gt(this.indexPath,"utf-8"));if(e?.version===2&&e.files&&typeof e.files=="object"){this.index=e;let n={};for(let[t,r]of Object.entries(e.files)){let i=await this.readThread(Ee(this.threadsDir,r));i&&(n[t]=i)}return this.cache={version:1,threads:n},this.cache}}catch{}try{let e=JSON.parse(await gt(this.legacyFilePath,"utf-8"));if(e?.version===1&&e.threads)return this.cache={version:1,threads:Object.fromEntries(Object.entries(e.threads).map(([n,t])=>[n,{...t,messages:t.messages.map(Ct)}]))},this.index={...nn,files:{},migratedFromLegacyAt:Date.now()},await this.persistAll(),this.cache}catch{}return this.cache={...xc,threads:{}},this.index={...nn,files:{}},this.cache}async getThread(e){return(await this.load()).threads[e]??null}async findContinuationThread(e){if(e.length===0)return null;let n=await this.load(),t=new Set(e);for(let r of Object.values(n.threads))if(r.elementIdentifiers.some(s=>t.has(s)))return r;return null}async createThread(e,n){let t=await this.load(),r={id:e,createdAt:Date.now(),updatedAt:Date.now(),elementIdentifiers:n,messages:[]};return t.threads[e]=r,await this.persistThread(r),r}async appendMessage(e,n){let r=(await this.load()).threads[e];r&&(r.messages.push(Ct(n)),r.updatedAt=Date.now(),await this.persistThread(r))}async appendMessageBeforeQueuedReplies(e,n){let r=(await this.load()).threads[e];if(!r)return;let i=r.messages.findIndex(s=>s.role==="human"&&!!s.replyToQuestion&&s.queued);i>=0?r.messages.splice(i,0,Ct(n)):r.messages.push(Ct(n)),r.updatedAt=Date.now(),await this.persistThread(r)}async updateMessage(e,n,t){let i=(await this.load()).threads[e];if(!i)return!1;let s=i.messages.filter(c=>c.jobId===n);if(s.length===0)return!1;for(let c of s)if(Object.assign(c,t),c.error){let d=Ct(c);Object.assign(c,d),delete c.responseText}return i.updatedAt=Date.now(),await this.persistThread(i),!0}async updateAssistantMessage(e,n,t){let i=(await this.load()).threads[e];if(!i)return!1;let s=[...i.messages].reverse().find(c=>c.role==="assistant"&&c.jobId===n);return s?(Object.assign(s,t),i.updatedAt=Date.now(),await this.persistThread(i),!0):!1}async addElementIdentifiers(e,n){let r=(await this.load()).threads[e];if(!r)return;let i=new Set(r.elementIdentifiers);for(let s of n)i.has(s)||r.elementIdentifiers.push(s);r.updatedAt=Date.now(),await this.persistThread(r)}async deleteThread(e){let n=await this.load();return n.threads[e]?(delete n.threads[e],await this.deletePersistedThread(e),!0):!1}async listRecent(e=5){let n=await this.load(),t=Object.values(n.threads);return t.sort((r,i)=>i.updatedAt-r.updatedAt),t.slice(0,e).map(r=>{let s=r.messages.find(v=>v.role==="human")?.feedbackSummary||"[thread]",c=r.messages.filter(v=>v.role==="assistant"),d=v=>{if(v.role!=="assistant")return;if(v.question)return v.question;let w=v.imprintSummary?.grounding;if(w?.question&&!v.imprintSummary?.resolvedAction)return w.question},p=r.messages.findLastIndex(v=>!!d(v)),x=r.messages.findLastIndex(v=>v.role==="human"),j=p>x?d(r.messages[p]):void 0,T=r.messages.at(-1)?.role,b=Array.from(new Set(r.messages.slice(0,Math.max(0,x)).filter(v=>v.role==="assistant"&&!!v.jobId).map(v=>v.jobId))),h=c.some(v=>!!v.responseText||!!v.question||!!v.result||!!v.memoryReviewCard||!!v.memoryReceipt),l=c.some(v=>!!v.error);return{id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,preview:s,messageCount:r.messages.length,hasReply:h,hasError:l,lastMessageRole:T,pendingQuestion:j,acknowledgedJobIds:b,elementIdentifiers:r.elementIdentifiers}})}async getThreadHistory(e,n=6){let t=await this.getThread(e);return!t||t.messages.length===0?[]:t.messages.length<=n?t.messages:[t.messages[0],...t.messages.slice(-(n-1))]}async readThread(e){try{let n=JSON.parse(await gt(e,"utf8"));if(n?.version!==2||!Array.isArray(n.messages))return null;let t=await Promise.all(n.messages.map(async({detailArtifact:r,...i})=>{let s={};if(r?.path)try{let c=await gt(Ee(Wn(this.legacyFilePath),r.path),"utf8");zn("sha256").update(c).digest("hex")===r.sha256&&(s=JSON.parse(c))}catch{}return Ct({...i,...s})}));return{id:n.id,createdAt:n.createdAt,updatedAt:n.updatedAt,elementIdentifiers:n.elementIdentifiers,messages:t}}catch{return null}}async encodeMessage(e){await this.persistMessageMedia(e);let n=Pc(e),t=kc(e);if(Object.keys(n).length===0)return t;let r=Sc(n),i=zn("sha256").update(r).digest("hex"),s=Ee("artifacts","thread-messages",`${i}.json`);await tn(this.artifactsDir,{recursive:!0});try{await gt(Ee(Wn(this.legacyFilePath),s),"utf8")}catch{await _t(Ee(Wn(this.legacyFilePath),s),r)}return{...t,detailArtifact:{path:s,sha256:i}}}async persistMessageMedia(e){let n=async t=>{if(Wn(t)===this.mediaDir)return t;try{let r=await gt(t),i=zn("sha256").update(r).digest("hex"),s=Ee(this.mediaDir,`${i}${bc(t)||".bin"}`);await tn(this.mediaDir,{recursive:!0});try{await gt(s)}catch{await _t(s,r)}return s}catch{return t}};e.screenshotPath&&(e.screenshotPath=await n(e.screenshotPath)),e.screenshotPaths&&(e.screenshotPaths=Object.fromEntries(await Promise.all(Object.entries(e.screenshotPaths).map(async([t,r])=>[t,await n(r)])))),e.imagePaths&&(e.imagePaths=Object.fromEntries(await Promise.all(Object.entries(e.imagePaths).map(async([t,r])=>[t,await Promise.all(r.map(n))])))),e.attachmentFiles&&(e.attachmentFiles=Object.fromEntries(await Promise.all(Object.entries(e.attachmentFiles).map(async([t,r])=>[t,await Promise.all(r.map(async i=>({...i,path:await n(i.path)})))])))),e.replyImagePaths&&(e.replyImagePaths=await Promise.all(e.replyImagePaths.map(n)))}async persistThread(e){this.writeChain=this.writeChain.then(async()=>{try{await tn(this.threadsDir,{recursive:!0});let n=this.index??{...nn,files:{}},t=n.files[e.id]??`${zn("sha256").update(e.id).digest("hex").slice(0,32)}.json`,r=await Promise.all(e.messages.map(s=>this.encodeMessage(s))),i={...e,version:2,messages:r};await _t(Ee(this.threadsDir,t),JSON.stringify(i,null,2)),n.files[e.id]=t,n.updatedAt=Date.now(),this.index=n,await _t(this.indexPath,JSON.stringify(n,null,2))}catch(n){console.error("[ThreadStore] Failed to persist thread:",n)}}),await this.writeChain}async persistAll(){if(this.cache){for(let e of Object.values(this.cache.threads))await this.persistThread(e);Object.keys(this.cache.threads).length===0&&(await tn(this.threadsDir,{recursive:!0}),this.index=this.index??{...nn,files:{}},await _t(this.indexPath,JSON.stringify(this.index,null,2)))}}async deletePersistedThread(e){this.writeChain=this.writeChain.then(async()=>{let n=this.index??{...nn,files:{}},t=n.files[e];t&&await Ic(Ee(this.threadsDir,t)).catch(()=>{}),delete n.files[e],n.updatedAt=Date.now(),this.index=n,await tn(this.threadsDir,{recursive:!0}),await _t(this.indexPath,JSON.stringify(n,null,2))}),await this.writeChain}};import{mkdir as Rc,open as Tc,readFile as jc,rename as Mc,unlink as Ac}from"fs/promises";import{dirname as Ec,join as _c}from"path";var ai={schemaVersion:1,theme:"auto",updatedAt:null};function ci(o){return o==="light"||o==="dark"||o==="auto"?o:null}async function Cc(o,e){await Rc(Ec(o),{recursive:!0});let n=`${o}.${process.pid}.${Date.now()}.tmp`;try{let t=await Tc(n,"w");try{await t.writeFile(`${JSON.stringify(e,null,2)}
174
- `,"utf8"),await t.sync()}finally{await t.close()}await Mc(n,o)}catch(t){throw await Ac(n).catch(()=>{}),t}}var Gn=class{constructor(e){this.path=_c(e,".popmelt","ui-preferences.json")}async load(){try{let e=JSON.parse(await jc(this.path,"utf8")),n=ci(e.theme);return n?{exists:!0,preferences:{schemaVersion:1,theme:n,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:null}}:{exists:!1,preferences:{...ai}}}catch{return{exists:!1,preferences:{...ai}}}}async setTheme(e){let n={schemaVersion:1,theme:e,updatedAt:new Date().toISOString()};return await Cc(this.path,n),n}};function di(o){return ci(o)!==null}function li(o){return Oc(o).slice(0,12)}var $c=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function Oc(o){let e=typeof TextEncoder<"u"?Array.from(new TextEncoder().encode(o)):Dc(o),n=e.length*8;for(e.push(128);e.length%64!==56;)e.push(0);for(let T=7;T>=0;T--)e.push(n/Math.pow(2,T*8)&255);let t=1779033703,r=3144134277,i=1013904242,s=2773480762,c=1359893119,d=2600822924,p=528734635,x=1541459225,j=new Array(64);for(let T=0;T<e.length;T+=64){for(let E=0;E<16;E++){let y=T+E*4;j[E]=(e[y]<<24|e[y+1]<<16|e[y+2]<<8|e[y+3])>>>0}for(let E=16;E<64;E++){let y=Ye(j[E-15],7)^Ye(j[E-15],18)^j[E-15]>>>3,L=Ye(j[E-2],17)^Ye(j[E-2],19)^j[E-2]>>>10;j[E]=j[E-16]+y+j[E-7]+L>>>0}let b=t,h=r,l=i,v=s,w=c,m=d,u=p,P=x;for(let E=0;E<64;E++){let y=Ye(w,6)^Ye(w,11)^Ye(w,25),L=w&m^~w&u,C=P+y+L+$c[E]+j[E]>>>0,f=Ye(b,2)^Ye(b,13)^Ye(b,22),M=b&h^b&l^h&l,D=f+M>>>0;P=u,u=m,m=w,w=v+C>>>0,v=l,l=h,h=b,b=C+D>>>0}t=t+b>>>0,r=r+h>>>0,i=i+l>>>0,s=s+v>>>0,c=c+w>>>0,d=d+m>>>0,p=p+u>>>0,x=x+P>>>0}return[t,r,i,s,c,d,p,x].map(T=>T.toString(16).padStart(8,"0")).join("")}function Ye(o,e){return o>>>e|o<<32-e}function Dc(o){let e=[];for(let n=0;n<o.length;n++){let t=o.charCodeAt(n);t<128?e.push(t):t<2048?e.push(192|t>>6,128|t&63):e.push(224|t>>12,128|t>>6&63,128|t&63)}return e}var pi={name:"@popmelt.com/core",version:"0.8.11",description:"The design collaboration layer for AI coding agents",license:"PolyForm-Shield-1.0.0",author:"Popmelt <reb@popmelt.com> (https://popmelt.com)",homepage:"https://github.com/popmelt/core",bugs:{url:"https://github.com/popmelt/core/issues"},repository:{type:"git",url:"git+https://github.com/popmelt/core.git"},keywords:["ai","annotations","collaboration","devtools","react","visual-feedback"],bin:{popmelt:"dist/cli.mjs"},sideEffects:!1,engines:{node:">=18.0.0"},scripts:{build:"tsup",clean:"git clean -xdf .turbo node_modules dist",format:'prettier --check "**/*.{ts,tsx}"',lint:"eslint .","pack:smoke":"node scripts/pack-smoke.mjs",prepublishOnly:"pnpm run verify",test:"vitest run","test:watch":"vitest",typecheck:"tsc --noEmit --incremental false",verify:"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build && pnpm run pack:smoke"},exports:{".":{source:"./src/index.ts",types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./provider":{source:"./src/components/PopmeltProvider.tsx",types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./server":{source:"./src/server/index.ts",types:"./dist/server.d.mts",import:"./dist/server.mjs"},"./memory":{source:"./src/memory/index.ts",types:"./dist/memory.d.mts",import:"./dist/memory.mjs"},"./memory/legacy":{source:"./src/server/memory/index.ts",types:"./dist/memory-legacy.d.mts",import:"./dist/memory-legacy.mjs"},"./memory/store":{source:"./src/server/memory/journal-index.ts",types:"./dist/memory-store.d.mts",import:"./dist/memory-store.mjs"},"./canvas":{source:"./src/canvas/index.ts",import:"./dist/canvas.mjs"},"./next":{source:"./src/plugins/next.ts",import:"./dist/plugin-next.mjs",default:"./dist/plugin-next.mjs"},"./vite":{source:"./src/plugins/vite.ts",types:"./dist/plugin-vite.d.mts",import:"./dist/plugin-vite.mjs",default:"./dist/plugin-vite.mjs"},"./astro":{source:"./src/plugins/astro.ts",types:"./dist/plugin-astro.d.mts",import:"./dist/plugin-astro.mjs",default:"./dist/plugin-astro.mjs"}},files:["dist","LICENSE","README.md","THIRD_PARTY_NOTICES.md"],dependencies:{"modern-screenshot":"4.7.0",ws:"8.21.1"},peerDependencies:{"lucide-react":">=1.23.0",next:">=14.0.0",react:">=18.0.0","react-dom":">=18.0.0"},peerDependenciesMeta:{next:{optional:!0}},devDependencies:{"@kit/eslint-config":"workspace:^","@types/react":"19.1.0","@types/react-dom":"19.1.2","@types/ws":"8.18.1",eslint:"^9.24.0",geist:"1.7.2",jsdom:"26.1.0","lucide-react":"^1.23.0",next:"15.3.8",prettier:"^3.5.3",react:"19.1.0","react-dom":"19.1.0",tsup:"^8.5.1",typescript:"^5.8.3",vitest:"^3.2.4"}};var on=pi.version;var Qc=1111,Xc=["Read","Edit","Write","Glob","Grep","Bash","WebFetch","WebSearch","Bash(curl:*)"],Yc=1800*1e3,Zc=3600*1e3,fi=45e3,ed=5e3,td=1e4,nd=2*1024*1024;function hi(o){return o.length<=1?o[0]??"":["The developer sent these queued steering messages while you were working:","",...o.map((e,n)=>`${n+1}. ${e}`)].join(`
174
+ `,"utf8"),await t.sync()}finally{await t.close()}await Mc(n,o)}catch(t){throw await Ac(n).catch(()=>{}),t}}var Gn=class{constructor(e){this.path=_c(e,".popmelt","ui-preferences.json")}async load(){try{let e=JSON.parse(await jc(this.path,"utf8")),n=ci(e.theme);return n?{exists:!0,preferences:{schemaVersion:1,theme:n,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:null}}:{exists:!1,preferences:{...ai}}}catch{return{exists:!1,preferences:{...ai}}}}async setTheme(e){let n={schemaVersion:1,theme:e,updatedAt:new Date().toISOString()};return await Cc(this.path,n),n}};function di(o){return ci(o)!==null}function li(o){return Oc(o).slice(0,12)}var $c=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function Oc(o){let e=typeof TextEncoder<"u"?Array.from(new TextEncoder().encode(o)):Dc(o),n=e.length*8;for(e.push(128);e.length%64!==56;)e.push(0);for(let T=7;T>=0;T--)e.push(n/Math.pow(2,T*8)&255);let t=1779033703,r=3144134277,i=1013904242,s=2773480762,c=1359893119,d=2600822924,p=528734635,x=1541459225,j=new Array(64);for(let T=0;T<e.length;T+=64){for(let E=0;E<16;E++){let y=T+E*4;j[E]=(e[y]<<24|e[y+1]<<16|e[y+2]<<8|e[y+3])>>>0}for(let E=16;E<64;E++){let y=Ye(j[E-15],7)^Ye(j[E-15],18)^j[E-15]>>>3,L=Ye(j[E-2],17)^Ye(j[E-2],19)^j[E-2]>>>10;j[E]=j[E-16]+y+j[E-7]+L>>>0}let b=t,h=r,l=i,v=s,w=c,m=d,u=p,P=x;for(let E=0;E<64;E++){let y=Ye(w,6)^Ye(w,11)^Ye(w,25),L=w&m^~w&u,C=P+y+L+$c[E]+j[E]>>>0,f=Ye(b,2)^Ye(b,13)^Ye(b,22),M=b&h^b&l^h&l,D=f+M>>>0;P=u,u=m,m=w,w=v+C>>>0,v=l,l=h,h=b,b=C+D>>>0}t=t+b>>>0,r=r+h>>>0,i=i+l>>>0,s=s+v>>>0,c=c+w>>>0,d=d+m>>>0,p=p+u>>>0,x=x+P>>>0}return[t,r,i,s,c,d,p,x].map(T=>T.toString(16).padStart(8,"0")).join("")}function Ye(o,e){return o>>>e|o<<32-e}function Dc(o){let e=[];for(let n=0;n<o.length;n++){let t=o.charCodeAt(n);t<128?e.push(t):t<2048?e.push(192|t>>6,128|t&63):e.push(224|t>>12,128|t>>6&63,128|t&63)}return e}var pi={name:"@popmelt.com/core",version:"0.8.12",description:"The design collaboration layer for AI coding agents",license:"PolyForm-Shield-1.0.0",author:"Popmelt <reb@popmelt.com> (https://popmelt.com)",homepage:"https://github.com/popmelt/core",bugs:{url:"https://github.com/popmelt/core/issues"},repository:{type:"git",url:"git+https://github.com/popmelt/core.git"},keywords:["ai","annotations","collaboration","devtools","react","visual-feedback"],bin:{popmelt:"dist/cli.mjs"},sideEffects:!1,engines:{node:">=18.0.0"},scripts:{build:"tsup",clean:"git clean -xdf .turbo node_modules dist",format:'prettier --check "**/*.{ts,tsx}"',lint:"eslint .","pack:smoke":"node scripts/pack-smoke.mjs",prepublishOnly:"pnpm run verify",test:"vitest run","test:watch":"vitest",typecheck:"tsc --noEmit --incremental false",verify:"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build && pnpm run pack:smoke"},exports:{".":{source:"./src/index.ts",types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./provider":{source:"./src/components/PopmeltProvider.tsx",types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./server":{source:"./src/server/index.ts",types:"./dist/server.d.mts",import:"./dist/server.mjs"},"./memory":{source:"./src/memory/index.ts",types:"./dist/memory.d.mts",import:"./dist/memory.mjs"},"./memory/legacy":{source:"./src/server/memory/index.ts",types:"./dist/memory-legacy.d.mts",import:"./dist/memory-legacy.mjs"},"./memory/store":{source:"./src/server/memory/journal-index.ts",types:"./dist/memory-store.d.mts",import:"./dist/memory-store.mjs"},"./canvas":{source:"./src/canvas/index.ts",import:"./dist/canvas.mjs"},"./next":{source:"./src/plugins/next.ts",import:"./dist/plugin-next.mjs",default:"./dist/plugin-next.mjs"},"./vite":{source:"./src/plugins/vite.ts",types:"./dist/plugin-vite.d.mts",import:"./dist/plugin-vite.mjs",default:"./dist/plugin-vite.mjs"},"./astro":{source:"./src/plugins/astro.ts",types:"./dist/plugin-astro.d.mts",import:"./dist/plugin-astro.mjs",default:"./dist/plugin-astro.mjs"}},files:["dist","LICENSE","README.md","THIRD_PARTY_NOTICES.md"],dependencies:{"modern-screenshot":"4.7.0",ws:"8.21.1"},peerDependencies:{"lucide-react":">=1.23.0",next:">=14.0.0",react:">=18.0.0","react-dom":">=18.0.0"},peerDependenciesMeta:{next:{optional:!0}},devDependencies:{"@kit/eslint-config":"workspace:^","@types/react":"19.1.0","@types/react-dom":"19.1.2","@types/ws":"8.18.1",eslint:"^9.24.0",geist:"1.7.2",jsdom:"26.1.0","lucide-react":"^1.23.0",next:"15.3.8",prettier:"^3.5.3",react:"19.1.0","react-dom":"19.1.0",tsup:"^8.5.1",typescript:"^5.8.3",vitest:"^3.2.4"}};var on=pi.version;var Qc=1111,Xc=["Read","Edit","Write","Glob","Grep","Bash","WebFetch","WebSearch","Bash(curl:*)"],Yc=1800*1e3,Zc=3600*1e3,fi=45e3,ed=5e3,td=1e4,nd=2*1024*1024;function hi(o){return o.length<=1?o[0]??"":["The developer sent these queued steering messages while you were working:","",...o.map((e,n)=>`${n+1}. ${e}`)].join(`
175
175
  `)}function rn(o){return[...new Set(o.flatMap(e=>{let n=e.imprintSummary;return e.role==="assistant"&&n?.grounding&&!n.resolvedAction?[n.grounding.explanationId]:[]}))]}function od(o,e){if(e.size===1)return[...o].reverse().find(n=>{let t=n.imprintSummary;return n.role==="assistant"&&!!t?.grounding&&!t?.resolvedAction&&e.has(t.grounding.explanationId)})}function wi(o){if(!o)return!1;try{let e=new URL(o);return e.hostname==="localhost"||e.hostname.endsWith(".localhost")||e.hostname==="127.0.0.1"||e.hostname==="::1"||e.hostname==="[::1]"}catch{return!1}}function rd(o,e){let n=[];for(let t of o)if(t.type==="delta"){let r=t.text;if(!r)continue;let i=n[n.length-1];i&&i.kind==="text"?i.text+=r:n.push({kind:"text",text:r})}else if(t.type==="tool_use"){let r=t.tool||"",i=t.file??void 0,s=t.content??void 0,c=i?i.split("/").pop()??i:void 0,d;switch(r){case"Read":d=c?`Reading ${c}`:"Reading file";break;case"Edit":d=c?`Editing ${c}`:"Editing file";break;case"Write":d=c?`Writing ${c}`:"Writing file";break;case"Bash":d=s?s.split(`
176
176
  `)[0].trim().slice(0,60):"Running command";break;case"Glob":d="Searching files";break;case"Grep":d="Searching code";break;case"WebFetch":d="Fetching page";break;case"WebSearch":d="Searching web";break;default:d=r?`Using ${r}`:"tool";break}let p=i??s??void 0,x=i?vi(i)?i:Vc(e,i):void 0,j=n[n.length-1];j&&j.kind==="tool_group"&&j.tool===r?j.items.push({label:d,detail:p,...x?{filePath:x}:{}}):n.push({kind:"tool_group",tool:r,items:[{label:d,detail:p,...x?{filePath:x}:{}}]})}else t.type==="orientation"&&n.push({kind:"orientation",orientation:t.orientation});return n}function id(o,e){if(o.processedIds.length===0&&o.success)return"No accepted decisions were ready for model projection.";if(o.success&&o.proposalId)return"";let n=[];return o.success?n.push("Model suggestion ready."):n.push("Model projection failed."),o.proposalId&&n.push("Review the proposed model changes below."),e&&(e.outputStats?n.push(`${e.outputStats.ruleCount} rules, ${e.outputStats.tokenSectionCount} token sections, ${e.outputStats.componentCount} components proposed from ${e.decisionIds.length} decision${e.decisionIds.length===1?"":"s"}.`):n.push(`${e.decisionIds.length} decision${e.decisionIds.length===1?"":"s"} processed.`)),o.error&&(n.push(""),n.push(`Error: ${o.error}`),n.push("The selected decisions were not marked applied and remain visible in projection history.")),n.join(`
177
177
  `)}function sd(o,e=96){let n=o.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}...`:n}function gi(o){let e=o.styleModifications.flatMap(s=>{let c=s.element?.reactComponent||s.element?.tagName||s.selector;return s.changes.map(d=>`${c}: ${d.property} ${d.original||"unset"} -> ${d.modified||"unset"}`)}),n=(o.spacingTokenChanges??[]).map(s=>`${s.tokenName}: ${s.originalPx}px -> ${s.newPx}px`),t=(o.textModifications??[]).map(s=>`${s.element?.reactComponent||s.element?.tagName||s.selector}: text ${s.original||"empty"} -> ${s.modified||"empty"}`),r=o.annotations.map(s=>{let c=s.instruction?.trim();if(c)return c;if(s.imageCount&&s.imageCount>0)return`${s.imageCount} image${s.imageCount===1?"":"s"}`;let d=s.elements?.[0]?.reactComponent||s.elements?.[0]?.selector||s.linkedSelector||s.type;return`${s.type==="annotation"?"Annotation":`${s.type} annotation`} on ${d}`}),i=[...e,...t,...n,...r].map(s=>sd(s)).filter(Boolean);return i.length===0?"Annotation":i.length<=3?i.join("; "):`${i.slice(0,3).join("; ")}; +${i.length-3} more`}function ad(o,e){let n=o.headers.origin;wi(n)&&(e.setHeader("Access-Control-Allow-Origin",n),e.setHeader("Access-Control-Allow-Methods","GET, POST, PATCH, DELETE, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, X-Popmelt-Project-Id"))}function _(o,e,n){o.writeHead(e,{"Content-Type":"application/json"}),o.end(JSON.stringify(n))}async function _e(o){let e=[],n=0;for await(let r of o){let i=typeof r=="string"?Buffer.from(r):r;if(n+=i.length,n>16384)throw new Error("Request body too large");e.push(i)}if(e.length===0)return{};let t=JSON.parse(Buffer.concat(e).toString("utf8"));if(!t||typeof t!="object"||Array.isArray(t))throw new Error("Expected a JSON object");return t}async function cd(o,e){let n=[],t=0;for await(let r of o){let i=typeof r=="string"?Buffer.from(r):r;if(t+=i.length,t>e)throw new Error("Request body too large");n.push(i)}return Buffer.concat(n)}function dd(o,e){let n=o.headers["x-popmelt-project-id"];return(Array.isArray(n)?n[0]:n)||e.searchParams.get("projectId")||null}function ld(o,e){if(!o)return e;let n=o.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);if(!n)return e;let[,t,r,i]=n;return`\x1B[38;2;${parseInt(t,16)};${parseInt(r,16)};${parseInt(i,16)}m${e}\x1B[0m`}function Qn(o,e){try{o.res.write(`event: ${e.type}
@@ -1 +1 @@
1
- import{a as p}from"./chunk-NOHXTT24.mjs";import{request as c}from"http";function u(){let e=process.env.POPMELT_BRIDGE_URL;if(!e)return null;try{let t=new URL(e);return{port:t.port?Number.parseInt(t.port,10):null,projectId:process.env.POPMELT_PROJECT_ID||null,leaseEligible:!1}}catch{return null}}async function m(e,t,n){let o=u();if(e?.bridge===!1||o)return o??{port:null,projectId:null,leaseEligible:!1};try{let{startPopmelt:i}=await import("./server-FFFFIJ7Y.mjs"),r=t.config?.server?.host,l=r===!0?"0.0.0.0":r||"localhost",s=t.config?.server?.port??n,d=`http://${l==="0.0.0.0"?"localhost":l}:${s}`,a=await i({port:e?.port,projectRoot:e?.projectRoot,devOrigin:d,force:!0,detached:!0,manageLease:!1});return console.log(`[popmelt] bridge ready at http://localhost:${a.port}`),{port:a.port,projectId:a.projectId,leaseEligible:!0}}catch(i){let r=i instanceof Error?i.message:String(i);return console.warn("[popmelt] bridge failed to start:",r),{port:null,projectId:null,leaseEligible:!1}}}async function v(e,t,n=fetch){if(!e.leaseEligible||e.port===null)return null;let o=await p({port:e.port,projectId:e.projectId},n);if(!o)return null;let i=()=>{r()},r=async()=>{process.removeListener("beforeExit",i),await o.release()};return process.once("beforeExit",i),t.httpServer?.once("close",()=>{r()}),{id:o.id,release:r}}function g(e,t,n){if(n.port===null||!t.startsWith(e))return null;let o=t.slice(e.length),i=o==="/status"?"/status":`/canvas${o}`,r=new URL(i,`http://localhost:${n.port}`);return n.projectId&&r.searchParams.set("projectId",n.projectId),r}function b(e,t){return(n,o,i)=>{let r=g(e,n.url||"",t());if(!r)return i();let l=c(r,{method:n.method,headers:{...n.headers,host:r.host}},s=>{o.writeHead(s.statusCode||502,s.headers),s.pipe(o)});l.on("error",()=>{o.writeHead(502,{"Content-Type":"text/plain"}),o.end(`Popmelt bridge not running on port ${t().port}`)}),n.pipe(l)}}function P(e){let t=e.port===null?null:`http://localhost:${e.port}`;return`window.__POPMELT_BRIDGE_URL__=${JSON.stringify(t)};window.__POPMELT_PROJECT_ID__=${JSON.stringify(e.projectId)};`}export{m as a,v as b,b as c,P as d};
1
+ import{a as p}from"./chunk-NOHXTT24.mjs";import{request as c}from"http";function u(){let e=process.env.POPMELT_BRIDGE_URL;if(!e)return null;try{let t=new URL(e);return{port:t.port?Number.parseInt(t.port,10):null,projectId:process.env.POPMELT_PROJECT_ID||null,leaseEligible:!1}}catch{return null}}async function m(e,t,n){let o=u();if(e?.bridge===!1||o)return o??{port:null,projectId:null,leaseEligible:!1};try{let{startPopmelt:i}=await import("./server-OGLISVYX.mjs"),r=t.config?.server?.host,l=r===!0?"0.0.0.0":r||"localhost",s=t.config?.server?.port??n,d=`http://${l==="0.0.0.0"?"localhost":l}:${s}`,a=await i({port:e?.port,projectRoot:e?.projectRoot,devOrigin:d,force:!0,detached:!0,manageLease:!1});return console.log(`[popmelt] bridge ready at http://localhost:${a.port}`),{port:a.port,projectId:a.projectId,leaseEligible:!0}}catch(i){let r=i instanceof Error?i.message:String(i);return console.warn("[popmelt] bridge failed to start:",r),{port:null,projectId:null,leaseEligible:!1}}}async function v(e,t,n=fetch){if(!e.leaseEligible||e.port===null)return null;let o=await p({port:e.port,projectId:e.projectId},n);if(!o)return null;let i=()=>{r()},r=async()=>{process.removeListener("beforeExit",i),await o.release()};return process.once("beforeExit",i),t.httpServer?.once("close",()=>{r()}),{id:o.id,release:r}}function g(e,t,n){if(n.port===null||!t.startsWith(e))return null;let o=t.slice(e.length),i=o==="/status"?"/status":`/canvas${o}`,r=new URL(i,`http://localhost:${n.port}`);return n.projectId&&r.searchParams.set("projectId",n.projectId),r}function b(e,t){return(n,o,i)=>{let r=g(e,n.url||"",t());if(!r)return i();let l=c(r,{method:n.method,headers:{...n.headers,host:r.host}},s=>{o.writeHead(s.statusCode||502,s.headers),s.pipe(o)});l.on("error",()=>{o.writeHead(502,{"Content-Type":"text/plain"}),o.end(`Popmelt bridge not running on port ${t().port}`)}),n.pipe(l)}}function P(e){let t=e.port===null?null:`http://localhost:${e.port}`;return`window.__POPMELT_BRIDGE_URL__=${JSON.stringify(t)};window.__POPMELT_PROJECT_ID__=${JSON.stringify(e.projectId)};`}export{m as a,v as b,b as c,P as d};
package/dist/cli.mjs CHANGED
@@ -172,7 +172,7 @@ These are public collaboration signals, not private reasoning. Keep each field c
172
172
  `,"utf8"),await t.sync()}finally{await t.close()}try{await sc(n,o)}catch(r){throw await ac(n).catch(()=>{}),r}}function dc(o,e){return{version:1,projectId:o,createdAt:e,updatedAt:e,head:{sequence:0,hash:null},explanations:[],concrete:[],relations:[]}}function lc(o,e){let n=o.explanations.findIndex(t=>t.id===e.id);n>=0?o.explanations[n]=Ee(e):o.explanations.push(Ee(e))}function Co(o,e){let n=Ee(o);for(let t of e)if(t.op==="add_explanation"){if(n.explanations.some(r=>r.id===t.explanation.id))throw new Error(`Imprint explanation already exists: ${t.explanation.id}`);n.explanations.push(Ee(t.explanation))}else if(t.op==="replace_explanation")lc(n,t.explanation);else if(t.op==="remove_explanation")n.explanations=n.explanations.filter(r=>r.id!==t.explanationId),n.relations=n.relations.filter(r=>r.fromId!==t.explanationId&&r.toId!==t.explanationId);else if(t.op==="add_concrete")n.concrete.some(r=>r.id===t.concrete.id)||n.concrete.push(Ee(t.concrete));else if(t.op==="remove_concrete")n.concrete=n.concrete.filter(r=>r.id!==t.concreteId),n.relations=n.relations.filter(r=>r.fromId!==t.concreteId&&r.toId!==t.concreteId);else if(t.op==="add_evidence"){let r=n.explanations.find(i=>i.id===t.explanationId);if(!r)throw new Error(`Unknown imprint explanation: ${t.explanationId}`);r.evidence.some(i=>i.id===t.evidence.id)||(r.evidence.push(Ee(t.evidence)),r.updatedAt=t.evidence.createdAt)}else if(t.op==="revise_explanation"){let r=n.explanations.find(i=>i.id===t.explanationId);if(!r)throw new Error(`Unknown imprint explanation: ${t.explanationId}`);Object.assign(r,Ee(t.patch),{updatedAt:t.updatedAt})}else if(t.op==="add_relation"){let r=n.explanations.some(s=>s.id===t.relation.fromId),i=n.explanations.some(s=>s.id===t.relation.toId)||n.concrete.some(s=>s.id===t.relation.toId);if(!r||!i)throw new Error(`Imprint relation references an unknown explanation: ${t.relation.id}`);n.relations.some(s=>s.id===t.relation.id)||n.relations.push(Ee(t.relation))}else t.op==="remove_relation"&&(n.relations=n.relations.filter(r=>r.id!==t.relationId));return n}function pc(o,e){let n=[],t=Ee(o);for(let r of e){if(r.op==="add_explanation")n.unshift({op:"remove_explanation",explanationId:r.explanation.id});else if(r.op==="remove_explanation"){let i=t.explanations.find(s=>s.id===r.explanationId);i&&n.unshift({op:"add_explanation",explanation:Ee(i)})}else if(r.op==="add_concrete")n.unshift({op:"remove_concrete",concreteId:r.concrete.id});else if(r.op==="remove_concrete"){let i=t.concrete.find(s=>s.id===r.concreteId);i&&n.unshift({op:"add_concrete",concrete:Ee(i)})}else if(r.op==="replace_explanation"||r.op==="revise_explanation"||r.op==="add_evidence"){let i=r.op==="replace_explanation"?r.explanation.id:r.explanationId,s=t.explanations.find(c=>c.id===i);s&&n.unshift({op:"replace_explanation",explanation:Ee(s)})}else if(r.op==="add_relation")n.unshift({op:"remove_relation",relationId:r.relation.id});else if(r.op==="remove_relation"){let i=t.relations.find(s=>s.id===r.relationId);i&&n.unshift({op:"add_relation",relation:Ee(i)})}t=Co(t,[r])}return n}function ti(o){return o.op==="add_explanation"||o.op==="replace_explanation"?[o.explanation.id]:o.op==="remove_explanation"||o.op==="add_evidence"||o.op==="revise_explanation"?[o.explanationId]:o.op==="add_relation"?[o.relation.fromId,o.relation.toId]:[]}var qn=class{constructor(e,n){this.projectRoot=e;this.projectId=n;this.writeChain=Promise.resolve();this.imprintDir=_t(e,".popmelt","imprint"),this.manifestPath=_t(this.imprintDir,"manifest.json"),this.graphPath=_t(this.imprintDir,"graph.json"),this.journalDir=_t(this.imprintDir,"journal")}async readManifest(){try{let e=JSON.parse(await Zr(this.manifestPath,"utf8"));if(e.version!==1||e.projectId!==this.projectId)throw new Error("Imprint manifest does not match this project.");return e}catch(e){if(e.code!=="ENOENT")throw e;let n=new Date().toISOString();return{version:1,projectId:this.projectId,createdAt:n,updatedAt:n,head:{sequence:0,hash:null}}}}async load(){let e=await this.readManifest(),t=(await ic(this.journalDir).catch(c=>{if(c.code==="ENOENT")return[];throw c})).filter(c=>/^\d{12}-.+\.json$/.test(c)).sort(),r=dc(this.projectId,e.createdAt),i=[],s=null;for(let c=0;c<t.length;c++){let d=JSON.parse(await Zr(_t(this.journalDir,t[c]),"utf8")),{hash:p,...x}=d;if(d.sequence!==c+1||d.previousHash!==s||p!==ei(x))throw new Error(`Imprint journal hash mismatch at sequence ${d.sequence}.`);r=Co(r,d.mutations),r.updatedAt=d.committedAt,r.head={sequence:d.sequence,hash:d.hash},i.push(d),s=d.hash}return{graph:r,transactions:i,recoveredTransactions:Math.max(0,i.length-e.head.sequence)}}async commit(e){let n;return this.writeChain=this.writeChain.then(async()=>{let t=await this.load();if(t.transactions.some(j=>j.transactionId===e.transactionId))throw new Error(`Imprint transaction already exists: ${e.transactionId}`);let r=t.graph.head.sequence+1,i=pc(t.graph,e.mutations),s={version:1,sequence:r,transactionId:e.transactionId,projectId:this.projectId,committedAt:e.committedAt,previousHash:t.graph.head.hash,source:e.source,summary:e.summary,mutations:Ee(e.mutations),inverseMutations:i,...e.undoesTransactionId?{undoesTransactionId:e.undoesTransactionId}:{}},c={...s,hash:ei(s)},d=Co(t.graph,c.mutations);d.updatedAt=e.committedAt,d.head={sequence:r,hash:c.hash};let p=`${String(r).padStart(12,"0")}-${e.transactionId}.json`;await nn(_t(this.journalDir,p),c);let x={version:1,projectId:this.projectId,createdAt:d.createdAt,updatedAt:e.committedAt,head:d.head};await nn(this.graphPath,d),await nn(this.manifestPath,x),n={graph:d,transaction:c}}),await this.writeChain,n}async undo(e,n,t,r){let i=await this.load(),s=i.transactions.find(p=>p.transactionId===e);if(!s)throw new Error("The imprint update is no longer available to undo.");if(i.transactions.some(p=>p.undoesTransactionId===e))throw new Error("This imprint update has already been undone.");let c=new Set(s.mutations.flatMap(ti));if(i.transactions.filter(p=>p.sequence>s.sequence).some(p=>p.mutations.some(x=>ti(x).some(j=>c.has(j)))))throw new Error("This imprint update has newer dependent changes and cannot be undone cleanly. Edit or challenge the current explanation instead.");return this.commit({transactionId:r,committedAt:t,source:n,summary:`Undo: ${s.summary}`,mutations:s.inverseMutations,undoesTransactionId:e})}async recover(){let e=await this.load();return await nn(this.graphPath,e.graph),await nn(this.manifestPath,{version:1,projectId:this.projectId,createdAt:e.graph.createdAt,updatedAt:e.graph.updatedAt,head:e.graph.head}),{...e,recoveredTransactions:0}}};var uc=new Set(["application_only","transient_state","concrete_without_model_path","duplicate","insufficient_evidence","task_specific_detail","no_shared_understanding_change"]),mc=new Set(["about","after","again","before","being","change","from","have","into","make","should","that","the","their","this","with","would","here","only"]);function fc(o){return o.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().replace(/[^a-z0-9]+/g," ").trim().replace(/\s+/g," ")}function zn(o){return new Set(fc(o).split(" ").filter(e=>e.length>2&&!mc.has(e)))}function Wn(o,e){if(!o.size||!e.size)return 0;let n=0;for(let t of o)e.has(t)&&(n+=1);return n/Math.min(o.size,e.size)}function $o(o){return!o||!Array.isArray(o.values)||o.values.length===0?{kind:"project",values:["*"]}:{kind:o.kind,values:[...new Set(o.values.map(e=>e.trim()).filter(Boolean))]}}function nt(o,e,n){return{id:Qe(),kind:e==="excepts"?"exception":e==="challenges"?"correction":"observation",stance:e,summary:n,threadId:o.threadId,jobId:o.jobId,createdAt:o.occurredAt??new Date().toISOString()}}function je(o,e=800){return typeof o=="string"?o.trim().slice(0,e):""}function ni(o){if(!o||typeof o!="object"||Array.isArray(o))return;let e=o;if(!["project","route","component","selector","file"].includes(String(e.kind))||!Array.isArray(e.values))return;let n=e.values.filter(t=>typeof t=="string"&&!!t.trim());return n.length?{kind:e.kind,values:n}:void 0}function oi(o,e){if(!o||!e.trim())return{found:!1};let n=o;for(let t of e.split(".").filter(Boolean))if(Array.isArray(n)){let r=Number(t);if(!Number.isInteger(r)||r<0||r>=n.length)return{found:!1};n=n[r]}else if(n&&typeof n=="object"&&Object.prototype.hasOwnProperty.call(n,t))n=n[t];else return{found:!1};return{found:!0,value:n}}function Oo(o){let e=[...o.matchAll(/<imprint>([\s\S]*?)<\/imprint>/g)],n=o.replace(/<imprint>[\s\S]*?<\/imprint>/g,"").replace(/<imprint>[\s\S]*$/g,"").trim(),t=e.at(-1)?.[1];if(!t)return{visibleText:n};try{let r=JSON.parse(t);if(r.decision==="none"){let T=String(r.reason);if(!uc.has(T))throw new Error("imprint no-op reason is invalid");return{draft:{decision:"none",reason:T},visibleText:n}}if(r.decision!==void 0&&r.decision!=="mutate")throw new Error("imprint decision is invalid");let i=r.summary,s=i?.kind;if(!["added","strengthened","refined","challenged","exception","consolidated"].includes(String(s)))throw new Error("summary.kind is invalid");let c={kind:s,title:je(i?.title,120),detail:je(i?.detail,500)};if(!c.title||!c.detail)throw new Error("summary title and detail are required");let d=Array.isArray(r.appliedExplanationIds)?r.appliedExplanationIds.filter(T=>typeof T=="string"&&!!T.trim()):[],p=[];for(let T of Array.isArray(r.mutations)?r.mutations:[]){if(!T||typeof T!="object")continue;let b=T;if(b.op==="add"&&["intention","principle","pattern"].includes(String(b.kind))){let h=je(b.statement),l=je(b.rationale);if(!h||!l)continue;p.push({op:"add",clientId:je(b.clientId,100)||void 0,kind:b.kind,statement:h,rationale:l,scope:ni(b.scope),rootReason:je(b.rootReason,300)||void 0})}else if(b.op==="revise"&&typeof b.explanationId=="string"){let h={op:"revise",explanationId:b.explanationId,statement:je(b.statement)||void 0,rationale:je(b.rationale)||void 0,scope:ni(b.scope),reopenGrounding:b.reopenGrounding===!0};(h.statement||h.rationale||h.scope||h.reopenGrounding)&&p.push(h)}else if(b.op==="evidence"&&typeof b.explanationId=="string"&&["supports","challenges","excepts"].includes(String(b.stance))){let h=je(b.summary);h&&p.push({op:"evidence",explanationId:b.explanationId,stance:b.stance,summary:h})}else if(b.op==="relation"&&typeof b.fromId=="string"&&typeof b.toId=="string"&&["operationalizes","refines","supports","contradicts","excepts","instantiates"].includes(String(b.type))){let h=je(b.rationale);if(!h)continue;p.push({op:"relation",type:b.type,fromId:b.fromId,toId:b.toId,rationale:h})}else if(b.op==="supersede"&&typeof b.explanationId=="string"&&typeof b.replacementId=="string"){let h=je(b.reason);h&&p.push({op:"supersede",explanationId:b.explanationId,replacementId:b.replacementId,reason:h})}else if(b.op==="bind_concrete"&&typeof b.explanationId=="string"){let h=je(b.modelPath,300);h&&p.push({op:"bind_concrete",explanationId:b.explanationId,modelPath:h,rationale:je(b.rationale)})}else b.op==="retire"&&typeof b.explanationId=="string"&&p.push({op:"retire",explanationId:b.explanationId,reason:je(b.reason)})}let x=r.grounding,j=x&&typeof x.explanationId=="string"&&je(x.question)?{explanationId:x.explanationId,question:je(x.question,300)}:void 0;return{draft:{decision:"mutate",summary:c,appliedExplanationIds:d,mutations:p,grounding:j},visibleText:n}}catch(r){return{visibleText:n,error:r instanceof Error?r.message:String(r)}}}function Do(o){let e=o?.explanations??[],n=new Set(o?.pendingGroundingExplanationIds??[]);return["","## Continuous imprinting","","An imprint is provisional shared understanding learned through human-AI collaboration. It is advisory, not authoritative product truth. Accepted product decisions above always win when they conflict.",...e.length?["","Relevant explanations from the project imprint:",...e.map((t,r)=>[`${r+1}. [${t.state}; ${t.kind}] ${t.statement}`,` - Why: ${t.rationale}`,` - Scope: ${t.scope.kind} ${t.scope.values.join(", ")}`,` - Explanation: ${t.id}`,...n.has(t.id)?[" - Grounding: already pending; do not ask again"]:[],...t.concrete.map(i=>` - Concrete terminal: ${i.modelPath} = ${JSON.stringify(i.value)}`)].join(`
173
173
  `)),...o?.truncated?["Additional imprint context exists outside this bounded packet."]:[]]:[],...o?.relations?.length?["","Known explanation topology:",...o.relations.map(t=>`- ${t.fromId} --${t.type}--> ${t.toId}: ${t.rationale}`)]:[],"","Work normally and preserve developer agency. You may use an emerging or testing explanation as a hypothesis without asking permission first. Silence is not confirmation.","The default outcome is no imprint mutation. Completing work, applying an existing explanation, or making a successful design choice does not by itself constitute learning.","Mutate the imprint only when this collaboration changed reusable shared understanding: a future agent facing a meaningfully different task would behave differently because of what was learned here.","","Before proposing a mutation, apply every admission test:","1. Reusable: it guides a future decision beyond reproducing this exact edit.","2. Novel: it is not already expressed by an explanation or its evidence.","3. Durable: it is an intention, rationale, relationship, or recurring pattern, not temporary implementation state.","4. Atomic: it expresses one claim at one abstraction level.","5. Scoped: its applicability can be named without silently generalizing.","6. Supported: the human supplied evidence, correction, or confirmation, not merely acceptance of completed work.","If any test fails, return a decision of none.","","Usually not learning: exact copy substitutions, one-pixel adjustments, element reordering, implementation mechanics, keeping something hidden temporarily, applying an already-known pattern, or a stylistic choice made without human feedback. A task-specific edit becomes learning only if the human establishes a reusable dependency or rationale beyond that edit.","When a candidate overlaps an existing explanation, consolidate before adding. Same meaning plus a new observation means evidence only. A concrete application means bind_concrete, not a broader explanation. A scope correction means revise scope. A direct disagreement means add the replacement and supersede the contradicted explanation. A different abstraction level means a separate related explanation.","Keep correction identity explicit. If feedback refines an emerging or testing explanation without rejecting its underlying claim, revise it and set reopenGrounding true; do not also add challenging evidence to that same explanation. If feedback rejects the claim as written, preserve that rejected wording, add a distinct replacement, and supersede the old explanation. Never revise an explanation and mark that same identity challenged in one update.","Topology assessment is mandatory for every add mutation. Connect the new clientId with relation or supersede mutations whenever it overlaps, specializes, operationalizes, supports, contradicts, or excepts another surfaced or newly-added explanation. If it is genuinely a new root with no meaningful relative, include rootReason on the add mutation explaining why. Unmapped additions without rootReason are rejected.","Never append implementation facts to an intention merely because they occurred in the same component. Grounded explanations are append-only: add evidence for a compatible observation, but never revise or demote the grounded explanation. A material change in meaning, causal rationale, abstraction level, or applicability must be a new testing explanation linked to the grounded parent with a refines, operationalizes, or excepts relation.","Grounded explanations may support new higher-level theory. Emerging explanations must not be the sole basis for another durable explanation. Concrete project facts should remain concrete; do not turn a one-off value into a universal principle.","Request grounding only when an ungrounded explanation materially influenced the action, this application produced genuinely new evidence, and that explanation does not already have grounding pending. Ask at most one grounding question per thread.","","At the end, append exactly one machine-readable decision block after the normal response. It is hidden from the developer:",'<imprint>{"decision":"none","reason":"application_only|transient_state|concrete_without_model_path|duplicate|insufficient_evidence|task_specific_detail|no_shared_understanding_change"}</imprint>',"Or, only after every admission test passes:",'<imprint>{"decision":"mutate","summary":{"kind":"added|strengthened|refined|challenged|exception|consolidated","title":"<short expandable-summary title>","detail":"<what changed in shared understanding>"},"appliedExplanationIds":["<only an ungrounded explanation materially tested here>"],"mutations":[{"op":"add","clientId":"new-1","kind":"intention|principle|pattern","statement":"<one durable atomic explanation>","rationale":"<why the evidence supports it>","scope":{"kind":"project|route|component|selector|file","values":["<scope>"]},"rootReason":"<only when this is genuinely unrelated to every surfaced or new explanation>"},{"op":"revise","explanationId":"<only an emerging or testing id>","statement":"<optional>","rationale":"<optional>","scope":{"kind":"component","values":["CardTile"]},"reopenGrounding":false},{"op":"evidence","explanationId":"<id>","stance":"supports|challenges|excepts","summary":"<thread evidence>"},{"op":"relation","type":"operationalizes|refines|supports|contradicts|excepts|instantiates","fromId":"<id or clientId>","toId":"<id or clientId>","rationale":"<why>"},{"op":"supersede","explanationId":"<contradicted old id>","replacementId":"<new clientId or existing id>","reason":"<direct conflict>"},{"op":"bind_concrete","explanationId":"<id or clientId>","modelPath":"<exact existing model path>","rationale":"<how this fact operationalizes the explanation>"},{"op":"retire","explanationId":"<id>","reason":"<why>"}],"grounding":{"explanationId":"<one applied ungrounded id or clientId>","question":"<brief post-application confirmation question>"}}</imprint>',"Include only mutation objects actually needed. Applying a grounded explanation requires neither appliedExplanationIds nor a mutation. Omit grounding unless its three conditions pass. Never claim that a new explanation is grounded."].join(`
174
174
  `)}var on=class{constructor(e,n){this.noopCounts=new Map;this.store=new qn(e,n)}recordNoop(e){this.noopCounts.set(e,(this.noopCounts.get(e)??0)+1)}diagnostics(){return{noopDecisions:Object.fromEntries(this.noopCounts)}}async contextualize(e){let n=zn(e.text??""),t=zn((e.subjectHints??[]).join(" ")),r=new Set(e.pendingGroundingExplanationIds??[]);if(!n.size&&!t.size&&!r.size)return;let{graph:i}=await this.store.load(),s=i.explanations.filter(h=>h.state!=="retired"&&h.state!=="challenged").map(h=>{let l=zn([h.statement,h.rationale].join(" ")),v=zn(h.scope.values.join(" ")),w=Wn(l,n),m=Wn(v,n),u=Wn(v,t),P=Wn(l,t),E=w+m*.2+u*.25+P*.1+(h.state==="grounded"?.08:0)+(r.has(h.id)?1:0),y=r.has(h.id)||(n.size?w>=.12||m>=.5:u>=.2||P>=.2);return{item:h,score:E,relevant:y}}).filter(h=>h.relevant&&h.score>=.18).sort((h,l)=>l.score-h.score||l.item.updatedAt.localeCompare(h.item.updatedAt)),c=Math.max(1,e.maxExplanations??6);if(!s.length)return;let d=s.slice(0,c).map(({item:h})=>h),p=new Set(d.map(h=>h.id)),x=new Set(i.relations.flatMap(h=>p.has(h.fromId)?[h.toId]:p.has(h.toId)?[h.fromId]:[])),j=new Set(i.explanations.flatMap(h=>x.has(h.id)&&h.state!=="retired"&&h.state!=="challenged"?[h.id]:[])),T=i.explanations.filter(h=>j.has(h.id)&&!p.has(h.id)).sort((h,l)=>l.updatedAt.localeCompare(h.updatedAt)).slice(0,4),b=[...d,...T];for(let h of T)p.add(h.id);return{explanations:b.map(h=>{let l=new Set(i.relations.filter(v=>v.fromId===h.id&&v.type==="instantiates").map(v=>v.toId));return{id:h.id,kind:h.kind,statement:h.statement,rationale:h.rationale,scope:h.scope,state:h.state,concrete:i.concrete.filter(v=>l.has(v.id)).map(v=>({id:v.id,modelPath:v.modelPath,value:v.value}))}}),truncated:s.length>d.length||T.length<j.size,...r.size?{pendingGroundingExplanationIds:[...r]}:{},relations:i.relations.filter(h=>p.has(h.fromId)&&p.has(h.toId)&&h.type!=="instantiates").map(h=>({id:h.id,type:h.type,fromId:h.fromId,toId:h.toId,rationale:h.rationale}))}}async capture(e,n){if(e.mutations.length===0&&e.appliedExplanationIds.length===0)return;let t=n.occurredAt??new Date().toISOString(),r=await this.store.load(),i=new Map(r.graph.explanations.map(f=>[f.id,f])),s=new Map,c=new Map,d=[],p=new Set,x=new Set(n.pendingGroundingExplanationIds??[]),j=new Set(e.mutations.flatMap(f=>f.op==="revise"&&e.mutations.some(M=>M.op==="evidence"&&M.stance==="challenges"&&M.explanationId===f.explanationId)?[f.explanationId]:[])),T=new Set(e.mutations.flatMap(f=>f.op==="add"&&f.clientId?[f.clientId]:[])),b=f=>i.has(f)||T.has(f),h=new Set;for(let f of e.mutations)f.op==="relation"&&f.fromId!==f.toId&&b(f.fromId)&&b(f.toId)?(h.add(f.fromId),h.add(f.toId)):f.op==="supersede"&&f.explanationId!==f.replacementId&&b(f.explanationId)&&b(f.replacementId)?(h.add(f.explanationId),h.add(f.replacementId)):f.op==="bind_concrete"&&b(f.explanationId)&&oi(n.concreteModel,f.modelPath).found&&h.add(f.explanationId);let l=r.graph.explanations.length===0;for(let f of e.mutations){if(f.op!=="add")continue;let M=!!(f.clientId&&h.has(f.clientId)),D=!!f.rootReason?.trim()||l;if(!M&&!D)continue;l&&(l=!1);let B=Qe();f.clientId&&s.set(f.clientId,B);let W=f.clientId?e.appliedExplanationIds.includes(f.clientId):!1,V={id:B,kind:f.kind,statement:f.statement,rationale:f.rationale,scope:$o(f.scope),state:W?"testing":"emerging",createdAt:t,updatedAt:t,evidence:[nt(n,"supports",e.summary.detail)]};i.set(B,V),p.add(B),d.push({op:"add_explanation",explanation:V})}let v=f=>s.get(f)??f;for(let f of e.mutations){if(f.op!=="revise")continue;let M=v(f.explanationId),D=i.get(M);if(D?.state!=="grounded")continue;let B=Qe(),W={id:B,kind:D.kind,statement:f.statement??D.statement,rationale:f.rationale??D.rationale,scope:f.scope?$o(f.scope):D.scope,state:"testing",createdAt:t,updatedAt:t,evidence:[nt(n,"supports",e.summary.detail)]};i.set(B,W),c.set(M,B),p.add(B),d.push({op:"add_explanation",explanation:W}),d.push({op:"add_relation",relation:{id:Qe(),type:"refines",fromId:B,toId:M,rationale:f.rationale??e.summary.detail,createdAt:t}})}let w=f=>{let M=v(f);return c.get(M)??M};for(let f of e.mutations){if(f.op==="add")continue;if(f.op==="bind_concrete"){let D=w(f.explanationId);if(!i.has(D))continue;let B=oi(n.concreteModel,f.modelPath);if(!B.found)continue;let W=r.graph.concrete.find(V=>V.modelPath===f.modelPath&&JSON.stringify(V.value)===JSON.stringify(B.value));W||(W={id:Qe(),modelPath:f.modelPath,value:structuredClone(B.value),createdAt:t,updatedAt:t},d.push({op:"add_concrete",concrete:W})),d.push({op:"add_relation",relation:{id:Qe(),type:"instantiates",fromId:D,toId:W.id,rationale:f.rationale,createdAt:t}}),p.add(D);continue}if(f.op==="relation"){let D=w(f.fromId),B=w(f.toId);if(!i.has(D)||!i.has(B)||D===B)continue;d.push({op:"add_relation",relation:{id:Qe(),type:f.type,fromId:D,toId:B,rationale:f.rationale,createdAt:t}}),p.add(D),p.add(B);continue}if(f.op==="supersede"){let D=w(f.explanationId),B=w(f.replacementId);if(!i.has(D)||!i.has(B)||D===B)continue;d.push({op:"add_evidence",explanationId:D,evidence:nt(n,"challenges",f.reason)}),d.push({op:"revise_explanation",explanationId:D,patch:{state:"challenged",supersededBy:B},updatedAt:t}),d.push({op:"add_relation",relation:{id:Qe(),type:"supersedes",fromId:B,toId:D,rationale:f.reason,createdAt:t}}),p.add(D),p.add(B);continue}let M=w(f.explanationId);if(i.has(M))if(p.add(M),f.op==="revise"){if(c.has(v(f.explanationId)))continue;let D=i.get(M);if(!D||D.state!=="emerging"&&D.state!=="testing")continue;let B={...f.statement?{statement:f.statement}:{},...f.rationale?{rationale:f.rationale}:{},...f.scope?{scope:$o(f.scope)}:{},...f.reopenGrounding||j.has(f.explanationId)?{state:"testing"}:{}};d.push({op:"revise_explanation",explanationId:M,patch:B,updatedAt:t})}else if(f.op==="evidence"){if(f.stance==="challenges"&&j.has(f.explanationId))continue;d.push({op:"add_evidence",explanationId:M,evidence:nt(n,f.stance,f.summary)}),f.stance==="challenges"&&d.push({op:"revise_explanation",explanationId:M,patch:{state:"challenged"},updatedAt:t})}else f.op==="retire"&&(d.push({op:"add_evidence",explanationId:M,evidence:nt(n,"challenges",f.reason||"Retired after contradictory collaboration evidence.")}),d.push({op:"revise_explanation",explanationId:M,patch:{state:"retired"},updatedAt:t}))}for(let f of e.appliedExplanationIds){let M=w(f),D=i.get(M);!D||D.state==="grounded"||D.state==="retired"||x.has(M)&&!p.has(M)||(p.has(M)||(p.add(M),d.push({op:"add_evidence",explanationId:M,evidence:{...nt(n,"supports",`Applied as an advisory hypothesis: ${e.summary.detail}`),kind:"application"}})),D.state==="emerging"&&d.push({op:"revise_explanation",explanationId:M,patch:{state:"testing"},updatedAt:t}))}if(!d.length)return;let m=Qe(),u=await this.store.commit({transactionId:m,committedAt:t,source:{kind:"automatic",threadId:n.threadId,jobId:n.jobId},summary:e.summary.title,mutations:d}),P=new Map(u.graph.explanations.map(f=>[f.id,f])),E=[...p].flatMap(f=>{let M=P.get(f);if(!M)return[];let D=!r.graph.explanations.some(W=>W.id===f),B=M.state==="challenged"||M.state==="retired";return[{explanationId:f,action:D?"added":B?"challenged":"revised",statement:M.statement,state:M.state}]}),y=e.grounding?w(e.grounding.explanationId):void 0,L=y?P.get(y):void 0,C=L?.state==="testing"&&!x.has(L.id)?{explanationId:L.id,question:e.grounding.question,state:"testing"}:void 0;return{transactionId:m,kind:e.summary.kind,title:e.summary.title,detail:e.summary.detail,changes:E,...C?{grounding:C}:{}}}async applyGroundingAction(e){let n=e.occurredAt??new Date().toISOString();if(e.action==="undo"||e.action==="dont_learn"){let p=[...new Set([e.summary.transactionId,...e.summary.coalescedTransactionIds??[]])].reverse();for(let x of p)await this.store.undo(x,{kind:"undo",threadId:e.threadId,jobId:e.jobId},n,Qe());return}let t=e.summary.grounding?.explanationId??e.summary.changes[0]?.explanationId;if(!t)throw new Error("This imprint summary has no explanation to update.");let i=(await this.store.load()).graph.explanations.find(p=>p.id===t);if(!i||i.state==="retired")throw new Error("This explanation is no longer active.");let s={kind:e.action==="confirm"?"grounding":"correction",threadId:e.threadId,jobId:e.jobId},c=[],d="";if(e.action==="confirm")c.push({op:"add_evidence",explanationId:t,evidence:{...nt(e,"supports","The developer confirmed that the applied reasoning matched their intent."),kind:"confirmation"}}),c.push({op:"revise_explanation",explanationId:t,patch:{state:"grounded"},updatedAt:n}),d=`Grounded: ${i.statement}`;else if(e.action==="reason_wrong")c.push({op:"add_evidence",explanationId:t,evidence:{...nt(e,"challenges",e.value?.trim()||"The result was right, but this explanation was not the reason."),kind:"correction"}}),c.push({op:"revise_explanation",explanationId:t,patch:{state:"challenged"},updatedAt:n}),d=`Challenged: ${i.statement}`;else if(e.action==="narrow"){let p=(e.value??"").split(",").map(x=>x.trim()).filter(Boolean);if(!p.length)throw new Error("A narrower scope is required.");c.push({op:"revise_explanation",explanationId:t,patch:{scope:{kind:i.scope.kind,values:p},state:"testing"},updatedAt:n}),d=`Narrowed scope: ${i.statement}`}else if(e.action==="exception")c.push({op:"add_evidence",explanationId:t,evidence:{...nt(e,"excepts",e.value?.trim()||"The developer marked this application as an exception."),kind:"exception"}}),d=`Exception recorded: ${i.statement}`;else if(e.action==="edit"){let p=e.value?.trim();if(!p)throw new Error("Edited explanation wording is required.");c.push({op:"revise_explanation",explanationId:t,patch:{statement:p,state:"testing"},updatedAt:n}),d=`Edited: ${p}`}if(!c.length)throw new Error("Unsupported imprint action.");await this.store.commit({transactionId:Qe(),committedAt:n,source:s,summary:d,mutations:c})}};function ri(o,e){return o?.projectId===e.projectId&&o.version===e.version&&o.restartMode===e.restartMode}function Gn(o){return(Array.isArray(o)?o[0]:o)?.split(",")[0]?.trim()||void 0}function No(o){if(!o)return null;try{let e=new URL(o);return["localhost","127.0.0.1","::1"].includes(e.hostname)?e.origin:null}catch{return null}}function ii(o){let e=No(Gn(o.origin));if(e)return e;let n=No(Gn(o.referer));if(n)return n;let t=Gn(o["x-forwarded-host"]);if(!t)return null;let r=Gn(o["x-forwarded-proto"])==="https"?"https":"http";return No(`${r}://${t}`)}function si(o,e,n=5){let t=(d,p)=>(p.completedAt??p.startedAt)-(d.completedAt??d.startedAt),r=[...o].sort(t).slice(0,n),i=o.filter(d=>d.status==="applied"||d.status==="failed").sort(t).slice(0,n),s=e.filter(d=>d.status==="pending"&&d.authorityStatus==="accepted").sort((d,p)=>p.updatedAt-d.updatedAt).slice(0,10),c=s.reduce((d,p)=>(d[p.status]=(d[p.status]??0)+1,d),{});return{recentRuns:r,recentAppliedRuns:i,actionableProposalCounts:c,actionableProposals:s}}import{createHash as Hn}from"crypto";import{mkdir as rn,readFile as vt,unlink as yc,writeFile as $t}from"fs/promises";import{dirname as Vn,extname as vc,join as _e}from"path";var hc={capacity:{label:"At capacity",message:"The model provider is temporarily unavailable. Try again shortly."},rate_limited:{label:"Rate limited",message:"The model provider is receiving too many requests. Try again shortly."},timeout:{label:"Timed out",message:"The model took too long to respond. Try again."},connection:{label:"Connection lost",message:"The model provider disconnected before the run completed. Try again."},authentication:{label:"Sign-in required",message:"The model provider needs to be authenticated before this run can continue."},failed:{label:"Failed",message:"The model could not complete this run. Try again, or inspect the job diagnostics if the problem continues."}};function gc(o){let e=typeof o=="string"?o:(()=>{try{return JSON.stringify(o)}catch{return String(o??"")}})();return/\b(?:http\s*)?503\b|server at capacity|\bat capacity\b|resource[_\s-]?exhausted|temporarily unavailable/i.test(e)?"capacity":/\b(?:http\s*)?429\b|rate[_\s-]?limit|too many requests/i.test(e)?"rate_limited":/timed?\s*out|timeout/i.test(e)?"timeout":/auth(?:entication|orization)? required|oauth|not authenticated|sign[ -]?in required|unauthorized|\b401\b/i.test(e)?"authentication":/transport channel closed|connection (?:closed|lost|reset)|socket hang up|network error|disconnected/i.test(e)?"connection":"failed"}function ai(o,e){let n=e??gc(o);return{kind:n,...hc[n]}}function Ct(o,e){return!o||e||o.attention!=="response_requested"?o:{...o,attention:"response_available"}}function ci(o){let e=Array.from(new Set((o.changedFiles??[]).filter(Boolean))),n=e.length>0?[{kind:"changes_applied",files:e}]:[{kind:"replied"}],t=o.decisionRequired?"decision_required":o.question||o.groundingRequired?"response_requested":o.reviewRequired||o.resolutions?.some(r=>r.status==="needs_review")?"review_required":"response_available";return o.imprintTransactionId&&n.push({kind:"imprint_updated",transactionId:o.imprintTransactionId}),{attention:t,outcomes:n}}var wc={version:1,threads:{}},di=["feedbackContext","annotationSnapshot","memoryReview","imprintContext","toolsUsed","editEvents","segments"],sn={version:2,updatedAt:0,files:{}};function Ic(o){return JSON.stringify(o,null,2)}function bc(o){return Object.fromEntries(di.flatMap(e=>o[e]===void 0?[]:[[e,o[e]]]))}function xc(o){let e={...o};for(let n of di)delete e[n];return e}function Ot(o){let e=o;if(o.error){let n=ai(o.error,o.errorKind);(o.error!==n.message||o.errorKind!==n.kind||o.responseText!==void 0)&&(e={...o,error:n.message,errorKind:n.kind},delete e.responseText)}if(e.imprintSummary?.resolvedAction&&!e.question){let n=Ct(e.result,!1),t=Ct(e.turn?.result,!1);(n!==e.result||t!==e.turn?.result)&&(e={...e,...n?{result:n}:{},...e.turn?{turn:{...e.turn,...t?{result:t}:{}}}:{}})}return e}var Kn=class{constructor(e){this.cache=null;this.index=null;this.writeChain=Promise.resolve();let n=_e(e,".popmelt");this.legacyFilePath=_e(n,"threads.json"),this.threadsDir=_e(n,"threads"),this.indexPath=_e(this.threadsDir,"index.json"),this.artifactsDir=_e(n,"artifacts","thread-messages"),this.mediaDir=_e(n,"artifacts","thread-media")}async load(){if(this.cache)return this.cache;try{let e=JSON.parse(await vt(this.indexPath,"utf-8"));if(e?.version===2&&e.files&&typeof e.files=="object"){this.index=e;let n={};for(let[t,r]of Object.entries(e.files)){let i=await this.readThread(_e(this.threadsDir,r));i&&(n[t]=i)}return this.cache={version:1,threads:n},this.cache}}catch{}try{let e=JSON.parse(await vt(this.legacyFilePath,"utf-8"));if(e?.version===1&&e.threads)return this.cache={version:1,threads:Object.fromEntries(Object.entries(e.threads).map(([n,t])=>[n,{...t,messages:t.messages.map(Ot)}]))},this.index={...sn,files:{},migratedFromLegacyAt:Date.now()},await this.persistAll(),this.cache}catch{}return this.cache={...wc,threads:{}},this.index={...sn,files:{}},this.cache}async getThread(e){return(await this.load()).threads[e]??null}async findContinuationThread(e){if(e.length===0)return null;let n=await this.load(),t=new Set(e);for(let r of Object.values(n.threads))if(r.elementIdentifiers.some(s=>t.has(s)))return r;return null}async createThread(e,n){let t=await this.load(),r={id:e,createdAt:Date.now(),updatedAt:Date.now(),elementIdentifiers:n,messages:[]};return t.threads[e]=r,await this.persistThread(r),r}async appendMessage(e,n){let r=(await this.load()).threads[e];r&&(r.messages.push(Ot(n)),r.updatedAt=Date.now(),await this.persistThread(r))}async appendMessageBeforeQueuedReplies(e,n){let r=(await this.load()).threads[e];if(!r)return;let i=r.messages.findIndex(s=>s.role==="human"&&!!s.replyToQuestion&&s.queued);i>=0?r.messages.splice(i,0,Ot(n)):r.messages.push(Ot(n)),r.updatedAt=Date.now(),await this.persistThread(r)}async updateMessage(e,n,t){let i=(await this.load()).threads[e];if(!i)return!1;let s=i.messages.filter(c=>c.jobId===n);if(s.length===0)return!1;for(let c of s)if(Object.assign(c,t),c.error){let d=Ot(c);Object.assign(c,d),delete c.responseText}return i.updatedAt=Date.now(),await this.persistThread(i),!0}async updateAssistantMessage(e,n,t){let i=(await this.load()).threads[e];if(!i)return!1;let s=[...i.messages].reverse().find(c=>c.role==="assistant"&&c.jobId===n);return s?(Object.assign(s,t),i.updatedAt=Date.now(),await this.persistThread(i),!0):!1}async addElementIdentifiers(e,n){let r=(await this.load()).threads[e];if(!r)return;let i=new Set(r.elementIdentifiers);for(let s of n)i.has(s)||r.elementIdentifiers.push(s);r.updatedAt=Date.now(),await this.persistThread(r)}async deleteThread(e){let n=await this.load();return n.threads[e]?(delete n.threads[e],await this.deletePersistedThread(e),!0):!1}async listRecent(e=5){let n=await this.load(),t=Object.values(n.threads);return t.sort((r,i)=>i.updatedAt-r.updatedAt),t.slice(0,e).map(r=>{let s=r.messages.find(v=>v.role==="human")?.feedbackSummary||"[thread]",c=r.messages.filter(v=>v.role==="assistant"),d=v=>{if(v.role!=="assistant")return;if(v.question)return v.question;let w=v.imprintSummary?.grounding;if(w?.question&&!v.imprintSummary?.resolvedAction)return w.question},p=r.messages.findLastIndex(v=>!!d(v)),x=r.messages.findLastIndex(v=>v.role==="human"),j=p>x?d(r.messages[p]):void 0,T=r.messages.at(-1)?.role,b=Array.from(new Set(r.messages.slice(0,Math.max(0,x)).filter(v=>v.role==="assistant"&&!!v.jobId).map(v=>v.jobId))),h=c.some(v=>!!v.responseText||!!v.question||!!v.result||!!v.memoryReviewCard||!!v.memoryReceipt),l=c.some(v=>!!v.error);return{id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,preview:s,messageCount:r.messages.length,hasReply:h,hasError:l,lastMessageRole:T,pendingQuestion:j,acknowledgedJobIds:b,elementIdentifiers:r.elementIdentifiers}})}async getThreadHistory(e,n=6){let t=await this.getThread(e);return!t||t.messages.length===0?[]:t.messages.length<=n?t.messages:[t.messages[0],...t.messages.slice(-(n-1))]}async readThread(e){try{let n=JSON.parse(await vt(e,"utf8"));if(n?.version!==2||!Array.isArray(n.messages))return null;let t=await Promise.all(n.messages.map(async({detailArtifact:r,...i})=>{let s={};if(r?.path)try{let c=await vt(_e(Vn(this.legacyFilePath),r.path),"utf8");Hn("sha256").update(c).digest("hex")===r.sha256&&(s=JSON.parse(c))}catch{}return Ot({...i,...s})}));return{id:n.id,createdAt:n.createdAt,updatedAt:n.updatedAt,elementIdentifiers:n.elementIdentifiers,messages:t}}catch{return null}}async encodeMessage(e){await this.persistMessageMedia(e);let n=bc(e),t=xc(e);if(Object.keys(n).length===0)return t;let r=Ic(n),i=Hn("sha256").update(r).digest("hex"),s=_e("artifacts","thread-messages",`${i}.json`);await rn(this.artifactsDir,{recursive:!0});try{await vt(_e(Vn(this.legacyFilePath),s),"utf8")}catch{await $t(_e(Vn(this.legacyFilePath),s),r)}return{...t,detailArtifact:{path:s,sha256:i}}}async persistMessageMedia(e){let n=async t=>{if(Vn(t)===this.mediaDir)return t;try{let r=await vt(t),i=Hn("sha256").update(r).digest("hex"),s=_e(this.mediaDir,`${i}${vc(t)||".bin"}`);await rn(this.mediaDir,{recursive:!0});try{await vt(s)}catch{await $t(s,r)}return s}catch{return t}};e.screenshotPath&&(e.screenshotPath=await n(e.screenshotPath)),e.screenshotPaths&&(e.screenshotPaths=Object.fromEntries(await Promise.all(Object.entries(e.screenshotPaths).map(async([t,r])=>[t,await n(r)])))),e.imagePaths&&(e.imagePaths=Object.fromEntries(await Promise.all(Object.entries(e.imagePaths).map(async([t,r])=>[t,await Promise.all(r.map(n))])))),e.attachmentFiles&&(e.attachmentFiles=Object.fromEntries(await Promise.all(Object.entries(e.attachmentFiles).map(async([t,r])=>[t,await Promise.all(r.map(async i=>({...i,path:await n(i.path)})))])))),e.replyImagePaths&&(e.replyImagePaths=await Promise.all(e.replyImagePaths.map(n)))}async persistThread(e){this.writeChain=this.writeChain.then(async()=>{try{await rn(this.threadsDir,{recursive:!0});let n=this.index??{...sn,files:{}},t=n.files[e.id]??`${Hn("sha256").update(e.id).digest("hex").slice(0,32)}.json`,r=await Promise.all(e.messages.map(s=>this.encodeMessage(s))),i={...e,version:2,messages:r};await $t(_e(this.threadsDir,t),JSON.stringify(i,null,2)),n.files[e.id]=t,n.updatedAt=Date.now(),this.index=n,await $t(this.indexPath,JSON.stringify(n,null,2))}catch(n){console.error("[ThreadStore] Failed to persist thread:",n)}}),await this.writeChain}async persistAll(){if(this.cache){for(let e of Object.values(this.cache.threads))await this.persistThread(e);Object.keys(this.cache.threads).length===0&&(await rn(this.threadsDir,{recursive:!0}),this.index=this.index??{...sn,files:{}},await $t(this.indexPath,JSON.stringify(this.index,null,2)))}}async deletePersistedThread(e){this.writeChain=this.writeChain.then(async()=>{let n=this.index??{...sn,files:{}},t=n.files[e];t&&await yc(_e(this.threadsDir,t)).catch(()=>{}),delete n.files[e],n.updatedAt=Date.now(),this.index=n,await rn(this.threadsDir,{recursive:!0}),await $t(this.indexPath,JSON.stringify(n,null,2))}),await this.writeChain}};import{mkdir as Sc,open as Pc,readFile as kc,rename as Rc,unlink as Tc}from"fs/promises";import{dirname as jc,join as Mc}from"path";var li={schemaVersion:1,theme:"auto",updatedAt:null};function pi(o){return o==="light"||o==="dark"||o==="auto"?o:null}async function Ac(o,e){await Sc(jc(o),{recursive:!0});let n=`${o}.${process.pid}.${Date.now()}.tmp`;try{let t=await Pc(n,"w");try{await t.writeFile(`${JSON.stringify(e,null,2)}
175
- `,"utf8"),await t.sync()}finally{await t.close()}await Rc(n,o)}catch(t){throw await Tc(n).catch(()=>{}),t}}var Qn=class{constructor(e){this.path=Mc(e,".popmelt","ui-preferences.json")}async load(){try{let e=JSON.parse(await kc(this.path,"utf8")),n=pi(e.theme);return n?{exists:!0,preferences:{schemaVersion:1,theme:n,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:null}}:{exists:!1,preferences:{...li}}}catch{return{exists:!1,preferences:{...li}}}}async setTheme(e){let n={schemaVersion:1,theme:e,updatedAt:new Date().toISOString()};return await Ac(this.path,n),n}};function ui(o){return pi(o)!==null}function mi(o){return _c(o).slice(0,12)}var Ec=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function _c(o){let e=typeof TextEncoder<"u"?Array.from(new TextEncoder().encode(o)):Cc(o),n=e.length*8;for(e.push(128);e.length%64!==56;)e.push(0);for(let T=7;T>=0;T--)e.push(n/Math.pow(2,T*8)&255);let t=1779033703,r=3144134277,i=1013904242,s=2773480762,c=1359893119,d=2600822924,p=528734635,x=1541459225,j=new Array(64);for(let T=0;T<e.length;T+=64){for(let E=0;E<16;E++){let y=T+E*4;j[E]=(e[y]<<24|e[y+1]<<16|e[y+2]<<8|e[y+3])>>>0}for(let E=16;E<64;E++){let y=Ze(j[E-15],7)^Ze(j[E-15],18)^j[E-15]>>>3,L=Ze(j[E-2],17)^Ze(j[E-2],19)^j[E-2]>>>10;j[E]=j[E-16]+y+j[E-7]+L>>>0}let b=t,h=r,l=i,v=s,w=c,m=d,u=p,P=x;for(let E=0;E<64;E++){let y=Ze(w,6)^Ze(w,11)^Ze(w,25),L=w&m^~w&u,C=P+y+L+Ec[E]+j[E]>>>0,f=Ze(b,2)^Ze(b,13)^Ze(b,22),M=b&h^b&l^h&l,D=f+M>>>0;P=u,u=m,m=w,w=v+C>>>0,v=l,l=h,h=b,b=C+D>>>0}t=t+b>>>0,r=r+h>>>0,i=i+l>>>0,s=s+v>>>0,c=c+w>>>0,d=d+m>>>0,p=p+u>>>0,x=x+P>>>0}return[t,r,i,s,c,d,p,x].map(T=>T.toString(16).padStart(8,"0")).join("")}function Ze(o,e){return o>>>e|o<<32-e}function Cc(o){let e=[];for(let n=0;n<o.length;n++){let t=o.charCodeAt(n);t<128?e.push(t):t<2048?e.push(192|t>>6,128|t&63):e.push(224|t>>12,128|t>>6&63,128|t&63)}return e}var fi={name:"@popmelt.com/core",version:"0.8.11",description:"The design collaboration layer for AI coding agents",license:"PolyForm-Shield-1.0.0",author:"Popmelt <reb@popmelt.com> (https://popmelt.com)",homepage:"https://github.com/popmelt/core",bugs:{url:"https://github.com/popmelt/core/issues"},repository:{type:"git",url:"git+https://github.com/popmelt/core.git"},keywords:["ai","annotations","collaboration","devtools","react","visual-feedback"],bin:{popmelt:"dist/cli.mjs"},sideEffects:!1,engines:{node:">=18.0.0"},scripts:{build:"tsup",clean:"git clean -xdf .turbo node_modules dist",format:'prettier --check "**/*.{ts,tsx}"',lint:"eslint .","pack:smoke":"node scripts/pack-smoke.mjs",prepublishOnly:"pnpm run verify",test:"vitest run","test:watch":"vitest",typecheck:"tsc --noEmit --incremental false",verify:"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build && pnpm run pack:smoke"},exports:{".":{source:"./src/index.ts",types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./provider":{source:"./src/components/PopmeltProvider.tsx",types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./server":{source:"./src/server/index.ts",types:"./dist/server.d.mts",import:"./dist/server.mjs"},"./memory":{source:"./src/memory/index.ts",types:"./dist/memory.d.mts",import:"./dist/memory.mjs"},"./memory/legacy":{source:"./src/server/memory/index.ts",types:"./dist/memory-legacy.d.mts",import:"./dist/memory-legacy.mjs"},"./memory/store":{source:"./src/server/memory/journal-index.ts",types:"./dist/memory-store.d.mts",import:"./dist/memory-store.mjs"},"./canvas":{source:"./src/canvas/index.ts",import:"./dist/canvas.mjs"},"./next":{source:"./src/plugins/next.ts",import:"./dist/plugin-next.mjs",default:"./dist/plugin-next.mjs"},"./vite":{source:"./src/plugins/vite.ts",types:"./dist/plugin-vite.d.mts",import:"./dist/plugin-vite.mjs",default:"./dist/plugin-vite.mjs"},"./astro":{source:"./src/plugins/astro.ts",types:"./dist/plugin-astro.d.mts",import:"./dist/plugin-astro.mjs",default:"./dist/plugin-astro.mjs"}},files:["dist","LICENSE","README.md","THIRD_PARTY_NOTICES.md"],dependencies:{"modern-screenshot":"4.7.0",ws:"8.21.1"},peerDependencies:{"lucide-react":">=1.23.0",next:">=14.0.0",react:">=18.0.0","react-dom":">=18.0.0"},peerDependenciesMeta:{next:{optional:!0}},devDependencies:{"@kit/eslint-config":"workspace:^","@types/react":"19.1.0","@types/react-dom":"19.1.2","@types/ws":"8.18.1",eslint:"^9.24.0",geist:"1.7.2",jsdom:"26.1.0","lucide-react":"^1.23.0",next:"15.3.8",prettier:"^3.5.3",react:"19.1.0","react-dom":"19.1.0",tsup:"^8.5.1",typescript:"^5.8.3",vitest:"^3.2.4"}};var an=fi.version;var Hc=1111,Vc=["Read","Edit","Write","Glob","Grep","Bash","WebFetch","WebSearch","Bash(curl:*)"],Kc=1800*1e3,Qc=3600*1e3,yi=45e3,Xc=5e3,Yc=1e4,Zc=2*1024*1024;function vi(o){return o.length<=1?o[0]??"":["The developer sent these queued steering messages while you were working:","",...o.map((e,n)=>`${n+1}. ${e}`)].join(`
175
+ `,"utf8"),await t.sync()}finally{await t.close()}await Rc(n,o)}catch(t){throw await Tc(n).catch(()=>{}),t}}var Qn=class{constructor(e){this.path=Mc(e,".popmelt","ui-preferences.json")}async load(){try{let e=JSON.parse(await kc(this.path,"utf8")),n=pi(e.theme);return n?{exists:!0,preferences:{schemaVersion:1,theme:n,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:null}}:{exists:!1,preferences:{...li}}}catch{return{exists:!1,preferences:{...li}}}}async setTheme(e){let n={schemaVersion:1,theme:e,updatedAt:new Date().toISOString()};return await Ac(this.path,n),n}};function ui(o){return pi(o)!==null}function mi(o){return _c(o).slice(0,12)}var Ec=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function _c(o){let e=typeof TextEncoder<"u"?Array.from(new TextEncoder().encode(o)):Cc(o),n=e.length*8;for(e.push(128);e.length%64!==56;)e.push(0);for(let T=7;T>=0;T--)e.push(n/Math.pow(2,T*8)&255);let t=1779033703,r=3144134277,i=1013904242,s=2773480762,c=1359893119,d=2600822924,p=528734635,x=1541459225,j=new Array(64);for(let T=0;T<e.length;T+=64){for(let E=0;E<16;E++){let y=T+E*4;j[E]=(e[y]<<24|e[y+1]<<16|e[y+2]<<8|e[y+3])>>>0}for(let E=16;E<64;E++){let y=Ze(j[E-15],7)^Ze(j[E-15],18)^j[E-15]>>>3,L=Ze(j[E-2],17)^Ze(j[E-2],19)^j[E-2]>>>10;j[E]=j[E-16]+y+j[E-7]+L>>>0}let b=t,h=r,l=i,v=s,w=c,m=d,u=p,P=x;for(let E=0;E<64;E++){let y=Ze(w,6)^Ze(w,11)^Ze(w,25),L=w&m^~w&u,C=P+y+L+Ec[E]+j[E]>>>0,f=Ze(b,2)^Ze(b,13)^Ze(b,22),M=b&h^b&l^h&l,D=f+M>>>0;P=u,u=m,m=w,w=v+C>>>0,v=l,l=h,h=b,b=C+D>>>0}t=t+b>>>0,r=r+h>>>0,i=i+l>>>0,s=s+v>>>0,c=c+w>>>0,d=d+m>>>0,p=p+u>>>0,x=x+P>>>0}return[t,r,i,s,c,d,p,x].map(T=>T.toString(16).padStart(8,"0")).join("")}function Ze(o,e){return o>>>e|o<<32-e}function Cc(o){let e=[];for(let n=0;n<o.length;n++){let t=o.charCodeAt(n);t<128?e.push(t):t<2048?e.push(192|t>>6,128|t&63):e.push(224|t>>12,128|t>>6&63,128|t&63)}return e}var fi={name:"@popmelt.com/core",version:"0.8.12",description:"The design collaboration layer for AI coding agents",license:"PolyForm-Shield-1.0.0",author:"Popmelt <reb@popmelt.com> (https://popmelt.com)",homepage:"https://github.com/popmelt/core",bugs:{url:"https://github.com/popmelt/core/issues"},repository:{type:"git",url:"git+https://github.com/popmelt/core.git"},keywords:["ai","annotations","collaboration","devtools","react","visual-feedback"],bin:{popmelt:"dist/cli.mjs"},sideEffects:!1,engines:{node:">=18.0.0"},scripts:{build:"tsup",clean:"git clean -xdf .turbo node_modules dist",format:'prettier --check "**/*.{ts,tsx}"',lint:"eslint .","pack:smoke":"node scripts/pack-smoke.mjs",prepublishOnly:"pnpm run verify",test:"vitest run","test:watch":"vitest",typecheck:"tsc --noEmit --incremental false",verify:"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build && pnpm run pack:smoke"},exports:{".":{source:"./src/index.ts",types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./provider":{source:"./src/components/PopmeltProvider.tsx",types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./server":{source:"./src/server/index.ts",types:"./dist/server.d.mts",import:"./dist/server.mjs"},"./memory":{source:"./src/memory/index.ts",types:"./dist/memory.d.mts",import:"./dist/memory.mjs"},"./memory/legacy":{source:"./src/server/memory/index.ts",types:"./dist/memory-legacy.d.mts",import:"./dist/memory-legacy.mjs"},"./memory/store":{source:"./src/server/memory/journal-index.ts",types:"./dist/memory-store.d.mts",import:"./dist/memory-store.mjs"},"./canvas":{source:"./src/canvas/index.ts",import:"./dist/canvas.mjs"},"./next":{source:"./src/plugins/next.ts",import:"./dist/plugin-next.mjs",default:"./dist/plugin-next.mjs"},"./vite":{source:"./src/plugins/vite.ts",types:"./dist/plugin-vite.d.mts",import:"./dist/plugin-vite.mjs",default:"./dist/plugin-vite.mjs"},"./astro":{source:"./src/plugins/astro.ts",types:"./dist/plugin-astro.d.mts",import:"./dist/plugin-astro.mjs",default:"./dist/plugin-astro.mjs"}},files:["dist","LICENSE","README.md","THIRD_PARTY_NOTICES.md"],dependencies:{"modern-screenshot":"4.7.0",ws:"8.21.1"},peerDependencies:{"lucide-react":">=1.23.0",next:">=14.0.0",react:">=18.0.0","react-dom":">=18.0.0"},peerDependenciesMeta:{next:{optional:!0}},devDependencies:{"@kit/eslint-config":"workspace:^","@types/react":"19.1.0","@types/react-dom":"19.1.2","@types/ws":"8.18.1",eslint:"^9.24.0",geist:"1.7.2",jsdom:"26.1.0","lucide-react":"^1.23.0",next:"15.3.8",prettier:"^3.5.3",react:"19.1.0","react-dom":"19.1.0",tsup:"^8.5.1",typescript:"^5.8.3",vitest:"^3.2.4"}};var an=fi.version;var Hc=1111,Vc=["Read","Edit","Write","Glob","Grep","Bash","WebFetch","WebSearch","Bash(curl:*)"],Kc=1800*1e3,Qc=3600*1e3,yi=45e3,Xc=5e3,Yc=1e4,Zc=2*1024*1024;function vi(o){return o.length<=1?o[0]??"":["The developer sent these queued steering messages while you were working:","",...o.map((e,n)=>`${n+1}. ${e}`)].join(`
176
176
  `)}function cn(o){return[...new Set(o.flatMap(e=>{let n=e.imprintSummary;return e.role==="assistant"&&n?.grounding&&!n.resolvedAction?[n.grounding.explanationId]:[]}))]}function ed(o,e){if(e.size===1)return[...o].reverse().find(n=>{let t=n.imprintSummary;return n.role==="assistant"&&!!t?.grounding&&!t?.resolvedAction&&e.has(t.grounding.explanationId)})}function xi(o){if(!o)return!1;try{let e=new URL(o);return e.hostname==="localhost"||e.hostname.endsWith(".localhost")||e.hostname==="127.0.0.1"||e.hostname==="::1"||e.hostname==="[::1]"}catch{return!1}}function td(o,e){let n=[];for(let t of o)if(t.type==="delta"){let r=t.text;if(!r)continue;let i=n[n.length-1];i&&i.kind==="text"?i.text+=r:n.push({kind:"text",text:r})}else if(t.type==="tool_use"){let r=t.tool||"",i=t.file??void 0,s=t.content??void 0,c=i?i.split("/").pop()??i:void 0,d;switch(r){case"Read":d=c?`Reading ${c}`:"Reading file";break;case"Edit":d=c?`Editing ${c}`:"Editing file";break;case"Write":d=c?`Writing ${c}`:"Writing file";break;case"Bash":d=s?s.split(`
177
177
  `)[0].trim().slice(0,60):"Running command";break;case"Glob":d="Searching files";break;case"Grep":d="Searching code";break;case"WebFetch":d="Fetching page";break;case"WebSearch":d="Searching web";break;default:d=r?`Using ${r}`:"tool";break}let p=i??s??void 0,x=i?bi(i)?i:Wc(e,i):void 0,j=n[n.length-1];j&&j.kind==="tool_group"&&j.tool===r?j.items.push({label:d,detail:p,...x?{filePath:x}:{}}):n.push({kind:"tool_group",tool:r,items:[{label:d,detail:p,...x?{filePath:x}:{}}]})}else t.type==="orientation"&&n.push({kind:"orientation",orientation:t.orientation});return n}function nd(o,e){if(o.processedIds.length===0&&o.success)return"No accepted decisions were ready for model projection.";if(o.success&&o.proposalId)return"";let n=[];return o.success?n.push("Model suggestion ready."):n.push("Model projection failed."),o.proposalId&&n.push("Review the proposed model changes below."),e&&(e.outputStats?n.push(`${e.outputStats.ruleCount} rules, ${e.outputStats.tokenSectionCount} token sections, ${e.outputStats.componentCount} components proposed from ${e.decisionIds.length} decision${e.decisionIds.length===1?"":"s"}.`):n.push(`${e.decisionIds.length} decision${e.decisionIds.length===1?"":"s"} processed.`)),o.error&&(n.push(""),n.push(`Error: ${o.error}`),n.push("The selected decisions were not marked applied and remain visible in projection history.")),n.join(`
178
178
  `)}function od(o,e=96){let n=o.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}...`:n}function wi(o){let e=o.styleModifications.flatMap(s=>{let c=s.element?.reactComponent||s.element?.tagName||s.selector;return s.changes.map(d=>`${c}: ${d.property} ${d.original||"unset"} -> ${d.modified||"unset"}`)}),n=(o.spacingTokenChanges??[]).map(s=>`${s.tokenName}: ${s.originalPx}px -> ${s.newPx}px`),t=(o.textModifications??[]).map(s=>`${s.element?.reactComponent||s.element?.tagName||s.selector}: text ${s.original||"empty"} -> ${s.modified||"empty"}`),r=o.annotations.map(s=>{let c=s.instruction?.trim();if(c)return c;if(s.imageCount&&s.imageCount>0)return`${s.imageCount} image${s.imageCount===1?"":"s"}`;let d=s.elements?.[0]?.reactComponent||s.elements?.[0]?.selector||s.linkedSelector||s.type;return`${s.type==="annotation"?"Annotation":`${s.type} annotation`} on ${d}`}),i=[...e,...t,...n,...r].map(s=>od(s)).filter(Boolean);return i.length===0?"Annotation":i.length<=3?i.join("; "):`${i.slice(0,3).join("; ")}; +${i.length-3} more`}function rd(o,e){let n=o.headers.origin;xi(n)&&(e.setHeader("Access-Control-Allow-Origin",n),e.setHeader("Access-Control-Allow-Methods","GET, POST, PATCH, DELETE, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, X-Popmelt-Project-Id"))}function _(o,e,n){o.writeHead(e,{"Content-Type":"application/json"}),o.end(JSON.stringify(n))}async function Ce(o){let e=[],n=0;for await(let r of o){let i=typeof r=="string"?Buffer.from(r):r;if(n+=i.length,n>16384)throw new Error("Request body too large");e.push(i)}if(e.length===0)return{};let t=JSON.parse(Buffer.concat(e).toString("utf8"));if(!t||typeof t!="object"||Array.isArray(t))throw new Error("Expected a JSON object");return t}async function id(o,e){let n=[],t=0;for await(let r of o){let i=typeof r=="string"?Buffer.from(r):r;if(t+=i.length,t>e)throw new Error("Request body too large");n.push(i)}return Buffer.concat(n)}function sd(o,e){let n=o.headers["x-popmelt-project-id"];return(Array.isArray(n)?n[0]:n)||e.searchParams.get("projectId")||null}function ad(o,e){if(!o)return e;let n=o.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);if(!n)return e;let[,t,r,i]=n;return`\x1B[38;2;${parseInt(t,16)};${parseInt(r,16)};${parseInt(i,16)}m${e}\x1B[0m`}function Zn(o,e){try{o.res.write(`event: ${e.type}