@popmelt.com/core 0.14.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/dist/bridge-entry.mjs +1 -1
- package/dist/{chunk-WVBQZISK.mjs → chunk-NPY4CUO4.mjs} +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +39 -39
- package/dist/plugin-astro.mjs +1 -1
- package/dist/plugin-vite.mjs +1 -1
- package/dist/{server-PUB4CXLY.mjs → server-2EWUDZZ5.mjs} +1 -1
- package/dist/server.mjs +1 -1
- package/package.json +1 -1
package/dist/bridge-entry.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import{mkdir as Pp,unlink as Ap,writeFile as jp}from"fs/promises";import{join as
|
|
|
3
3
|
`);let n=new Map;for(let r of e){let i=r.pathname||"(unknown)",s=n.get(i)??[];s.push(r.instruction),n.set(i,s)}return[...n.entries()].map(([r,i])=>`\`${r}\`
|
|
4
4
|
${i.map(s=>`- ${s}`).join(`
|
|
5
5
|
`)}`).join(`
|
|
6
|
-
`)}var Hr={name:"@popmelt.com/core",version:"0.14.
|
|
6
|
+
`)}var Hr={name:"@popmelt.com/core",version:"0.14.1",description:"A tiny, powerful design layer for humans and AI",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 . && node scripts/check-eslint-suppressions.mjs","pack:smoke":"node scripts/pack-smoke.mjs","peer:smoke":"node scripts/peer-compat-smoke.mjs",prepublishOnly:"pnpm run verify",test:"vitest run","test:coverage":"vitest run --coverage.enabled","test:watch":"vitest",typecheck:"tsc --noEmit --incremental false",verify:"pnpm run typecheck && pnpm run format && pnpm run lint && pnpm run test:coverage && pnpm run build && pnpm run pack:smoke"},exports:{".":{types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./provider":{types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./server":{types:"./dist/server.d.mts",import:"./dist/server.mjs"},"./memory":{types:"./dist/memory.d.mts",import:"./dist/memory.mjs"},"./memory/legacy":{types:"./dist/memory-legacy.d.mts",import:"./dist/memory-legacy.mjs"},"./memory/store":{types:"./dist/memory-store.d.mts",import:"./dist/memory-store.mjs"},"./next":{types:"./dist/plugin-next.d.mts",import:"./dist/plugin-next.mjs",default:"./dist/plugin-next.mjs"},"./vite":{types:"./dist/plugin-vite.d.mts",import:"./dist/plugin-vite.mjs",default:"./dist/plugin-vite.mjs"},"./astro":{types:"./dist/plugin-astro.d.mts",import:"./dist/plugin-astro.mjs",default:"./dist/plugin-astro.mjs"}},files:["dist","codex-plugin","LICENSE","README.md","THIRD_PARTY_NOTICES.md"],dependencies:{"modern-screenshot":"4.7.0",ws:"8.21.3"},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:^","@tanstack/react-router":"1.120.5","@types/react":"19.1.0","@types/react-dom":"19.1.2","@types/ws":"8.18.1","@vitejs/plugin-react":"^5.1.1","@vitest/coverage-v8":"3.2.4",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",vite:"7.3.6",vitest:"^3.2.4"}};var pn=Hr.version;var Ia=new Set(["minimal","low","medium","high","xhigh","max","ultra"]),wa=new Set(["default","flex","fast","priority"]);function Bt(o){let e=typeof o.reasoningEffort=="string"&&Ia.has(o.reasoningEffort)?o.reasoningEffort:void 0,t=typeof o.serviceTier=="string"&&wa.has(o.serviceTier)?o.serviceTier:void 0;return e||t?{reasoningEffort:e,serviceTier:t}:void 0}function Kn(o){let e=[];return o?.reasoningEffort&&e.push(`model_reasoning_effort=${JSON.stringify(o.reasoningEffort)}`),o?.serviceTier&&e.push(`service_tier=${JSON.stringify(o.serviceTier)}`),e}import{createHash as Dd,randomUUID as Nd}from"crypto";import{isAbsolute as Bd,relative as Jd}from"path";import{randomUUID as at}from"crypto";var Qr={project:0,route:1,component:2,selector:2,file:3},Xr={intention:0,principle:1,pattern:2};function Jt(o,e){let t=Qr[o.scope.kind]-Qr[e.scope.kind];return t!==0?t:Xr[o.kind]-Xr[e.kind]}function Yr(o){return o==="expresses"||o==="excepts"}function va(o,e){if(e.type==="expresses"||e.type==="excepts")return structuredClone(e);if(e.type==="operationalizes")return{...structuredClone(e),type:"expresses"};if(e.type==="instantiates")return{...structuredClone(e),type:"expresses",fromId:e.toId,toId:e.fromId};if(e.type==="refines"){let t=o.explanations.find(i=>i.id===e.fromId),n=o.explanations.find(i=>i.id===e.toId);if(!t||!n)return;let r=Jt(t,n);return r===0?void 0:r>0?{...structuredClone(e),type:"expresses"}:{...structuredClone(e),type:"expresses",fromId:e.toId,toId:e.fromId}}}function Rt(o){let e=structuredClone(o),t=new Set;return e.relations=o.relations.flatMap(n=>{let r=va(o,n);if(!r)return[];let i=`${r.type}:${r.fromId}:${r.toStoreId??""}:${r.toId}`;return t.has(i)?[]:(t.add(i),[r])}),e}import{createHash as ba}from"crypto";import{mkdir as xa,open as Sa,readFile as Zr,readdir as Ta,rename as ka,unlink as Ra}from"fs/promises";import{dirname as Pa,join as qt}from"path";function qe(o){return structuredClone(o)}function ei(o){return ba("sha256").update(JSON.stringify(o)).digest("hex")}async function Pt(o,e){await xa(Pa(o),{recursive:!0});let t=`${o}.${process.pid}.${Date.now()}.tmp`,n=await Sa(t,"w");try{await n.writeFile(`${JSON.stringify(e,null,2)}
|
|
7
7
|
`,"utf8"),await n.sync()}finally{await n.close()}try{await ka(t,o)}catch(r){throw await Ra(t).catch(()=>{}),r}}function Aa(o,e){return{version:1,projectId:o,createdAt:e,updatedAt:e,head:{sequence:0,hash:null},explanations:[],concrete:[],relations:[]}}function ja(o,e){let t=o.explanations.findIndex(n=>n.id===e.id);t>=0?o.explanations[t]=qe(e):o.explanations.push(qe(e))}function Wo(o,e){let t=qe(o);for(let n of e)if(n.op==="add_explanation"){if(t.explanations.some(r=>r.id===n.explanation.id))throw new Error(`Imprint explanation already exists: ${n.explanation.id}`);t.explanations.push(qe(n.explanation))}else if(n.op==="replace_explanation")ja(t,n.explanation);else if(n.op==="remove_explanation")t.explanations=t.explanations.filter(r=>r.id!==n.explanationId),t.relations=t.relations.filter(r=>r.fromId!==n.explanationId&&(r.toStoreId!==void 0||r.toId!==n.explanationId));else if(n.op==="add_concrete")t.concrete.some(r=>r.id===n.concrete.id)||t.concrete.push(qe(n.concrete));else if(n.op==="remove_concrete")t.concrete=t.concrete.filter(r=>r.id!==n.concreteId),t.relations=t.relations.filter(r=>r.fromId!==n.concreteId&&(r.toStoreId!==void 0||r.toId!==n.concreteId));else if(n.op==="add_evidence"){let r=t.explanations.find(i=>i.id===n.explanationId);if(!r)throw new Error(`Unknown imprint explanation: ${n.explanationId}`);r.evidence.some(i=>i.id===n.evidence.id)||(r.evidence.push(qe(n.evidence)),r.updatedAt=n.evidence.createdAt)}else if(n.op==="revise_explanation"){let r=t.explanations.find(i=>i.id===n.explanationId);if(!r)throw new Error(`Unknown imprint explanation: ${n.explanationId}`);Object.assign(r,qe(n.patch),{updatedAt:n.updatedAt})}else if(n.op==="add_relation"){let r=n.relation,i=t.explanations.find(w=>w.id===r.fromId),s=!!r.toStoreId,a=s?void 0:t.explanations.find(w=>w.id===r.toId),d=t.concrete.some(w=>w.id===r.fromId),l=!s&&t.concrete.some(w=>w.id===r.toId);if(Yr(r.type)){if(!(r.type==="expresses"?s?!!i:!!((i||d)&&a):!!(i&&(a||s))))throw new Error(`Imprint ${r.type} relation has invalid endpoints: ${r.id}`);if(t.relations.some(b=>b.type===r.type&&b.fromId===r.fromId&&b.toStoreId===r.toStoreId&&b.toId===r.toId))throw new Error(`Duplicate imprint relation: ${r.type}:${r.fromId}:${r.toStoreId??""}:${r.toId}`);if(r.type==="expresses"&&i&&a){if(Jt(i,a)<0)throw new Error(`Imprint expresses relation must point from specific to abstract: ${r.id}`);let b=new Map;for(let x of t.relations)x.type!=="expresses"||x.toStoreId||b.set(x.fromId,[...b.get(x.fromId)??[],x.toId]);let y=[r.toId],k=new Set;for(;y.length;){let x=y.pop();if(x===r.fromId)throw new Error(`Imprint expresses relation would create a cycle: ${r.id}`);k.has(x)||(k.add(x),y.push(...b.get(x)??[]))}}}else if(!i||!a&&!l)throw new Error(`Imprint relation references an unknown explanation: ${r.id}`);t.relations.some(w=>w.id===r.id)||t.relations.push(qe(r))}else n.op==="remove_relation"&&(t.relations=t.relations.filter(r=>r.id!==n.relationId));return t}function Ma(o,e){let t=[],n=qe(o);for(let r of e){if(r.op==="add_explanation")t.unshift({op:"remove_explanation",explanationId:r.explanation.id});else if(r.op==="remove_explanation"){let i=n.explanations.find(s=>s.id===r.explanationId);i&&t.unshift({op:"add_explanation",explanation:qe(i)})}else if(r.op==="add_concrete")t.unshift({op:"remove_concrete",concreteId:r.concrete.id});else if(r.op==="remove_concrete"){let i=n.concrete.find(s=>s.id===r.concreteId);i&&t.unshift({op:"add_concrete",concrete:qe(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=n.explanations.find(a=>a.id===i);s&&t.unshift({op:"replace_explanation",explanation:qe(s)})}else if(r.op==="add_relation")t.unshift({op:"remove_relation",relationId:r.relation.id});else if(r.op==="remove_relation"){let i=n.relations.find(s=>s.id===r.relationId);i&&t.unshift({op:"add_relation",relation:qe(i)})}n=Wo(n,[r])}return t}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.toStoreId?[]:[o.relation.toId]]:[]}var Vn=class{constructor(e,t){this.projectRoot=e;this.projectId=t;this.writeChain=Promise.resolve();this.imprintDir=qt(e,".popmelt","imprint"),this.manifestPath=qt(this.imprintDir,"manifest.json"),this.graphPath=qt(this.imprintDir,"graph.json"),this.journalDir=qt(this.imprintDir,"journal")}async readHead(){return(await this.readManifest()).head}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 t=new Date().toISOString();return{version:1,projectId:this.projectId,createdAt:t,updatedAt:t,head:{sequence:0,hash:null}}}}async loadRaw(){let e=await this.readManifest(),n=(await Ta(this.journalDir).catch(a=>{if(a.code==="ENOENT")return[];throw a})).filter(a=>/^\d{12}-.+\.json$/.test(a)).sort(),r=Aa(this.projectId,e.createdAt),i=[],s=null;for(let a=0;a<n.length;a++){let d=JSON.parse(await Zr(qt(this.journalDir,n[a]),"utf8")),{hash:l,...w}=d;if(d.sequence!==a+1||d.previousHash!==s||l!==ei(w))throw new Error(`Imprint journal hash mismatch at sequence ${d.sequence}.`);r=Wo(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 load(){let e=await this.loadRaw();return{...e,graph:Rt(e.graph)}}async migrateTopology(){let e=await this.readManifest();if(e.topologyVersion===2)return{migrated:!1,relationMutations:0};let t=await this.loadRaw(),n=Rt(t.graph),r=new Map(n.relations.map(s=>[s.id,s])),i=[];for(let s of t.graph.relations){let a=r.get(s.id);a&&a.type===s.type&&a.fromId===s.fromId&&a.toStoreId===s.toStoreId&&a.toId===s.toId||(i.push({op:"remove_relation",relationId:s.id}),a&&i.push({op:"add_relation",relation:a}))}if(i.length){let s=new Date().toISOString();return await this.commit({transactionId:`topology-v2-${t.graph.head.sequence+1}`,committedAt:s,source:{kind:"migration",threadId:"imprint-topology",jobId:"imprint-topology-v2"},summary:"Simplify Imprint topology to expresses and excepts",mutations:i}),{migrated:!0,relationMutations:i.length}}return await Pt(this.graphPath,n),await Pt(this.manifestPath,{...e,topologyVersion:2}),{migrated:!0,relationMutations:0}}async commit(e){let t;return this.writeChain=this.writeChain.then(async()=>{let n=await this.load();if(n.transactions.some(b=>b.transactionId===e.transactionId))throw new Error(`Imprint transaction already exists: ${e.transactionId}`);let r=n.graph.head.sequence+1,i=Ma(n.graph,e.mutations),s={version:1,sequence:r,transactionId:e.transactionId,projectId:this.projectId,committedAt:e.committedAt,previousHash:n.graph.head.hash,source:e.source,summary:e.summary,mutations:qe(e.mutations),inverseMutations:i,...e.undoesTransactionId?{undoesTransactionId:e.undoesTransactionId}:{}},a={...s,hash:ei(s)},d=Wo(n.graph,a.mutations);d.updatedAt=e.committedAt,d.head={sequence:r,hash:a.hash};let l=`${String(r).padStart(12,"0")}-${e.transactionId}.json`;await Pt(qt(this.journalDir,l),a);let w={version:1,topologyVersion:2,projectId:this.projectId,createdAt:d.createdAt,updatedAt:e.committedAt,head:d.head};await Pt(this.graphPath,d),await Pt(this.manifestPath,w),t={graph:d,transaction:a}}),await this.writeChain,t}async undo(e,t,n,r){let i=await this.load(),s=i.transactions.find(l=>l.transactionId===e);if(!s)throw new Error("The imprint update is no longer available to undo.");if(i.transactions.some(l=>l.undoesTransactionId===e))throw new Error("This imprint update has already been undone.");let a=new Set(s.mutations.flatMap(ti));if(i.transactions.filter(l=>l.sequence>s.sequence).some(l=>l.mutations.some(w=>ti(w).some(b=>a.has(b)))))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:n,source:t,summary:`Undo: ${s.summary}`,mutations:s.inverseMutations,undoesTransactionId:e})}async recover(){let e=await this.load();return await Pt(this.graphPath,e.graph),await Pt(this.manifestPath,{version:1,topologyVersion:2,projectId:this.projectId,createdAt:e.graph.createdAt,updatedAt:e.graph.updatedAt,head:e.graph.head}),{...e,recoveredTransactions:0}}};var Ea=new Set(["application_only","transient_state","concrete_without_model_path","duplicate","insufficient_evidence","task_specific_detail","no_shared_understanding_change"]),_a=new Set(["about","after","again","before","being","change","from","have","into","make","should","that","the","their","this","with","would","here","only","consistent","match","matched","matching","mirror","mirrored","mirroring","align","aligned","aligning"]),Ca=[/\bconsistent\s+with\b/i,/\bmatch(?:es|ed|ing)?\b/i,/\bmirror(?:s|ed|ing)?\b/i,/\bthe\s+same\s+as\b/i,/\bborrow(?:s|ed|ing)?\s+from\b/i,/\balign(?:s|ed|ing)?\s+with\b/i,/\b(?:more|look|looks|feel|feels|behave|behaves)\s+like\b/i],$a=/\b(all|any|every|everywhere|across|throughout|globally|project[- ]wide)\b/i;function Ko(o){return!!(o&&$a.test(o))}function Oa(o){return o.scope.kind==="project"||Ko(`${o.statement} ${o.rationale}`)}function Da(o){let e=o?.scope.values.filter(t=>t!=="*").join(", ");return e?`Does applying this understanding here match your intent for ${e}?`:"Does applying this understanding here match your intent?"}function Na(o){return o.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().replace(/[^a-z0-9]+/g," ").trim().replace(/\s+/g," ")}function Ba(o){return o.length>4&&o.endsWith("ies")?[o,`${o.slice(0,-3)}y`]:o.length>3&&o.endsWith("s")&&!o.endsWith("ss")?[o,o.slice(0,-1)]:[o]}function st(o){return new Set(Na(o).split(" ").filter(e=>e.length>2&&!_a.has(e)).flatMap(Ba))}function ni(o){return o.replace(/^\s*(?:please\s+)?(?:let(?:'|’)s\s+)?(?:make|apply|use|keep|change|update)\s+/i,"").replace(/[\s,.:;!?]+$/g,"").trim().slice(0,240)}function Ja(o){if(o)for(let e of Ca){let t=e.exec(o);if(!t||t.index<=0)continue;let n=ni(o.slice(0,t.index)),r=ni(o.slice(t.index+t[0].length));if(n&&r)return{target:n,reference:r}}}function gt(o,e){if(!o.size||!e.size)return 0;let t=0;for(let n of o)e.has(n)&&(t+=1);return t/Math.min(o.size,e.size)}function Go(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 yt(o,e,t){return{id:at(),kind:e==="excepts"?"exception":e==="challenges"?"correction":"observation",stance:e,summary:t,threadId:o.threadId,jobId:o.jobId,createdAt:o.occurredAt??new Date().toISOString()}}function ve(o,e=800){return typeof o=="string"?o.trim().slice(0,e):""}function oi(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 t=e.values.filter(n=>typeof n=="string"&&!!n.trim());return t.length?{kind:e.kind,values:t}:void 0}function ri(o,e,t){if(o&&typeof o=="object"&&!Array.isArray(o)){let i=o,s=ve(i.explanationId,100),a=ve(i.clientId,100),d=ve(i.storeId,100);if(s&&a)throw new Error("relation endpoint must use either explanationId or clientId, not both");let l=s||a;return l?{explanationId:l,...d?{storeId:d}:{}}:void 0}let n=ve(e,100),r=ve(t,100);return n?{explanationId:n,...r?{storeId:r}:{}}:void 0}function ii(o,e){if(!o||!e.trim())return{found:!1};let t=o;for(let n of e.split(".").filter(Boolean))if(Array.isArray(t)){let r=Number(n);if(!Number.isInteger(r)||r<0||r>=t.length)return{found:!1};t=t[r]}else if(t&&typeof t=="object"&&Object.prototype.hasOwnProperty.call(t,n))t=t[n];else return{found:!1};return{found:!0,value:t}}function un(o,e={}){let t=[...o.matchAll(/<imprint>([\s\S]*?)<\/imprint>/g)],n=o.replace(/<imprint>[\s\S]*?<\/imprint>/g,"").replace(/<imprint>[\s\S]*$/g,"").trim(),r=t.at(-1)?.[1],i,s=[];if(r)i=r;else{let d=[...o.matchAll(/<resolution>\s*([\s\S]*?)\s*<\/resolution>/g)].at(-1)?.[1];if(!d)return{visibleText:n,error:"imprint assessment is missing"};try{let l=JSON.parse(d);if(!l||typeof l!="object"||Array.isArray(l)||!Object.prototype.hasOwnProperty.call(l,"imprint"))return{visibleText:n,error:"imprint assessment is missing"};let w=l;i=w.imprint,s=Array.isArray(w.annotations)?w.annotations:[]}catch{return{visibleText:n,error:"resolution envelope is invalid"}}}try{let a=typeof i=="string"?JSON.parse(i):i;if(!a||typeof a!="object"||Array.isArray(a))throw new Error("imprint assessment is invalid");if(a.decision==="none"){let h=String(a.reason);if(!Ea.has(h))throw new Error("imprint no-op reason is invalid");if(h==="task_specific_detail"&&s.some(j=>{if(!j||typeof j!="object"||Array.isArray(j))return!1;let $=j;return($.finalScope??$.inferredScope)?.breadth==="pattern"}))throw new Error("pattern-scoped resolution cannot be classified as task_specific_detail");let u=Array.isArray(a.usedExplanationIds)?a.usedExplanationIds.filter(j=>typeof j=="string"&&!!j.trim()):[],g=Array.isArray(a.appliedExplanationIds)?a.appliedExplanationIds.filter(j=>typeof j=="string"&&!!j.trim()):[],I=new Set(e.context?.explanations.map(j=>j.id)??[]);if([...new Set([...u,...g])].some(j=>!I.has(j)))throw new Error("imprint use must cite only surfaced explanations");let A=[...new Set([...u,...e.applicationOccurred?[]:g])],m=e.applicationOccurred?g:[],f;if(m.length){f=m;let j=new Set(e.context?.pendingGroundingExplanationIds??[]),$=m.filter(R=>{let _=e.context?.explanations.find(X=>X.id===R);return I.has(R)&&_&&(_.state==="emerging"||_.state==="testing")&&!j.has(R)});if($.length){let R=a.grounding,_=typeof R?.explanationId=="string"&&$.includes(R.explanationId)?R.explanationId:$[0],X=ve(R?.question,300);return{draft:{decision:"apply",summary:{title:ve(a.summary?.title,120)||"Applied shared understanding",detail:ve(a.summary?.detail,500)||ve(e.requestText||n,500)||"Applied an ungrounded explanation in a new context."},appliedExplanationIds:m,grounding:{explanationId:_,question:X||"Does applying this understanding here match your intent?"}},visibleText:n}}}if(h==="duplicate"){let j=ve(a.duplicateOfExplanationId,100),$=a.scopeComparison;if(!j)throw new Error("duplicate assessment requires duplicateOfExplanationId");if($!=="equivalent"&&$!=="existing_broader")throw new Error("duplicate assessment requires an equivalent or existing_broader scopeComparison");let R=e.context?.explanations.find(_=>_.id===j);if(!R)throw new Error("duplicate assessment must cite a surfaced explanation");if(Ko(e.requestText)&&!Oa(R))throw new Error("duplicate explanation does not cover the requested broader scope");return{draft:{decision:"none",reason:h,duplicateOfExplanationId:j,scopeComparison:$,...A.length?{usedExplanationIds:A}:{},...f?{appliedExplanationIds:f}:{}},visibleText:n}}return{draft:{decision:"none",reason:h,...A.length?{usedExplanationIds:A}:{},...f?{appliedExplanationIds:f}:{}},visibleText:n}}if(a.decision==="recognize"){let h=ve(a.explanationId,100);if(!h)throw new Error("recognition requires explanationId");let u=e.context?.explanations.find(p=>p.id===h);if(!u)throw new Error("recognition must cite a surfaced explanation");if(u.state!=="grounded")throw new Error("recognition must cite a grounded explanation");let g=a.summary,I={title:ve(g?.title,120),detail:ve(g?.detail,500)};if(!I.title||!I.detail)throw new Error("recognition summary title and detail are required");return{draft:{decision:"recognize",explanationId:h,summary:I},visibleText:n}}if(a.decision==="apply"){let h=a.summary,u={title:ve(h?.title,120),detail:ve(h?.detail,500)};if(!u.title||!u.detail)throw new Error("application summary title and detail are required");let g=Array.isArray(a.appliedExplanationIds)?a.appliedExplanationIds.filter(j=>typeof j=="string"&&!!j.trim()):[];if(!g.length)throw new Error("application requires appliedExplanationIds");let I=new Map(e.context?.explanations.map(j=>[j.id,j])??[]);if(g.some(j=>!I.has(j)))throw new Error("application must cite only surfaced explanations");if(!e.applicationOccurred)return{draft:{decision:"none",reason:"application_only",usedExplanationIds:[...new Set(g)]},visibleText:n};let p=new Set(e.context?.pendingGroundingExplanationIds??[]),A=g.filter(j=>{let $=I.get(j);return $&&($.state==="emerging"||$.state==="testing")&&!p.has(j)});if(!A.length){if(g.every($=>I.get($)?.state==="grounded"||p.has($)))return{draft:{decision:"none",reason:"application_only",appliedExplanationIds:g},visibleText:n};throw new Error("application must cite a surfaced ungrounded explanation")}let m=a.grounding,f=typeof m?.explanationId=="string"&&A.includes(m.explanationId)?m.explanationId:A[0];return{draft:{decision:"apply",summary:u,appliedExplanationIds:g,grounding:{explanationId:f,question:ve(m?.question,300)||"Does applying this understanding here match your intent?"}},visibleText:n}}if(a.decision!==void 0&&a.decision!=="mutate")throw new Error("imprint decision is invalid");let d=a.summary,l=d?.kind;if(!["added","strengthened","refined","challenged","exception","consolidated"].includes(String(l)))throw new Error("summary.kind is invalid");let w={kind:l,title:ve(d?.title,120),detail:ve(d?.detail,500)};if(!w.title||!w.detail)throw new Error("summary title and detail are required");let b=Array.isArray(a.appliedExplanationIds)?a.appliedExplanationIds.filter(h=>typeof h=="string"&&!!h.trim()):[],y=[];for(let h of Array.isArray(a.mutations)?a.mutations:[]){if(!h||typeof h!="object")continue;let u=h;if(u.op==="add"&&["intention","principle","pattern"].includes(String(u.kind))){let g=ve(u.statement),I=ve(u.rationale);if(!g||!I)continue;y.push({op:"add",clientId:ve(u.clientId,100)||void 0,kind:u.kind,statement:g,rationale:I,scope:oi(u.scope),rootReason:ve(u.rootReason,300)||void 0})}else if(u.op==="revise"&&typeof u.explanationId=="string"){let g={op:"revise",explanationId:u.explanationId,statement:ve(u.statement)||void 0,rationale:ve(u.rationale)||void 0,scope:oi(u.scope),reopenGrounding:u.reopenGrounding===!0};(g.statement||g.rationale||g.scope||g.reopenGrounding)&&y.push(g)}else if(u.op==="evidence"&&typeof u.explanationId=="string"&&["supports","challenges","excepts"].includes(String(u.stance))){let g=ve(u.summary);g&&y.push({op:"evidence",explanationId:u.explanationId,stance:u.stance,summary:g})}else if(u.op==="relation"){if(!["expresses","excepts"].includes(String(u.type)))throw new Error("relation type is invalid");let g=ve(u.rationale),I=ri(u.from,u.fromId,u.fromStoreId),p=ri(u.to,u.toId,u.toStoreId);if(!g)throw new Error("relation rationale is required");if(!I||!p)throw new Error("relation endpoints require an explanationId or clientId");y.push({op:"relation",type:u.type,from:I,to:p,rationale:g})}else if(u.op==="supersede"&&typeof u.explanationId=="string"&&typeof u.replacementId=="string"){let g=ve(u.reason);g&&y.push({op:"supersede",explanationId:u.explanationId,replacementId:u.replacementId,reason:g})}else if(u.op==="bind_concrete"&&typeof u.explanationId=="string"){let g=ve(u.modelPath,300);g&&y.push({op:"bind_concrete",explanationId:u.explanationId,modelPath:g,rationale:ve(u.rationale)})}else u.op==="retire"&&typeof u.explanationId=="string"&&y.push({op:"retire",explanationId:u.explanationId,reason:ve(u.reason)})}let k=a.grounding,x=k&&typeof k.explanationId=="string"&&ve(k.question)?{explanationId:k.explanationId,question:ve(k.question,300)}:void 0;return{draft:{decision:"mutate",summary:w,appliedExplanationIds:b,mutations:y,grounding:x},visibleText:n}}catch(a){return{visibleText:n,error:a instanceof Error?a.message:String(a)}}}function mn(o,e={}){let t=o?.explanations??[],n=new Set(o?.pendingGroundingExplanationIds??[]),r=new Set(o?.correctionExplanationIds??[]),i=Ko(e.requestText),s=o?.retrievalIntent,a=o?.historicalCaveats??[],d=t.find(y=>y.storeId&&!y.readOnly)?.storeId,l=(y,k)=>{let x=y[k];return x?`[${x.storeId}] ${x.explanationId}`:k==="from"?y.fromId:y.toId},w=!!o?.relations?.some(y=>y.from&&y.to&&y.from.storeId!==y.to.storeId),b=t.some(y=>y.readOnly);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.",...t.length?["","Relevant explanations from the project imprint:",...t.map((y,k)=>[`${k+1}. [${y.state}; ${y.kind}] ${y.statement}`,` - Why: ${y.rationale}`,` - Scope: ${y.scope.kind} ${y.scope.values.join(", ")}`,` - Explanation: ${y.id}`,...y.storeId?[` - Store: ${y.storeId}${y.readOnly?" (read-only)":" (writable primary)"}`]:[],...n.has(y.id)?[" - Grounding: already pending; do not ask again"]:[],...r.has(y.id)?[" - Correction: the developer selected No for this explanation and the current reply supplies the missing correction context"]:[],...y.concrete.map(x=>` - Concrete terminal: ${x.modelPath} = ${JSON.stringify(x.value)}`)].join(`
|
|
8
8
|
`)),...o?.truncated?["Additional imprint context exists outside this bounded packet."]:[]]:[],...o?.relations?.length?["","Known explanation topology:",...o.relations.map(y=>`- ${y.storeId?`[owned by ${y.storeId}${y.readOnly?"; read-only":""}] `:""}${l(y,"from")} --${y.type}--> ${l(y,"to")}: ${y.rationale}`)]:[],...b||w?["","Store-qualified topology remains locally owned: the relation must originate at an explanation in the writable primary store, while its target may be in a mounted read-only store. Never proxy a relation whose source belongs to a mounted store.",`For a cross-store relation, use qualified endpoints: {"op":"relation","type":"expresses|excepts","from":{"storeId":"${d??"<writable-primary-store>"}","clientId":"<new-specific-client-id>"},"to":{"storeId":"<mounted-target-store>","explanationId":"<existing-abstract-target-id>"},"rationale":"<why>"}. Use clientId for a new explanation created in this transaction and explanationId for an existing durable explanation.`]:[],...s?["","Explicit pattern transfer detected:",`- Target: ${s.target}`,`- Reference: ${s.reference}`,"Before editing, state which dimensions you intend to transfer from the reference and which target-specific behavior you will preserve. Compare the relevant surface, spacing, typography, radius, and interaction behavior; transfer only the dimensions supported by the request and evidence. If the intended transfer remains materially ambiguous after inspecting both anchors, ask one focused question."]:[],...a.length?["","Directly relevant challenged history (historical caveats, not current Imprint truth):",...a.map((y,k)=>[`${k+1}. [challenged; ${y.kind}] ${y.statement}`,` - Why it was previously proposed: ${y.rationale}`,` - Scope: ${y.scope.kind} ${y.scope.values.join(", ")}`,` - Historical explanation: ${y.id}`,...y.storeId?[` - Store: ${y.storeId}${y.readOnly?" (read-only)":" (writable primary)"}`]:[]].join(`
|
|
9
9
|
`)),"Use these caveats only to avoid repeating a rejected or over-broad transfer. Do not cite them as usedExplanationIds or treat them as active guidance."]:[],...t.some(y=>y.readOnly)?["","Mounted-store explanations are read-only context. They may inform the work and be cited as used understanding, but do not mutate, ground, revise, or add evidence to them without an explicit writable orientation for that store."]:[],...o?.unavailableStoreIds?.length?["",`Some mounted Imprint knowledge was unavailable during this bounded read: ${o.unavailableStoreIds.join(", ")}. Do not infer its contents.`]:[],...o?.unavailableTopologyStoreIds?.length?["",`Some mounted Imprint topology was unavailable during this bounded read: ${o.unavailableTopologyStoreIds.join(", ")}. Available explanations remain usable, but do not infer missing relationships.`]:[],"","Work normally and preserve developer agency. A testing explanation may guide action as a hypothesis without asking permission first. An emerging explanation is observation-only: use it to recognize recurrence, not to choose behavior. If the developer independently repeats an emerging observation in a meaningfully different occurrence, that new application may promote it into testing and request grounding. Silence is not confirmation.","Assess learning proactively as part of completing every thread. Do not wait for the developer to ask whether there was a learning. Before choosing none, look one abstraction level above the exact edit and ask: would the reasoning behind this outcome change how a future agent handles a meaningfully different occurrence?","The developer's original annotation, ordinary instruction, scope language, and later corrections are already human-supplied evidence. They can support learning when they establish a reusable dependency, boundary, or rationale; a separate post-completion learning prompt is not required. Mere acceptance of completed work is still insufficient.","The default outcome is no imprint mutation. Completing work or making a successful design choice does not by itself constitute learning.","Application evidence is distinct from changing shared understanding. When an emerging or testing explanation materially influenced a completed action, report decision apply even when no explanation wording changed.","Applying grounded understanding does not mutate the graph. Usually report none. Use decision recognize only when visibly acknowledging the grounded explanation closes a correction loop or otherwise makes consequential reuse legible to the developer. Recognition must cite one exact surfaced grounded explanation ID; never infer or invent an ID.","Application and recognition are whole-statement operations. Cite an existing explanation only when the completed behavior is compatible with every material clause, its scope, and its exceptions. Sharing one useful clause is not a match. If the durable behavior is narrower, add one atomic explanation linked to the broader explanation when the admission tests pass; otherwise report none.","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.","Relationship-first admission: before calling any completed change task-specific, compare its requested behavior and effective scope with every surfaced explanation that could plausibly govern the same subject or treatment. The developer does not need to name an Imprint concept or relation. Infer the relationship from the ordinary instruction, the annotated context, the implementation, and the surfaced explanations.","A narrower completed behavior that departs from an applicable broader explanation establishes an applicability boundary even when the developer did not say exception. Add one narrow testing explanation and link it to the broader rule with excepts. If the behaviors concern distinct concepts rather than the same rule, assess the reusable behavior as a sibling explanation instead. Do not manufacture an exception merely because implementations differ.","Scope and Imprint assessment must agree. If any resolved annotation has an effective inferred or final breadth of pattern, do not classify the Imprint decision as task_specific_detail. Either capture the reusable conceptual change, report application of existing understanding, cite a valid duplicate, or use another accurate no-op reason. The bridge rejects pattern-scoped task_specific_detail assessments.","","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 anywhere in the thread, including the original instruction, not merely acceptance of completed work or the model's own implementation choice.","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. Distinguish mechanics from the reusable reasoning they may reveal: a CSS property alone is not learning, but a human-directed causal rule such as keeping optical adjustment out of layout geometry may be. This heuristic never overrides relationship-first admission: a small local change that narrows or contradicts an applicable surfaced explanation may establish an exception or correction. A task-specific edit otherwise becomes learning only if the human establishes a reusable dependency, applicability boundary, 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.","Duplicate means the same reusable claim is already represented at an equivalent or broader conceptual scope. Shared code, a centralized component, or implementation reuse does not establish conceptual duplication. A narrower component-, route-, selector-, or file-scoped explanation is not a duplicate of newly broadened applicability.","Words such as all, every, across, throughout, globally, and project-wide are explicit applicability signals. When the human broadens a grounded explanation, preserve the grounded narrower explanation and add a broader testing explanation. Link the narrower explanation to the broader one with expresses. Do not substitute another no-op reason for that scope change.",...i?["CURRENT SCOPE SIGNAL: The developer used explicit broadening language in this instruction. Do not classify it as duplicate unless the cited existing explanation already expresses universal or project-wide applicability."]:[],"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.","When an explanation is marked Correction in the supplied context, the developer selected No but the graph has not yet been changed. Interpret the current reply before mutating anything. Decide whether it corrects only the implementation result, the explanation scope, or the reasoning. Do not challenge the whole explanation for a narrow correction, and do not recognize a different explanation merely because one clause overlaps.","Topology assessment is mandatory for every add mutation. Imprint topology has exactly two relation types: expresses and excepts. expresses always points from the more specific, concrete, or lower-level explanation to the more abstract explanation it expresses. excepts points from the narrower exception to the rule whose applicability it limits. Support and challenge belong in evidence; correction belongs in supersede; neither is a topology relation. If an addition is genuinely a new root with no meaningful relative, include rootReason 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 with expresses or excepts. Multiple specific explanations may express the same parent, and one explanation may express multiple parents; never create an expresses cycle.","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 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. The bridge supplies a fallback question when the application is otherwise valid.","","At the end, emit exactly one machine-readable <resolution> envelope after the normal response. Its `annotations` array reports annotation outcomes, and its required `imprint` field completes the learning assessment. The envelope is hidden from the developer. Do not emit a separate <imprint> block.",'As soon as one or more surfaced explanations become actively useful during the work, emit `<imprint-use>{"explanationIds":["<every actively useful surfaced explanation id>"]}</imprint-use>` immediately. This live receipt is hidden from conversational prose. Emit it at the point of use rather than waiting for the final response. Emit a later marker only when additional explanations become actively useful. Never emit it for explanations that were merely retrieved, read, searched, or considered.',"Treat Imprint as actively useful when a surfaced explanation materially informs an answer, recommendation, implementation choice, or other decision. Whenever it is actively useful, always cite every materially used surfaced explanation in `usedExplanationIds`. This produces a usage receipt only; it does not strengthen or mutate shared understanding. Do not cite explanations that were merely retrieved, read, or considered but did not influence the result.","`appliedExplanationIds` is narrower: include an explanation there only when it governed a completed implementation or other observable action that genuinely tests the explanation. Never use `appliedExplanationIds` for an answer-only, informational, research, or read-only request. An explanation may be used without being applied; every applied explanation is also understood to be used.","For no learning, include:",'"imprint":{"decision":"none","reason":"application_only|transient_state|concrete_without_model_path|duplicate|insufficient_evidence|task_specific_detail|no_shared_understanding_change","usedExplanationIds":["<every surfaced explanation that was actively useful, or omit when none>"]}',"A no-op reason cannot suppress genuine application evidence. When a completed action was governed by an ungrounded explanation, report decision apply directly so the summary and grounding question are intentional. Answering a question with that explanation is usage, not application.","When and only when reason is duplicate, also include `duplicateOfExplanationId` naming one surfaced explanation and `scopeComparison` set to `equivalent` or `existing_broader`. The bridge rejects uncited duplicates and duplicates whose cited explanation cannot cover explicit broadening language.","For application evidence without a conceptual change, include:",'"imprint":{"decision":"apply","summary":{"title":"<short expandable-summary title>","detail":"<how the explanation influenced this completed action>"},"appliedExplanationIds":["<surfaced emerging or testing explanation id>"],"grounding":{"explanationId":"<one applied id>","question":"<brief post-application confirmation question>"}}',"For a consequential, non-mutating reuse of grounded understanding that should be visible, include:",'"imprint":{"decision":"recognize","explanationId":"<one exact surfaced grounded explanation id>","summary":{"title":"<short name for the recognized understanding>","detail":"<how it guided this outcome>"}}',"Or, only after every admission test passes for a conceptual change:",'"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":"expresses|excepts","from":{"clientId":"<new-specific-client-id>"},"to":{"explanationId":"<existing-abstract-id>"},"rationale":"<why; use clientId for new transaction-local explanations and explanationId for existing durable explanations>"},{"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 expresses the explanation>"},{"op":"retire","explanationId":"<id>","reason":"<why>"}],"grounding":{"explanationId":"<one applied ungrounded id or clientId>","question":"<brief post-application confirmation question>"}}','The final shape is `<resolution>{"annotations":[...],"imprint":{...}}</resolution>`. The `imprint` field is required even when the decision is none; omission leaves the completed run explicitly unassessed.',"Include only mutation objects actually needed. A new explanation established through completed implementation must include its clientId in appliedExplanationIds; the bridge also derives this application from a completed change as a safeguard. Applying a grounded explanation never requires a mutation, but actively using it still requires its id in appliedExplanationIds. Never claim that a new explanation is grounded."].join(`
|
|
@@ -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 h(e,t,i){let r=u();if(e?.bridge===!1||r)return r??{port:null,projectId:null,leaseEligible:!1};try{let{startPopmelt:o}=await import("./server-
|
|
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 h(e,t,i){let r=u();if(e?.bridge===!1||r)return r??{port:null,projectId:null,leaseEligible:!1};try{let{startPopmelt:o}=await import("./server-2EWUDZZ5.mjs"),n=t.config?.server?.host,l=n===!0?"0.0.0.0":n||"localhost",s=t.config?.server?.port??i,d=`http://${l==="0.0.0.0"?"localhost":l}:${s}`,a=await o({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(o){let n=o instanceof Error?o.message:String(o);return console.warn("[popmelt] bridge failed to start:",n),{port:null,projectId:null,leaseEligible:!1}}}async function v(e,t,i=fetch){if(!e.leaseEligible||e.port===null)return null;let r=await p({port:e.port,projectId:e.projectId},i);if(!r)return null;let o=()=>{n()},n=async()=>{process.removeListener("beforeExit",o),await r.release()};return process.once("beforeExit",o),t.httpServer?.once("close",()=>{n()}),{id:r.id,release:n}}function g(e,t,i){if(i.port===null)return null;let r=new URL(t,"http://popmelt.local");if(r.pathname!==`${e}/status`)return null;let o=new URL("/status",`http://localhost:${i.port}`);return r.searchParams.forEach((n,l)=>o.searchParams.append(l,n)),i.projectId&&o.searchParams.set("projectId",i.projectId),o}function b(e,t){return(i,r,o)=>{let n=g(e,i.url||"",t());if(!n)return o();let l=c(n,{method:i.method,headers:{...i.headers,host:n.host}},s=>{r.writeHead(s.statusCode||502,s.headers),s.pipe(r)});l.on("error",()=>{r.writeHead(502,{"Content-Type":"text/plain"}),r.end(`Popmelt bridge not running on port ${t().port}`)}),i.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{h as a,v as b,b as c,P as d};
|
package/dist/cli.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import{spawn as af}from"child_process";import{readFile as df,unlink as cf}from"f
|
|
|
4
4
|
`);let o=new Map;for(let r of e){let i=r.pathname||"(unknown)",s=o.get(i)??[];s.push(r.instruction),o.set(i,s)}return[...o.entries()].map(([r,i])=>`\`${r}\`
|
|
5
5
|
${i.map(s=>`- ${s}`).join(`
|
|
6
6
|
`)}`).join(`
|
|
7
|
-
`)}var Oi={name:"@popmelt.com/core",version:"0.14.
|
|
7
|
+
`)}var Oi={name:"@popmelt.com/core",version:"0.14.1",description:"A tiny, powerful design layer for humans and AI",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 . && node scripts/check-eslint-suppressions.mjs","pack:smoke":"node scripts/pack-smoke.mjs","peer:smoke":"node scripts/peer-compat-smoke.mjs",prepublishOnly:"pnpm run verify",test:"vitest run","test:coverage":"vitest run --coverage.enabled","test:watch":"vitest",typecheck:"tsc --noEmit --incremental false",verify:"pnpm run typecheck && pnpm run format && pnpm run lint && pnpm run test:coverage && pnpm run build && pnpm run pack:smoke"},exports:{".":{types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./provider":{types:"./dist/index.d.mts",import:"./dist/index.mjs"},"./server":{types:"./dist/server.d.mts",import:"./dist/server.mjs"},"./memory":{types:"./dist/memory.d.mts",import:"./dist/memory.mjs"},"./memory/legacy":{types:"./dist/memory-legacy.d.mts",import:"./dist/memory-legacy.mjs"},"./memory/store":{types:"./dist/memory-store.d.mts",import:"./dist/memory-store.mjs"},"./next":{types:"./dist/plugin-next.d.mts",import:"./dist/plugin-next.mjs",default:"./dist/plugin-next.mjs"},"./vite":{types:"./dist/plugin-vite.d.mts",import:"./dist/plugin-vite.mjs",default:"./dist/plugin-vite.mjs"},"./astro":{types:"./dist/plugin-astro.d.mts",import:"./dist/plugin-astro.mjs",default:"./dist/plugin-astro.mjs"}},files:["dist","codex-plugin","LICENSE","README.md","THIRD_PARTY_NOTICES.md"],dependencies:{"modern-screenshot":"4.7.0",ws:"8.21.3"},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:^","@tanstack/react-router":"1.120.5","@types/react":"19.1.0","@types/react-dom":"19.1.2","@types/ws":"8.18.1","@vitejs/plugin-react":"^5.1.1","@vitest/coverage-v8":"3.2.4",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",vite:"7.3.6",vitest:"^3.2.4"}};var Qe=Oi.version;var Nd=new Set(["minimal","low","medium","high","xhigh","max","ultra"]),Bd=new Set(["default","flex","fast","priority"]);function Vt(t){let e=typeof t.reasoningEffort=="string"&&Nd.has(t.reasoningEffort)?t.reasoningEffort:void 0,n=typeof t.serviceTier=="string"&&Bd.has(t.serviceTier)?t.serviceTier:void 0;return e||n?{reasoningEffort:e,serviceTier:n}:void 0}function yo(t){let e=[];return t?.reasoningEffort&&e.push(`model_reasoning_effort=${JSON.stringify(t.reasoningEffort)}`),t?.serviceTier&&e.push(`service_tier=${JSON.stringify(t.serviceTier)}`),e}import{createHash as Qc,randomUUID as Xc}from"crypto";import{isAbsolute as Yc,relative as Zc}from"path";import{randomUUID as lt}from"crypto";var Di={project:0,route:1,component:2,selector:2,file:3},Ni={intention:0,principle:1,pattern:2};function Kt(t,e){let n=Di[t.scope.kind]-Di[e.scope.kind];return n!==0?n:Ni[t.kind]-Ni[e.kind]}function Bi(t){return t==="expresses"||t==="excepts"}function Jd(t,e){if(e.type==="expresses"||e.type==="excepts")return structuredClone(e);if(e.type==="operationalizes")return{...structuredClone(e),type:"expresses"};if(e.type==="instantiates")return{...structuredClone(e),type:"expresses",fromId:e.toId,toId:e.fromId};if(e.type==="refines"){let n=t.explanations.find(i=>i.id===e.fromId),o=t.explanations.find(i=>i.id===e.toId);if(!n||!o)return;let r=Kt(n,o);return r===0?void 0:r>0?{...structuredClone(e),type:"expresses"}:{...structuredClone(e),type:"expresses",fromId:e.toId,toId:e.fromId}}}function $t(t){let e=structuredClone(t),n=new Set;return e.relations=t.relations.flatMap(o=>{let r=Jd(t,o);if(!r)return[];let i=`${r.type}:${r.fromId}:${r.toStoreId??""}:${r.toId}`;return n.has(i)?[]:(n.add(i),[r])}),e}import{createHash as qd}from"crypto";import{mkdir as Ld,open as Fd,readFile as Ji,readdir as Ud,rename as zd,unlink as Wd}from"fs/promises";import{dirname as Gd,join as Qt}from"path";function Le(t){return structuredClone(t)}function qi(t){return qd("sha256").update(JSON.stringify(t)).digest("hex")}async function Ot(t,e){await Ld(Gd(t),{recursive:!0});let n=`${t}.${process.pid}.${Date.now()}.tmp`,o=await Fd(n,"w");try{await o.writeFile(`${JSON.stringify(e,null,2)}
|
|
8
8
|
`,"utf8"),await o.sync()}finally{await o.close()}try{await zd(n,t)}catch(r){throw await Wd(n).catch(()=>{}),r}}function Hd(t,e){return{version:1,projectId:t,createdAt:e,updatedAt:e,head:{sequence:0,hash:null},explanations:[],concrete:[],relations:[]}}function Vd(t,e){let n=t.explanations.findIndex(o=>o.id===e.id);n>=0?t.explanations[n]=Le(e):t.explanations.push(Le(e))}function yr(t,e){let n=Le(t);for(let o of e)if(o.op==="add_explanation"){if(n.explanations.some(r=>r.id===o.explanation.id))throw new Error(`Imprint explanation already exists: ${o.explanation.id}`);n.explanations.push(Le(o.explanation))}else if(o.op==="replace_explanation")Vd(n,o.explanation);else if(o.op==="remove_explanation")n.explanations=n.explanations.filter(r=>r.id!==o.explanationId),n.relations=n.relations.filter(r=>r.fromId!==o.explanationId&&(r.toStoreId!==void 0||r.toId!==o.explanationId));else if(o.op==="add_concrete")n.concrete.some(r=>r.id===o.concrete.id)||n.concrete.push(Le(o.concrete));else if(o.op==="remove_concrete")n.concrete=n.concrete.filter(r=>r.id!==o.concreteId),n.relations=n.relations.filter(r=>r.fromId!==o.concreteId&&(r.toStoreId!==void 0||r.toId!==o.concreteId));else if(o.op==="add_evidence"){let r=n.explanations.find(i=>i.id===o.explanationId);if(!r)throw new Error(`Unknown imprint explanation: ${o.explanationId}`);r.evidence.some(i=>i.id===o.evidence.id)||(r.evidence.push(Le(o.evidence)),r.updatedAt=o.evidence.createdAt)}else if(o.op==="revise_explanation"){let r=n.explanations.find(i=>i.id===o.explanationId);if(!r)throw new Error(`Unknown imprint explanation: ${o.explanationId}`);Object.assign(r,Le(o.patch),{updatedAt:o.updatedAt})}else if(o.op==="add_relation"){let r=o.relation,i=n.explanations.find(y=>y.id===r.fromId),s=!!r.toStoreId,a=s?void 0:n.explanations.find(y=>y.id===r.toId),d=n.concrete.some(y=>y.id===r.fromId),c=!s&&n.concrete.some(y=>y.id===r.toId);if(Bi(r.type)){if(!(r.type==="expresses"?s?!!i:!!((i||d)&&a):!!(i&&(a||s))))throw new Error(`Imprint ${r.type} relation has invalid endpoints: ${r.id}`);if(n.relations.some(v=>v.type===r.type&&v.fromId===r.fromId&&v.toStoreId===r.toStoreId&&v.toId===r.toId))throw new Error(`Duplicate imprint relation: ${r.type}:${r.fromId}:${r.toStoreId??""}:${r.toId}`);if(r.type==="expresses"&&i&&a){if(Kt(i,a)<0)throw new Error(`Imprint expresses relation must point from specific to abstract: ${r.id}`);let v=new Map;for(let x of n.relations)x.type!=="expresses"||x.toStoreId||v.set(x.fromId,[...v.get(x.fromId)??[],x.toId]);let h=[r.toId],P=new Set;for(;h.length;){let x=h.pop();if(x===r.fromId)throw new Error(`Imprint expresses relation would create a cycle: ${r.id}`);P.has(x)||(P.add(x),h.push(...v.get(x)??[]))}}}else if(!i||!a&&!c)throw new Error(`Imprint relation references an unknown explanation: ${r.id}`);n.relations.some(y=>y.id===r.id)||n.relations.push(Le(r))}else o.op==="remove_relation"&&(n.relations=n.relations.filter(r=>r.id!==o.relationId));return n}function Kd(t,e){let n=[],o=Le(t);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=o.explanations.find(s=>s.id===r.explanationId);i&&n.unshift({op:"add_explanation",explanation:Le(i)})}else if(r.op==="add_concrete")n.unshift({op:"remove_concrete",concreteId:r.concrete.id});else if(r.op==="remove_concrete"){let i=o.concrete.find(s=>s.id===r.concreteId);i&&n.unshift({op:"add_concrete",concrete:Le(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=o.explanations.find(a=>a.id===i);s&&n.unshift({op:"replace_explanation",explanation:Le(s)})}else if(r.op==="add_relation")n.unshift({op:"remove_relation",relationId:r.relation.id});else if(r.op==="remove_relation"){let i=o.relations.find(s=>s.id===r.relationId);i&&n.unshift({op:"add_relation",relation:Le(i)})}o=yr(o,[r])}return n}function Li(t){return t.op==="add_explanation"||t.op==="replace_explanation"?[t.explanation.id]:t.op==="remove_explanation"||t.op==="add_evidence"||t.op==="revise_explanation"?[t.explanationId]:t.op==="add_relation"?[t.relation.fromId,...t.relation.toStoreId?[]:[t.relation.toId]]:[]}var Io=class{constructor(e,n){this.projectRoot=e;this.projectId=n;this.writeChain=Promise.resolve();this.imprintDir=Qt(e,".popmelt","imprint"),this.manifestPath=Qt(this.imprintDir,"manifest.json"),this.graphPath=Qt(this.imprintDir,"graph.json"),this.journalDir=Qt(this.imprintDir,"journal")}async readHead(){return(await this.readManifest()).head}async readManifest(){try{let e=JSON.parse(await Ji(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 loadRaw(){let e=await this.readManifest(),o=(await Ud(this.journalDir).catch(a=>{if(a.code==="ENOENT")return[];throw a})).filter(a=>/^\d{12}-.+\.json$/.test(a)).sort(),r=Hd(this.projectId,e.createdAt),i=[],s=null;for(let a=0;a<o.length;a++){let d=JSON.parse(await Ji(Qt(this.journalDir,o[a]),"utf8")),{hash:c,...y}=d;if(d.sequence!==a+1||d.previousHash!==s||c!==qi(y))throw new Error(`Imprint journal hash mismatch at sequence ${d.sequence}.`);r=yr(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 load(){let e=await this.loadRaw();return{...e,graph:$t(e.graph)}}async migrateTopology(){let e=await this.readManifest();if(e.topologyVersion===2)return{migrated:!1,relationMutations:0};let n=await this.loadRaw(),o=$t(n.graph),r=new Map(o.relations.map(s=>[s.id,s])),i=[];for(let s of n.graph.relations){let a=r.get(s.id);a&&a.type===s.type&&a.fromId===s.fromId&&a.toStoreId===s.toStoreId&&a.toId===s.toId||(i.push({op:"remove_relation",relationId:s.id}),a&&i.push({op:"add_relation",relation:a}))}if(i.length){let s=new Date().toISOString();return await this.commit({transactionId:`topology-v2-${n.graph.head.sequence+1}`,committedAt:s,source:{kind:"migration",threadId:"imprint-topology",jobId:"imprint-topology-v2"},summary:"Simplify Imprint topology to expresses and excepts",mutations:i}),{migrated:!0,relationMutations:i.length}}return await Ot(this.graphPath,o),await Ot(this.manifestPath,{...e,topologyVersion:2}),{migrated:!0,relationMutations:0}}async commit(e){let n;return this.writeChain=this.writeChain.then(async()=>{let o=await this.load();if(o.transactions.some(v=>v.transactionId===e.transactionId))throw new Error(`Imprint transaction already exists: ${e.transactionId}`);let r=o.graph.head.sequence+1,i=Kd(o.graph,e.mutations),s={version:1,sequence:r,transactionId:e.transactionId,projectId:this.projectId,committedAt:e.committedAt,previousHash:o.graph.head.hash,source:e.source,summary:e.summary,mutations:Le(e.mutations),inverseMutations:i,...e.undoesTransactionId?{undoesTransactionId:e.undoesTransactionId}:{}},a={...s,hash:qi(s)},d=yr(o.graph,a.mutations);d.updatedAt=e.committedAt,d.head={sequence:r,hash:a.hash};let c=`${String(r).padStart(12,"0")}-${e.transactionId}.json`;await Ot(Qt(this.journalDir,c),a);let y={version:1,topologyVersion:2,projectId:this.projectId,createdAt:d.createdAt,updatedAt:e.committedAt,head:d.head};await Ot(this.graphPath,d),await Ot(this.manifestPath,y),n={graph:d,transaction:a}}),await this.writeChain,n}async undo(e,n,o,r){let i=await this.load(),s=i.transactions.find(c=>c.transactionId===e);if(!s)throw new Error("The imprint update is no longer available to undo.");if(i.transactions.some(c=>c.undoesTransactionId===e))throw new Error("This imprint update has already been undone.");let a=new Set(s.mutations.flatMap(Li));if(i.transactions.filter(c=>c.sequence>s.sequence).some(c=>c.mutations.some(y=>Li(y).some(v=>a.has(v)))))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:o,source:n,summary:`Undo: ${s.summary}`,mutations:s.inverseMutations,undoesTransactionId:e})}async recover(){let e=await this.load();return await Ot(this.graphPath,e.graph),await Ot(this.manifestPath,{version:1,topologyVersion:2,projectId:this.projectId,createdAt:e.graph.createdAt,updatedAt:e.graph.updatedAt,head:e.graph.head}),{...e,recoveredTransactions:0}}};var Qd=new Set(["application_only","transient_state","concrete_without_model_path","duplicate","insufficient_evidence","task_specific_detail","no_shared_understanding_change"]),Xd=new Set(["about","after","again","before","being","change","from","have","into","make","should","that","the","their","this","with","would","here","only","consistent","match","matched","matching","mirror","mirrored","mirroring","align","aligned","aligning"]),Yd=[/\bconsistent\s+with\b/i,/\bmatch(?:es|ed|ing)?\b/i,/\bmirror(?:s|ed|ing)?\b/i,/\bthe\s+same\s+as\b/i,/\bborrow(?:s|ed|ing)?\s+from\b/i,/\balign(?:s|ed|ing)?\s+with\b/i,/\b(?:more|look|looks|feel|feels|behave|behaves)\s+like\b/i],Zd=/\b(all|any|every|everywhere|across|throughout|globally|project[- ]wide)\b/i;function wr(t){return!!(t&&Zd.test(t))}function ec(t){return t.scope.kind==="project"||wr(`${t.statement} ${t.rationale}`)}function tc(t){let e=t?.scope.values.filter(n=>n!=="*").join(", ");return e?`Does applying this understanding here match your intent for ${e}?`:"Does applying this understanding here match your intent?"}function nc(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().replace(/[^a-z0-9]+/g," ").trim().replace(/\s+/g," ")}function oc(t){return t.length>4&&t.endsWith("ies")?[t,`${t.slice(0,-3)}y`]:t.length>3&&t.endsWith("s")&&!t.endsWith("ss")?[t,t.slice(0,-1)]:[t]}function ct(t){return new Set(nc(t).split(" ").filter(e=>e.length>2&&!Xd.has(e)).flatMap(oc))}function Fi(t){return t.replace(/^\s*(?:please\s+)?(?:let(?:'|’)s\s+)?(?:make|apply|use|keep|change|update)\s+/i,"").replace(/[\s,.:;!?]+$/g,"").trim().slice(0,240)}function rc(t){if(t)for(let e of Yd){let n=e.exec(t);if(!n||n.index<=0)continue;let o=Fi(t.slice(0,n.index)),r=Fi(t.slice(n.index+n[0].length));if(o&&r)return{target:o,reference:r}}}function xt(t,e){if(!t.size||!e.size)return 0;let n=0;for(let o of t)e.has(o)&&(n+=1);return n/Math.min(t.size,e.size)}function Ir(t){return!t||!Array.isArray(t.values)||t.values.length===0?{kind:"project",values:["*"]}:{kind:t.kind,values:[...new Set(t.values.map(e=>e.trim()).filter(Boolean))]}}function St(t,e,n){return{id:lt(),kind:e==="excepts"?"exception":e==="challenges"?"correction":"observation",stance:e,summary:n,threadId:t.threadId,jobId:t.jobId,createdAt:t.occurredAt??new Date().toISOString()}}function ve(t,e=800){return typeof t=="string"?t.trim().slice(0,e):""}function Ui(t){if(!t||typeof t!="object"||Array.isArray(t))return;let e=t;if(!["project","route","component","selector","file"].includes(String(e.kind))||!Array.isArray(e.values))return;let n=e.values.filter(o=>typeof o=="string"&&!!o.trim());return n.length?{kind:e.kind,values:n}:void 0}function zi(t,e,n){if(t&&typeof t=="object"&&!Array.isArray(t)){let i=t,s=ve(i.explanationId,100),a=ve(i.clientId,100),d=ve(i.storeId,100);if(s&&a)throw new Error("relation endpoint must use either explanationId or clientId, not both");let c=s||a;return c?{explanationId:c,...d?{storeId:d}:{}}:void 0}let o=ve(e,100),r=ve(n,100);return o?{explanationId:o,...r?{storeId:r}:{}}:void 0}function Wi(t,e){if(!t||!e.trim())return{found:!1};let n=t;for(let o of e.split(".").filter(Boolean))if(Array.isArray(n)){let r=Number(o);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,o))n=n[o];else return{found:!1};return{found:!0,value:n}}function An(t,e={}){let n=[...t.matchAll(/<imprint>([\s\S]*?)<\/imprint>/g)],o=t.replace(/<imprint>[\s\S]*?<\/imprint>/g,"").replace(/<imprint>[\s\S]*$/g,"").trim(),r=n.at(-1)?.[1],i,s=[];if(r)i=r;else{let d=[...t.matchAll(/<resolution>\s*([\s\S]*?)\s*<\/resolution>/g)].at(-1)?.[1];if(!d)return{visibleText:o,error:"imprint assessment is missing"};try{let c=JSON.parse(d);if(!c||typeof c!="object"||Array.isArray(c)||!Object.prototype.hasOwnProperty.call(c,"imprint"))return{visibleText:o,error:"imprint assessment is missing"};let y=c;i=y.imprint,s=Array.isArray(y.annotations)?y.annotations:[]}catch{return{visibleText:o,error:"resolution envelope is invalid"}}}try{let a=typeof i=="string"?JSON.parse(i):i;if(!a||typeof a!="object"||Array.isArray(a))throw new Error("imprint assessment is invalid");if(a.decision==="none"){let g=String(a.reason);if(!Qd.has(g))throw new Error("imprint no-op reason is invalid");if(g==="task_specific_detail"&&s.some(A=>{if(!A||typeof A!="object"||Array.isArray(A))return!1;let $=A;return($.finalScope??$.inferredScope)?.breadth==="pattern"}))throw new Error("pattern-scoped resolution cannot be classified as task_specific_detail");let u=Array.isArray(a.usedExplanationIds)?a.usedExplanationIds.filter(A=>typeof A=="string"&&!!A.trim()):[],I=Array.isArray(a.appliedExplanationIds)?a.appliedExplanationIds.filter(A=>typeof A=="string"&&!!A.trim()):[],w=new Set(e.context?.explanations.map(A=>A.id)??[]);if([...new Set([...u,...I])].some(A=>!w.has(A)))throw new Error("imprint use must cite only surfaced explanations");let j=[...new Set([...u,...e.applicationOccurred?[]:I])],m=e.applicationOccurred?I:[],f;if(m.length){f=m;let A=new Set(e.context?.pendingGroundingExplanationIds??[]),$=m.filter(k=>{let C=e.context?.explanations.find(X=>X.id===k);return w.has(k)&&C&&(C.state==="emerging"||C.state==="testing")&&!A.has(k)});if($.length){let k=a.grounding,C=typeof k?.explanationId=="string"&&$.includes(k.explanationId)?k.explanationId:$[0],X=ve(k?.question,300);return{draft:{decision:"apply",summary:{title:ve(a.summary?.title,120)||"Applied shared understanding",detail:ve(a.summary?.detail,500)||ve(e.requestText||o,500)||"Applied an ungrounded explanation in a new context."},appliedExplanationIds:m,grounding:{explanationId:C,question:X||"Does applying this understanding here match your intent?"}},visibleText:o}}}if(g==="duplicate"){let A=ve(a.duplicateOfExplanationId,100),$=a.scopeComparison;if(!A)throw new Error("duplicate assessment requires duplicateOfExplanationId");if($!=="equivalent"&&$!=="existing_broader")throw new Error("duplicate assessment requires an equivalent or existing_broader scopeComparison");let k=e.context?.explanations.find(C=>C.id===A);if(!k)throw new Error("duplicate assessment must cite a surfaced explanation");if(wr(e.requestText)&&!ec(k))throw new Error("duplicate explanation does not cover the requested broader scope");return{draft:{decision:"none",reason:g,duplicateOfExplanationId:A,scopeComparison:$,...j.length?{usedExplanationIds:j}:{},...f?{appliedExplanationIds:f}:{}},visibleText:o}}return{draft:{decision:"none",reason:g,...j.length?{usedExplanationIds:j}:{},...f?{appliedExplanationIds:f}:{}},visibleText:o}}if(a.decision==="recognize"){let g=ve(a.explanationId,100);if(!g)throw new Error("recognition requires explanationId");let u=e.context?.explanations.find(p=>p.id===g);if(!u)throw new Error("recognition must cite a surfaced explanation");if(u.state!=="grounded")throw new Error("recognition must cite a grounded explanation");let I=a.summary,w={title:ve(I?.title,120),detail:ve(I?.detail,500)};if(!w.title||!w.detail)throw new Error("recognition summary title and detail are required");return{draft:{decision:"recognize",explanationId:g,summary:w},visibleText:o}}if(a.decision==="apply"){let g=a.summary,u={title:ve(g?.title,120),detail:ve(g?.detail,500)};if(!u.title||!u.detail)throw new Error("application summary title and detail are required");let I=Array.isArray(a.appliedExplanationIds)?a.appliedExplanationIds.filter(A=>typeof A=="string"&&!!A.trim()):[];if(!I.length)throw new Error("application requires appliedExplanationIds");let w=new Map(e.context?.explanations.map(A=>[A.id,A])??[]);if(I.some(A=>!w.has(A)))throw new Error("application must cite only surfaced explanations");if(!e.applicationOccurred)return{draft:{decision:"none",reason:"application_only",usedExplanationIds:[...new Set(I)]},visibleText:o};let p=new Set(e.context?.pendingGroundingExplanationIds??[]),j=I.filter(A=>{let $=w.get(A);return $&&($.state==="emerging"||$.state==="testing")&&!p.has(A)});if(!j.length){if(I.every($=>w.get($)?.state==="grounded"||p.has($)))return{draft:{decision:"none",reason:"application_only",appliedExplanationIds:I},visibleText:o};throw new Error("application must cite a surfaced ungrounded explanation")}let m=a.grounding,f=typeof m?.explanationId=="string"&&j.includes(m.explanationId)?m.explanationId:j[0];return{draft:{decision:"apply",summary:u,appliedExplanationIds:I,grounding:{explanationId:f,question:ve(m?.question,300)||"Does applying this understanding here match your intent?"}},visibleText:o}}if(a.decision!==void 0&&a.decision!=="mutate")throw new Error("imprint decision is invalid");let d=a.summary,c=d?.kind;if(!["added","strengthened","refined","challenged","exception","consolidated"].includes(String(c)))throw new Error("summary.kind is invalid");let y={kind:c,title:ve(d?.title,120),detail:ve(d?.detail,500)};if(!y.title||!y.detail)throw new Error("summary title and detail are required");let v=Array.isArray(a.appliedExplanationIds)?a.appliedExplanationIds.filter(g=>typeof g=="string"&&!!g.trim()):[],h=[];for(let g of Array.isArray(a.mutations)?a.mutations:[]){if(!g||typeof g!="object")continue;let u=g;if(u.op==="add"&&["intention","principle","pattern"].includes(String(u.kind))){let I=ve(u.statement),w=ve(u.rationale);if(!I||!w)continue;h.push({op:"add",clientId:ve(u.clientId,100)||void 0,kind:u.kind,statement:I,rationale:w,scope:Ui(u.scope),rootReason:ve(u.rootReason,300)||void 0})}else if(u.op==="revise"&&typeof u.explanationId=="string"){let I={op:"revise",explanationId:u.explanationId,statement:ve(u.statement)||void 0,rationale:ve(u.rationale)||void 0,scope:Ui(u.scope),reopenGrounding:u.reopenGrounding===!0};(I.statement||I.rationale||I.scope||I.reopenGrounding)&&h.push(I)}else if(u.op==="evidence"&&typeof u.explanationId=="string"&&["supports","challenges","excepts"].includes(String(u.stance))){let I=ve(u.summary);I&&h.push({op:"evidence",explanationId:u.explanationId,stance:u.stance,summary:I})}else if(u.op==="relation"){if(!["expresses","excepts"].includes(String(u.type)))throw new Error("relation type is invalid");let I=ve(u.rationale),w=zi(u.from,u.fromId,u.fromStoreId),p=zi(u.to,u.toId,u.toStoreId);if(!I)throw new Error("relation rationale is required");if(!w||!p)throw new Error("relation endpoints require an explanationId or clientId");h.push({op:"relation",type:u.type,from:w,to:p,rationale:I})}else if(u.op==="supersede"&&typeof u.explanationId=="string"&&typeof u.replacementId=="string"){let I=ve(u.reason);I&&h.push({op:"supersede",explanationId:u.explanationId,replacementId:u.replacementId,reason:I})}else if(u.op==="bind_concrete"&&typeof u.explanationId=="string"){let I=ve(u.modelPath,300);I&&h.push({op:"bind_concrete",explanationId:u.explanationId,modelPath:I,rationale:ve(u.rationale)})}else u.op==="retire"&&typeof u.explanationId=="string"&&h.push({op:"retire",explanationId:u.explanationId,reason:ve(u.reason)})}let P=a.grounding,x=P&&typeof P.explanationId=="string"&&ve(P.question)?{explanationId:P.explanationId,question:ve(P.question,300)}:void 0;return{draft:{decision:"mutate",summary:y,appliedExplanationIds:v,mutations:h,grounding:x},visibleText:o}}catch(a){return{visibleText:o,error:a instanceof Error?a.message:String(a)}}}function Mn(t,e={}){let n=t?.explanations??[],o=new Set(t?.pendingGroundingExplanationIds??[]),r=new Set(t?.correctionExplanationIds??[]),i=wr(e.requestText),s=t?.retrievalIntent,a=t?.historicalCaveats??[],d=n.find(h=>h.storeId&&!h.readOnly)?.storeId,c=(h,P)=>{let x=h[P];return x?`[${x.storeId}] ${x.explanationId}`:P==="from"?h.fromId:h.toId},y=!!t?.relations?.some(h=>h.from&&h.to&&h.from.storeId!==h.to.storeId),v=n.some(h=>h.readOnly);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.",...n.length?["","Relevant explanations from the project imprint:",...n.map((h,P)=>[`${P+1}. [${h.state}; ${h.kind}] ${h.statement}`,` - Why: ${h.rationale}`,` - Scope: ${h.scope.kind} ${h.scope.values.join(", ")}`,` - Explanation: ${h.id}`,...h.storeId?[` - Store: ${h.storeId}${h.readOnly?" (read-only)":" (writable primary)"}`]:[],...o.has(h.id)?[" - Grounding: already pending; do not ask again"]:[],...r.has(h.id)?[" - Correction: the developer selected No for this explanation and the current reply supplies the missing correction context"]:[],...h.concrete.map(x=>` - Concrete terminal: ${x.modelPath} = ${JSON.stringify(x.value)}`)].join(`
|
|
9
9
|
`)),...t?.truncated?["Additional imprint context exists outside this bounded packet."]:[]]:[],...t?.relations?.length?["","Known explanation topology:",...t.relations.map(h=>`- ${h.storeId?`[owned by ${h.storeId}${h.readOnly?"; read-only":""}] `:""}${c(h,"from")} --${h.type}--> ${c(h,"to")}: ${h.rationale}`)]:[],...v||y?["","Store-qualified topology remains locally owned: the relation must originate at an explanation in the writable primary store, while its target may be in a mounted read-only store. Never proxy a relation whose source belongs to a mounted store.",`For a cross-store relation, use qualified endpoints: {"op":"relation","type":"expresses|excepts","from":{"storeId":"${d??"<writable-primary-store>"}","clientId":"<new-specific-client-id>"},"to":{"storeId":"<mounted-target-store>","explanationId":"<existing-abstract-target-id>"},"rationale":"<why>"}. Use clientId for a new explanation created in this transaction and explanationId for an existing durable explanation.`]:[],...s?["","Explicit pattern transfer detected:",`- Target: ${s.target}`,`- Reference: ${s.reference}`,"Before editing, state which dimensions you intend to transfer from the reference and which target-specific behavior you will preserve. Compare the relevant surface, spacing, typography, radius, and interaction behavior; transfer only the dimensions supported by the request and evidence. If the intended transfer remains materially ambiguous after inspecting both anchors, ask one focused question."]:[],...a.length?["","Directly relevant challenged history (historical caveats, not current Imprint truth):",...a.map((h,P)=>[`${P+1}. [challenged; ${h.kind}] ${h.statement}`,` - Why it was previously proposed: ${h.rationale}`,` - Scope: ${h.scope.kind} ${h.scope.values.join(", ")}`,` - Historical explanation: ${h.id}`,...h.storeId?[` - Store: ${h.storeId}${h.readOnly?" (read-only)":" (writable primary)"}`]:[]].join(`
|
|
10
10
|
`)),"Use these caveats only to avoid repeating a rejected or over-broad transfer. Do not cite them as usedExplanationIds or treat them as active guidance."]:[],...n.some(h=>h.readOnly)?["","Mounted-store explanations are read-only context. They may inform the work and be cited as used understanding, but do not mutate, ground, revise, or add evidence to them without an explicit writable orientation for that store."]:[],...t?.unavailableStoreIds?.length?["",`Some mounted Imprint knowledge was unavailable during this bounded read: ${t.unavailableStoreIds.join(", ")}. Do not infer its contents.`]:[],...t?.unavailableTopologyStoreIds?.length?["",`Some mounted Imprint topology was unavailable during this bounded read: ${t.unavailableTopologyStoreIds.join(", ")}. Available explanations remain usable, but do not infer missing relationships.`]:[],"","Work normally and preserve developer agency. A testing explanation may guide action as a hypothesis without asking permission first. An emerging explanation is observation-only: use it to recognize recurrence, not to choose behavior. If the developer independently repeats an emerging observation in a meaningfully different occurrence, that new application may promote it into testing and request grounding. Silence is not confirmation.","Assess learning proactively as part of completing every thread. Do not wait for the developer to ask whether there was a learning. Before choosing none, look one abstraction level above the exact edit and ask: would the reasoning behind this outcome change how a future agent handles a meaningfully different occurrence?","The developer's original annotation, ordinary instruction, scope language, and later corrections are already human-supplied evidence. They can support learning when they establish a reusable dependency, boundary, or rationale; a separate post-completion learning prompt is not required. Mere acceptance of completed work is still insufficient.","The default outcome is no imprint mutation. Completing work or making a successful design choice does not by itself constitute learning.","Application evidence is distinct from changing shared understanding. When an emerging or testing explanation materially influenced a completed action, report decision apply even when no explanation wording changed.","Applying grounded understanding does not mutate the graph. Usually report none. Use decision recognize only when visibly acknowledging the grounded explanation closes a correction loop or otherwise makes consequential reuse legible to the developer. Recognition must cite one exact surfaced grounded explanation ID; never infer or invent an ID.","Application and recognition are whole-statement operations. Cite an existing explanation only when the completed behavior is compatible with every material clause, its scope, and its exceptions. Sharing one useful clause is not a match. If the durable behavior is narrower, add one atomic explanation linked to the broader explanation when the admission tests pass; otherwise report none.","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.","Relationship-first admission: before calling any completed change task-specific, compare its requested behavior and effective scope with every surfaced explanation that could plausibly govern the same subject or treatment. The developer does not need to name an Imprint concept or relation. Infer the relationship from the ordinary instruction, the annotated context, the implementation, and the surfaced explanations.","A narrower completed behavior that departs from an applicable broader explanation establishes an applicability boundary even when the developer did not say exception. Add one narrow testing explanation and link it to the broader rule with excepts. If the behaviors concern distinct concepts rather than the same rule, assess the reusable behavior as a sibling explanation instead. Do not manufacture an exception merely because implementations differ.","Scope and Imprint assessment must agree. If any resolved annotation has an effective inferred or final breadth of pattern, do not classify the Imprint decision as task_specific_detail. Either capture the reusable conceptual change, report application of existing understanding, cite a valid duplicate, or use another accurate no-op reason. The bridge rejects pattern-scoped task_specific_detail assessments.","","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 anywhere in the thread, including the original instruction, not merely acceptance of completed work or the model's own implementation choice.","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. Distinguish mechanics from the reusable reasoning they may reveal: a CSS property alone is not learning, but a human-directed causal rule such as keeping optical adjustment out of layout geometry may be. This heuristic never overrides relationship-first admission: a small local change that narrows or contradicts an applicable surfaced explanation may establish an exception or correction. A task-specific edit otherwise becomes learning only if the human establishes a reusable dependency, applicability boundary, 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.","Duplicate means the same reusable claim is already represented at an equivalent or broader conceptual scope. Shared code, a centralized component, or implementation reuse does not establish conceptual duplication. A narrower component-, route-, selector-, or file-scoped explanation is not a duplicate of newly broadened applicability.","Words such as all, every, across, throughout, globally, and project-wide are explicit applicability signals. When the human broadens a grounded explanation, preserve the grounded narrower explanation and add a broader testing explanation. Link the narrower explanation to the broader one with expresses. Do not substitute another no-op reason for that scope change.",...i?["CURRENT SCOPE SIGNAL: The developer used explicit broadening language in this instruction. Do not classify it as duplicate unless the cited existing explanation already expresses universal or project-wide applicability."]:[],"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.","When an explanation is marked Correction in the supplied context, the developer selected No but the graph has not yet been changed. Interpret the current reply before mutating anything. Decide whether it corrects only the implementation result, the explanation scope, or the reasoning. Do not challenge the whole explanation for a narrow correction, and do not recognize a different explanation merely because one clause overlaps.","Topology assessment is mandatory for every add mutation. Imprint topology has exactly two relation types: expresses and excepts. expresses always points from the more specific, concrete, or lower-level explanation to the more abstract explanation it expresses. excepts points from the narrower exception to the rule whose applicability it limits. Support and challenge belong in evidence; correction belongs in supersede; neither is a topology relation. If an addition is genuinely a new root with no meaningful relative, include rootReason 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 with expresses or excepts. Multiple specific explanations may express the same parent, and one explanation may express multiple parents; never create an expresses cycle.","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 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. The bridge supplies a fallback question when the application is otherwise valid.","","At the end, emit exactly one machine-readable <resolution> envelope after the normal response. Its `annotations` array reports annotation outcomes, and its required `imprint` field completes the learning assessment. The envelope is hidden from the developer. Do not emit a separate <imprint> block.",'As soon as one or more surfaced explanations become actively useful during the work, emit `<imprint-use>{"explanationIds":["<every actively useful surfaced explanation id>"]}</imprint-use>` immediately. This live receipt is hidden from conversational prose. Emit it at the point of use rather than waiting for the final response. Emit a later marker only when additional explanations become actively useful. Never emit it for explanations that were merely retrieved, read, searched, or considered.',"Treat Imprint as actively useful when a surfaced explanation materially informs an answer, recommendation, implementation choice, or other decision. Whenever it is actively useful, always cite every materially used surfaced explanation in `usedExplanationIds`. This produces a usage receipt only; it does not strengthen or mutate shared understanding. Do not cite explanations that were merely retrieved, read, or considered but did not influence the result.","`appliedExplanationIds` is narrower: include an explanation there only when it governed a completed implementation or other observable action that genuinely tests the explanation. Never use `appliedExplanationIds` for an answer-only, informational, research, or read-only request. An explanation may be used without being applied; every applied explanation is also understood to be used.","For no learning, include:",'"imprint":{"decision":"none","reason":"application_only|transient_state|concrete_without_model_path|duplicate|insufficient_evidence|task_specific_detail|no_shared_understanding_change","usedExplanationIds":["<every surfaced explanation that was actively useful, or omit when none>"]}',"A no-op reason cannot suppress genuine application evidence. When a completed action was governed by an ungrounded explanation, report decision apply directly so the summary and grounding question are intentional. Answering a question with that explanation is usage, not application.","When and only when reason is duplicate, also include `duplicateOfExplanationId` naming one surfaced explanation and `scopeComparison` set to `equivalent` or `existing_broader`. The bridge rejects uncited duplicates and duplicates whose cited explanation cannot cover explicit broadening language.","For application evidence without a conceptual change, include:",'"imprint":{"decision":"apply","summary":{"title":"<short expandable-summary title>","detail":"<how the explanation influenced this completed action>"},"appliedExplanationIds":["<surfaced emerging or testing explanation id>"],"grounding":{"explanationId":"<one applied id>","question":"<brief post-application confirmation question>"}}',"For a consequential, non-mutating reuse of grounded understanding that should be visible, include:",'"imprint":{"decision":"recognize","explanationId":"<one exact surfaced grounded explanation id>","summary":{"title":"<short name for the recognized understanding>","detail":"<how it guided this outcome>"}}',"Or, only after every admission test passes for a conceptual change:",'"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":"expresses|excepts","from":{"clientId":"<new-specific-client-id>"},"to":{"explanationId":"<existing-abstract-id>"},"rationale":"<why; use clientId for new transaction-local explanations and explanationId for existing durable explanations>"},{"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 expresses the explanation>"},{"op":"retire","explanationId":"<id>","reason":"<why>"}],"grounding":{"explanationId":"<one applied ungrounded id or clientId>","question":"<brief post-application confirmation question>"}}','The final shape is `<resolution>{"annotations":[...],"imprint":{...}}</resolution>`. The `imprint` field is required even when the decision is none; omission leaves the completed run explicitly unassessed.',"Include only mutation objects actually needed. A new explanation established through completed implementation must include its clientId in appliedExplanationIds; the bridge also derives this application from a completed change as a safeguard. Applying a grounded explanation never requires a mutation, but actively using it still requires its id in appliedExplanationIds. Never claim that a new explanation is grounded."].join(`
|