@ai-matrx/alchemy 0.22.40 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/surface.js CHANGED
@@ -1,2 +1,2 @@
1
- var DEFAULT_MAX_INHERITANCE_DEPTH=3;var APPLET_CATEGORY="applet";function compact(value){return Object.fromEntries(Object.entries(value).filter(([,v])=>v!==void 0))}function surfaceActionRowToAction(row){return compact({name:row.name,category:row.category,label:row.label,description:row.description,input:row.input??void 0,output:row.output??void 0,runs:row.runs,target:row.target??void 0,triggeredBy:[...row.triggered_by],policy:row.policy,updatesValue:row.updates_value??void 0,itemType:row.item_type||void 0,sortOrder:row.sort_order,origin:compact({source:"surface-action",surfaceName:row.surface_name,surfaceId:row.surface_id,id:row.id,declaredBy:row.declared_by,codeRef:row.code_ref??void 0,organizationId:row.organization_id??void 0})})}function toActionInfo(declaration,declaredOn){return compact({name:declaration.name,category:declaration.category??APPLET_CATEGORY,label:declaration.label,description:declaration.description,runs:declaration.runs,policy:declaration.policy,triggeredBy:[...declaration.triggeredBy],input:declaration.input,output:declaration.output,declaredOn,target:declaration.target,updatesValue:declaration.updatesValue,itemType:declaration.itemType,source:declaration.origin?.source})}function resolveActionChain(chain,options={}){let maxDepth=options.maxDepth??DEFAULT_MAX_INHERITANCE_DEPTH,names=chain.map(link=>link.surfaceName),seen=new Set;for(let name of names){if(seen.has(name))throw new Error(`[actions] inheritance CYCLE detected at "${name}". Fix the surface chain: ${names.join(" \u2192 ")}`);seen.add(name)}if(chain.length-1>maxDepth)throw new Error(`[actions] inheritance chain for "${names[names.length-1]}" exceeds depth ${maxDepth}: ${names.join(" \u2192 ")}`);let byName=new Map;for(let link of chain){let own=new Set;for(let action of link.actions){if(own.has(action.name))throw new Error(`[actions] surface "${link.surfaceName}" declares Action "${action.name}" twice. Names are unique; nothing was overwritten.`);own.add(action.name),byName.set(action.name,toActionInfo(action,link.surfaceName))}}return[...byName.values()]}function asSurfaceClient(client){let c=client;if(typeof c.schema!="function")throw new Error("[alchemy/surface] the surface runtime needs a supabase-js v2 client carrying the viewer's session (it has no schema()).");return c}function readError(error,code="read_failed"){let out={code:error.code?`${code}:${error.code}`:code,message:error.message,retryable:!1};return error.details&&(out.diagnostic=error.details),out}async function read(query,shape){try{let answer=await query();return answer.error?{ok:!1,error:readError(answer.error)}:{ok:!0,data:shape(answer.data)}}catch(err){return{ok:!1,error:{code:"unreachable",message:err instanceof Error?err.message:String(err),retryable:!0}}}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var APPLET_SURFACE_PREFIX="applets/";function fail(code,message,retryable=!1){return{ok:!1,error:{code,message,retryable}}}function surfaceActionVisible(row,organizationIds){return row.declared_by==="code"||row.surface_name.startsWith(APPLET_SURFACE_PREFIX)?!0:typeof row.organization_id=="string"&&(organizationIds??[]).includes(row.organization_id)}async function readSurfaceChain(client,surfaceName,options={}){let db;try{db=asSurfaceClient(client)}catch(err){return fail("client_invalid",err instanceof Error?err.message:String(err))}let maxDepth=options.maxDepth??DEFAULT_MAX_INHERITANCE_DEPTH,names=[],at=surfaceName;for(;at;){if(names.includes(at))return fail("surface_cycle",`The surface chain loops at "${at}": ${[...names,at].join(" \u2192 ")}.`);if(names.length>maxDepth)return fail("surface_too_deep",`The surface chain for "${surfaceName}" is deeper than ${maxDepth}: ${[...names,at].join(" \u2192 ")}.`);let name=at,row=await read(()=>db.schema("ui").from("ui_surface").select("name, parent_surface_name").eq("name",name).is("deleted_at",null).maybeSingle(),d=>d);if(!row.ok)return row;if(!isRecord(row.data))return fail("surface_not_found",names.length===0?`The surface "${at}" does not exist yet; saving the Applet writes it (ui.save_applet_surface).`:`The surface "${names[names.length-1]}" names a parent "${at}" that does not exist.`);names.push(at);let parent=row.data.parent_surface_name;at=typeof parent=="string"&&parent?parent:null}let rows=await read(()=>db.schema("ui").from("ui_surface_action").select("*").in("surface_name",names).is("deleted_at",null).order("sort_order",{ascending:!0}),d=>Array.isArray(d)?d:[]);if(!rows.ok)return rows;let visible=rows.data.filter(r=>surfaceActionVisible(r,options.organizationIds)),chain=[...names].reverse().map(name=>({surfaceName:name,actions:visible.filter(r=>r.surface_name===name).map(surfaceActionRowToAction)}));try{return{ok:!0,data:resolveActionChain(chain,{maxDepth})}}catch(err){return fail("surface_chain",err instanceof Error?err.message:String(err))}}function fail2(code,message,retryable=!1,diagnostic){return{ok:!1,error:diagnostic?{code,message,retryable,diagnostic}:{code,message,retryable}}}function messageOf(error){return error instanceof Error&&error.message.trim()?error.message:typeof error=="string"&&error.trim()?error:"The run failed without saying why."}function newRunId(){let c=globalThis.crypto;return c?.randomUUID?c.randomUUID():`run-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function fillActionTarget(template,input){let source=input&&typeof input=="object"&&!Array.isArray(input)?input:{},missing=[];return{value:template.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(_,key)=>{let v=source[key];return v==null||v===""||typeof v=="object"?(missing.push(key),""):encodeURIComponent(String(v))}),missing}}function fillName(template,input){let filled=fillActionTarget(template,input);return{value:decodeURIComponent(filled.value),missing:filled.missing}}function toJson(value){return value===void 0?null:JSON.parse(JSON.stringify(value))}function refuseCaller(info,by){return info.triggeredBy.includes(by)?info.policy==="manual"&&by!=="person"?{code:"manual_only",message:`"${info.label}" (${info.name}) runs only when a person starts it.`,retryable:!1}:null:{code:"caller_not_allowed",message:`"${info.label}" (${info.name}) can't be started by ${CALLER_WORDS[by]}; it allows ${info.triggeredBy.join(", ")||"no one"}.`,retryable:!1}}var CALLER_WORDS={person:"a person",agent:"an agent",applet:"an applet",automation:"an automation"};function absent(info,capability){return fail2("capability_absent",`"${info.label}" can't run here: ${capability} isn't available on this page.`)}async function runSurfaceAction(info,input,by,ports,options={}){let refusal=refuseCaller(info,by);if(refusal)return{ok:!1,error:refusal};let context={runId:options.runId??newRunId(),by,viewerId:options.viewerId??null,surfaceName:info.declaredOn,policy:info.policy},capture=(error,stage)=>{try{ports.diagnostics.capture(error,{area:"actions",detail:{action:info.name,runs:info.runs,stage,runId:context.runId}})}catch{}};try{if(info.source==="write-target"&&ports.door){let receipt=await ports.door.write({surfaceName:info.declaredOn,target:info.name,...info.itemType?{itemType:info.itemType}:{},...options.itemIdentity?{itemIdentity:options.itemIdentity}:{},...options.ops?{ops:options.ops}:{value:input},by,runId:context.runId},options.signal);return receipt.status==="refused"?{ok:!1,error:{code:receipt.reason,message:receipt.sentence,retryable:receipt.reason==="failed",remedy:receipt.remedy}}:{ok:!0,data:receipt}}if(info.policy==="ask"&&by!=="person"&&info.runs!=="server"){if(!ports.approvals)return fail2("needs_approval",`"${info.label}" needs a person's approval, and there is no one to ask here.`);if(!await ports.approvals.ask({action:info.name,label:info.label,description:info.description,input:toJson(input),by,surfaceName:info.declaredOn,runId:context.runId}))return fail2("declined",`"${info.label}" was not approved, so it did not run.`)}switch(info.runs){case"server":{if(!ports.serverActions)return absent(info,"server actions");let filled=fillName(info.target??info.name,input);if(filled.missing.length)return fail2("input_missing",`"${info.label}" needs ${filled.missing.join(", ")}.`);let response=await ports.serverActions.run({name:filled.value,input:toJson(input),by,surface_name:info.declaredOn,policy:info.policy});return response.status==="refused"?fail2("refused",response.message):{ok:!0,data:response}}case"mandate":{if(!ports.mandates)return absent(info,"running a job");if(!info.target)return fail2("target_missing",`"${info.label}" names no job to run.`);let filled=fillName(info.target,input);if(filled.missing.length)return fail2("input_missing",`"${info.label}" needs ${filled.missing.join(", ")}.`);let record=input&&typeof input=="object"&&!Array.isArray(input)?input:{},variables=/\{[A-Za-z_]/.test(info.target)?record.variables&&typeof record.variables=="object"?toJson(record.variables):{}:toJson(record),userInput=typeof record.userInput=="string"?record.userInput:void 0;return{ok:!0,data:await ports.mandates.run({alias:filled.value,variables,...userInput!==void 0?{userInput}:{},by,policy:info.policy})}}case"navigate":{if(!ports.overlay)return absent(info,"navigation");let filled=fillActionTarget(info.target??"",input);if(filled.missing.length)return fail2("input_missing",`"${info.label}" needs ${filled.missing.join(", ")}.`);let to=info.target&&/^\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(info.target)?decodeURIComponent(filled.value):filled.value;return to?(ports.overlay.navigate(to),{ok:!0,data:{to}}):fail2("target_missing",`"${info.label}" names no page to open.`)}case"page":return ports.pageActions?await ports.pageActions.dispatch(info.name,input,context):absent(info,"this page's actions");default:{let runs=info.runs;return fail2("runs_unknown",`"${info.label}" runs as "${String(runs)}", which nothing here knows how to run.`)}}}catch(error){return capture(error,"run"),fail2("run_failed",messageOf(error),!0)}}function isNamed(v){return typeof v=="object"&&v!==null&&"id"in v&&"name"in v}function mergeLiveCapture(base,contributions){let owners=new Map(base.sections.map(s=>[s.id,"page"])),sections=[...base.sections],identity={...base.identity};for(let c of contributions){for(let[k,v]of Object.entries(c.identity??{})){let prior=identity[k];(prior==null||isNamed(prior)&&!prior.name)&&(identity[k]=v)}for(let s of c.sections){let prior=owners.get(s.id);if(prior)throw new Error(`[live values] section "${s.id}" is claimed by both "${prior}" and "${c.owner}"`);owners.set(s.id,c.owner),sections.push(s)}}return{...base,identity,sections}}function liveSlotsOf(capture){let onDemand=capture.sections.filter(s=>typeof s.load=="function").map(s=>({id:s.id,title:s.title,...s.description?{description:s.description}:{},role:s.role,...s.brief!==void 0?{brief:s.brief}:{},load:()=>s.load()}));return{selection:{choices:capture.selection,text:null},"on-demand":onDemand,errors:capture.errors,requests:capture.requests}}function liveValueOf(capture,name){switch(name){case"selection":return capture.selection;case"errors":return capture.errors;case"requests":return capture.requests;case"on-demand":return capture.sections.filter(s=>typeof s.load=="function").map(s=>({id:s.id,title:s.title,role:s.role}));case"title":case"route":case"url":case"kind":case"identity":return capture[name];default:break}return Object.prototype.hasOwnProperty.call(capture.identity,name)?capture.identity[name]:Object.prototype.hasOwnProperty.call(capture.selection,name)?capture.selection[name]:capture.sections.find(s=>s.id===name)?.value}function createLiveValues(){let nextId=0,version=0,pages=[],parts=[],listeners=new Set,emit=()=>{version+=1;for(let listener of[...listeners])listener()},contributions=()=>parts.map(p=>{let got=p.read();return Array.isArray(got)?{owner:p.owner,sections:got}:{owner:p.owner,...got}}),read2=()=>{let top=pages[pages.length-1];return top?mergeLiveCapture(top.read(),contributions()):null};return{publish(get){let id=++nextId;return pages=[...pages,{id,read:get}],emit(),()=>{pages=pages.filter(p=>p.id!==id),emit()}},contribute(owner,get){let id=++nextId;return parts=[...parts,{id,owner,read:get}],emit(),()=>{parts=parts.filter(p=>p.id!==id),emit()}},touch:emit,has:()=>pages.length>0,read:read2,outline(){let top=pages[pages.length-1];if(!top)return null;let base=top.read(),sections=[...base.sections,...contributions().flatMap(c=>c.sections)];return{surfaceName:base.surfaceName??null,kind:base.kind,title:base.title,loadable:sections.filter(s=>typeof s.load=="function").map(s=>({id:s.id,title:s.title}))}},readFor(surfaceName){let capture=read2();return capture&&capture.surfaceName===surfaceName?capture:null},subscribe(listener){return listeners.add(listener),()=>{listeners.delete(listener)}},version:()=>version}}var liveValues=createLiveValues();var PAGE_ACTION_STREAM="actions",valueStream=name=>`value:${name}`;function clone(value){if(value===void 0)return value;let sc=globalThis.structuredClone;return sc?sc(value):JSON.parse(JSON.stringify(value))}function errorOf(err,code="surface_failed"){return{ok:!1,error:{code,message:err instanceof Error&&err.message?err.message:String(err),retryable:!1}}}var sequence=0;function defaultMint(prefix){let c=globalThis.crypto;return c?.randomUUID?`${prefix}-${c.randomUUID()}`:`${prefix}-${Date.now().toString(36)}-${(sequence++).toString(36)}`}function createSurfacePort(opts){let mint=opts.mintId??defaultMint,pending=opts.pending??new Map,parked=new Set,values=new Map,mounted=null,disposed=!1,report=(error,stage,detail={})=>{try{opts.ports.diagnostics.capture(error,{area:"actions",detail:{stage:`surface.${stage}`,...detail}})}catch{}},memberships=async()=>{if(opts.organizationIds)try{return await opts.organizationIds()}catch(err){report(err,"organizationIds");return}},read2=async name=>{let organizationIds=await memberships();return readSurfaceChain(opts.client,name,{...opts.maxDepth!==void 0?{maxDepth:opts.maxDepth}:{},...organizationIds?{organizationIds}:{}})},currentChain=async fresh=>{if(mounted&&!fresh)return{ok:!0,data:mounted.chain};let name=mounted?.name??(opts.surfaceName?await opts.surfaceName():null);if(!name)return{ok:!1,error:{code:"not_mounted",message:"No surface is mounted here yet.",retryable:!1}};let chain=await read2(name);return chain.ok&&mounted?.name===name&&(mounted.chain=chain.data),chain},awaitPageAction=runId=>disposed?Promise.resolve({ok:!1,error:{code:"host_disposed",message:"This page has closed.",retryable:!1}}):new Promise(resolve=>{parked.add(runId),pending.set(runId,resolve)}),selfRouted={dispatch(name,input,context){let waiting=awaitPageAction(context.runId),event={action:name,input,runId:context.runId,by:context.by},forget=()=>{pending.delete(context.runId),parked.delete(context.runId)};if(disposed)return forget(),Promise.resolve({ok:!1,error:{code:"host_disposed",message:"This page closed, so the action did not run.",retryable:!1}});let heard;try{heard=opts.emit(PAGE_ACTION_STREAM,event)}catch(err){throw forget(),err}return heard!==!0?(forget(),Promise.resolve({ok:!1,error:{code:"action_unhandled",message:`No page is open to run "${name}".`,retryable:!1}})):waiting}},port={async mount(name){try{let chain=await read2(name);if(!chain.ok)return chain;if(opts.seedValues)try{let seeds=await opts.seedValues();for(let[key,v]of Object.entries(seeds))values.has(key)||values.set(key,clone(v))}catch(err){report(err,"seedValues",{surface:name})}return mounted={mountId:mint("mount"),name,chain:chain.data},{ok:!0,data:{mountId:mounted.mountId}}}catch(err){return errorOf(err)}},async unmount(mountId){mounted?.mountId===mountId&&(mounted=null)},async getValue(name){if(values.has(name)||!opts.live||!mounted)return clone(values.get(name));try{let capture=opts.live.readFor(mounted.name);return capture?clone(liveValueOf(capture,name)):void 0}catch(err){report(err,"live",{name});return}},async setValue(name,v){let copy;try{copy=clone(v)}catch(err){report(err,"setValue",{name});return}values.set(name,copy);try{opts.emit(valueStream(name),clone(v))}catch(err){report(err,"emit",{stream:valueStream(name)})}},async listActions(){try{let chain=await currentChain(!1);return chain.ok?clone(chain.data):(report(chain.error,"listActions"),[])}catch(err){return report(err,"listActions"),[]}},async runAction(name,input,by){let info;try{let known=await currentChain(!1);if(info=known.ok?known.data.find(a=>a.name===name):void 0,!info){let fresh=await currentChain(!0);if(!fresh.ok)return fresh;info=fresh.data.find(a=>a.name===name)}}catch(err){return errorOf(err)}if(!info)return{ok:!1,error:{code:"action_not_found",message:`This page has no action named "${name}".`,retryable:!1}};let viewerId=null;try{viewerId=opts.viewerId?await opts.viewerId():null}catch(err){report(err,"viewerId")}let ports={...opts.ports,pageActions:opts.pageActions??selfRouted},result=await runSurfaceAction(info,input,by,ports,{runId:mint("act"),viewerId});return result.ok&&info.updatesValue&&await port.setValue(info.updatesValue,result.data),result},async completeAction(runId,result){let resolve=pending.get(runId);if(!resolve){report(new Error(`completeAction for run "${runId}", which is not waiting (already answered, never routed here, or the page closed).`),"completeAction",{runId});return}pending.delete(runId),parked.delete(runId),resolve?.(result)},awaitPageAction,dispose(){disposed=!0;for(let runId of parked){let resolve=pending.get(runId);pending.delete(runId),resolve?.({ok:!1,error:{code:"host_disposed",message:"This page closed before the action finished.",retryable:!1}})}parked.clear(),mounted=null,values.clear()}};return port}function createItemSources(onError){let sources=new Map;return{register(containerId,source){return sources.set(containerId,source),()=>{sources.get(containerId)===source&&sources.delete(containerId)}},resolve(target){let source=sources.get(target.containerId);if(!source)return null;try{return source(target)??null}catch(error){return onError?.(error,target),null}},has:containerId=>sources.has(containerId)}}var itemSources=createItemSources((error,target)=>{console.error(`[alchemy items] the source for "${target.containerId}" threw resolving ${target.level}`,error)});export{APPLET_SURFACE_PREFIX,PAGE_ACTION_STREAM,createItemSources,createLiveValues,createSurfacePort,itemSources,liveSlotsOf,liveValueOf,liveValues,mergeLiveCapture,readSurfaceChain,surfaceActionVisible,valueStream};
1
+ import{createDb,listAll,read as readRow}from"@ai-matrx/data/db";var uiSurface={schema:"ui",name:"ui_surface",kind:"table",type:"entity",pk:["name"],org:{rule:"binding"},versioned:!1,softDelete:!0,archive:null,readOnly:!1,deletesRefused:!1,readOnlyColumns:[],listScope:"organization",realtime:!1,createdBy:!0},uiSurfaceAction={schema:"ui",name:"ui_surface_action",kind:"table",type:null,pk:["id"],org:{rule:"binding"},versioned:!1,softDelete:!0,archive:null,readOnly:!1,deletesRefused:!1,readOnlyColumns:[],listScope:null,realtime:!1,createdBy:!0};var DEFAULT_MAX_INHERITANCE_DEPTH=3;var APPLET_CATEGORY="applet";function compact(value){return Object.fromEntries(Object.entries(value).filter(([,v])=>v!==void 0))}function surfaceActionRowToAction(row){return compact({name:row.name,category:row.category,label:row.label,description:row.description,input:row.input??void 0,output:row.output??void 0,runs:row.runs,target:row.target??void 0,triggeredBy:[...row.triggered_by],policy:row.policy,updatesValue:row.updates_value??void 0,itemType:row.item_type||void 0,sortOrder:row.sort_order,origin:compact({source:"surface-action",surfaceName:row.surface_name,surfaceId:row.surface_id,id:row.id,declaredBy:row.declared_by,codeRef:row.code_ref??void 0,organizationId:row.organization_id??void 0})})}function toActionInfo(declaration,declaredOn){return compact({name:declaration.name,category:declaration.category??APPLET_CATEGORY,label:declaration.label,description:declaration.description,runs:declaration.runs,policy:declaration.policy,triggeredBy:[...declaration.triggeredBy],input:declaration.input,output:declaration.output,declaredOn,target:declaration.target,updatesValue:declaration.updatesValue,itemType:declaration.itemType,source:declaration.origin?.source})}function resolveActionChain(chain,options={}){let maxDepth=options.maxDepth??DEFAULT_MAX_INHERITANCE_DEPTH,names=chain.map(link=>link.surfaceName),seen=new Set;for(let name of names){if(seen.has(name))throw new Error(`[actions] inheritance CYCLE detected at "${name}". Fix the surface chain: ${names.join(" \u2192 ")}`);seen.add(name)}if(chain.length-1>maxDepth)throw new Error(`[actions] inheritance chain for "${names[names.length-1]}" exceeds depth ${maxDepth}: ${names.join(" \u2192 ")}`);let byName=new Map;for(let link of chain){let own=new Set;for(let action of link.actions){if(own.has(action.name))throw new Error(`[actions] surface "${link.surfaceName}" declares Action "${action.name}" twice. Names are unique; nothing was overwritten.`);own.add(action.name),byName.set(action.name,toActionInfo(action,link.surfaceName))}}return[...byName.values()]}function asSurfaceClient(client){let c=client;if(typeof c.schema!="function")throw new Error("[alchemy/surface] the surface runtime needs a supabase-js v2 client carrying the viewer's session (it has no schema()).");return c}function readError(error,code="read_failed"){let out={code:error.code?`${code}:${error.code}`:code,message:error.message,retryable:!1};return error.details&&(out.diagnostic=error.details),out}async function door(run){try{return{ok:!0,data:await run()}}catch(err){let cause=err??{};return cause.name==="DatabaseError"&&cause.cause?{ok:!1,error:readError(cause.cause)}:{ok:!1,error:{code:"unreachable",message:err instanceof Error?err.message:String(err),retryable:!0}}}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var APPLET_SURFACE_PREFIX="applets/";function fail(code,message,retryable=!1){return{ok:!1,error:{code,message,retryable}}}function surfaceActionVisible(row,organizationIds){return row.declared_by==="code"||row.surface_name.startsWith(APPLET_SURFACE_PREFIX)?!0:typeof row.organization_id=="string"&&(organizationIds??[]).includes(row.organization_id)}async function readSurfaceChain(client,surfaceName,options={}){let db;try{db=createDb({client:asSurfaceClient(client)})}catch(err){return fail("client_invalid",err instanceof Error?err.message:String(err))}let maxDepth=options.maxDepth??DEFAULT_MAX_INHERITANCE_DEPTH,names=[],at=surfaceName;for(;at;){if(names.includes(at))return fail("surface_cycle",`The surface chain loops at "${at}": ${[...names,at].join(" \u2192 ")}.`);if(names.length>maxDepth)return fail("surface_too_deep",`The surface chain for "${surfaceName}" is deeper than ${maxDepth}: ${[...names,at].join(" \u2192 ")}.`);let name=at,row=await door(()=>readRow(db,uiSurface,name,{columns:["name","parent_surface_name"]}));if(!row.ok)return row;if(!isRecord(row.data))return fail("surface_not_found",names.length===0?`The surface "${at}" does not exist yet; saving the Applet writes it (ui.save_applet_surface).`:`The surface "${names[names.length-1]}" names a parent "${at}" that does not exist.`);names.push(at);let parent=row.data.parent_surface_name;at=typeof parent=="string"&&parent?parent:null}let rows=await door(async()=>await listAll(db,uiSurfaceAction,q=>q.in("surface_name",names),{orderBy:"sort_order"}));if(!rows.ok)return rows;let visible=rows.data.filter(r=>surfaceActionVisible(r,options.organizationIds)),chain=[...names].reverse().map(name=>({surfaceName:name,actions:visible.filter(r=>r.surface_name===name).map(surfaceActionRowToAction)}));try{return{ok:!0,data:resolveActionChain(chain,{maxDepth})}}catch(err){return fail("surface_chain",err instanceof Error?err.message:String(err))}}function fail2(code,message,retryable=!1,diagnostic){return{ok:!1,error:diagnostic?{code,message,retryable,diagnostic}:{code,message,retryable}}}function messageOf(error){return error instanceof Error&&error.message.trim()?error.message:typeof error=="string"&&error.trim()?error:"The run failed without saying why."}function newRunId(){let c=globalThis.crypto;return c?.randomUUID?c.randomUUID():`run-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function fillActionTarget(template,input){let source=input&&typeof input=="object"&&!Array.isArray(input)?input:{},missing=[];return{value:template.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(_,key)=>{let v=source[key];return v==null||v===""||typeof v=="object"?(missing.push(key),""):encodeURIComponent(String(v))}),missing}}function fillName(template,input){let filled=fillActionTarget(template,input);return{value:decodeURIComponent(filled.value),missing:filled.missing}}function toJson(value){return value===void 0?null:JSON.parse(JSON.stringify(value))}function refuseCaller(info,by){return info.triggeredBy.includes(by)?info.policy==="manual"&&by!=="person"?{code:"manual_only",message:`"${info.label}" (${info.name}) runs only when a person starts it.`,retryable:!1}:null:{code:"caller_not_allowed",message:`"${info.label}" (${info.name}) can't be started by ${CALLER_WORDS[by]}; it allows ${info.triggeredBy.join(", ")||"no one"}.`,retryable:!1}}var CALLER_WORDS={person:"a person",agent:"an agent",applet:"an applet",automation:"an automation"};function absent(info,capability){return fail2("capability_absent",`"${info.label}" can't run here: ${capability} isn't available on this page.`)}async function runSurfaceAction(info,input,by,ports,options={}){let refusal=refuseCaller(info,by);if(refusal)return{ok:!1,error:refusal};let context={runId:options.runId??newRunId(),by,viewerId:options.viewerId??null,surfaceName:info.declaredOn,policy:info.policy},capture=(error,stage)=>{try{ports.diagnostics.capture(error,{area:"actions",detail:{action:info.name,runs:info.runs,stage,runId:context.runId}})}catch{}};try{if(info.source==="write-target"&&ports.door){let receipt=await ports.door.write({surfaceName:info.declaredOn,target:info.name,...info.itemType?{itemType:info.itemType}:{},...options.itemIdentity?{itemIdentity:options.itemIdentity}:{},...options.ops?{ops:options.ops}:{value:input},by,runId:context.runId},options.signal);return receipt.status==="refused"?{ok:!1,error:{code:receipt.reason,message:receipt.sentence,retryable:receipt.reason==="failed",remedy:receipt.remedy}}:{ok:!0,data:receipt}}if(info.policy==="ask"&&by!=="person"&&info.runs!=="server"){if(!ports.approvals)return fail2("needs_approval",`"${info.label}" needs a person's approval, and there is no one to ask here.`);if(!await ports.approvals.ask({action:info.name,label:info.label,description:info.description,input:toJson(input),by,surfaceName:info.declaredOn,runId:context.runId}))return fail2("declined",`"${info.label}" was not approved, so it did not run.`)}switch(info.runs){case"server":{if(!ports.serverActions)return absent(info,"server actions");let filled=fillName(info.target??info.name,input);if(filled.missing.length)return fail2("input_missing",`"${info.label}" needs ${filled.missing.join(", ")}.`);let response=await ports.serverActions.run({name:filled.value,input:toJson(input),by,surface_name:info.declaredOn,policy:info.policy});return response.status==="refused"?fail2("refused",response.message):{ok:!0,data:response}}case"mandate":{if(!ports.mandates)return absent(info,"running a job");if(!info.target)return fail2("target_missing",`"${info.label}" names no job to run.`);let filled=fillName(info.target,input);if(filled.missing.length)return fail2("input_missing",`"${info.label}" needs ${filled.missing.join(", ")}.`);let record=input&&typeof input=="object"&&!Array.isArray(input)?input:{},variables=/\{[A-Za-z_]/.test(info.target)?record.variables&&typeof record.variables=="object"?toJson(record.variables):{}:toJson(record),userInput=typeof record.userInput=="string"?record.userInput:void 0;return{ok:!0,data:await ports.mandates.run({alias:filled.value,variables,...userInput!==void 0?{userInput}:{},by,policy:info.policy})}}case"navigate":{if(!ports.overlay)return absent(info,"navigation");let filled=fillActionTarget(info.target??"",input);if(filled.missing.length)return fail2("input_missing",`"${info.label}" needs ${filled.missing.join(", ")}.`);let to=info.target&&/^\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(info.target)?decodeURIComponent(filled.value):filled.value;return to?(ports.overlay.navigate(to),{ok:!0,data:{to}}):fail2("target_missing",`"${info.label}" names no page to open.`)}case"page":return ports.pageActions?await ports.pageActions.dispatch(info.name,input,context):absent(info,"this page's actions");default:{let runs=info.runs;return fail2("runs_unknown",`"${info.label}" runs as "${String(runs)}", which nothing here knows how to run.`)}}}catch(error){return capture(error,"run"),fail2("run_failed",messageOf(error),!0)}}function isNamed(v){return typeof v=="object"&&v!==null&&"id"in v&&"name"in v}function mergeLiveCapture(base,contributions){let owners=new Map(base.sections.map(s=>[s.id,"page"])),sections=[...base.sections],identity={...base.identity};for(let c of contributions){for(let[k,v]of Object.entries(c.identity??{})){let prior=identity[k];(prior==null||isNamed(prior)&&!prior.name)&&(identity[k]=v)}for(let s of c.sections){let prior=owners.get(s.id);if(prior)throw new Error(`[live values] section "${s.id}" is claimed by both "${prior}" and "${c.owner}"`);owners.set(s.id,c.owner),sections.push(s)}}return{...base,identity,sections}}function liveSlotsOf(capture){let onDemand=capture.sections.filter(s=>typeof s.load=="function").map(s=>({id:s.id,title:s.title,...s.description?{description:s.description}:{},role:s.role,...s.brief!==void 0?{brief:s.brief}:{},load:()=>s.load()}));return{selection:{choices:capture.selection,text:null},"on-demand":onDemand,errors:capture.errors,requests:capture.requests}}function liveValueOf(capture,name){switch(name){case"selection":return capture.selection;case"errors":return capture.errors;case"requests":return capture.requests;case"on-demand":return capture.sections.filter(s=>typeof s.load=="function").map(s=>({id:s.id,title:s.title,role:s.role}));case"title":case"route":case"url":case"kind":case"identity":return capture[name];default:break}return Object.prototype.hasOwnProperty.call(capture.identity,name)?capture.identity[name]:Object.prototype.hasOwnProperty.call(capture.selection,name)?capture.selection[name]:capture.sections.find(s=>s.id===name)?.value}function createLiveValues(){let nextId=0,version=0,pages=[],parts=[],listeners=new Set,emit=()=>{version+=1;for(let listener of[...listeners])listener()},contributions=()=>parts.map(p=>{let got=p.read();return Array.isArray(got)?{owner:p.owner,sections:got}:{owner:p.owner,...got}}),read=()=>{let top=pages[pages.length-1];return top?mergeLiveCapture(top.read(),contributions()):null};return{publish(get){let id=++nextId;return pages=[...pages,{id,read:get}],emit(),()=>{pages=pages.filter(p=>p.id!==id),emit()}},contribute(owner,get){let id=++nextId;return parts=[...parts,{id,owner,read:get}],emit(),()=>{parts=parts.filter(p=>p.id!==id),emit()}},touch:emit,has:()=>pages.length>0,read,outline(){let top=pages[pages.length-1];if(!top)return null;let base=top.read(),sections=[...base.sections,...contributions().flatMap(c=>c.sections)];return{surfaceName:base.surfaceName??null,kind:base.kind,title:base.title,loadable:sections.filter(s=>typeof s.load=="function").map(s=>({id:s.id,title:s.title}))}},readFor(surfaceName){let capture=read();return capture&&capture.surfaceName===surfaceName?capture:null},subscribe(listener){return listeners.add(listener),()=>{listeners.delete(listener)}},version:()=>version}}var liveValues=createLiveValues();var PAGE_ACTION_STREAM="actions",valueStream=name=>`value:${name}`;function clone(value){if(value===void 0)return value;let sc=globalThis.structuredClone;return sc?sc(value):JSON.parse(JSON.stringify(value))}function errorOf(err,code="surface_failed"){return{ok:!1,error:{code,message:err instanceof Error&&err.message?err.message:String(err),retryable:!1}}}var sequence=0;function defaultMint(prefix){let c=globalThis.crypto;return c?.randomUUID?`${prefix}-${c.randomUUID()}`:`${prefix}-${Date.now().toString(36)}-${(sequence++).toString(36)}`}function createSurfacePort(opts){let mint=opts.mintId??defaultMint,pending=opts.pending??new Map,parked=new Set,values=new Map,mounted=null,disposed=!1,report=(error,stage,detail={})=>{try{opts.ports.diagnostics.capture(error,{area:"actions",detail:{stage:`surface.${stage}`,...detail}})}catch{}},memberships=async()=>{if(opts.organizationIds)try{return await opts.organizationIds()}catch(err){report(err,"organizationIds");return}},read=async name=>{let organizationIds=await memberships();return readSurfaceChain(opts.client,name,{...opts.maxDepth!==void 0?{maxDepth:opts.maxDepth}:{},...organizationIds?{organizationIds}:{}})},currentChain=async fresh=>{if(mounted&&!fresh)return{ok:!0,data:mounted.chain};let name=mounted?.name??(opts.surfaceName?await opts.surfaceName():null);if(!name)return{ok:!1,error:{code:"not_mounted",message:"No surface is mounted here yet.",retryable:!1}};let chain=await read(name);return chain.ok&&mounted?.name===name&&(mounted.chain=chain.data),chain},awaitPageAction=runId=>disposed?Promise.resolve({ok:!1,error:{code:"host_disposed",message:"This page has closed.",retryable:!1}}):new Promise(resolve=>{parked.add(runId),pending.set(runId,resolve)}),selfRouted={dispatch(name,input,context){let waiting=awaitPageAction(context.runId),event={action:name,input,runId:context.runId,by:context.by},forget=()=>{pending.delete(context.runId),parked.delete(context.runId)};if(disposed)return forget(),Promise.resolve({ok:!1,error:{code:"host_disposed",message:"This page closed, so the action did not run.",retryable:!1}});let heard;try{heard=opts.emit(PAGE_ACTION_STREAM,event)}catch(err){throw forget(),err}return heard!==!0?(forget(),Promise.resolve({ok:!1,error:{code:"action_unhandled",message:`No page is open to run "${name}".`,retryable:!1}})):waiting}},port={async mount(name){try{let chain=await read(name);if(!chain.ok)return chain;if(opts.seedValues)try{let seeds=await opts.seedValues();for(let[key,v]of Object.entries(seeds))values.has(key)||values.set(key,clone(v))}catch(err){report(err,"seedValues",{surface:name})}return mounted={mountId:mint("mount"),name,chain:chain.data},{ok:!0,data:{mountId:mounted.mountId}}}catch(err){return errorOf(err)}},async unmount(mountId){mounted?.mountId===mountId&&(mounted=null)},async getValue(name){if(values.has(name)||!opts.live||!mounted)return clone(values.get(name));try{let capture=opts.live.readFor(mounted.name);return capture?clone(liveValueOf(capture,name)):void 0}catch(err){report(err,"live",{name});return}},async setValue(name,v){let copy;try{copy=clone(v)}catch(err){report(err,"setValue",{name});return}values.set(name,copy);try{opts.emit(valueStream(name),clone(v))}catch(err){report(err,"emit",{stream:valueStream(name)})}},async listActions(){try{let chain=await currentChain(!1);return chain.ok?clone(chain.data):(report(chain.error,"listActions"),[])}catch(err){return report(err,"listActions"),[]}},async runAction(name,input,by){let info;try{let known=await currentChain(!1);if(info=known.ok?known.data.find(a=>a.name===name):void 0,!info){let fresh=await currentChain(!0);if(!fresh.ok)return fresh;info=fresh.data.find(a=>a.name===name)}}catch(err){return errorOf(err)}if(!info)return{ok:!1,error:{code:"action_not_found",message:`This page has no action named "${name}".`,retryable:!1}};let viewerId=null;try{viewerId=opts.viewerId?await opts.viewerId():null}catch(err){report(err,"viewerId")}let ports={...opts.ports,pageActions:opts.pageActions??selfRouted},result=await runSurfaceAction(info,input,by,ports,{runId:mint("act"),viewerId});return result.ok&&info.updatesValue&&await port.setValue(info.updatesValue,result.data),result},async completeAction(runId,result){let resolve=pending.get(runId);if(!resolve){report(new Error(`completeAction for run "${runId}", which is not waiting (already answered, never routed here, or the page closed).`),"completeAction",{runId});return}pending.delete(runId),parked.delete(runId),resolve?.(result)},awaitPageAction,dispose(){disposed=!0;for(let runId of parked){let resolve=pending.get(runId);pending.delete(runId),resolve?.({ok:!1,error:{code:"host_disposed",message:"This page closed before the action finished.",retryable:!1}})}parked.clear(),mounted=null,values.clear()}};return port}function createItemSources(onError){let sources=new Map;return{register(containerId,source){return sources.set(containerId,source),()=>{sources.get(containerId)===source&&sources.delete(containerId)}},resolve(target){let source=sources.get(target.containerId);if(!source)return null;try{return source(target)??null}catch(error){return onError?.(error,target),null}},has:containerId=>sources.has(containerId)}}var itemSources=createItemSources((error,target)=>{console.error(`[alchemy items] the source for "${target.containerId}" threw resolving ${target.level}`,error)});export{APPLET_SURFACE_PREFIX,PAGE_ACTION_STREAM,createItemSources,createLiveValues,createSurfacePort,itemSources,liveSlotsOf,liveValueOf,liveValues,mergeLiveCapture,readSurfaceChain,surfaceActionVisible,valueStream};
2
2
  //# sourceMappingURL=surface.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/declare/registry.ts","../src/actions/declarations.ts","../src/surface/client.ts","../src/surface/chain.ts","../src/actions/surface-run.ts","../src/surface/live.ts","../src/surface/port.ts","../src/surface/items.ts"],"sourcesContent":["/**\n * The declaration registry: inheritance, baseline injection, provenance and\n * group synthesis (CONTRACT §2.1 `DeclarationRegistry`). Ported verbatim in\n * behaviour from matrx-frontend `features/surfaces/manifests/registry.ts`\n * (ALC-14); the app now supplies its declarations and baselines.\n *\n * Guards are LOUD by design: an unknown parent, a cycle, a chain deeper than\n * the limit, a reserved or duplicate group key, a value naming an undeclared\n * group, or a reserved platform name throws on resolution — a build fails\n * instead of silently dropping values.\n */\nimport { declarationHash } from \"./hash\";\nimport type {\n DeclarationExtension,\n DeclarationIssue,\n DeclaredValue,\n ItemType,\n ResolvedSurfaceDeclaration,\n ResolvedValue,\n SurfaceDeclaration,\n ValueGroup,\n ValueProvenance,\n} from \"./types\";\nimport { validateDeclarations, type ValidateOptions } from \"./validate\";\n\nexport const RESERVED_GROUP_KEYS = {\n general: \"general\",\n baseline: \"baseline\",\n inheritedPrefix: \"inherited:\",\n} as const;\n\n/** Group sortOrder bands. Curated groups author 0–899; the rest is reserved. */\nexport const GENERAL_GROUP_ORDER = 850;\nexport const INHERITED_GROUP_ORDER_BASE = 9000;\nexport const BASELINE_GROUP_ORDER = 9900;\nexport const DEFAULT_MAX_INHERITANCE_DEPTH = 3;\n\nimport { DEFAULT_SENSITIVITY, resolveSensitivity } from \"./sensitivity\";\nexport { DEFAULT_SENSITIVITY, resolveSensitivity };\n\nexport type Resolved<D extends SurfaceDeclaration> = Omit<D, \"values\" | \"groups\"> & {\n values: readonly (D[\"values\"][number] & ResolvedValue)[];\n groups: readonly ValueGroup[];\n contentHash: string;\n};\n\nexport interface DeclarationRegistryOptions {\n /** Generic values injected into every declaration unless `skipBaselineValues`. */\n baselineValues?: readonly DeclaredValue[];\n /**\n * Item types every declaration carries unless it declares one of the same name or sets\n * `skipBaselineItemTypes` (ALC-18: the canonical table row, `TABLE_ROW_ITEM_TYPE`).\n */\n baselineItemTypes?: readonly ItemType[];\n /** Value names only the platform writes; a declaration claiming one is refused. */\n reservedValueNames?: readonly string[];\n /** Write-target names only the platform writes. */\n reservedWriteTargetNames?: readonly string[];\n maxInheritanceDepth?: number;\n}\n\nexport interface DeclarationRegistry<D extends SurfaceDeclaration> {\n /** Refuses a second declaration of the same surfaceName. */\n register(declaration: D): void;\n registerExtension(extension: DeclarationExtension<D>): void;\n extensions(): readonly DeclarationExtension<D>[];\n /** Declarations exactly as authored (inheritance unresolved, no baselines). */\n raw(): readonly D[];\n getRaw(surfaceName: string): D | undefined;\n /** Parent chain, ROOT FIRST. Unknown surfaces return []. */\n ancestry(surfaceName: string): string[];\n /** Direct children (declarations naming it in `inheritsFrom`), in declaration order. */\n children(surfaceName: string): string[];\n /** Inheritance + baseline + groups resolved; provenance kept. */\n all(): readonly Resolved<D>[];\n get(surfaceName: string): Resolved<D> | undefined;\n validate(options?: ValidateOptions): readonly DeclarationIssue[];\n}\n\nexport function createDeclarationRegistry<D extends SurfaceDeclaration>(\n options: DeclarationRegistryOptions = {},\n): DeclarationRegistry<D> {\n const baselineValues = options.baselineValues ?? [];\n const baselineNames = new Set(baselineValues.map((v) => v.name));\n const baselineItemTypes = options.baselineItemTypes ?? [];\n const reservedValues = new Set(options.reservedValueNames ?? []);\n const reservedTargets = new Set(options.reservedWriteTargetNames ?? []);\n const maxDepth = options.maxInheritanceDepth ?? DEFAULT_MAX_INHERITANCE_DEPTH;\n const declarations: D[] = [];\n const index = new Map<string, D>();\n const extensionList: DeclarationExtension<D>[] = [];\n let resolvedCache: Resolved<D>[] | null = null;\n let resolvedIndex = new Map<string, Resolved<D>>();\n\n function ancestry(surfaceName: string): string[] {\n const chain: string[] = [];\n const seen = new Set<string>([surfaceName]);\n let current = index.get(surfaceName)?.inheritsFrom;\n while (current) {\n if (seen.has(current)) {\n throw new Error(\n `[surfaces] inheritsFrom CYCLE detected at \"${current}\" (from \"${surfaceName}\"). ` +\n `Fix the manifest chain: ${[...seen].join(\" → \")} → ${current}`,\n );\n }\n const parent = index.get(current);\n if (!parent) {\n throw new Error(\n `[surfaces] \"${surfaceName}\" inheritsFrom unknown surface \"${current}\" — ` +\n `the parent must be a registered declaration`,\n );\n }\n seen.add(current);\n chain.unshift(current);\n if (chain.length > maxDepth) {\n throw new Error(\n `[surfaces] inheritance chain for \"${surfaceName}\" exceeds depth ${maxDepth}: ` + chain.join(\" → \"),\n );\n }\n current = parent.inheritsFrom;\n }\n return chain;\n }\n\n function groupKeyFor(value: DeclaredValue, provenance: ValueProvenance): string {\n if (provenance.kind === \"own\" && value.group) return value.group;\n if (baselineNames.has(value.name)) return RESERVED_GROUP_KEYS.baseline;\n if (provenance.kind === \"inherited\") return `${RESERVED_GROUP_KEYS.inheritedPrefix}${provenance.from}`;\n if (provenance.kind === \"baseline\") return RESERVED_GROUP_KEYS.baseline;\n return RESERVED_GROUP_KEYS.general;\n }\n\n function resolve(declaration: D): Resolved<D> {\n const chain = ancestry(declaration.surfaceName);\n const lineage: { layer: D; from: string | null }[] = [\n ...chain.map((name) => {\n const layer = index.get(name);\n if (!layer) throw new Error(`[surfaces] missing inherited declaration \"${name}\"`);\n return { layer, from: name };\n }),\n { layer: declaration, from: null },\n ];\n\n const curatedKeys = new Set<string>();\n for (const group of declaration.groups ?? []) {\n if (\n group.key === RESERVED_GROUP_KEYS.general ||\n group.key === RESERVED_GROUP_KEYS.baseline ||\n group.key.startsWith(RESERVED_GROUP_KEYS.inheritedPrefix)\n ) {\n throw new Error(\n `[surfaces] \"${declaration.surfaceName}\" declares reserved group key \"${group.key}\" — ` +\n `general/baseline/inherited:* are synthesized by the registry`,\n );\n }\n if (curatedKeys.has(group.key)) {\n throw new Error(`[surfaces] \"${declaration.surfaceName}\" declares duplicate group key \"${group.key}\"`);\n }\n curatedKeys.add(group.key);\n }\n for (const value of declaration.values) {\n if (reservedValues.has(value.name)) {\n throw new Error(\n `[surfaces] \"${declaration.surfaceName}\" declares value \"${value.name}\" — that name is written by the platform; choose another name`,\n );\n }\n if (value.group && !curatedKeys.has(value.group)) {\n throw new Error(\n `[surfaces] \"${declaration.surfaceName}\" value \"${value.name}\" references undeclared ` +\n `group \"${value.group}\" — declare it in the manifest's \\`groups\\``,\n );\n }\n }\n for (const target of declaration.writeTargets ?? []) {\n if (reservedTargets.has(target.name)) {\n throw new Error(\n `[surfaces] \"${declaration.surfaceName}\" declares write target \"${target.name}\" — that name is written by the platform; choose another name`,\n );\n }\n }\n\n const valuesByName = new Map<string, D[\"values\"][number] & ResolvedValue>();\n const inheritedLists = new Map<string, Map<string, unknown>>();\n const coreLists: { field: string; identity(entry: unknown): string }[] = [\n { field: \"configNamespaces\", identity: (entry) => (entry as { namespace: string }).namespace },\n {\n field: \"evidenceSources\",\n identity: (entry) => `${(entry as { kind: string }).kind}:${(entry as { idValue: string }).idValue}`,\n },\n ];\n const lists = [...coreLists, ...extensionList.flatMap((extension) => extension.inheritedLists ?? [])];\n for (const { layer, from } of lineage) {\n for (const value of layer.values) {\n const provenance: ValueProvenance = from ? { kind: \"inherited\", from } : { kind: \"own\" };\n valuesByName.set(value.name, {\n ...value,\n provenance,\n groupKey: groupKeyFor(value, provenance),\n resolvedSensitivity: resolveSensitivity(value),\n });\n }\n for (const list of lists) {\n const entries = (layer as unknown as Record<string, unknown>)[list.field];\n if (!Array.isArray(entries)) continue;\n const byIdentity = inheritedLists.get(list.field) ?? new Map<string, unknown>();\n for (const entry of entries) byIdentity.set(list.identity(entry), entry);\n inheritedLists.set(list.field, byIdentity);\n }\n }\n\n if (!declaration.skipBaselineValues) {\n for (const baseline of baselineValues) {\n if (valuesByName.has(baseline.name)) continue;\n valuesByName.set(baseline.name, {\n ...baseline,\n provenance: { kind: \"baseline\" },\n groupKey: RESERVED_GROUP_KEYS.baseline,\n resolvedSensitivity: resolveSensitivity(baseline),\n } as D[\"values\"][number] & ResolvedValue);\n }\n }\n\n const ownItemTypes = declaration.itemTypes ?? [];\n const itemTypes: ItemType[] = [...ownItemTypes];\n if (!declaration.skipBaselineItemTypes) {\n for (const baseline of baselineItemTypes) {\n if (!itemTypes.some((item) => item.name === baseline.name)) itemTypes.push(baseline);\n }\n }\n\n const usedGroupKeys = new Set(Array.from(valuesByName.values(), (value) => value.groupKey));\n const groups: ValueGroup[] = [...(declaration.groups ?? [])];\n if (usedGroupKeys.has(RESERVED_GROUP_KEYS.general)) {\n groups.push({ key: RESERVED_GROUP_KEYS.general, label: \"General\", sortOrder: GENERAL_GROUP_ORDER });\n }\n for (let i = chain.length - 1, distance = 0; i >= 0; i -= 1, distance += 1) {\n const parentName = chain[i]!;\n const key = `${RESERVED_GROUP_KEYS.inheritedPrefix}${parentName}`;\n if (!usedGroupKeys.has(key)) continue;\n const parentLabel = index.get(parentName)?.label ?? parentName;\n groups.push({\n key,\n label: `Inherited from ${parentLabel}`,\n sortOrder: INHERITED_GROUP_ORDER_BASE + distance * 10,\n });\n }\n if (usedGroupKeys.has(RESERVED_GROUP_KEYS.baseline)) {\n groups.push({ key: RESERVED_GROUP_KEYS.baseline, label: \"Generic baselines\", sortOrder: BASELINE_GROUP_ORDER });\n }\n groups.sort((a, b) => a.sortOrder - b.sortOrder);\n\n const groupOrder = new Map(groups.map((group) => [group.key, group.sortOrder] as const));\n const values = Array.from(valuesByName.values()).sort((a, b) => {\n const ga = groupOrder.get(a.groupKey) ?? GENERAL_GROUP_ORDER;\n const gb = groupOrder.get(b.groupKey) ?? GENERAL_GROUP_ORDER;\n if (ga !== gb) return ga - gb;\n return (a.sortOrder ?? 1000) - (b.sortOrder ?? 1000);\n });\n\n const merged: Record<string, unknown> = {};\n for (const [field, byIdentity] of inheritedLists) {\n if (byIdentity.size > 0) merged[field] = Array.from(byIdentity.values());\n }\n return {\n ...declaration,\n values,\n groups,\n ...merged,\n ...(itemTypes.length > 0 ? { itemTypes } : {}),\n contentHash: declarationHash(declaration),\n } as Resolved<D>;\n }\n\n function resolvedAll(): Resolved<D>[] {\n if (!resolvedCache) {\n resolvedCache = declarations.map(resolve);\n resolvedIndex = new Map(resolvedCache.map((entry) => [entry.surfaceName, entry] as const));\n }\n return resolvedCache;\n }\n\n const registry: DeclarationRegistry<D> = {\n register(declaration) {\n if (index.has(declaration.surfaceName)) {\n throw new Error(`[surfaces] \"${declaration.surfaceName}\" is declared twice — one surface, one declaration`);\n }\n declarations.push(declaration);\n index.set(declaration.surfaceName, declaration);\n resolvedCache = null;\n },\n registerExtension(extension) {\n if (extensionList.some((existing) => existing.key === extension.key)) {\n throw new Error(`[surfaces] declaration extension \"${extension.key}\" is registered twice`);\n }\n extensionList.push(extension);\n resolvedCache = null;\n },\n extensions: () => extensionList,\n raw: () => declarations,\n getRaw: (surfaceName) => index.get(surfaceName),\n ancestry,\n children: (surfaceName) =>\n declarations.filter((d) => d.inheritsFrom === surfaceName).map((d) => d.surfaceName),\n all: () => resolvedAll(),\n get(surfaceName) {\n resolvedAll();\n return resolvedIndex.get(surfaceName);\n },\n validate: (validateOptions) =>\n validateDeclarations(resolvedAll() as unknown as readonly ResolvedSurfaceDeclaration[], {\n ...validateOptions,\n extensions: [...(validateOptions?.extensions ?? []), ...(extensionList as DeclarationExtension[])],\n baselineNames: validateOptions?.baselineNames ?? [...baselineNames],\n }),\n };\n return registry;\n}\n","/**\n * Every source of an Action projects onto ONE shape (Applets CONTRACTS §6):\n * a declared write target, a client tool row, a `ui.ui_surface_action` row.\n * Pure functions, zero loss (the census in `declarations.test.ts` proves every\n * source field lands). Then the chain: a child surface's Action wins by name.\n */\nimport { DEFAULT_MAX_INHERITANCE_DEPTH } from \"../declare/registry\";\nimport type { Json, WriteTarget } from \"../declare/types\";\nimport type {\n ActionCaller,\n ActionDeclaration,\n ActionDeclaredBy,\n ActionInfo,\n ActionInput,\n ActionOrigin,\n ActionPolicy,\n ActionRuns,\n ActionWriteMode,\n} from \"./applet-types\";\n\n/** Default `category` of an Action that names none. */\nexport const APPLET_CATEGORY = \"applet\";\n\n/** The DB default of `ui.ui_surface_action.triggered_by`, used where a source carries no list. */\nexport const DEFAULT_TRIGGERED_BY: readonly ActionCaller[] = [\"person\", \"agent\", \"applet\"];\n\nexport const ACTION_CALLERS: readonly ActionCaller[] = [\"person\", \"agent\", \"applet\", \"automation\"];\nexport const ACTION_RUNS: readonly ActionRuns[] = [\"page\", \"server\", \"mandate\", \"navigate\"];\nexport const ACTION_POLICIES: readonly ActionPolicy[] = [\"ask\", \"auto\", \"manual\"];\n\n/** A `ui.ui_surface_client_tool` row (live columns that carry meaning). */\nexport interface ClientToolRow {\n id?: string;\n surface_name: string;\n name: string;\n label: string;\n description: string;\n input_schema: Json;\n /** Live values: \"ui\" (applied directly) | \"draft\" (proposed for review). */\n mode: \"ui\" | \"draft\";\n declared_by?: ActionDeclaredBy;\n}\n\n/** A `ui.ui_surface_action` row. */\nexport interface SurfaceActionRow {\n id?: string;\n surface_id: string;\n surface_name: string;\n /** '' = the screen itself. */\n item_type: string;\n name: string;\n category: string;\n label: string;\n description: string;\n input: ActionInput | null;\n output: string | null;\n runs: ActionRuns;\n target: string | null;\n triggered_by: ActionCaller[];\n policy: ActionPolicy;\n updates_value: string | null;\n code_ref: string | null;\n declared_by: ActionDeclaredBy;\n sort_order: number;\n /**\n * The row's organization. A `declared_by='database'` row on a surface outside `applets/` is that\n * organization's EXTENSION and applies only to its members (`readSurfaceChain`, aidream `visible_actions`).\n */\n organization_id?: string | null;\n}\n\ntype Loose<T> = { [K in keyof T]: T[K] | undefined };\n\n/** Drop undefined keys (exactOptionalPropertyTypes: an absent field is absent, never `undefined`). */\nfunction compact<T extends object>(value: Loose<T>): T {\n return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as T;\n}\n\nconst POLICY_OF_APPLY: Record<NonNullable<WriteTarget[\"applyPolicy\"]>, ActionPolicy> = {\n manual: \"manual\",\n ask: \"ask\",\n auto: \"auto\",\n // Filed for an organization's review: never applied without someone saying yes.\n queued: \"ask\",\n};\n\n/** A declared write target → an Action that runs on the page. */\nexport function writeTargetToAction(target: WriteTarget): ActionDeclaration {\n const applyPolicy = target.applyPolicy ?? \"manual\";\n return compact<ActionDeclaration>({\n name: target.name,\n label: target.label,\n description: target.description,\n input: target.valueKind ?? { jsonSchema: target.valueType === \"document\" ? {} : { type: target.valueType } },\n runs: \"page\",\n triggeredBy: [...DEFAULT_TRIGGERED_BY],\n policy: POLICY_OF_APPLY[applyPolicy],\n updatesValue: target.updatesValue,\n mode: target.mode as ActionWriteMode,\n patchable: target.patchable,\n approvalComparison: target.approvalComparison,\n streamOps: target.streamOps ? [...target.streamOps] : undefined,\n destination: target.destination,\n groupKey: target.group,\n itemType: target.itemType,\n applyPolicy: target.applyPolicy,\n valueType: target.valueType,\n valueKind: target.valueKind,\n sortOrder: target.sortOrder,\n origin: { source: \"write-target\", declaredBy: \"code\" },\n });\n}\n\n/** A client tool row → an Action an agent runs on the page (\"draft\" tools are proposed first). */\nexport function clientToolToAction(row: ClientToolRow): ActionDeclaration {\n return compact<ActionDeclaration>({\n name: row.name,\n label: row.label,\n description: row.description,\n input: { jsonSchema: (row.input_schema ?? {}) as object },\n runs: \"page\",\n triggeredBy: [\"agent\"],\n policy: row.mode === \"draft\" ? \"ask\" : \"auto\",\n mode: row.mode,\n origin: compact<ActionOrigin>({ source: \"client-tool\", surfaceName: row.surface_name, id: row.id, declaredBy: row.declared_by }),\n });\n}\n\n/** A `ui.ui_surface_action` row → its Action. */\nexport function surfaceActionRowToAction(row: SurfaceActionRow): ActionDeclaration {\n return compact<ActionDeclaration>({\n name: row.name,\n category: row.category,\n label: row.label,\n description: row.description,\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n runs: row.runs,\n target: row.target ?? undefined,\n triggeredBy: [...row.triggered_by],\n policy: row.policy,\n updatesValue: row.updates_value ?? undefined,\n itemType: row.item_type || undefined,\n sortOrder: row.sort_order,\n origin: compact<ActionOrigin>({\n source: \"surface-action\",\n surfaceName: row.surface_name,\n surfaceId: row.surface_id,\n id: row.id,\n declaredBy: row.declared_by,\n codeRef: row.code_ref ?? undefined,\n organizationId: row.organization_id ?? undefined,\n }),\n });\n}\n\n/** JSON-only view of an Action as declared on `declaredOn`. */\nexport function toActionInfo(declaration: ActionDeclaration, declaredOn: string): ActionInfo {\n return compact<ActionInfo>({\n name: declaration.name,\n category: declaration.category ?? APPLET_CATEGORY,\n label: declaration.label,\n description: declaration.description,\n runs: declaration.runs,\n policy: declaration.policy,\n triggeredBy: [...declaration.triggeredBy],\n input: declaration.input,\n output: declaration.output,\n declaredOn,\n target: declaration.target,\n updatesValue: declaration.updatesValue,\n itemType: declaration.itemType,\n source: declaration.origin?.source,\n });\n}\n\nexport interface ActionChainLink {\n surfaceName: string;\n actions: readonly ActionDeclaration[];\n}\n\n/**\n * The Actions a mount sees: its own plus every ancestor's, a child winning by\n * name. `chain` runs MOST GENERAL FIRST (root parent … the mounted surface),\n * as `DeclarationRegistry` resolves inheritance. Guards are loud, like the\n * declaration registry's: a surface twice in the chain is a cycle, more\n * ancestors than `maxDepth` throws, and one surface naming an Action twice throws.\n */\nexport function resolveActionChain(\n chain: readonly ActionChainLink[],\n options: { maxDepth?: number } = {},\n): ActionInfo[] {\n const maxDepth = options.maxDepth ?? DEFAULT_MAX_INHERITANCE_DEPTH;\n const names = chain.map((link) => link.surfaceName);\n const seen = new Set<string>();\n for (const name of names) {\n if (seen.has(name)) {\n throw new Error(`[actions] inheritance CYCLE detected at \"${name}\". Fix the surface chain: ${names.join(\" → \")}`);\n }\n seen.add(name);\n }\n if (chain.length - 1 > maxDepth) {\n throw new Error(\n `[actions] inheritance chain for \"${names[names.length - 1]}\" exceeds depth ${maxDepth}: ${names.join(\" → \")}`,\n );\n }\n const byName = new Map<string, ActionInfo>();\n for (const link of chain) {\n const own = new Set<string>();\n for (const action of link.actions) {\n if (own.has(action.name)) {\n throw new Error(\n `[actions] surface \"${link.surfaceName}\" declares Action \"${action.name}\" twice. Names are unique; nothing was overwritten.`,\n );\n }\n own.add(action.name);\n byName.set(action.name, toActionInfo(action, link.surfaceName));\n }\n }\n return [...byName.values()];\n}\n","/**\n * The few reads the surface runtime makes through the VIEWER's supabase client, typed STRUCTURALLY.\n *\n * Alchemy never imports supabase or the host (package rule 13). Deliberately not\n * `SupabaseClient<Database>` either: a generated `Database` type makes `schema().from().select()`\n * enormous and a host passing its typed client hits TS2589. The host hands its client in as an\n * `object`; the ONE cast lives in `asSurfaceClient`, and every read names its schema out loud.\n *\n * Holds no key and opens no connection: the client carries the person's session, so row security\n * decides every answer.\n */\nimport type { ActionError, ActionResult } from \"../actions/applet-types\";\n\n/** What a supabase-js read resolves with. */\nexport interface SurfaceReadAnswer {\n data: unknown;\n error: { message: string; code?: string; details?: string; hint?: string } | null;\n}\n\n/** The filter chain the reads use — a subset of supabase-js's `PostgrestFilterBuilder`. */\nexport interface SurfaceReadChain extends PromiseLike<SurfaceReadAnswer> {\n eq(column: string, value: unknown): SurfaceReadChain;\n in(column: string, values: readonly unknown[]): SurfaceReadChain;\n is(column: string, value: null): SurfaceReadChain;\n order(column: string, options?: { ascending?: boolean }): SurfaceReadChain;\n maybeSingle(): PromiseLike<SurfaceReadAnswer>;\n}\n\n/** The part of a supabase-js v2 client the surface runtime reads through. */\nexport interface SurfaceClient {\n schema(name: string): { from(table: string): { select(columns: string): SurfaceReadChain } };\n}\n\n/** Bind the host's client. A value without `schema()` is refused by name. */\nexport function asSurfaceClient(client: object): SurfaceClient {\n // The one cast: the host's typed client is passed as `object` (see above) and checked here.\n const c = client as Partial<SurfaceClient>;\n if (typeof c.schema !== \"function\") {\n throw new Error(\"[alchemy/surface] the surface runtime needs a supabase-js v2 client carrying the viewer's session (it has no schema()).\");\n }\n return c as SurfaceClient;\n}\n\n/** A read's error: the database's own sentence, never paraphrased. */\nexport function readError(error: NonNullable<SurfaceReadAnswer[\"error\"]>, code = \"read_failed\"): ActionError {\n const out: ActionError = { code: error.code ? `${code}:${error.code}` : code, message: error.message, retryable: false };\n if (error.details) out.diagnostic = error.details;\n return out;\n}\n\n/** Run a read (built inside the guard); a thrown transport error answers `unreachable` (retryable), never throws. */\nexport async function read<T>(query: () => PromiseLike<SurfaceReadAnswer>, shape: (data: unknown) => T): Promise<ActionResult<T>> {\n try {\n const answer = await query();\n if (answer.error) return { ok: false, error: readError(answer.error) };\n return { ok: true, data: shape(answer.data) };\n } catch (err) {\n return { ok: false, error: { code: \"unreachable\", message: err instanceof Error ? err.message : String(err), retryable: true } };\n }\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","/**\n * `readSurfaceChain` — the Actions a surface offers, read from the DATABASE (Applets CONTRACTS §6).\n *\n * Walks `ui.ui_surface` by `parent_surface_name` (live rows only), reads every surface's\n * `ui.ui_surface_action` rows for the whole chain in ONE query, projects each row with\n * `surfaceActionRowToAction` and resolves the chain with `resolveActionChain` (a child's Action\n * wins by name). Loud, named refusals for a cycle, a chain too deep, and a missing surface.\n *\n * Organization scoping — the same rule as aidream's `visible_actions`: a `declared_by='database'`\n * row on a surface OUTSIDE `applets/` is one organization's EXTENSION and is kept only when its\n * `organization_id` is one of the viewer's memberships (`organizationIds` = ALL of them; the active\n * organization is never a filter). No `organizationIds` = extensions are dropped (fail closed).\n * Code rows and `applets/*` rows are always kept. This scopes WHICH extension applies; row\n * security still decides what the client can read at all.\n *\n * The client is the viewer's supabase-js v2 client, typed STRUCTURALLY (`./client.ts`): the package\n * never imports supabase or the host. Never throws: a transport failure answers `unreachable`\n * (retryable); a database error keeps the database's own sentence.\n */\nimport { DEFAULT_MAX_INHERITANCE_DEPTH } from \"../declare/registry\";\nimport type { ActionInfo, ActionResult } from \"../actions/applet-types\";\nimport { resolveActionChain, surfaceActionRowToAction, type ActionChainLink, type SurfaceActionRow } from \"../actions/declarations\";\nimport { asSurfaceClient, isRecord, read, type SurfaceClient } from \"./client\";\n\n/** Surfaces under this prefix belong to one Applet; their database rows are never \"extensions\". */\nexport const APPLET_SURFACE_PREFIX = \"applets/\";\n\nexport interface ReadSurfaceChainOptions {\n /** Most ancestors a surface may have (alchemy's declaration default when absent). */\n maxDepth?: number;\n /** ALL of the viewer's organization memberships. Absent = organization extensions are dropped. */\n organizationIds?: readonly string[];\n}\n\nfunction fail(code: string, message: string, retryable = false): { ok: false; error: { code: string; message: string; retryable: boolean } } {\n return { ok: false, error: { code, message, retryable } };\n}\n\n/** Whether a row applies to a viewer with these memberships (aidream `visible_actions`). */\nexport function surfaceActionVisible(row: Pick<SurfaceActionRow, \"declared_by\" | \"surface_name\" | \"organization_id\">, organizationIds: readonly string[] | undefined): boolean {\n // Only a CODE row is everyone's; anything else (database, or a value nobody declared) is an extension\n // until proven otherwise — fail closed.\n if (row.declared_by === \"code\") return true;\n if (row.surface_name.startsWith(APPLET_SURFACE_PREFIX)) return true;\n return typeof row.organization_id === \"string\" && (organizationIds ?? []).includes(row.organization_id);\n}\n\nexport async function readSurfaceChain(\n client: object,\n surfaceName: string,\n options: ReadSurfaceChainOptions = {},\n): Promise<ActionResult<ActionInfo[]>> {\n let db: SurfaceClient;\n try {\n db = asSurfaceClient(client);\n } catch (err) {\n return fail(\"client_invalid\", err instanceof Error ? err.message : String(err));\n }\n const maxDepth = options.maxDepth ?? DEFAULT_MAX_INHERITANCE_DEPTH;\n const names: string[] = [];\n let at: string | null = surfaceName;\n while (at) {\n if (names.includes(at)) return fail(\"surface_cycle\", `The surface chain loops at \"${at}\": ${[...names, at].join(\" → \")}.`);\n if (names.length > maxDepth) {\n return fail(\"surface_too_deep\", `The surface chain for \"${surfaceName}\" is deeper than ${maxDepth}: ${[...names, at].join(\" → \")}.`);\n }\n const name: string = at;\n const row: ActionResult<unknown> = await read(\n () => db.schema(\"ui\").from(\"ui_surface\").select(\"name, parent_surface_name\").eq(\"name\", name).is(\"deleted_at\", null).maybeSingle(),\n (d) => d,\n );\n if (!row.ok) return row;\n if (!isRecord(row.data)) {\n return fail(\n \"surface_not_found\",\n names.length === 0\n ? `The surface \"${at}\" does not exist yet; saving the Applet writes it (ui.save_applet_surface).`\n : `The surface \"${names[names.length - 1]}\" names a parent \"${at}\" that does not exist.`,\n );\n }\n names.push(at);\n const parent: unknown = row.data.parent_surface_name;\n at = typeof parent === \"string\" && parent ? parent : null;\n }\n const rows = await read(\n () =>\n db\n .schema(\"ui\")\n .from(\"ui_surface_action\")\n .select(\"*\")\n .in(\"surface_name\", names)\n .is(\"deleted_at\", null)\n .order(\"sort_order\", { ascending: true }),\n (d) => (Array.isArray(d) ? (d as SurfaceActionRow[]) : []),\n );\n if (!rows.ok) return rows;\n const visible = rows.data.filter((r) => surfaceActionVisible(r, options.organizationIds));\n // Most general first (root parent … the surface itself), as resolveActionChain expects.\n const chain: ActionChainLink[] = [...names].reverse().map((name) => ({\n surfaceName: name,\n actions: visible.filter((r) => r.surface_name === name).map(surfaceActionRowToAction),\n }));\n try {\n return { ok: true, data: resolveActionChain(chain, { maxDepth }) };\n } catch (err) {\n return fail(\"surface_chain\", err instanceof Error ? err.message : String(err));\n }\n}\n","/**\n * THE ONE RUNNER for surface Actions (Applets CONTRACTS §6). Every caller — a\n * person's click, an agent, an applet, an automation — runs an Action through\n * here, so policy and caller rules live once.\n *\n * Policy \"ask\": a person's own click is the approval. Started by an agent, applet or automation,\n * a \"server\" run carries the policy to aidream (which answers with a proposal); every other run\n * asks the person through `ports.approvals` first, and is refused by name without that port.\n *\n * Dispatch by `runs`:\n * \"server\" → `ports.serverActions.run({ name: target, input, by, surface_name, policy })`\n * \"mandate\" → `ports.mandates.run({ alias: target, variables, by, policy })` — answers with the\n * started run's `MandateRunRef`; the result streams later on `run:<requestId>`\n * \"navigate\" → `ports.overlay.navigate(target)` with `{param}` filled from the input\n * \"page\" → `ports.pageActions.dispatch(name, input, context)`\n * A port the host did not bind means that capability is ABSENT: the run is\n * refused with a sentence, never stubbed (ports rule).\n *\n * Write targets (ALC-17): an Action projected from a declared write target (`source: \"write-target\"`)\n * goes through `ports.door.write` when a door is bound — the door applies the target's own policy\n * (manual / ask / queued / auto) and its receipt becomes the result (`applied` / `queued` → ok with\n * the receipt; refused → an error whose code is the refusal reason and whose `remedy` is the door's).\n * Without a door it dispatches to `pageActions` as before.\n *\n * Never throws: every outcome is a `Result` whose error message is the\n * system's own sentence.\n */\nimport type { AlchemyHostPorts, Json } from \"../ports\";\nimport type { WriteOp } from \"../operate/door\";\nimport type { ActionCaller, ActionContext, ActionError, ActionInfo, ActionResult } from \"./applet-types\";\n\nexport type SurfaceActionPorts = Pick<\n AlchemyHostPorts,\n \"diagnostics\" | \"serverActions\" | \"mandates\" | \"pageActions\" | \"overlay\" | \"approvals\" | \"door\"\n>;\n\nexport interface RunSurfaceActionOptions {\n runId?: string;\n viewerId?: string | null;\n signal?: AbortSignal;\n /** Which item a write-target Action writes into (by its declared identity values). */\n itemIdentity?: Record<string, string>;\n /** Text edits for a stream or patchable write target, instead of the input as the whole value. */\n ops?: readonly WriteOp[];\n}\n\nfunction fail(code: string, message: string, retryable = false, diagnostic?: string): { ok: false; error: ActionError } {\n return { ok: false, error: diagnostic ? { code, message, retryable, diagnostic } : { code, message, retryable } };\n}\n\nfunction messageOf(error: unknown): string {\n if (error instanceof Error && error.message.trim()) return error.message;\n if (typeof error === \"string\" && error.trim()) return error;\n return \"The run failed without saying why.\";\n}\n\nfunction newRunId(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n return `run-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Fill `{param}` placeholders from the input object. Returns the names it could not fill. */\nexport function fillActionTarget(template: string, input: unknown): { value: string; missing: string[] } {\n const source = input && typeof input === \"object\" && !Array.isArray(input) ? (input as Record<string, unknown>) : {};\n const missing: string[] = [];\n const value = template.replace(/\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, key: string) => {\n const v = source[key];\n if (v === undefined || v === null || v === \"\" || typeof v === \"object\") {\n missing.push(key);\n return \"\";\n }\n return encodeURIComponent(String(v));\n });\n return { value, missing };\n}\n\n/** Same as fillActionTarget, without URL-encoding (a mandate alias or server action name). */\nfunction fillName(template: string, input: unknown): { value: string; missing: string[] } {\n const filled = fillActionTarget(template, input);\n return { value: decodeURIComponent(filled.value), missing: filled.missing };\n}\n\nfunction toJson(value: unknown): Json {\n if (value === undefined) return null;\n return JSON.parse(JSON.stringify(value)) as Json;\n}\n\n/**\n * Who may run this Action, under its policy. Returns the refusal, or null.\n * \"manual\" = a person only. `triggeredBy` lists every caller allowed at all.\n */\nexport function refuseCaller(info: Pick<ActionInfo, \"name\" | \"label\" | \"policy\" | \"triggeredBy\">, by: ActionCaller): ActionError | null {\n if (!info.triggeredBy.includes(by)) {\n return {\n code: \"caller_not_allowed\",\n message: `\"${info.label}\" (${info.name}) can't be started by ${CALLER_WORDS[by]}; it allows ${info.triggeredBy.join(\", \") || \"no one\"}.`,\n retryable: false,\n };\n }\n if (info.policy === \"manual\" && by !== \"person\") {\n return {\n code: \"manual_only\",\n message: `\"${info.label}\" (${info.name}) runs only when a person starts it.`,\n retryable: false,\n };\n }\n return null;\n}\n\nconst CALLER_WORDS: Record<ActionCaller, string> = {\n person: \"a person\",\n agent: \"an agent\",\n applet: \"an applet\",\n automation: \"an automation\",\n};\n\nfunction absent(info: ActionInfo, capability: string): { ok: false; error: ActionError } {\n return fail(\"capability_absent\", `\"${info.label}\" can't run here: ${capability} isn't available on this page.`);\n}\n\nexport async function runSurfaceAction(\n info: ActionInfo,\n input: unknown,\n by: ActionCaller,\n ports: SurfaceActionPorts,\n options: RunSurfaceActionOptions = {},\n): Promise<ActionResult<unknown>> {\n const refusal = refuseCaller(info, by);\n if (refusal) return { ok: false, error: refusal };\n const context: ActionContext = {\n runId: options.runId ?? newRunId(),\n by,\n viewerId: options.viewerId ?? null,\n surfaceName: info.declaredOn,\n policy: info.policy,\n };\n const capture = (error: unknown, stage: string) => {\n try {\n ports.diagnostics.capture(error, { area: \"actions\", detail: { action: info.name, runs: info.runs, stage, runId: context.runId } });\n } catch {\n // A broken diagnostics port never turns a refusal into a throw.\n }\n };\n\n try {\n if (info.source === \"write-target\" && ports.door) {\n const receipt = await ports.door.write(\n {\n surfaceName: info.declaredOn,\n target: info.name,\n ...(info.itemType ? { itemType: info.itemType } : {}),\n ...(options.itemIdentity ? { itemIdentity: options.itemIdentity } : {}),\n ...(options.ops ? { ops: options.ops } : { value: input }),\n by,\n runId: context.runId,\n },\n options.signal,\n );\n if (receipt.status === \"refused\") {\n return { ok: false, error: { code: receipt.reason, message: receipt.sentence, retryable: receipt.reason === \"failed\", remedy: receipt.remedy } };\n }\n return { ok: true, data: receipt };\n }\n if (info.policy === \"ask\" && by !== \"person\" && info.runs !== \"server\") {\n if (!ports.approvals) {\n return fail(\"needs_approval\", `\"${info.label}\" needs a person's approval, and there is no one to ask here.`);\n }\n const approved = await ports.approvals.ask({\n action: info.name,\n label: info.label,\n description: info.description,\n input: toJson(input),\n by,\n surfaceName: info.declaredOn,\n runId: context.runId,\n });\n if (!approved) return fail(\"declined\", `\"${info.label}\" was not approved, so it did not run.`);\n }\n switch (info.runs) {\n case \"server\": {\n if (!ports.serverActions) return absent(info, \"server actions\");\n const filled = fillName(info.target ?? info.name, input);\n if (filled.missing.length) return fail(\"input_missing\", `\"${info.label}\" needs ${filled.missing.join(\", \")}.`);\n const response = await ports.serverActions.run({\n name: filled.value,\n input: toJson(input),\n by,\n surface_name: info.declaredOn,\n policy: info.policy,\n });\n if (response.status === \"refused\") return fail(\"refused\", response.message);\n return { ok: true, data: response };\n }\n case \"mandate\": {\n if (!ports.mandates) return absent(info, \"running a job\");\n if (!info.target) return fail(\"target_missing\", `\"${info.label}\" names no job to run.`);\n const filled = fillName(info.target, input);\n if (filled.missing.length) return fail(\"input_missing\", `\"${info.label}\" needs ${filled.missing.join(\", \")}.`);\n const record = input && typeof input === \"object\" && !Array.isArray(input) ? (input as Record<string, unknown>) : {};\n // A generic \"run a job\" Action carries { alias, variables, userInput }; a dedicated one's input IS the variables.\n const generic = /\\{[A-Za-z_]/.test(info.target);\n const variables = generic\n ? ((record.variables && typeof record.variables === \"object\" ? toJson(record.variables) : {}) as Record<string, Json>)\n : (toJson(record) as Record<string, Json>);\n const userInput = typeof record.userInput === \"string\" ? record.userInput : undefined;\n // The Action answers with the run's identity (RunRef); its result streams on `run:<requestId>`.\n const ref = await ports.mandates.run({\n alias: filled.value,\n variables,\n ...(userInput !== undefined ? { userInput } : {}),\n by,\n policy: info.policy,\n });\n return { ok: true, data: ref };\n }\n case \"navigate\": {\n if (!ports.overlay) return absent(info, \"navigation\");\n const filled = fillActionTarget(info.target ?? \"\", input);\n if (filled.missing.length) return fail(\"input_missing\", `\"${info.label}\" needs ${filled.missing.join(\", \")}.`);\n // `{to}` is a whole route: keep its slashes.\n const to = info.target && /^\\{[A-Za-z_][A-Za-z0-9_]*\\}$/.test(info.target) ? decodeURIComponent(filled.value) : filled.value;\n if (!to) return fail(\"target_missing\", `\"${info.label}\" names no page to open.`);\n ports.overlay.navigate(to);\n return { ok: true, data: { to } };\n }\n case \"page\": {\n if (!ports.pageActions) return absent(info, \"this page's actions\");\n return await ports.pageActions.dispatch(info.name, input, context);\n }\n default: {\n const runs: never = info.runs;\n return fail(\"runs_unknown\", `\"${info.label}\" runs as \"${String(runs)}\", which nothing here knows how to run.`);\n }\n }\n } catch (error) {\n capture(error, \"run\");\n return fail(\"run_failed\", messageOf(error), true);\n }\n}\n","/**\n * LIVE VALUES — what a mounted page holds right now (ALC-18, LIST.md D3).\n *\n * A page publishes ONE live capture while it is mounted: its title and route, what it is OF\n * (`identity`), the exact choices the person made (`selection`), its data sections, the errors on\n * screen and its recent requests. Descendants that hold state the page does not (a grid's rows, a\n * compare view) contribute sections. Every reader — the page's Alchemy menu, the admin debug\n * context, an agent through `SurfacePort.getValue` — reads the SAME capture through this store, at\n * read time, from the live getters. There is no second capture path.\n *\n * The four declared live slots (`LiveSlot`: selection, on-demand, errors, requests) are views of\n * the capture (`liveSlotsOf`), and a surface's named value reads through `liveValueOf`.\n *\n * Framework-neutral: no React, no DOM. A host hook subscribes with `subscribe` + `version`\n * (`useSyncExternalStore`). The most recent publication wins (a dialog over a page, a page over\n * the shell's default).\n */\nimport type { LiveValues, OnDemandSection, RecentRequest, Json } from \"../declare/types\";\n\nexport type LiveCaptureKind = \"table-page\" | \"record\" | \"dialog\" | \"admin-page\";\n\n/** A chosen thing, by name and id. Either may be null (not chosen / not loaded). */\nexport interface LiveNamed {\n id: string | null;\n name: string | null;\n}\n\nexport type LiveCaptureValue = LiveNamed | string | number | boolean | null;\n\nexport interface LiveSection {\n /** Stable id, unique within one capture. */\n id: string;\n /** What the person calls this part of the page. */\n title: string;\n description?: string;\n /** `data` survives \"Only the data\"; `request` does not. */\n role: \"data\" | \"request\";\n value: unknown;\n /** The one-line brief (counts, a sentence). */\n brief?: unknown;\n /** A section too big to hold on the page: `value` is the honest stub and `load` reads it on use. */\n load?: () => Promise<unknown>;\n}\n\nexport interface LiveRequest {\n method: string;\n path: string;\n status: string;\n httpStatus?: number;\n durationMs?: number;\n requestId?: string;\n /** Which client door (supabase-rest, supabase-rpc, aidream, next-api …). */\n client?: string;\n /** The JSON request body, credentials redacted. */\n requestBody?: unknown;\n requestBodyNote?: string;\n /** A failed request's own sentence from the server, verbatim. */\n errorSentence?: string;\n timestamp: number;\n}\n\nexport interface LiveCapture {\n /** The declared surface these are live values of. Absent/null = the page declares no surface yet. */\n surfaceName?: string | null;\n kind: LiveCaptureKind;\n title: string;\n route: string;\n url?: string;\n /** What this page is OF (table, record, dialog subject …), names and ids. */\n identity: Record<string, LiveCaptureValue>;\n /** The exact choices the person made on the page, in order. */\n selection: Record<string, LiveCaptureValue>;\n sections: LiveSection[];\n /** The error sentences on screen, verbatim. */\n errors: string[];\n requests: LiveRequest[];\n}\n\nexport interface LiveContribution {\n owner: string;\n sections: LiveSection[];\n /** Names a descendant knows and the page does not. */\n identity?: Record<string, LiveCaptureValue>;\n}\n\n/** What a reader shows before anyone uses the capture: no section value is walked. */\nexport interface LiveOutline {\n surfaceName: string | null;\n kind: LiveCaptureKind;\n title: string;\n loadable: Array<Pick<LiveSection, \"id\" | \"title\">>;\n}\n\nfunction isNamed(v: unknown): v is LiveNamed {\n return typeof v === \"object\" && v !== null && \"id\" in v && \"name\" in v;\n}\n\n/**\n * The page's capture plus its descendants' contributions. A descendant fills a name the page left\n * empty and never overrides one; a section id claimed twice throws, naming both owners.\n */\nexport function mergeLiveCapture(base: LiveCapture, contributions: readonly LiveContribution[]): LiveCapture {\n const owners = new Map<string, string>(base.sections.map((s) => [s.id, \"page\"]));\n const sections = [...base.sections];\n const identity = { ...base.identity };\n for (const c of contributions) {\n for (const [k, v] of Object.entries(c.identity ?? {})) {\n const prior = identity[k];\n if (prior === undefined || prior === null || (isNamed(prior) && !prior.name)) identity[k] = v;\n }\n for (const s of c.sections) {\n const prior = owners.get(s.id);\n if (prior) throw new Error(`[live values] section \"${s.id}\" is claimed by both \"${prior}\" and \"${c.owner}\"`);\n owners.set(s.id, c.owner);\n sections.push(s);\n }\n }\n return { ...base, identity, sections };\n}\n\n/** The four declared live slots (`LiveSlot`) as views of one capture. */\nexport function liveSlotsOf(capture: LiveCapture): LiveValues {\n const onDemand: OnDemandSection[] = capture.sections\n .filter((s) => typeof s.load === \"function\")\n .map((s) => ({\n id: s.id,\n title: s.title,\n ...(s.description ? { description: s.description } : {}),\n role: s.role,\n ...(s.brief !== undefined ? { brief: s.brief as Json } : {}),\n load: () => s.load!() as Promise<Json>,\n }));\n return {\n selection: { choices: capture.selection as Record<string, Json>, text: null },\n \"on-demand\": onDemand,\n errors: capture.errors,\n requests: capture.requests as RecentRequest[],\n };\n}\n\n/**\n * One named live value of a capture, or `undefined` when the capture holds none by that name.\n * Slot names (`selection`, `errors`, `requests`, `on-demand`) read the slot; `title`, `route`,\n * `url`, `kind` and `identity` read the page; any other name reads an identity or selection entry,\n * then a held section's value (a section that must be loaded answers its stub).\n */\nexport function liveValueOf(capture: LiveCapture, name: string): unknown {\n switch (name) {\n case \"selection\":\n return capture.selection;\n case \"errors\":\n return capture.errors;\n case \"requests\":\n return capture.requests;\n case \"on-demand\":\n return capture.sections.filter((s) => typeof s.load === \"function\").map((s) => ({ id: s.id, title: s.title, role: s.role }));\n case \"title\":\n case \"route\":\n case \"url\":\n case \"kind\":\n case \"identity\":\n return capture[name];\n default:\n break;\n }\n if (Object.prototype.hasOwnProperty.call(capture.identity, name)) return capture.identity[name];\n if (Object.prototype.hasOwnProperty.call(capture.selection, name)) return capture.selection[name];\n return capture.sections.find((s) => s.id === name)?.value;\n}\n\nexport interface LiveValuesStore {\n /** A page's live capture, read at read time. Returns its unpublish. The most recent wins. */\n publish(read: () => LiveCapture): () => void;\n /** A descendant's sections (and names). Returns its removal. */\n contribute(owner: string, read: () => LiveSection[] | Omit<LiveContribution, \"owner\">): () => void;\n /** Say a getter's answer changed (readers re-render). */\n touch(): void;\n /** Whether any page is publishing right now. */\n has(): boolean;\n /** The live capture: the latest publication merged with every contribution. */\n read(): LiveCapture | null;\n /** The outline without building section values (safe in render). */\n outline(): LiveOutline | null;\n /** The live capture of ONE surface, when the publishing page is that surface. */\n readFor(surfaceName: string): LiveCapture | null;\n subscribe(listener: () => void): () => void;\n /** Bumps on every publish / contribute / touch. */\n version(): number;\n}\n\nexport function createLiveValues(): LiveValuesStore {\n let nextId = 0;\n let version = 0;\n let pages: Array<{ id: number; read: () => LiveCapture }> = [];\n let parts: Array<{ id: number; owner: string; read: () => LiveSection[] | Omit<LiveContribution, \"owner\"> }> = [];\n const listeners = new Set<() => void>();\n const emit = () => {\n version += 1;\n for (const listener of [...listeners]) listener();\n };\n const contributions = (): LiveContribution[] =>\n parts.map((p) => {\n const got = p.read();\n return Array.isArray(got) ? { owner: p.owner, sections: got } : { owner: p.owner, ...got };\n });\n const read = (): LiveCapture | null => {\n const top = pages[pages.length - 1];\n return top ? mergeLiveCapture(top.read(), contributions()) : null;\n };\n return {\n publish(get) {\n const id = ++nextId;\n pages = [...pages, { id, read: get }];\n emit();\n return () => {\n pages = pages.filter((p) => p.id !== id);\n emit();\n };\n },\n contribute(owner, get) {\n const id = ++nextId;\n parts = [...parts, { id, owner, read: get }];\n emit();\n return () => {\n parts = parts.filter((p) => p.id !== id);\n emit();\n };\n },\n touch: emit,\n has: () => pages.length > 0,\n read,\n outline() {\n const top = pages[pages.length - 1];\n if (!top) return null;\n const base = top.read();\n const sections = [...base.sections, ...contributions().flatMap((c) => c.sections)];\n return {\n surfaceName: base.surfaceName ?? null,\n kind: base.kind,\n title: base.title,\n loadable: sections.filter((s) => typeof s.load === \"function\").map((s) => ({ id: s.id, title: s.title })),\n };\n },\n readFor(surfaceName) {\n const capture = read();\n return capture && capture.surfaceName === surfaceName ? capture : null;\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n version: () => version,\n };\n}\n\n/** THE live-values store of this JS realm: every host page publishes here, every reader reads here. */\nexport const liveValues: LiveValuesStore = createLiveValues();\n","/**\n * `createSurfacePort` — the one SurfacePort runtime (Applets CONTRACTS §6 + Amendment 2.1).\n *\n * A parent surface offers every Action and value it has; a user's or organization's surface\n * extends it. This is the runtime a host binds once and hands to a frame:\n *\n * mount reads the chain from the DATABASE (`readSurfaceChain`); the frame's `parent`\n * argument names the same thing and is not trusted over it\n * get/setValue the surface's named values, cloned both ways; `setValue` emits `value:<name>`\n * listActions never throws — a refusal goes to `ports.diagnostics` and answers `[]`\n * runAction found by name in the mounted chain (or a fresh read), run through\n * `runSurfaceAction` (the one runner); an Action that `updatesValue` sets it\n * completeAction settles a pending page-Action run by its runId\n *\n * Page Actions: with `opts.pageActions` the host routes them (e.g. to the frame that declared the\n * surface) and may park the run with `awaitPageAction(runId)`. Without it the port routes them\n * itself: it emits `\"actions\"` `{ action, input, runId, by }` and waits for `completeAction`.\n * `dispose()` settles every run this port parked with `host_disposed`.\n *\n * The package never imports the host or supabase: the client is structural (`./client.ts`), and\n * every capability arrives as a port. Nothing here picks an organization.\n */\nimport type { PageActionPort } from \"../ports\";\nimport type { ActionCaller, ActionContext, ActionInfo, ActionResult, SurfacePort } from \"../actions/applet-types\";\nimport { runSurfaceAction, type SurfaceActionPorts } from \"../actions/surface-run\";\nimport { readSurfaceChain } from \"./chain\";\nimport { liveValueOf, type LiveValuesStore } from \"./live\";\n\n/** The stream a self-routed page Action travels on (CONTRACTS Amendment 2.1). */\nexport const PAGE_ACTION_STREAM = \"actions\";\n/** The stream a surface value travels on. */\nexport const valueStream = (name: string): string => `value:${name}`;\n\n/** What travels on `\"actions\"`; the frame answers with `surface.completeAction(runId, result)`. */\nexport interface PageActionEvent {\n action: string;\n input: unknown;\n runId: string;\n by?: ActionCaller;\n}\n\n/** The runner's ports the host binds; page Actions are routed by `pageActions` / the port itself. */\nexport type SurfacePortRunPorts = Omit<SurfaceActionPorts, \"pageActions\">;\n\n/** One settle function per parked page-Action run. */\nexport type PendingPageActions = Map<string, (result: ActionResult<unknown>) => void>;\n\nexport interface CreateSurfacePortOptions {\n /** A supabase-js v2 client carrying the VIEWER's session. Typed `object` on purpose (see ./client.ts). */\n client: object;\n /** ALL of the viewer's memberships, for organization extensions. Absent = extensions are dropped. */\n organizationIds?: () => Promise<readonly string[]>;\n /** The viewer's user id, stamped on every run's context. */\n viewerId?: () => Promise<string | null>;\n /** The runner's capabilities. `diagnostics` is required; each absent port = that capability is absent. */\n ports: SurfacePortRunPorts;\n /** The host's own page-Action routing. Absent = the port emits `\"actions\"` and waits for `completeAction`. */\n pageActions?: PageActionPort;\n /**\n * The host's event hub: `value:<name>` on `setValue`, and `\"actions\"` for self-routed page Actions.\n * Return `true` when someone is subscribed to the stream and `false` when nobody is. A self-routed\n * page Action waits for `completeAction` ONLY when `emit` answered `true`; anything else is refused\n * `action_unhandled`, so a page Action can never wait for an answer that cannot come.\n */\n emit(stream: string, payload: unknown): boolean;\n /**\n * The page's live values (ALC-18): `getValue(name)` on a value nobody set reads the mounted\n * surface's live capture (`liveValueOf`) — only while a page publishing THAT surface is mounted.\n * Usually `liveValues` from `@ai-matrx/alchemy/surface`.\n */\n live?: LiveValuesStore;\n /** Values seeded at mount; a value already set is never overwritten. */\n seedValues?: () => Promise<Record<string, unknown>>;\n /** The surface to read when nothing is mounted yet (e.g. the Applet's own `applets/<id>`). */\n surfaceName?: () => Promise<string>;\n /** Most ancestors a surface may have. */\n maxDepth?: number;\n /** Ids for mounts (`\"mount\"`) and runs (`\"act\"`). */\n mintId?: (prefix: string) => string;\n /**\n * Share ONE map across the ports of one host tree, so a frame answering on its own host settles a\n * run another host routed to it. Absent = this port's own map.\n */\n pending?: PendingPageActions;\n}\n\nexport interface SurfacePortHandle extends SurfacePort {\n /** Park a page-Action run until `completeAction(runId, …)` (or `dispose()`) settles it. */\n awaitPageAction(runId: string): Promise<ActionResult<unknown>>;\n /** Settle every run this port parked with `host_disposed`, and forget the mount and values. */\n dispose(): void;\n}\n\nfunction clone<T>(value: T): T {\n if (value === undefined) return value;\n const sc = (globalThis as { structuredClone?: <V>(v: V) => V }).structuredClone;\n return sc ? sc(value) : (JSON.parse(JSON.stringify(value)) as T);\n}\n\nfunction errorOf(err: unknown, code = \"surface_failed\"): { ok: false; error: { code: string; message: string; retryable: boolean } } {\n return { ok: false, error: { code, message: err instanceof Error && err.message ? err.message : String(err), retryable: false } };\n}\n\nlet sequence = 0;\nfunction defaultMint(prefix: string): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n return c?.randomUUID ? `${prefix}-${c.randomUUID()}` : `${prefix}-${Date.now().toString(36)}-${(sequence++).toString(36)}`;\n}\n\nexport function createSurfacePort(opts: CreateSurfacePortOptions): SurfacePortHandle {\n const mint = opts.mintId ?? defaultMint;\n const pending: PendingPageActions = opts.pending ?? new Map();\n const parked = new Set<string>();\n const values = new Map<string, unknown>();\n let mounted: { mountId: string; name: string; chain: ActionInfo[] } | null = null;\n let disposed = false;\n\n const report = (error: unknown, stage: string, detail: Record<string, string> = {}) => {\n try {\n opts.ports.diagnostics.capture(error, { area: \"actions\", detail: { stage: `surface.${stage}`, ...detail } });\n } catch {\n // A broken diagnostics port never turns a refusal into a throw.\n }\n };\n\n const memberships = async (): Promise<readonly string[] | undefined> => {\n if (!opts.organizationIds) return undefined;\n try {\n return await opts.organizationIds();\n } catch (err) {\n // Fail closed: without memberships, organization extensions are dropped — and said so.\n report(err, \"organizationIds\");\n return undefined;\n }\n };\n\n const read = async (name: string): Promise<ActionResult<ActionInfo[]>> => {\n const organizationIds = await memberships();\n return readSurfaceChain(opts.client, name, {\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n ...(organizationIds ? { organizationIds } : {}),\n });\n };\n\n /** The chain as it stands: the mount's, re-read when `fresh`; else the default surface's. */\n const currentChain = async (fresh: boolean): Promise<ActionResult<ActionInfo[]>> => {\n if (mounted && !fresh) return { ok: true, data: mounted.chain };\n const name = mounted?.name ?? (opts.surfaceName ? await opts.surfaceName() : null);\n if (!name) return { ok: false, error: { code: \"not_mounted\", message: \"No surface is mounted here yet.\", retryable: false } };\n const chain = await read(name);\n if (chain.ok && mounted?.name === name) mounted.chain = chain.data;\n return chain;\n };\n\n const awaitPageAction = (runId: string): Promise<ActionResult<unknown>> => {\n if (disposed) return Promise.resolve({ ok: false, error: { code: \"host_disposed\", message: \"This page has closed.\", retryable: false } });\n return new Promise((resolve) => {\n parked.add(runId);\n pending.set(runId, resolve);\n });\n };\n\n const selfRouted: PageActionPort = {\n dispatch(name: string, input: unknown, context: ActionContext): Promise<ActionResult<unknown>> {\n const waiting = awaitPageAction(context.runId);\n const event: PageActionEvent = { action: name, input, runId: context.runId, by: context.by };\n const forget = () => {\n pending.delete(context.runId);\n parked.delete(context.runId);\n };\n if (disposed) {\n forget();\n return Promise.resolve({ ok: false, error: { code: \"host_disposed\", message: \"This page closed, so the action did not run.\", retryable: false } });\n }\n let heard: boolean;\n try {\n heard = opts.emit(PAGE_ACTION_STREAM, event);\n } catch (err) {\n forget();\n throw err; // the runner captures it and answers run_failed\n }\n if (heard !== true) {\n forget();\n return Promise.resolve({ ok: false, error: { code: \"action_unhandled\", message: `No page is open to run \"${name}\".`, retryable: false } });\n }\n return waiting;\n },\n };\n\n const port: SurfacePortHandle = {\n async mount(name) {\n try {\n const chain = await read(name);\n if (!chain.ok) return chain;\n if (opts.seedValues) {\n try {\n const seeds = await opts.seedValues();\n for (const [key, v] of Object.entries(seeds)) if (!values.has(key)) values.set(key, clone(v));\n } catch (err) {\n report(err, \"seedValues\", { surface: name });\n }\n }\n mounted = { mountId: mint(\"mount\"), name, chain: chain.data };\n return { ok: true, data: { mountId: mounted.mountId } };\n } catch (err) {\n return errorOf(err);\n }\n },\n async unmount(mountId) {\n if (mounted?.mountId === mountId) mounted = null;\n },\n async getValue(name) {\n if (values.has(name) || !opts.live || !mounted) return clone(values.get(name));\n try {\n const capture = opts.live.readFor(mounted.name);\n return capture ? clone(liveValueOf(capture, name)) : undefined;\n } catch (err) {\n report(err, \"live\", { name });\n return undefined;\n }\n },\n async setValue(name, v) {\n let copy: unknown;\n try {\n copy = clone(v);\n } catch (err) {\n // A value that cannot be copied (a function, a live handle) is not stored, and never turns an\n // Action that already ran into a failure — it is reported by name instead.\n report(err, \"setValue\", { name });\n return;\n }\n values.set(name, copy);\n try {\n opts.emit(valueStream(name), clone(v));\n } catch (err) {\n report(err, \"emit\", { stream: valueStream(name) });\n }\n },\n async listActions() {\n try {\n const chain = await currentChain(false);\n if (!chain.ok) {\n report(chain.error, \"listActions\");\n return [];\n }\n return clone(chain.data);\n } catch (err) {\n report(err, \"listActions\");\n return [];\n }\n },\n async runAction(name, input, by) {\n let info: ActionInfo | undefined;\n try {\n const known = await currentChain(false);\n info = known.ok ? known.data.find((a) => a.name === name) : undefined;\n if (!info) {\n // Not in the mounted chain: the database may have gained it since the mount.\n const fresh = await currentChain(true);\n if (!fresh.ok) return fresh;\n info = fresh.data.find((a) => a.name === name);\n }\n } catch (err) {\n return errorOf(err);\n }\n if (!info) return { ok: false, error: { code: \"action_not_found\", message: `This page has no action named \"${name}\".`, retryable: false } };\n let viewerId: string | null = null;\n try {\n viewerId = opts.viewerId ? await opts.viewerId() : null;\n } catch (err) {\n report(err, \"viewerId\");\n }\n const ports: SurfaceActionPorts = { ...opts.ports, pageActions: opts.pageActions ?? selfRouted };\n const result = await runSurfaceAction(info, input, by, ports, { runId: mint(\"act\"), viewerId });\n if (result.ok && info.updatesValue) await port.setValue(info.updatesValue, result.data);\n return result;\n },\n async completeAction(runId, result) {\n const resolve = pending.get(runId);\n if (!resolve) {\n // A late, duplicate or misrouted answer leaves a trace instead of vanishing.\n report(new Error(`completeAction for run \"${runId}\", which is not waiting (already answered, never routed here, or the page closed).`), \"completeAction\", { runId });\n return;\n }\n pending.delete(runId);\n parked.delete(runId);\n resolve?.(result);\n },\n awaitPageAction,\n dispose() {\n disposed = true;\n for (const runId of parked) {\n const resolve = pending.get(runId);\n pending.delete(runId);\n resolve?.({ ok: false, error: { code: \"host_disposed\", message: \"This page closed before the action finished.\", retryable: false } });\n }\n parked.clear();\n mounted = null;\n values.clear();\n },\n };\n return port;\n}\n","/**\n * ITEM SOURCES — the one path from \"the person pointed at this\" to a declared item (ALC-18, D4).\n *\n * A mounted container (a canonical table, a message list) registers ONE source under its own id.\n * When a menu opens on an anchor inside it, the host asks `itemSources.resolve(containerId, target)`\n * and gets back the declared item — `itemType`, `identity`, `level`, `readOnly`, `readValues` — plus\n * the opaque `host` data the container's owner attached (the menu rows it builds for that item). The\n * package never reads `host`; it never crosses into a model.\n *\n * A container that answers an item type no surface declares is a defect the host's guard names;\n * the canonical table answers `TABLE_ROW_ITEM_TYPE` (`@ai-matrx/alchemy/declare`), which every\n * surface carries as a baseline.\n */\nimport type { InternalResolvedItem } from \"../declare/host\";\n\n/** What was pointed at inside a container, in the container's own words. */\nexport interface ItemTarget {\n containerId: string;\n /** The level aimed at (a table: selection | cell | column | row | table). */\n level: string;\n /** The item's id within the container (a table's row id). */\n itemId?: string;\n /** A sub-part of the item (a table's column id). */\n partId?: string;\n}\n\n/** A resolved item, plus the container owner's opaque data for it. */\nexport interface ItemHit<H = unknown> {\n item: InternalResolvedItem;\n host?: H;\n}\n\nexport type ItemSource<H = unknown> = (target: ItemTarget) => ItemHit<H> | null;\n\nexport interface ItemSourceRegistry {\n /** One source per mounted container. A re-register replaces; the returned removal removes only its own. */\n register<H>(containerId: string, source: ItemSource<H>): () => void;\n /** The item at the target, or null when no container answers it. A throwing source answers null. */\n resolve<H = unknown>(target: ItemTarget): ItemHit<H> | null;\n has(containerId: string): boolean;\n}\n\nexport function createItemSources(onError?: (error: unknown, target: ItemTarget) => void): ItemSourceRegistry {\n const sources = new Map<string, ItemSource>();\n return {\n register(containerId, source) {\n sources.set(containerId, source as ItemSource);\n return () => {\n if (sources.get(containerId) === source) sources.delete(containerId);\n };\n },\n resolve<H>(target: ItemTarget): ItemHit<H> | null {\n const source = sources.get(target.containerId);\n if (!source) return null;\n try {\n return (source(target) as ItemHit<H> | null) ?? null;\n } catch (error) {\n onError?.(error, target);\n return null;\n }\n },\n has: (containerId) => sources.has(containerId),\n };\n}\n\n/** THE item-source registry of this JS realm. */\nexport const itemSources: ItemSourceRegistry = createItemSources((error, target) => {\n // Loud, never silent: a source that throws leaves the menu without its item and says why.\n console.error(`[alchemy items] the source for \"${target.containerId}\" threw resolving ${target.level}`, error);\n});\n"],"mappings":"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","names":["fail","read","read"]}
1
+ {"version":3,"sources":["../src/surface/chain.ts","../src/db/ui.ts","../src/declare/registry.ts","../src/actions/declarations.ts","../src/surface/client.ts","../src/actions/surface-run.ts","../src/surface/live.ts","../src/surface/port.ts","../src/surface/items.ts"],"sourcesContent":["/**\n * `readSurfaceChain` — the Actions a surface offers, read from the DATABASE (Applets CONTRACTS §6).\n *\n * Walks `ui.ui_surface` by `parent_surface_name` (live rows only), reads every surface's\n * `ui.ui_surface_action` rows for the whole chain in ONE query, projects each row with\n * `surfaceActionRowToAction` and resolves the chain with `resolveActionChain` (a child's Action\n * wins by name). Loud, named refusals for a cycle, a chain too deep, and a missing surface.\n *\n * Organization scoping — the same rule as aidream's `visible_actions`: a `declared_by='database'`\n * row on a surface OUTSIDE `applets/` is one organization's EXTENSION and is kept only when its\n * `organization_id` is one of the viewer's memberships (`organizationIds` = ALL of them; the active\n * organization is never a filter). No `organizationIds` = extensions are dropped (fail closed).\n * Code rows and `applets/*` rows are always kept. This scopes WHICH extension applies; row\n * security still decides what the client can read at all.\n *\n * The client is the viewer's supabase-js v2 client, typed STRUCTURALLY (`./client.ts`): the package\n * never imports supabase or the host. Every read goes through `@ai-matrx/data`'s doors (descriptors\n * generated into `../db/ui.ts` by `pnpm db:generate`). Never throws: a transport failure answers\n * `unreachable` (retryable); a database error keeps the database's own sentence.\n */\nimport { createDb, listAll, read as readRow, type SupabaseLike } from \"@ai-matrx/data/db\";\nimport { uiSurface, uiSurfaceAction } from \"../db/ui\";\nimport { DEFAULT_MAX_INHERITANCE_DEPTH } from \"../declare/registry\";\nimport type { ActionInfo, ActionResult } from \"../actions/applet-types\";\nimport { resolveActionChain, surfaceActionRowToAction, type ActionChainLink, type SurfaceActionRow } from \"../actions/declarations\";\nimport { asSurfaceClient, door, isRecord } from \"./client\";\n\n/** Surfaces under this prefix belong to one Applet; their database rows are never \"extensions\". */\nexport const APPLET_SURFACE_PREFIX = \"applets/\";\n\nexport interface ReadSurfaceChainOptions {\n /** Most ancestors a surface may have (alchemy's declaration default when absent). */\n maxDepth?: number;\n /** ALL of the viewer's organization memberships. Absent = organization extensions are dropped. */\n organizationIds?: readonly string[];\n}\n\nfunction fail(code: string, message: string, retryable = false): { ok: false; error: { code: string; message: string; retryable: boolean } } {\n return { ok: false, error: { code, message, retryable } };\n}\n\n/** Whether a row applies to a viewer with these memberships (aidream `visible_actions`). */\nexport function surfaceActionVisible(row: Pick<SurfaceActionRow, \"declared_by\" | \"surface_name\" | \"organization_id\">, organizationIds: readonly string[] | undefined): boolean {\n // Only a CODE row is everyone's; anything else (database, or a value nobody declared) is an extension\n // until proven otherwise — fail closed.\n if (row.declared_by === \"code\") return true;\n if (row.surface_name.startsWith(APPLET_SURFACE_PREFIX)) return true;\n return typeof row.organization_id === \"string\" && (organizationIds ?? []).includes(row.organization_id);\n}\n\nexport async function readSurfaceChain(\n client: object,\n surfaceName: string,\n options: ReadSurfaceChainOptions = {},\n): Promise<ActionResult<ActionInfo[]>> {\n let db: ReturnType<typeof createDb>;\n try {\n db = createDb({ client: asSurfaceClient(client) as unknown as SupabaseLike });\n } catch (err) {\n return fail(\"client_invalid\", err instanceof Error ? err.message : String(err));\n }\n const maxDepth = options.maxDepth ?? DEFAULT_MAX_INHERITANCE_DEPTH;\n const names: string[] = [];\n let at: string | null = surfaceName;\n while (at) {\n if (names.includes(at)) return fail(\"surface_cycle\", `The surface chain loops at \"${at}\": ${[...names, at].join(\" → \")}.`);\n if (names.length > maxDepth) {\n return fail(\"surface_too_deep\", `The surface chain for \"${surfaceName}\" is deeper than ${maxDepth}: ${[...names, at].join(\" → \")}.`);\n }\n const name: string = at;\n // Live rows only: the door excludes soft-deleted rows.\n const row: ActionResult<unknown> = await door(() => readRow(db, uiSurface, name, { columns: [\"name\", \"parent_surface_name\"] }));\n if (!row.ok) return row;\n if (!isRecord(row.data)) {\n return fail(\n \"surface_not_found\",\n names.length === 0\n ? `The surface \"${at}\" does not exist yet; saving the Applet writes it (ui.save_applet_surface).`\n : `The surface \"${names[names.length - 1]}\" names a parent \"${at}\" that does not exist.`,\n );\n }\n names.push(at);\n const parent: unknown = row.data.parent_surface_name;\n at = typeof parent === \"string\" && parent ? parent : null;\n }\n // EVERY live row of the chain (paged past the 1,000-row cap), by sort_order then id.\n const rows = await door(async () =>\n (await listAll(db, uiSurfaceAction, (q) => q.in(\"surface_name\", names), { orderBy: \"sort_order\" })) as unknown as SurfaceActionRow[],\n );\n if (!rows.ok) return rows;\n const visible = rows.data.filter((r) => surfaceActionVisible(r, options.organizationIds));\n // Most general first (root parent … the surface itself), as resolveActionChain expects.\n const chain: ActionChainLink[] = [...names].reverse().map((name) => ({\n surfaceName: name,\n actions: visible.filter((r) => r.surface_name === name).map(surfaceActionRowToAction),\n }));\n try {\n return { ok: true, data: resolveActionChain(chain, { maxDepth }) };\n } catch (err) {\n return fail(\"surface_chain\", err instanceof Error ? err.message : String(err));\n }\n}\n","/**\n * GENERATED by `matrx-data generate` from the database description — never edit by hand.\n * schema: ui · description 9dec9d77b9f9\n * Regenerate: matrx-data generate (see @ai-matrx/data README).\n */\n/* eslint-disable */\nimport type { FunctionDescriptor, TableDescriptor } from \"@ai-matrx/data/db\";\n\ntype Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[];\n\nexport interface DecisionPickRow {\n id: string;\n decision_id: string | null;\n winner: string | null;\n note: string | null;\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\";\n custom_fields: Json;\n organization_id: string;\n created_by: string | null;\n updated_by: string | null;\n created_at: string;\n updated_at: string;\n deleted_at: string | null;\n version: number;\n metadata: Json;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n}\nexport interface DecisionPickInsert {\n id?: string;\n decision_id?: string | null;\n winner?: string | null;\n note?: string | null;\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\";\n custom_fields?: Json;\n organization_id?: string;\n created_by?: string | null;\n updated_by?: string | null;\n created_at?: string;\n updated_at?: string;\n deleted_at?: string | null;\n version?: number;\n metadata?: Json;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n}\nexport type DecisionPickUpdate = Partial<DecisionPickInsert>;\nexport const decisionPick = {\"schema\":\"ui\",\"name\":\"decision_pick\",\"kind\":\"table\",\"type\":null,\"pk\":[\"id\"],\"org\":{\"rule\":\"binding\"},\"versioned\":true,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<DecisionPickRow, DecisionPickInsert, DecisionPickUpdate>;\n\nexport interface UiClientRow {\n name: string;\n description: string;\n is_active: boolean;\n sort_order: number;\n created_at: string;\n updated_at: string;\n id: string;\n organization_id: string;\n metadata: Json;\n created_by: string | null;\n updated_by: string | null;\n version: number;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at: string | null;\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n}\nexport interface UiClientInsert {\n name: string;\n description?: string;\n is_active?: boolean;\n sort_order?: number;\n created_at?: string;\n updated_at?: string;\n id?: string;\n organization_id?: string;\n metadata?: Json;\n created_by?: string | null;\n updated_by?: string | null;\n version?: number;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at?: string | null;\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n}\nexport type UiClientUpdate = Partial<UiClientInsert>;\nexport const uiClient = {\"schema\":\"ui\",\"name\":\"ui_client\",\"kind\":\"table\",\"type\":\"reference\",\"pk\":[\"name\"],\"org\":{\"rule\":\"binding\"},\"versioned\":false,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiClientRow, UiClientInsert, UiClientUpdate>;\n\nexport interface UiSurfaceRow {\n name: string;\n client_name: string;\n description: string;\n is_active: boolean;\n sort_order: number;\n created_at: string;\n updated_at: string;\n url_pattern: string | null;\n executor_name: string | null;\n parent_surface_name: string | null;\n execution_mode: string;\n supports_dictionary: boolean;\n id: string;\n intro: string | null;\n label: string | null;\n value_groups: Json;\n readiness: string | null;\n readiness_note: string | null;\n overlay_id: string | null;\n metadata: Json;\n last_checked_at: string | null;\n last_checked_by: string | null;\n last_check: Json | null;\n check_claimed_at: string | null;\n check_claimed_by: string | null;\n created_by: string | null;\n updated_by: string | null;\n custom_fields: Json;\n content_hash: string | null;\n deleted_at: string | null;\n declared_by: string;\n organization_id: string;\n version: number;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n situation: string | null;\n}\nexport interface UiSurfaceInsert {\n name: string;\n client_name: string;\n description?: string;\n is_active?: boolean;\n sort_order?: number;\n created_at?: string;\n updated_at?: string;\n url_pattern?: string | null;\n executor_name?: string | null;\n parent_surface_name?: string | null;\n execution_mode?: string;\n supports_dictionary?: boolean;\n id?: string;\n intro?: string | null;\n label?: string | null;\n value_groups?: Json;\n readiness?: string | null;\n readiness_note?: string | null;\n overlay_id?: string | null;\n metadata?: Json;\n last_checked_at?: string | null;\n last_checked_by?: string | null;\n last_check?: Json | null;\n check_claimed_at?: string | null;\n check_claimed_by?: string | null;\n created_by?: string | null;\n updated_by?: string | null;\n custom_fields?: Json;\n content_hash?: string | null;\n deleted_at?: string | null;\n declared_by?: string;\n organization_id?: string;\n version?: number;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n situation?: string | null;\n}\nexport type UiSurfaceUpdate = Partial<UiSurfaceInsert>;\nexport const uiSurface = {\"schema\":\"ui\",\"name\":\"ui_surface\",\"kind\":\"table\",\"type\":\"entity\",\"pk\":[\"name\"],\"org\":{\"rule\":\"binding\"},\"versioned\":false,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceRow, UiSurfaceInsert, UiSurfaceUpdate>;\n\nexport interface UiSurfaceActionRow {\n id: string;\n surface_id: string;\n surface_name: string;\n item_type: string;\n name: string;\n category: string;\n label: string;\n description: string;\n input: Json | null;\n output: string | null;\n runs: string;\n target: string | null;\n triggered_by: string[];\n policy: string;\n updates_value: string | null;\n code_ref: string | null;\n declared_by: string;\n sort_order: number;\n organization_id: string;\n created_by: string | null;\n updated_by: string | null;\n created_at: string;\n updated_at: string;\n deleted_at: string | null;\n version: number;\n metadata: Json;\n}\nexport interface UiSurfaceActionInsert {\n id?: string;\n surface_id: string;\n surface_name: string;\n item_type?: string;\n name: string;\n category?: string;\n label: string;\n description?: string;\n input?: Json | null;\n output?: string | null;\n runs: string;\n target?: string | null;\n triggered_by?: string[];\n policy?: string;\n updates_value?: string | null;\n code_ref?: string | null;\n declared_by?: string;\n sort_order?: number;\n organization_id?: string;\n created_by?: string | null;\n updated_by?: string | null;\n created_at?: string;\n updated_at?: string;\n deleted_at?: string | null;\n version?: number;\n metadata?: Json;\n}\nexport type UiSurfaceActionUpdate = Partial<UiSurfaceActionInsert>;\nexport const uiSurfaceAction = {\"schema\":\"ui\",\"name\":\"ui_surface_action\",\"kind\":\"table\",\"type\":null,\"pk\":[\"id\"],\"org\":{\"rule\":\"binding\"},\"versioned\":false,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":null,\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceActionRow, UiSurfaceActionInsert, UiSurfaceActionUpdate>;\n\nexport interface UiSurfaceAgentPrefRow {\n id: string;\n surface_name: string;\n role_name: string;\n agent_id: string;\n kind: string;\n position: number;\n settings: Json;\n user_id: string | null;\n organization_id: string;\n scope_id: string | null;\n created_at: string;\n updated_at: string;\n created_by: string | null;\n updated_by: string | null;\n version: number;\n metadata: Json;\n deleted_at: string | null;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n custom_fields: Json;\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n}\nexport interface UiSurfaceAgentPrefInsert {\n id?: string;\n surface_name: string;\n role_name: string;\n agent_id: string;\n kind?: string;\n position?: number;\n settings?: Json;\n user_id?: string | null;\n organization_id?: string;\n scope_id?: string | null;\n created_at?: string;\n updated_at?: string;\n created_by?: string | null;\n updated_by?: string | null;\n version?: number;\n metadata?: Json;\n deleted_at?: string | null;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n custom_fields?: Json;\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n}\nexport type UiSurfaceAgentPrefUpdate = Partial<UiSurfaceAgentPrefInsert>;\nexport const uiSurfaceAgentPref = {\"schema\":\"ui\",\"name\":\"ui_surface_agent_pref\",\"kind\":\"table\",\"type\":\"entity\",\"pk\":[\"id\"],\"org\":{\"rule\":\"binding\"},\"versioned\":true,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceAgentPrefRow, UiSurfaceAgentPrefInsert, UiSurfaceAgentPrefUpdate>;\n\nexport interface UiSurfaceAgentRoleRow {\n surface_name: string;\n name: string;\n label: string;\n description: string;\n kind: string;\n default_agent_id: string | null;\n max_agents: number;\n allow_custom: boolean;\n auto_run: string;\n sort_order: number;\n created_at: string;\n updated_at: string;\n mandate_key: string | null;\n synced_by: string | null;\n synced_from: string | null;\n id: string;\n organization_id: string;\n metadata: Json;\n created_by: string | null;\n updated_by: string | null;\n version: number;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at: string | null;\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n declared_by: string;\n}\nexport interface UiSurfaceAgentRoleInsert {\n surface_name: string;\n name: string;\n label?: string;\n description?: string;\n kind?: string;\n default_agent_id?: string | null;\n max_agents?: number;\n allow_custom?: boolean;\n auto_run?: string;\n sort_order?: number;\n created_at?: string;\n updated_at?: string;\n mandate_key?: string | null;\n synced_by?: string | null;\n synced_from?: string | null;\n id?: string;\n organization_id?: string;\n metadata?: Json;\n created_by?: string | null;\n updated_by?: string | null;\n version?: number;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at?: string | null;\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n declared_by?: string;\n}\nexport type UiSurfaceAgentRoleUpdate = Partial<UiSurfaceAgentRoleInsert>;\nexport const uiSurfaceAgentRole = {\"schema\":\"ui\",\"name\":\"ui_surface_agent_role\",\"kind\":\"table\",\"type\":\"reference\",\"pk\":[\"surface_name\",\"name\"],\"org\":{\"rule\":\"binding\"},\"versioned\":false,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceAgentRoleRow, UiSurfaceAgentRoleInsert, UiSurfaceAgentRoleUpdate>;\n\nexport interface UiSurfaceClientToolRow {\n surface_name: string;\n name: string;\n label: string;\n description: string;\n input_schema: Json;\n mode: string;\n created_at: string;\n updated_at: string;\n synced_by: string | null;\n synced_from: string | null;\n id: string;\n organization_id: string;\n metadata: Json;\n created_by: string | null;\n updated_by: string | null;\n version: number;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at: string | null;\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n declared_by: string;\n}\nexport interface UiSurfaceClientToolInsert {\n surface_name: string;\n name: string;\n label?: string;\n description?: string;\n input_schema?: Json;\n mode?: string;\n created_at?: string;\n updated_at?: string;\n synced_by?: string | null;\n synced_from?: string | null;\n id?: string;\n organization_id?: string;\n metadata?: Json;\n created_by?: string | null;\n updated_by?: string | null;\n version?: number;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at?: string | null;\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n declared_by?: string;\n}\nexport type UiSurfaceClientToolUpdate = Partial<UiSurfaceClientToolInsert>;\nexport const uiSurfaceClientTool = {\"schema\":\"ui\",\"name\":\"ui_surface_client_tool\",\"kind\":\"table\",\"type\":\"reference\",\"pk\":[\"surface_name\",\"name\"],\"org\":{\"rule\":\"binding\"},\"versioned\":false,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceClientToolRow, UiSurfaceClientToolInsert, UiSurfaceClientToolUpdate>;\n\nexport interface UiSurfaceConfigRow {\n id: string;\n surface_name: string;\n namespace: string;\n config: Json;\n user_id: string | null;\n organization_id: string;\n scope_id: string | null;\n created_at: string;\n updated_at: string;\n created_by: string | null;\n updated_by: string | null;\n version: number;\n metadata: Json;\n deleted_at: string | null;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n custom_fields: Json;\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n}\nexport interface UiSurfaceConfigInsert {\n id?: string;\n surface_name: string;\n namespace: string;\n config?: Json;\n user_id?: string | null;\n organization_id?: string;\n scope_id?: string | null;\n created_at?: string;\n updated_at?: string;\n created_by?: string | null;\n updated_by?: string | null;\n version?: number;\n metadata?: Json;\n deleted_at?: string | null;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n custom_fields?: Json;\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n}\nexport type UiSurfaceConfigUpdate = Partial<UiSurfaceConfigInsert>;\nexport const uiSurfaceConfig = {\"schema\":\"ui\",\"name\":\"ui_surface_config\",\"kind\":\"table\",\"type\":\"entity\",\"pk\":[\"id\"],\"org\":{\"rule\":\"binding\"},\"versioned\":true,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceConfigRow, UiSurfaceConfigInsert, UiSurfaceConfigUpdate>;\n\nexport interface UiSurfaceItemTypeRow {\n id: string;\n surface_name: string;\n name: string;\n label: string;\n description: string;\n identity: string[];\n levels: string[] | null;\n entity_type: string | null;\n sort_order: number;\n synced_by: string | null;\n synced_from: string | null;\n organization_id: string;\n created_by: string | null;\n updated_by: string | null;\n created_at: string;\n updated_at: string;\n version: number;\n metadata: Json;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at: string | null;\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n declared_by: string;\n}\nexport interface UiSurfaceItemTypeInsert {\n id?: string;\n surface_name: string;\n name: string;\n label: string;\n description?: string;\n identity: string[];\n levels?: string[] | null;\n entity_type?: string | null;\n sort_order?: number;\n synced_by?: string | null;\n synced_from?: string | null;\n organization_id?: string;\n created_by?: string | null;\n updated_by?: string | null;\n created_at?: string;\n updated_at?: string;\n version?: number;\n metadata?: Json;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at?: string | null;\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n declared_by?: string;\n}\nexport type UiSurfaceItemTypeUpdate = Partial<UiSurfaceItemTypeInsert>;\nexport const uiSurfaceItemType = {\"schema\":\"ui\",\"name\":\"ui_surface_item_type\",\"kind\":\"table\",\"type\":null,\"pk\":[\"id\"],\"org\":{\"rule\":\"binding\"},\"versioned\":false,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceItemTypeRow, UiSurfaceItemTypeInsert, UiSurfaceItemTypeUpdate>;\n\nexport interface UiSurfaceValueRow {\n surface_name: string;\n name: string;\n label: string;\n description: string;\n value_type: string;\n always_available: boolean;\n typical_char_count: number;\n sort_order: number;\n created_at: string;\n updated_at: string;\n auto_context: boolean;\n group_key: string;\n synced_by: string | null;\n synced_from: string | null;\n id: string;\n organization_id: string;\n metadata: Json;\n created_by: string | null;\n updated_by: string | null;\n version: number;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n exportable: boolean;\n classification: string;\n included_by_default: boolean;\n kind_key: string | null;\n live_slot: string | null;\n role: string;\n item_type: string;\n max_inline_chars: number | null;\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at: string | null;\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n declared_by: string;\n}\nexport interface UiSurfaceValueInsert {\n surface_name: string;\n name: string;\n label?: string;\n description?: string;\n value_type?: string;\n always_available?: boolean;\n typical_char_count?: number;\n sort_order?: number;\n created_at?: string;\n updated_at?: string;\n auto_context?: boolean;\n group_key?: string;\n synced_by?: string | null;\n synced_from?: string | null;\n id?: string;\n organization_id?: string;\n metadata?: Json;\n created_by?: string | null;\n updated_by?: string | null;\n version?: number;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n exportable?: boolean;\n classification?: string;\n included_by_default?: boolean;\n kind_key?: string | null;\n live_slot?: string | null;\n role?: string;\n item_type?: string;\n max_inline_chars?: number | null;\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at?: string | null;\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n declared_by?: string;\n}\nexport type UiSurfaceValueUpdate = Partial<UiSurfaceValueInsert>;\nexport const uiSurfaceValue = {\"schema\":\"ui\",\"name\":\"ui_surface_value\",\"kind\":\"table\",\"type\":\"reference\",\"pk\":[\"surface_name\",\"item_type\",\"name\"],\"org\":{\"rule\":\"binding\"},\"versioned\":false,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceValueRow, UiSurfaceValueInsert, UiSurfaceValueUpdate>;\n\nexport interface UiSurfaceWriteTargetRow {\n surface_name: string;\n name: string;\n label: string;\n description: string;\n value_type: string;\n mode: string;\n updates_value: string | null;\n group_key: string;\n sort_order: number;\n created_at: string;\n updated_at: string;\n apply_policy: string;\n synced_by: string | null;\n synced_from: string | null;\n kind_key: string | null;\n id: string;\n organization_id: string;\n metadata: Json;\n created_by: string | null;\n updated_by: string | null;\n version: number;\n visibility: \"personal\" | \"internal\" | \"link\" | \"public\";\n patchable: boolean;\n approval_comparison: string | null;\n stream_ops: string[] | null;\n destination: boolean;\n item_type: string;\n shown_to: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at: string | null;\n published_to_web: boolean;\n published_to_web_at: string | null;\n published_to_web_by: string | null;\n declared_by: string;\n}\nexport interface UiSurfaceWriteTargetInsert {\n surface_name: string;\n name: string;\n label?: string;\n description?: string;\n value_type?: string;\n mode?: string;\n updates_value?: string | null;\n group_key?: string;\n sort_order?: number;\n created_at?: string;\n updated_at?: string;\n apply_policy?: string;\n synced_by?: string | null;\n synced_from?: string | null;\n kind_key?: string | null;\n id?: string;\n organization_id?: string;\n metadata?: Json;\n created_by?: string | null;\n updated_by?: string | null;\n version?: number;\n visibility?: \"personal\" | \"internal\" | \"link\" | \"public\";\n patchable?: boolean;\n approval_comparison?: string | null;\n stream_ops?: string[] | null;\n destination?: boolean;\n item_type?: string;\n shown_to?: \"only_me\" | \"my_team\" | \"everyone\" | \"everyone_on_ai_matrx\" | null;\n deleted_at?: string | null;\n published_to_web?: boolean;\n published_to_web_at?: string | null;\n published_to_web_by?: string | null;\n declared_by?: string;\n}\nexport type UiSurfaceWriteTargetUpdate = Partial<UiSurfaceWriteTargetInsert>;\nexport const uiSurfaceWriteTarget = {\"schema\":\"ui\",\"name\":\"ui_surface_write_target\",\"kind\":\"table\",\"type\":\"reference\",\"pk\":[\"surface_name\",\"item_type\",\"name\"],\"org\":{\"rule\":\"binding\"},\"versioned\":false,\"softDelete\":true,\"archive\":null,\"readOnly\":false,\"deletesRefused\":false,\"readOnlyColumns\":[],\"listScope\":\"organization\",\"realtime\":false,\"createdBy\":true} as unknown as TableDescriptor<UiSurfaceWriteTargetRow, UiSurfaceWriteTargetInsert, UiSurfaceWriteTargetUpdate>;\n\nexport type SaveAppletSurfaceArgs = { p_applet_id: string; p_spec?: Json };\nexport type SaveAppletSurfaceResult = Json;\nexport const saveAppletSurface = {\"schema\":\"ui\",\"name\":\"save_applet_surface\",\"roles\":[\"authenticated\",\"service_role\"],\"registered\":false} as unknown as FunctionDescriptor<SaveAppletSurfaceArgs, SaveAppletSurfaceResult>;\n\nexport type SaveSurfaceExtensionArgs = { p_surface_name: string; p_organization_id: string; p_actions?: Json };\nexport type SaveSurfaceExtensionResult = Json;\nexport const saveSurfaceExtension = {\"schema\":\"ui\",\"name\":\"save_surface_extension\",\"roles\":[\"authenticated\",\"service_role\"],\"registered\":true} as unknown as FunctionDescriptor<SaveSurfaceExtensionArgs, SaveSurfaceExtensionResult>;\n\nexport type SurfaceCodeRefsBrokenArgs = Record<string, never>;\nexport type SurfaceCodeRefsBrokenResult = { action_id: string | null; surface_name: string | null; action_name: string | null; code_ref: string | null; reason: string | null }[];\nexport const surfaceCodeRefsBroken = {\"schema\":\"ui\",\"name\":\"surface_code_refs_broken\",\"roles\":[\"authenticated\",\"service_role\"],\"registered\":false} as unknown as FunctionDescriptor<SurfaceCodeRefsBrokenArgs, SurfaceCodeRefsBrokenResult>;\n","/**\n * The declaration registry: inheritance, baseline injection, provenance and\n * group synthesis (CONTRACT §2.1 `DeclarationRegistry`). Ported verbatim in\n * behaviour from matrx-frontend `features/surfaces/manifests/registry.ts`\n * (ALC-14); the app now supplies its declarations and baselines.\n *\n * Guards are LOUD by design: an unknown parent, a cycle, a chain deeper than\n * the limit, a reserved or duplicate group key, a value naming an undeclared\n * group, or a reserved platform name throws on resolution — a build fails\n * instead of silently dropping values.\n */\nimport { declarationHash } from \"./hash\";\nimport type {\n DeclarationExtension,\n DeclarationIssue,\n DeclaredValue,\n ItemType,\n ResolvedSurfaceDeclaration,\n ResolvedValue,\n SurfaceDeclaration,\n ValueGroup,\n ValueProvenance,\n} from \"./types\";\nimport { validateDeclarations, type ValidateOptions } from \"./validate\";\n\nexport const RESERVED_GROUP_KEYS = {\n general: \"general\",\n baseline: \"baseline\",\n inheritedPrefix: \"inherited:\",\n} as const;\n\n/** Group sortOrder bands. Curated groups author 0–899; the rest is reserved. */\nexport const GENERAL_GROUP_ORDER = 850;\nexport const INHERITED_GROUP_ORDER_BASE = 9000;\nexport const BASELINE_GROUP_ORDER = 9900;\nexport const DEFAULT_MAX_INHERITANCE_DEPTH = 3;\n\nimport { DEFAULT_SENSITIVITY, resolveSensitivity } from \"./sensitivity\";\nexport { DEFAULT_SENSITIVITY, resolveSensitivity };\n\nexport type Resolved<D extends SurfaceDeclaration> = Omit<D, \"values\" | \"groups\"> & {\n values: readonly (D[\"values\"][number] & ResolvedValue)[];\n groups: readonly ValueGroup[];\n contentHash: string;\n};\n\nexport interface DeclarationRegistryOptions {\n /** Generic values injected into every declaration unless `skipBaselineValues`. */\n baselineValues?: readonly DeclaredValue[];\n /**\n * Item types every declaration carries unless it declares one of the same name or sets\n * `skipBaselineItemTypes` (ALC-18: the canonical table row, `TABLE_ROW_ITEM_TYPE`).\n */\n baselineItemTypes?: readonly ItemType[];\n /** Value names only the platform writes; a declaration claiming one is refused. */\n reservedValueNames?: readonly string[];\n /** Write-target names only the platform writes. */\n reservedWriteTargetNames?: readonly string[];\n maxInheritanceDepth?: number;\n}\n\nexport interface DeclarationRegistry<D extends SurfaceDeclaration> {\n /** Refuses a second declaration of the same surfaceName. */\n register(declaration: D): void;\n registerExtension(extension: DeclarationExtension<D>): void;\n extensions(): readonly DeclarationExtension<D>[];\n /** Declarations exactly as authored (inheritance unresolved, no baselines). */\n raw(): readonly D[];\n getRaw(surfaceName: string): D | undefined;\n /** Parent chain, ROOT FIRST. Unknown surfaces return []. */\n ancestry(surfaceName: string): string[];\n /** Direct children (declarations naming it in `inheritsFrom`), in declaration order. */\n children(surfaceName: string): string[];\n /** Inheritance + baseline + groups resolved; provenance kept. */\n all(): readonly Resolved<D>[];\n get(surfaceName: string): Resolved<D> | undefined;\n validate(options?: ValidateOptions): readonly DeclarationIssue[];\n}\n\nexport function createDeclarationRegistry<D extends SurfaceDeclaration>(\n options: DeclarationRegistryOptions = {},\n): DeclarationRegistry<D> {\n const baselineValues = options.baselineValues ?? [];\n const baselineNames = new Set(baselineValues.map((v) => v.name));\n const baselineItemTypes = options.baselineItemTypes ?? [];\n const reservedValues = new Set(options.reservedValueNames ?? []);\n const reservedTargets = new Set(options.reservedWriteTargetNames ?? []);\n const maxDepth = options.maxInheritanceDepth ?? DEFAULT_MAX_INHERITANCE_DEPTH;\n const declarations: D[] = [];\n const index = new Map<string, D>();\n const extensionList: DeclarationExtension<D>[] = [];\n let resolvedCache: Resolved<D>[] | null = null;\n let resolvedIndex = new Map<string, Resolved<D>>();\n\n function ancestry(surfaceName: string): string[] {\n const chain: string[] = [];\n const seen = new Set<string>([surfaceName]);\n let current = index.get(surfaceName)?.inheritsFrom;\n while (current) {\n if (seen.has(current)) {\n throw new Error(\n `[surfaces] inheritsFrom CYCLE detected at \"${current}\" (from \"${surfaceName}\"). ` +\n `Fix the manifest chain: ${[...seen].join(\" → \")} → ${current}`,\n );\n }\n const parent = index.get(current);\n if (!parent) {\n throw new Error(\n `[surfaces] \"${surfaceName}\" inheritsFrom unknown surface \"${current}\" — ` +\n `the parent must be a registered declaration`,\n );\n }\n seen.add(current);\n chain.unshift(current);\n if (chain.length > maxDepth) {\n throw new Error(\n `[surfaces] inheritance chain for \"${surfaceName}\" exceeds depth ${maxDepth}: ` + chain.join(\" → \"),\n );\n }\n current = parent.inheritsFrom;\n }\n return chain;\n }\n\n function groupKeyFor(value: DeclaredValue, provenance: ValueProvenance): string {\n if (provenance.kind === \"own\" && value.group) return value.group;\n if (baselineNames.has(value.name)) return RESERVED_GROUP_KEYS.baseline;\n if (provenance.kind === \"inherited\") return `${RESERVED_GROUP_KEYS.inheritedPrefix}${provenance.from}`;\n if (provenance.kind === \"baseline\") return RESERVED_GROUP_KEYS.baseline;\n return RESERVED_GROUP_KEYS.general;\n }\n\n function resolve(declaration: D): Resolved<D> {\n const chain = ancestry(declaration.surfaceName);\n const lineage: { layer: D; from: string | null }[] = [\n ...chain.map((name) => {\n const layer = index.get(name);\n if (!layer) throw new Error(`[surfaces] missing inherited declaration \"${name}\"`);\n return { layer, from: name };\n }),\n { layer: declaration, from: null },\n ];\n\n const curatedKeys = new Set<string>();\n for (const group of declaration.groups ?? []) {\n if (\n group.key === RESERVED_GROUP_KEYS.general ||\n group.key === RESERVED_GROUP_KEYS.baseline ||\n group.key.startsWith(RESERVED_GROUP_KEYS.inheritedPrefix)\n ) {\n throw new Error(\n `[surfaces] \"${declaration.surfaceName}\" declares reserved group key \"${group.key}\" — ` +\n `general/baseline/inherited:* are synthesized by the registry`,\n );\n }\n if (curatedKeys.has(group.key)) {\n throw new Error(`[surfaces] \"${declaration.surfaceName}\" declares duplicate group key \"${group.key}\"`);\n }\n curatedKeys.add(group.key);\n }\n for (const value of declaration.values) {\n if (reservedValues.has(value.name)) {\n throw new Error(\n `[surfaces] \"${declaration.surfaceName}\" declares value \"${value.name}\" — that name is written by the platform; choose another name`,\n );\n }\n if (value.group && !curatedKeys.has(value.group)) {\n throw new Error(\n `[surfaces] \"${declaration.surfaceName}\" value \"${value.name}\" references undeclared ` +\n `group \"${value.group}\" — declare it in the manifest's \\`groups\\``,\n );\n }\n }\n for (const target of declaration.writeTargets ?? []) {\n if (reservedTargets.has(target.name)) {\n throw new Error(\n `[surfaces] \"${declaration.surfaceName}\" declares write target \"${target.name}\" — that name is written by the platform; choose another name`,\n );\n }\n }\n\n const valuesByName = new Map<string, D[\"values\"][number] & ResolvedValue>();\n const inheritedLists = new Map<string, Map<string, unknown>>();\n const coreLists: { field: string; identity(entry: unknown): string }[] = [\n { field: \"configNamespaces\", identity: (entry) => (entry as { namespace: string }).namespace },\n {\n field: \"evidenceSources\",\n identity: (entry) => `${(entry as { kind: string }).kind}:${(entry as { idValue: string }).idValue}`,\n },\n ];\n const lists = [...coreLists, ...extensionList.flatMap((extension) => extension.inheritedLists ?? [])];\n for (const { layer, from } of lineage) {\n for (const value of layer.values) {\n const provenance: ValueProvenance = from ? { kind: \"inherited\", from } : { kind: \"own\" };\n valuesByName.set(value.name, {\n ...value,\n provenance,\n groupKey: groupKeyFor(value, provenance),\n resolvedSensitivity: resolveSensitivity(value),\n });\n }\n for (const list of lists) {\n const entries = (layer as unknown as Record<string, unknown>)[list.field];\n if (!Array.isArray(entries)) continue;\n const byIdentity = inheritedLists.get(list.field) ?? new Map<string, unknown>();\n for (const entry of entries) byIdentity.set(list.identity(entry), entry);\n inheritedLists.set(list.field, byIdentity);\n }\n }\n\n if (!declaration.skipBaselineValues) {\n for (const baseline of baselineValues) {\n if (valuesByName.has(baseline.name)) continue;\n valuesByName.set(baseline.name, {\n ...baseline,\n provenance: { kind: \"baseline\" },\n groupKey: RESERVED_GROUP_KEYS.baseline,\n resolvedSensitivity: resolveSensitivity(baseline),\n } as D[\"values\"][number] & ResolvedValue);\n }\n }\n\n const ownItemTypes = declaration.itemTypes ?? [];\n const itemTypes: ItemType[] = [...ownItemTypes];\n if (!declaration.skipBaselineItemTypes) {\n for (const baseline of baselineItemTypes) {\n if (!itemTypes.some((item) => item.name === baseline.name)) itemTypes.push(baseline);\n }\n }\n\n const usedGroupKeys = new Set(Array.from(valuesByName.values(), (value) => value.groupKey));\n const groups: ValueGroup[] = [...(declaration.groups ?? [])];\n if (usedGroupKeys.has(RESERVED_GROUP_KEYS.general)) {\n groups.push({ key: RESERVED_GROUP_KEYS.general, label: \"General\", sortOrder: GENERAL_GROUP_ORDER });\n }\n for (let i = chain.length - 1, distance = 0; i >= 0; i -= 1, distance += 1) {\n const parentName = chain[i]!;\n const key = `${RESERVED_GROUP_KEYS.inheritedPrefix}${parentName}`;\n if (!usedGroupKeys.has(key)) continue;\n const parentLabel = index.get(parentName)?.label ?? parentName;\n groups.push({\n key,\n label: `Inherited from ${parentLabel}`,\n sortOrder: INHERITED_GROUP_ORDER_BASE + distance * 10,\n });\n }\n if (usedGroupKeys.has(RESERVED_GROUP_KEYS.baseline)) {\n groups.push({ key: RESERVED_GROUP_KEYS.baseline, label: \"Generic baselines\", sortOrder: BASELINE_GROUP_ORDER });\n }\n groups.sort((a, b) => a.sortOrder - b.sortOrder);\n\n const groupOrder = new Map(groups.map((group) => [group.key, group.sortOrder] as const));\n const values = Array.from(valuesByName.values()).sort((a, b) => {\n const ga = groupOrder.get(a.groupKey) ?? GENERAL_GROUP_ORDER;\n const gb = groupOrder.get(b.groupKey) ?? GENERAL_GROUP_ORDER;\n if (ga !== gb) return ga - gb;\n return (a.sortOrder ?? 1000) - (b.sortOrder ?? 1000);\n });\n\n const merged: Record<string, unknown> = {};\n for (const [field, byIdentity] of inheritedLists) {\n if (byIdentity.size > 0) merged[field] = Array.from(byIdentity.values());\n }\n return {\n ...declaration,\n values,\n groups,\n ...merged,\n ...(itemTypes.length > 0 ? { itemTypes } : {}),\n contentHash: declarationHash(declaration),\n } as Resolved<D>;\n }\n\n function resolvedAll(): Resolved<D>[] {\n if (!resolvedCache) {\n resolvedCache = declarations.map(resolve);\n resolvedIndex = new Map(resolvedCache.map((entry) => [entry.surfaceName, entry] as const));\n }\n return resolvedCache;\n }\n\n const registry: DeclarationRegistry<D> = {\n register(declaration) {\n if (index.has(declaration.surfaceName)) {\n throw new Error(`[surfaces] \"${declaration.surfaceName}\" is declared twice — one surface, one declaration`);\n }\n declarations.push(declaration);\n index.set(declaration.surfaceName, declaration);\n resolvedCache = null;\n },\n registerExtension(extension) {\n if (extensionList.some((existing) => existing.key === extension.key)) {\n throw new Error(`[surfaces] declaration extension \"${extension.key}\" is registered twice`);\n }\n extensionList.push(extension);\n resolvedCache = null;\n },\n extensions: () => extensionList,\n raw: () => declarations,\n getRaw: (surfaceName) => index.get(surfaceName),\n ancestry,\n children: (surfaceName) =>\n declarations.filter((d) => d.inheritsFrom === surfaceName).map((d) => d.surfaceName),\n all: () => resolvedAll(),\n get(surfaceName) {\n resolvedAll();\n return resolvedIndex.get(surfaceName);\n },\n validate: (validateOptions) =>\n validateDeclarations(resolvedAll() as unknown as readonly ResolvedSurfaceDeclaration[], {\n ...validateOptions,\n extensions: [...(validateOptions?.extensions ?? []), ...(extensionList as DeclarationExtension[])],\n baselineNames: validateOptions?.baselineNames ?? [...baselineNames],\n }),\n };\n return registry;\n}\n","/**\n * Every source of an Action projects onto ONE shape (Applets CONTRACTS §6):\n * a declared write target, a client tool row, a `ui.ui_surface_action` row.\n * Pure functions, zero loss (the census in `declarations.test.ts` proves every\n * source field lands). Then the chain: a child surface's Action wins by name.\n */\nimport { DEFAULT_MAX_INHERITANCE_DEPTH } from \"../declare/registry\";\nimport type { Json, WriteTarget } from \"../declare/types\";\nimport type {\n ActionCaller,\n ActionDeclaration,\n ActionDeclaredBy,\n ActionInfo,\n ActionInput,\n ActionOrigin,\n ActionPolicy,\n ActionRuns,\n ActionWriteMode,\n} from \"./applet-types\";\n\n/** Default `category` of an Action that names none. */\nexport const APPLET_CATEGORY = \"applet\";\n\n/** The DB default of `ui.ui_surface_action.triggered_by`, used where a source carries no list. */\nexport const DEFAULT_TRIGGERED_BY: readonly ActionCaller[] = [\"person\", \"agent\", \"applet\"];\n\nexport const ACTION_CALLERS: readonly ActionCaller[] = [\"person\", \"agent\", \"applet\", \"automation\"];\nexport const ACTION_RUNS: readonly ActionRuns[] = [\"page\", \"server\", \"mandate\", \"navigate\"];\nexport const ACTION_POLICIES: readonly ActionPolicy[] = [\"ask\", \"auto\", \"manual\"];\n\n/** A `ui.ui_surface_client_tool` row (live columns that carry meaning). */\nexport interface ClientToolRow {\n id?: string;\n surface_name: string;\n name: string;\n label: string;\n description: string;\n input_schema: Json;\n /** Live values: \"ui\" (applied directly) | \"draft\" (proposed for review). */\n mode: \"ui\" | \"draft\";\n declared_by?: ActionDeclaredBy;\n}\n\n/** A `ui.ui_surface_action` row. */\nexport interface SurfaceActionRow {\n id?: string;\n surface_id: string;\n surface_name: string;\n /** '' = the screen itself. */\n item_type: string;\n name: string;\n category: string;\n label: string;\n description: string;\n input: ActionInput | null;\n output: string | null;\n runs: ActionRuns;\n target: string | null;\n triggered_by: ActionCaller[];\n policy: ActionPolicy;\n updates_value: string | null;\n code_ref: string | null;\n declared_by: ActionDeclaredBy;\n sort_order: number;\n /**\n * The row's organization. A `declared_by='database'` row on a surface outside `applets/` is that\n * organization's EXTENSION and applies only to its members (`readSurfaceChain`, aidream `visible_actions`).\n */\n organization_id?: string | null;\n}\n\ntype Loose<T> = { [K in keyof T]: T[K] | undefined };\n\n/** Drop undefined keys (exactOptionalPropertyTypes: an absent field is absent, never `undefined`). */\nfunction compact<T extends object>(value: Loose<T>): T {\n return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as T;\n}\n\nconst POLICY_OF_APPLY: Record<NonNullable<WriteTarget[\"applyPolicy\"]>, ActionPolicy> = {\n manual: \"manual\",\n ask: \"ask\",\n auto: \"auto\",\n // Filed for an organization's review: never applied without someone saying yes.\n queued: \"ask\",\n};\n\n/** A declared write target → an Action that runs on the page. */\nexport function writeTargetToAction(target: WriteTarget): ActionDeclaration {\n const applyPolicy = target.applyPolicy ?? \"manual\";\n return compact<ActionDeclaration>({\n name: target.name,\n label: target.label,\n description: target.description,\n input: target.valueKind ?? { jsonSchema: target.valueType === \"document\" ? {} : { type: target.valueType } },\n runs: \"page\",\n triggeredBy: [...DEFAULT_TRIGGERED_BY],\n policy: POLICY_OF_APPLY[applyPolicy],\n updatesValue: target.updatesValue,\n mode: target.mode as ActionWriteMode,\n patchable: target.patchable,\n approvalComparison: target.approvalComparison,\n streamOps: target.streamOps ? [...target.streamOps] : undefined,\n destination: target.destination,\n groupKey: target.group,\n itemType: target.itemType,\n applyPolicy: target.applyPolicy,\n valueType: target.valueType,\n valueKind: target.valueKind,\n sortOrder: target.sortOrder,\n origin: { source: \"write-target\", declaredBy: \"code\" },\n });\n}\n\n/** A client tool row → an Action an agent runs on the page (\"draft\" tools are proposed first). */\nexport function clientToolToAction(row: ClientToolRow): ActionDeclaration {\n return compact<ActionDeclaration>({\n name: row.name,\n label: row.label,\n description: row.description,\n input: { jsonSchema: (row.input_schema ?? {}) as object },\n runs: \"page\",\n triggeredBy: [\"agent\"],\n policy: row.mode === \"draft\" ? \"ask\" : \"auto\",\n mode: row.mode,\n origin: compact<ActionOrigin>({ source: \"client-tool\", surfaceName: row.surface_name, id: row.id, declaredBy: row.declared_by }),\n });\n}\n\n/** A `ui.ui_surface_action` row → its Action. */\nexport function surfaceActionRowToAction(row: SurfaceActionRow): ActionDeclaration {\n return compact<ActionDeclaration>({\n name: row.name,\n category: row.category,\n label: row.label,\n description: row.description,\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n runs: row.runs,\n target: row.target ?? undefined,\n triggeredBy: [...row.triggered_by],\n policy: row.policy,\n updatesValue: row.updates_value ?? undefined,\n itemType: row.item_type || undefined,\n sortOrder: row.sort_order,\n origin: compact<ActionOrigin>({\n source: \"surface-action\",\n surfaceName: row.surface_name,\n surfaceId: row.surface_id,\n id: row.id,\n declaredBy: row.declared_by,\n codeRef: row.code_ref ?? undefined,\n organizationId: row.organization_id ?? undefined,\n }),\n });\n}\n\n/** JSON-only view of an Action as declared on `declaredOn`. */\nexport function toActionInfo(declaration: ActionDeclaration, declaredOn: string): ActionInfo {\n return compact<ActionInfo>({\n name: declaration.name,\n category: declaration.category ?? APPLET_CATEGORY,\n label: declaration.label,\n description: declaration.description,\n runs: declaration.runs,\n policy: declaration.policy,\n triggeredBy: [...declaration.triggeredBy],\n input: declaration.input,\n output: declaration.output,\n declaredOn,\n target: declaration.target,\n updatesValue: declaration.updatesValue,\n itemType: declaration.itemType,\n source: declaration.origin?.source,\n });\n}\n\nexport interface ActionChainLink {\n surfaceName: string;\n actions: readonly ActionDeclaration[];\n}\n\n/**\n * The Actions a mount sees: its own plus every ancestor's, a child winning by\n * name. `chain` runs MOST GENERAL FIRST (root parent … the mounted surface),\n * as `DeclarationRegistry` resolves inheritance. Guards are loud, like the\n * declaration registry's: a surface twice in the chain is a cycle, more\n * ancestors than `maxDepth` throws, and one surface naming an Action twice throws.\n */\nexport function resolveActionChain(\n chain: readonly ActionChainLink[],\n options: { maxDepth?: number } = {},\n): ActionInfo[] {\n const maxDepth = options.maxDepth ?? DEFAULT_MAX_INHERITANCE_DEPTH;\n const names = chain.map((link) => link.surfaceName);\n const seen = new Set<string>();\n for (const name of names) {\n if (seen.has(name)) {\n throw new Error(`[actions] inheritance CYCLE detected at \"${name}\". Fix the surface chain: ${names.join(\" → \")}`);\n }\n seen.add(name);\n }\n if (chain.length - 1 > maxDepth) {\n throw new Error(\n `[actions] inheritance chain for \"${names[names.length - 1]}\" exceeds depth ${maxDepth}: ${names.join(\" → \")}`,\n );\n }\n const byName = new Map<string, ActionInfo>();\n for (const link of chain) {\n const own = new Set<string>();\n for (const action of link.actions) {\n if (own.has(action.name)) {\n throw new Error(\n `[actions] surface \"${link.surfaceName}\" declares Action \"${action.name}\" twice. Names are unique; nothing was overwritten.`,\n );\n }\n own.add(action.name);\n byName.set(action.name, toActionInfo(action, link.surfaceName));\n }\n }\n return [...byName.values()];\n}\n","/**\n * The few reads the surface runtime makes through the VIEWER's supabase client, typed STRUCTURALLY.\n *\n * Alchemy never imports supabase or the host (package rule 13). Deliberately not\n * `SupabaseClient<Database>` either: a generated `Database` type makes `schema().from().select()`\n * enormous and a host passing its typed client hits TS2589. The host hands its client in as an\n * `object`; the ONE cast lives in `asSurfaceClient`, and every read names its schema out loud.\n *\n * Holds no key and opens no connection: the client carries the person's session, so row security\n * decides every answer.\n */\nimport type { ActionError, ActionResult } from \"../actions/applet-types\";\n\n/** What a supabase-js read resolves with. */\nexport interface SurfaceReadAnswer {\n data: unknown;\n error: { message: string; code?: string; details?: string; hint?: string } | null;\n}\n\n/** The filter chain the reads use — a subset of supabase-js's `PostgrestFilterBuilder`. */\nexport interface SurfaceReadChain extends PromiseLike<SurfaceReadAnswer> {\n eq(column: string, value: unknown): SurfaceReadChain;\n in(column: string, values: readonly unknown[]): SurfaceReadChain;\n is(column: string, value: null): SurfaceReadChain;\n order(column: string, options?: { ascending?: boolean }): SurfaceReadChain;\n maybeSingle(): PromiseLike<SurfaceReadAnswer>;\n}\n\n/** The part of a supabase-js v2 client the surface runtime reads through. */\nexport interface SurfaceClient {\n schema(name: string): { from(table: string): { select(columns: string): SurfaceReadChain } };\n}\n\n/** Bind the host's client. A value without `schema()` is refused by name. */\nexport function asSurfaceClient(client: object): SurfaceClient {\n // The one cast: the host's typed client is passed as `object` (see above) and checked here.\n const c = client as Partial<SurfaceClient>;\n if (typeof c.schema !== \"function\") {\n throw new Error(\"[alchemy/surface] the surface runtime needs a supabase-js v2 client carrying the viewer's session (it has no schema()).\");\n }\n return c as SurfaceClient;\n}\n\n/** A read's error: the database's own sentence, never paraphrased. */\nexport function readError(error: NonNullable<SurfaceReadAnswer[\"error\"]>, code = \"read_failed\"): ActionError {\n const out: ActionError = { code: error.code ? `${code}:${error.code}` : code, message: error.message, retryable: false };\n if (error.details) out.diagnostic = error.details;\n return out;\n}\n\n/** Run a read (built inside the guard); a thrown transport error answers `unreachable` (retryable), never throws. */\nexport async function read<T>(query: () => PromiseLike<SurfaceReadAnswer>, shape: (data: unknown) => T): Promise<ActionResult<T>> {\n try {\n const answer = await query();\n if (answer.error) return { ok: false, error: readError(answer.error) };\n return { ok: true, data: shape(answer.data) };\n } catch (err) {\n return { ok: false, error: { code: \"unreachable\", message: err instanceof Error ? err.message : String(err), retryable: true } };\n }\n}\n\n/**\n * Run a `@ai-matrx/data` door; same answers as `read`: a database error keeps the database's own\n * sentence (and code), anything else thrown answers `unreachable` (retryable). Never throws.\n */\nexport async function door<T>(run: () => Promise<T>): Promise<ActionResult<T>> {\n try {\n return { ok: true, data: await run() };\n } catch (err) {\n const cause = (err as { name?: string; cause?: SurfaceReadAnswer[\"error\"] }) ?? {};\n if (cause.name === \"DatabaseError\" && cause.cause) return { ok: false, error: readError(cause.cause) };\n return { ok: false, error: { code: \"unreachable\", message: err instanceof Error ? err.message : String(err), retryable: true } };\n }\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","/**\n * THE ONE RUNNER for surface Actions (Applets CONTRACTS §6). Every caller — a\n * person's click, an agent, an applet, an automation — runs an Action through\n * here, so policy and caller rules live once.\n *\n * Policy \"ask\": a person's own click is the approval. Started by an agent, applet or automation,\n * a \"server\" run carries the policy to aidream (which answers with a proposal); every other run\n * asks the person through `ports.approvals` first, and is refused by name without that port.\n *\n * Dispatch by `runs`:\n * \"server\" → `ports.serverActions.run({ name: target, input, by, surface_name, policy })`\n * \"mandate\" → `ports.mandates.run({ alias: target, variables, by, policy })` — answers with the\n * started run's `MandateRunRef`; the result streams later on `run:<requestId>`\n * \"navigate\" → `ports.overlay.navigate(target)` with `{param}` filled from the input\n * \"page\" → `ports.pageActions.dispatch(name, input, context)`\n * A port the host did not bind means that capability is ABSENT: the run is\n * refused with a sentence, never stubbed (ports rule).\n *\n * Write targets (ALC-17): an Action projected from a declared write target (`source: \"write-target\"`)\n * goes through `ports.door.write` when a door is bound — the door applies the target's own policy\n * (manual / ask / queued / auto) and its receipt becomes the result (`applied` / `queued` → ok with\n * the receipt; refused → an error whose code is the refusal reason and whose `remedy` is the door's).\n * Without a door it dispatches to `pageActions` as before.\n *\n * Never throws: every outcome is a `Result` whose error message is the\n * system's own sentence.\n */\nimport type { AlchemyHostPorts, Json } from \"../ports\";\nimport type { WriteOp } from \"../operate/door\";\nimport type { ActionCaller, ActionContext, ActionError, ActionInfo, ActionResult } from \"./applet-types\";\n\nexport type SurfaceActionPorts = Pick<\n AlchemyHostPorts,\n \"diagnostics\" | \"serverActions\" | \"mandates\" | \"pageActions\" | \"overlay\" | \"approvals\" | \"door\"\n>;\n\nexport interface RunSurfaceActionOptions {\n runId?: string;\n viewerId?: string | null;\n signal?: AbortSignal;\n /** Which item a write-target Action writes into (by its declared identity values). */\n itemIdentity?: Record<string, string>;\n /** Text edits for a stream or patchable write target, instead of the input as the whole value. */\n ops?: readonly WriteOp[];\n}\n\nfunction fail(code: string, message: string, retryable = false, diagnostic?: string): { ok: false; error: ActionError } {\n return { ok: false, error: diagnostic ? { code, message, retryable, diagnostic } : { code, message, retryable } };\n}\n\nfunction messageOf(error: unknown): string {\n if (error instanceof Error && error.message.trim()) return error.message;\n if (typeof error === \"string\" && error.trim()) return error;\n return \"The run failed without saying why.\";\n}\n\nfunction newRunId(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n return `run-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Fill `{param}` placeholders from the input object. Returns the names it could not fill. */\nexport function fillActionTarget(template: string, input: unknown): { value: string; missing: string[] } {\n const source = input && typeof input === \"object\" && !Array.isArray(input) ? (input as Record<string, unknown>) : {};\n const missing: string[] = [];\n const value = template.replace(/\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, key: string) => {\n const v = source[key];\n if (v === undefined || v === null || v === \"\" || typeof v === \"object\") {\n missing.push(key);\n return \"\";\n }\n return encodeURIComponent(String(v));\n });\n return { value, missing };\n}\n\n/** Same as fillActionTarget, without URL-encoding (a mandate alias or server action name). */\nfunction fillName(template: string, input: unknown): { value: string; missing: string[] } {\n const filled = fillActionTarget(template, input);\n return { value: decodeURIComponent(filled.value), missing: filled.missing };\n}\n\nfunction toJson(value: unknown): Json {\n if (value === undefined) return null;\n return JSON.parse(JSON.stringify(value)) as Json;\n}\n\n/**\n * Who may run this Action, under its policy. Returns the refusal, or null.\n * \"manual\" = a person only. `triggeredBy` lists every caller allowed at all.\n */\nexport function refuseCaller(info: Pick<ActionInfo, \"name\" | \"label\" | \"policy\" | \"triggeredBy\">, by: ActionCaller): ActionError | null {\n if (!info.triggeredBy.includes(by)) {\n return {\n code: \"caller_not_allowed\",\n message: `\"${info.label}\" (${info.name}) can't be started by ${CALLER_WORDS[by]}; it allows ${info.triggeredBy.join(\", \") || \"no one\"}.`,\n retryable: false,\n };\n }\n if (info.policy === \"manual\" && by !== \"person\") {\n return {\n code: \"manual_only\",\n message: `\"${info.label}\" (${info.name}) runs only when a person starts it.`,\n retryable: false,\n };\n }\n return null;\n}\n\nconst CALLER_WORDS: Record<ActionCaller, string> = {\n person: \"a person\",\n agent: \"an agent\",\n applet: \"an applet\",\n automation: \"an automation\",\n};\n\nfunction absent(info: ActionInfo, capability: string): { ok: false; error: ActionError } {\n return fail(\"capability_absent\", `\"${info.label}\" can't run here: ${capability} isn't available on this page.`);\n}\n\nexport async function runSurfaceAction(\n info: ActionInfo,\n input: unknown,\n by: ActionCaller,\n ports: SurfaceActionPorts,\n options: RunSurfaceActionOptions = {},\n): Promise<ActionResult<unknown>> {\n const refusal = refuseCaller(info, by);\n if (refusal) return { ok: false, error: refusal };\n const context: ActionContext = {\n runId: options.runId ?? newRunId(),\n by,\n viewerId: options.viewerId ?? null,\n surfaceName: info.declaredOn,\n policy: info.policy,\n };\n const capture = (error: unknown, stage: string) => {\n try {\n ports.diagnostics.capture(error, { area: \"actions\", detail: { action: info.name, runs: info.runs, stage, runId: context.runId } });\n } catch {\n // A broken diagnostics port never turns a refusal into a throw.\n }\n };\n\n try {\n if (info.source === \"write-target\" && ports.door) {\n const receipt = await ports.door.write(\n {\n surfaceName: info.declaredOn,\n target: info.name,\n ...(info.itemType ? { itemType: info.itemType } : {}),\n ...(options.itemIdentity ? { itemIdentity: options.itemIdentity } : {}),\n ...(options.ops ? { ops: options.ops } : { value: input }),\n by,\n runId: context.runId,\n },\n options.signal,\n );\n if (receipt.status === \"refused\") {\n return { ok: false, error: { code: receipt.reason, message: receipt.sentence, retryable: receipt.reason === \"failed\", remedy: receipt.remedy } };\n }\n return { ok: true, data: receipt };\n }\n if (info.policy === \"ask\" && by !== \"person\" && info.runs !== \"server\") {\n if (!ports.approvals) {\n return fail(\"needs_approval\", `\"${info.label}\" needs a person's approval, and there is no one to ask here.`);\n }\n const approved = await ports.approvals.ask({\n action: info.name,\n label: info.label,\n description: info.description,\n input: toJson(input),\n by,\n surfaceName: info.declaredOn,\n runId: context.runId,\n });\n if (!approved) return fail(\"declined\", `\"${info.label}\" was not approved, so it did not run.`);\n }\n switch (info.runs) {\n case \"server\": {\n if (!ports.serverActions) return absent(info, \"server actions\");\n const filled = fillName(info.target ?? info.name, input);\n if (filled.missing.length) return fail(\"input_missing\", `\"${info.label}\" needs ${filled.missing.join(\", \")}.`);\n const response = await ports.serverActions.run({\n name: filled.value,\n input: toJson(input),\n by,\n surface_name: info.declaredOn,\n policy: info.policy,\n });\n if (response.status === \"refused\") return fail(\"refused\", response.message);\n return { ok: true, data: response };\n }\n case \"mandate\": {\n if (!ports.mandates) return absent(info, \"running a job\");\n if (!info.target) return fail(\"target_missing\", `\"${info.label}\" names no job to run.`);\n const filled = fillName(info.target, input);\n if (filled.missing.length) return fail(\"input_missing\", `\"${info.label}\" needs ${filled.missing.join(\", \")}.`);\n const record = input && typeof input === \"object\" && !Array.isArray(input) ? (input as Record<string, unknown>) : {};\n // A generic \"run a job\" Action carries { alias, variables, userInput }; a dedicated one's input IS the variables.\n const generic = /\\{[A-Za-z_]/.test(info.target);\n const variables = generic\n ? ((record.variables && typeof record.variables === \"object\" ? toJson(record.variables) : {}) as Record<string, Json>)\n : (toJson(record) as Record<string, Json>);\n const userInput = typeof record.userInput === \"string\" ? record.userInput : undefined;\n // The Action answers with the run's identity (RunRef); its result streams on `run:<requestId>`.\n const ref = await ports.mandates.run({\n alias: filled.value,\n variables,\n ...(userInput !== undefined ? { userInput } : {}),\n by,\n policy: info.policy,\n });\n return { ok: true, data: ref };\n }\n case \"navigate\": {\n if (!ports.overlay) return absent(info, \"navigation\");\n const filled = fillActionTarget(info.target ?? \"\", input);\n if (filled.missing.length) return fail(\"input_missing\", `\"${info.label}\" needs ${filled.missing.join(\", \")}.`);\n // `{to}` is a whole route: keep its slashes.\n const to = info.target && /^\\{[A-Za-z_][A-Za-z0-9_]*\\}$/.test(info.target) ? decodeURIComponent(filled.value) : filled.value;\n if (!to) return fail(\"target_missing\", `\"${info.label}\" names no page to open.`);\n ports.overlay.navigate(to);\n return { ok: true, data: { to } };\n }\n case \"page\": {\n if (!ports.pageActions) return absent(info, \"this page's actions\");\n return await ports.pageActions.dispatch(info.name, input, context);\n }\n default: {\n const runs: never = info.runs;\n return fail(\"runs_unknown\", `\"${info.label}\" runs as \"${String(runs)}\", which nothing here knows how to run.`);\n }\n }\n } catch (error) {\n capture(error, \"run\");\n return fail(\"run_failed\", messageOf(error), true);\n }\n}\n","/**\n * LIVE VALUES — what a mounted page holds right now (ALC-18, LIST.md D3).\n *\n * A page publishes ONE live capture while it is mounted: its title and route, what it is OF\n * (`identity`), the exact choices the person made (`selection`), its data sections, the errors on\n * screen and its recent requests. Descendants that hold state the page does not (a grid's rows, a\n * compare view) contribute sections. Every reader — the page's Alchemy menu, the admin debug\n * context, an agent through `SurfacePort.getValue` — reads the SAME capture through this store, at\n * read time, from the live getters. There is no second capture path.\n *\n * The four declared live slots (`LiveSlot`: selection, on-demand, errors, requests) are views of\n * the capture (`liveSlotsOf`), and a surface's named value reads through `liveValueOf`.\n *\n * Framework-neutral: no React, no DOM. A host hook subscribes with `subscribe` + `version`\n * (`useSyncExternalStore`). The most recent publication wins (a dialog over a page, a page over\n * the shell's default).\n */\nimport type { LiveValues, OnDemandSection, RecentRequest, Json } from \"../declare/types\";\n\nexport type LiveCaptureKind = \"table-page\" | \"record\" | \"dialog\" | \"admin-page\";\n\n/** A chosen thing, by name and id. Either may be null (not chosen / not loaded). */\nexport interface LiveNamed {\n id: string | null;\n name: string | null;\n}\n\nexport type LiveCaptureValue = LiveNamed | string | number | boolean | null;\n\nexport interface LiveSection {\n /** Stable id, unique within one capture. */\n id: string;\n /** What the person calls this part of the page. */\n title: string;\n description?: string;\n /** `data` survives \"Only the data\"; `request` does not. */\n role: \"data\" | \"request\";\n value: unknown;\n /** The one-line brief (counts, a sentence). */\n brief?: unknown;\n /** A section too big to hold on the page: `value` is the honest stub and `load` reads it on use. */\n load?: () => Promise<unknown>;\n}\n\nexport interface LiveRequest {\n method: string;\n path: string;\n status: string;\n httpStatus?: number;\n durationMs?: number;\n requestId?: string;\n /** Which client door (supabase-rest, supabase-rpc, aidream, next-api …). */\n client?: string;\n /** The JSON request body, credentials redacted. */\n requestBody?: unknown;\n requestBodyNote?: string;\n /** A failed request's own sentence from the server, verbatim. */\n errorSentence?: string;\n timestamp: number;\n}\n\nexport interface LiveCapture {\n /** The declared surface these are live values of. Absent/null = the page declares no surface yet. */\n surfaceName?: string | null;\n kind: LiveCaptureKind;\n title: string;\n route: string;\n url?: string;\n /** What this page is OF (table, record, dialog subject …), names and ids. */\n identity: Record<string, LiveCaptureValue>;\n /** The exact choices the person made on the page, in order. */\n selection: Record<string, LiveCaptureValue>;\n sections: LiveSection[];\n /** The error sentences on screen, verbatim. */\n errors: string[];\n requests: LiveRequest[];\n}\n\nexport interface LiveContribution {\n owner: string;\n sections: LiveSection[];\n /** Names a descendant knows and the page does not. */\n identity?: Record<string, LiveCaptureValue>;\n}\n\n/** What a reader shows before anyone uses the capture: no section value is walked. */\nexport interface LiveOutline {\n surfaceName: string | null;\n kind: LiveCaptureKind;\n title: string;\n loadable: Array<Pick<LiveSection, \"id\" | \"title\">>;\n}\n\nfunction isNamed(v: unknown): v is LiveNamed {\n return typeof v === \"object\" && v !== null && \"id\" in v && \"name\" in v;\n}\n\n/**\n * The page's capture plus its descendants' contributions. A descendant fills a name the page left\n * empty and never overrides one; a section id claimed twice throws, naming both owners.\n */\nexport function mergeLiveCapture(base: LiveCapture, contributions: readonly LiveContribution[]): LiveCapture {\n const owners = new Map<string, string>(base.sections.map((s) => [s.id, \"page\"]));\n const sections = [...base.sections];\n const identity = { ...base.identity };\n for (const c of contributions) {\n for (const [k, v] of Object.entries(c.identity ?? {})) {\n const prior = identity[k];\n if (prior === undefined || prior === null || (isNamed(prior) && !prior.name)) identity[k] = v;\n }\n for (const s of c.sections) {\n const prior = owners.get(s.id);\n if (prior) throw new Error(`[live values] section \"${s.id}\" is claimed by both \"${prior}\" and \"${c.owner}\"`);\n owners.set(s.id, c.owner);\n sections.push(s);\n }\n }\n return { ...base, identity, sections };\n}\n\n/** The four declared live slots (`LiveSlot`) as views of one capture. */\nexport function liveSlotsOf(capture: LiveCapture): LiveValues {\n const onDemand: OnDemandSection[] = capture.sections\n .filter((s) => typeof s.load === \"function\")\n .map((s) => ({\n id: s.id,\n title: s.title,\n ...(s.description ? { description: s.description } : {}),\n role: s.role,\n ...(s.brief !== undefined ? { brief: s.brief as Json } : {}),\n load: () => s.load!() as Promise<Json>,\n }));\n return {\n selection: { choices: capture.selection as Record<string, Json>, text: null },\n \"on-demand\": onDemand,\n errors: capture.errors,\n requests: capture.requests as RecentRequest[],\n };\n}\n\n/**\n * One named live value of a capture, or `undefined` when the capture holds none by that name.\n * Slot names (`selection`, `errors`, `requests`, `on-demand`) read the slot; `title`, `route`,\n * `url`, `kind` and `identity` read the page; any other name reads an identity or selection entry,\n * then a held section's value (a section that must be loaded answers its stub).\n */\nexport function liveValueOf(capture: LiveCapture, name: string): unknown {\n switch (name) {\n case \"selection\":\n return capture.selection;\n case \"errors\":\n return capture.errors;\n case \"requests\":\n return capture.requests;\n case \"on-demand\":\n return capture.sections.filter((s) => typeof s.load === \"function\").map((s) => ({ id: s.id, title: s.title, role: s.role }));\n case \"title\":\n case \"route\":\n case \"url\":\n case \"kind\":\n case \"identity\":\n return capture[name];\n default:\n break;\n }\n if (Object.prototype.hasOwnProperty.call(capture.identity, name)) return capture.identity[name];\n if (Object.prototype.hasOwnProperty.call(capture.selection, name)) return capture.selection[name];\n return capture.sections.find((s) => s.id === name)?.value;\n}\n\nexport interface LiveValuesStore {\n /** A page's live capture, read at read time. Returns its unpublish. The most recent wins. */\n publish(read: () => LiveCapture): () => void;\n /** A descendant's sections (and names). Returns its removal. */\n contribute(owner: string, read: () => LiveSection[] | Omit<LiveContribution, \"owner\">): () => void;\n /** Say a getter's answer changed (readers re-render). */\n touch(): void;\n /** Whether any page is publishing right now. */\n has(): boolean;\n /** The live capture: the latest publication merged with every contribution. */\n read(): LiveCapture | null;\n /** The outline without building section values (safe in render). */\n outline(): LiveOutline | null;\n /** The live capture of ONE surface, when the publishing page is that surface. */\n readFor(surfaceName: string): LiveCapture | null;\n subscribe(listener: () => void): () => void;\n /** Bumps on every publish / contribute / touch. */\n version(): number;\n}\n\nexport function createLiveValues(): LiveValuesStore {\n let nextId = 0;\n let version = 0;\n let pages: Array<{ id: number; read: () => LiveCapture }> = [];\n let parts: Array<{ id: number; owner: string; read: () => LiveSection[] | Omit<LiveContribution, \"owner\"> }> = [];\n const listeners = new Set<() => void>();\n const emit = () => {\n version += 1;\n for (const listener of [...listeners]) listener();\n };\n const contributions = (): LiveContribution[] =>\n parts.map((p) => {\n const got = p.read();\n return Array.isArray(got) ? { owner: p.owner, sections: got } : { owner: p.owner, ...got };\n });\n const read = (): LiveCapture | null => {\n const top = pages[pages.length - 1];\n return top ? mergeLiveCapture(top.read(), contributions()) : null;\n };\n return {\n publish(get) {\n const id = ++nextId;\n pages = [...pages, { id, read: get }];\n emit();\n return () => {\n pages = pages.filter((p) => p.id !== id);\n emit();\n };\n },\n contribute(owner, get) {\n const id = ++nextId;\n parts = [...parts, { id, owner, read: get }];\n emit();\n return () => {\n parts = parts.filter((p) => p.id !== id);\n emit();\n };\n },\n touch: emit,\n has: () => pages.length > 0,\n read,\n outline() {\n const top = pages[pages.length - 1];\n if (!top) return null;\n const base = top.read();\n const sections = [...base.sections, ...contributions().flatMap((c) => c.sections)];\n return {\n surfaceName: base.surfaceName ?? null,\n kind: base.kind,\n title: base.title,\n loadable: sections.filter((s) => typeof s.load === \"function\").map((s) => ({ id: s.id, title: s.title })),\n };\n },\n readFor(surfaceName) {\n const capture = read();\n return capture && capture.surfaceName === surfaceName ? capture : null;\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n version: () => version,\n };\n}\n\n/** THE live-values store of this JS realm: every host page publishes here, every reader reads here. */\nexport const liveValues: LiveValuesStore = createLiveValues();\n","/**\n * `createSurfacePort` — the one SurfacePort runtime (Applets CONTRACTS §6 + Amendment 2.1).\n *\n * A parent surface offers every Action and value it has; a user's or organization's surface\n * extends it. This is the runtime a host binds once and hands to a frame:\n *\n * mount reads the chain from the DATABASE (`readSurfaceChain`); the frame's `parent`\n * argument names the same thing and is not trusted over it\n * get/setValue the surface's named values, cloned both ways; `setValue` emits `value:<name>`\n * listActions never throws — a refusal goes to `ports.diagnostics` and answers `[]`\n * runAction found by name in the mounted chain (or a fresh read), run through\n * `runSurfaceAction` (the one runner); an Action that `updatesValue` sets it\n * completeAction settles a pending page-Action run by its runId\n *\n * Page Actions: with `opts.pageActions` the host routes them (e.g. to the frame that declared the\n * surface) and may park the run with `awaitPageAction(runId)`. Without it the port routes them\n * itself: it emits `\"actions\"` `{ action, input, runId, by }` and waits for `completeAction`.\n * `dispose()` settles every run this port parked with `host_disposed`.\n *\n * The package never imports the host or supabase: the client is structural (`./client.ts`), and\n * every capability arrives as a port. Nothing here picks an organization.\n */\nimport type { PageActionPort } from \"../ports\";\nimport type { ActionCaller, ActionContext, ActionInfo, ActionResult, SurfacePort } from \"../actions/applet-types\";\nimport { runSurfaceAction, type SurfaceActionPorts } from \"../actions/surface-run\";\nimport { readSurfaceChain } from \"./chain\";\nimport { liveValueOf, type LiveValuesStore } from \"./live\";\n\n/** The stream a self-routed page Action travels on (CONTRACTS Amendment 2.1). */\nexport const PAGE_ACTION_STREAM = \"actions\";\n/** The stream a surface value travels on. */\nexport const valueStream = (name: string): string => `value:${name}`;\n\n/** What travels on `\"actions\"`; the frame answers with `surface.completeAction(runId, result)`. */\nexport interface PageActionEvent {\n action: string;\n input: unknown;\n runId: string;\n by?: ActionCaller;\n}\n\n/** The runner's ports the host binds; page Actions are routed by `pageActions` / the port itself. */\nexport type SurfacePortRunPorts = Omit<SurfaceActionPorts, \"pageActions\">;\n\n/** One settle function per parked page-Action run. */\nexport type PendingPageActions = Map<string, (result: ActionResult<unknown>) => void>;\n\nexport interface CreateSurfacePortOptions {\n /** A supabase-js v2 client carrying the VIEWER's session. Typed `object` on purpose (see ./client.ts). */\n client: object;\n /** ALL of the viewer's memberships, for organization extensions. Absent = extensions are dropped. */\n organizationIds?: () => Promise<readonly string[]>;\n /** The viewer's user id, stamped on every run's context. */\n viewerId?: () => Promise<string | null>;\n /** The runner's capabilities. `diagnostics` is required; each absent port = that capability is absent. */\n ports: SurfacePortRunPorts;\n /** The host's own page-Action routing. Absent = the port emits `\"actions\"` and waits for `completeAction`. */\n pageActions?: PageActionPort;\n /**\n * The host's event hub: `value:<name>` on `setValue`, and `\"actions\"` for self-routed page Actions.\n * Return `true` when someone is subscribed to the stream and `false` when nobody is. A self-routed\n * page Action waits for `completeAction` ONLY when `emit` answered `true`; anything else is refused\n * `action_unhandled`, so a page Action can never wait for an answer that cannot come.\n */\n emit(stream: string, payload: unknown): boolean;\n /**\n * The page's live values (ALC-18): `getValue(name)` on a value nobody set reads the mounted\n * surface's live capture (`liveValueOf`) — only while a page publishing THAT surface is mounted.\n * Usually `liveValues` from `@ai-matrx/alchemy/surface`.\n */\n live?: LiveValuesStore;\n /** Values seeded at mount; a value already set is never overwritten. */\n seedValues?: () => Promise<Record<string, unknown>>;\n /** The surface to read when nothing is mounted yet (e.g. the Applet's own `applets/<id>`). */\n surfaceName?: () => Promise<string>;\n /** Most ancestors a surface may have. */\n maxDepth?: number;\n /** Ids for mounts (`\"mount\"`) and runs (`\"act\"`). */\n mintId?: (prefix: string) => string;\n /**\n * Share ONE map across the ports of one host tree, so a frame answering on its own host settles a\n * run another host routed to it. Absent = this port's own map.\n */\n pending?: PendingPageActions;\n}\n\nexport interface SurfacePortHandle extends SurfacePort {\n /** Park a page-Action run until `completeAction(runId, …)` (or `dispose()`) settles it. */\n awaitPageAction(runId: string): Promise<ActionResult<unknown>>;\n /** Settle every run this port parked with `host_disposed`, and forget the mount and values. */\n dispose(): void;\n}\n\nfunction clone<T>(value: T): T {\n if (value === undefined) return value;\n const sc = (globalThis as { structuredClone?: <V>(v: V) => V }).structuredClone;\n return sc ? sc(value) : (JSON.parse(JSON.stringify(value)) as T);\n}\n\nfunction errorOf(err: unknown, code = \"surface_failed\"): { ok: false; error: { code: string; message: string; retryable: boolean } } {\n return { ok: false, error: { code, message: err instanceof Error && err.message ? err.message : String(err), retryable: false } };\n}\n\nlet sequence = 0;\nfunction defaultMint(prefix: string): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n return c?.randomUUID ? `${prefix}-${c.randomUUID()}` : `${prefix}-${Date.now().toString(36)}-${(sequence++).toString(36)}`;\n}\n\nexport function createSurfacePort(opts: CreateSurfacePortOptions): SurfacePortHandle {\n const mint = opts.mintId ?? defaultMint;\n const pending: PendingPageActions = opts.pending ?? new Map();\n const parked = new Set<string>();\n const values = new Map<string, unknown>();\n let mounted: { mountId: string; name: string; chain: ActionInfo[] } | null = null;\n let disposed = false;\n\n const report = (error: unknown, stage: string, detail: Record<string, string> = {}) => {\n try {\n opts.ports.diagnostics.capture(error, { area: \"actions\", detail: { stage: `surface.${stage}`, ...detail } });\n } catch {\n // A broken diagnostics port never turns a refusal into a throw.\n }\n };\n\n const memberships = async (): Promise<readonly string[] | undefined> => {\n if (!opts.organizationIds) return undefined;\n try {\n return await opts.organizationIds();\n } catch (err) {\n // Fail closed: without memberships, organization extensions are dropped — and said so.\n report(err, \"organizationIds\");\n return undefined;\n }\n };\n\n const read = async (name: string): Promise<ActionResult<ActionInfo[]>> => {\n const organizationIds = await memberships();\n return readSurfaceChain(opts.client, name, {\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n ...(organizationIds ? { organizationIds } : {}),\n });\n };\n\n /** The chain as it stands: the mount's, re-read when `fresh`; else the default surface's. */\n const currentChain = async (fresh: boolean): Promise<ActionResult<ActionInfo[]>> => {\n if (mounted && !fresh) return { ok: true, data: mounted.chain };\n const name = mounted?.name ?? (opts.surfaceName ? await opts.surfaceName() : null);\n if (!name) return { ok: false, error: { code: \"not_mounted\", message: \"No surface is mounted here yet.\", retryable: false } };\n const chain = await read(name);\n if (chain.ok && mounted?.name === name) mounted.chain = chain.data;\n return chain;\n };\n\n const awaitPageAction = (runId: string): Promise<ActionResult<unknown>> => {\n if (disposed) return Promise.resolve({ ok: false, error: { code: \"host_disposed\", message: \"This page has closed.\", retryable: false } });\n return new Promise((resolve) => {\n parked.add(runId);\n pending.set(runId, resolve);\n });\n };\n\n const selfRouted: PageActionPort = {\n dispatch(name: string, input: unknown, context: ActionContext): Promise<ActionResult<unknown>> {\n const waiting = awaitPageAction(context.runId);\n const event: PageActionEvent = { action: name, input, runId: context.runId, by: context.by };\n const forget = () => {\n pending.delete(context.runId);\n parked.delete(context.runId);\n };\n if (disposed) {\n forget();\n return Promise.resolve({ ok: false, error: { code: \"host_disposed\", message: \"This page closed, so the action did not run.\", retryable: false } });\n }\n let heard: boolean;\n try {\n heard = opts.emit(PAGE_ACTION_STREAM, event);\n } catch (err) {\n forget();\n throw err; // the runner captures it and answers run_failed\n }\n if (heard !== true) {\n forget();\n return Promise.resolve({ ok: false, error: { code: \"action_unhandled\", message: `No page is open to run \"${name}\".`, retryable: false } });\n }\n return waiting;\n },\n };\n\n const port: SurfacePortHandle = {\n async mount(name) {\n try {\n const chain = await read(name);\n if (!chain.ok) return chain;\n if (opts.seedValues) {\n try {\n const seeds = await opts.seedValues();\n for (const [key, v] of Object.entries(seeds)) if (!values.has(key)) values.set(key, clone(v));\n } catch (err) {\n report(err, \"seedValues\", { surface: name });\n }\n }\n mounted = { mountId: mint(\"mount\"), name, chain: chain.data };\n return { ok: true, data: { mountId: mounted.mountId } };\n } catch (err) {\n return errorOf(err);\n }\n },\n async unmount(mountId) {\n if (mounted?.mountId === mountId) mounted = null;\n },\n async getValue(name) {\n if (values.has(name) || !opts.live || !mounted) return clone(values.get(name));\n try {\n const capture = opts.live.readFor(mounted.name);\n return capture ? clone(liveValueOf(capture, name)) : undefined;\n } catch (err) {\n report(err, \"live\", { name });\n return undefined;\n }\n },\n async setValue(name, v) {\n let copy: unknown;\n try {\n copy = clone(v);\n } catch (err) {\n // A value that cannot be copied (a function, a live handle) is not stored, and never turns an\n // Action that already ran into a failure — it is reported by name instead.\n report(err, \"setValue\", { name });\n return;\n }\n values.set(name, copy);\n try {\n opts.emit(valueStream(name), clone(v));\n } catch (err) {\n report(err, \"emit\", { stream: valueStream(name) });\n }\n },\n async listActions() {\n try {\n const chain = await currentChain(false);\n if (!chain.ok) {\n report(chain.error, \"listActions\");\n return [];\n }\n return clone(chain.data);\n } catch (err) {\n report(err, \"listActions\");\n return [];\n }\n },\n async runAction(name, input, by) {\n let info: ActionInfo | undefined;\n try {\n const known = await currentChain(false);\n info = known.ok ? known.data.find((a) => a.name === name) : undefined;\n if (!info) {\n // Not in the mounted chain: the database may have gained it since the mount.\n const fresh = await currentChain(true);\n if (!fresh.ok) return fresh;\n info = fresh.data.find((a) => a.name === name);\n }\n } catch (err) {\n return errorOf(err);\n }\n if (!info) return { ok: false, error: { code: \"action_not_found\", message: `This page has no action named \"${name}\".`, retryable: false } };\n let viewerId: string | null = null;\n try {\n viewerId = opts.viewerId ? await opts.viewerId() : null;\n } catch (err) {\n report(err, \"viewerId\");\n }\n const ports: SurfaceActionPorts = { ...opts.ports, pageActions: opts.pageActions ?? selfRouted };\n const result = await runSurfaceAction(info, input, by, ports, { runId: mint(\"act\"), viewerId });\n if (result.ok && info.updatesValue) await port.setValue(info.updatesValue, result.data);\n return result;\n },\n async completeAction(runId, result) {\n const resolve = pending.get(runId);\n if (!resolve) {\n // A late, duplicate or misrouted answer leaves a trace instead of vanishing.\n report(new Error(`completeAction for run \"${runId}\", which is not waiting (already answered, never routed here, or the page closed).`), \"completeAction\", { runId });\n return;\n }\n pending.delete(runId);\n parked.delete(runId);\n resolve?.(result);\n },\n awaitPageAction,\n dispose() {\n disposed = true;\n for (const runId of parked) {\n const resolve = pending.get(runId);\n pending.delete(runId);\n resolve?.({ ok: false, error: { code: \"host_disposed\", message: \"This page closed before the action finished.\", retryable: false } });\n }\n parked.clear();\n mounted = null;\n values.clear();\n },\n };\n return port;\n}\n","/**\n * ITEM SOURCES — the one path from \"the person pointed at this\" to a declared item (ALC-18, D4).\n *\n * A mounted container (a canonical table, a message list) registers ONE source under its own id.\n * When a menu opens on an anchor inside it, the host asks `itemSources.resolve(containerId, target)`\n * and gets back the declared item — `itemType`, `identity`, `level`, `readOnly`, `readValues` — plus\n * the opaque `host` data the container's owner attached (the menu rows it builds for that item). The\n * package never reads `host`; it never crosses into a model.\n *\n * A container that answers an item type no surface declares is a defect the host's guard names;\n * the canonical table answers `TABLE_ROW_ITEM_TYPE` (`@ai-matrx/alchemy/declare`), which every\n * surface carries as a baseline.\n */\nimport type { InternalResolvedItem } from \"../declare/host\";\n\n/** What was pointed at inside a container, in the container's own words. */\nexport interface ItemTarget {\n containerId: string;\n /** The level aimed at (a table: selection | cell | column | row | table). */\n level: string;\n /** The item's id within the container (a table's row id). */\n itemId?: string;\n /** A sub-part of the item (a table's column id). */\n partId?: string;\n}\n\n/** A resolved item, plus the container owner's opaque data for it. */\nexport interface ItemHit<H = unknown> {\n item: InternalResolvedItem;\n host?: H;\n}\n\nexport type ItemSource<H = unknown> = (target: ItemTarget) => ItemHit<H> | null;\n\nexport interface ItemSourceRegistry {\n /** One source per mounted container. A re-register replaces; the returned removal removes only its own. */\n register<H>(containerId: string, source: ItemSource<H>): () => void;\n /** The item at the target, or null when no container answers it. A throwing source answers null. */\n resolve<H = unknown>(target: ItemTarget): ItemHit<H> | null;\n has(containerId: string): boolean;\n}\n\nexport function createItemSources(onError?: (error: unknown, target: ItemTarget) => void): ItemSourceRegistry {\n const sources = new Map<string, ItemSource>();\n return {\n register(containerId, source) {\n sources.set(containerId, source as ItemSource);\n return () => {\n if (sources.get(containerId) === source) sources.delete(containerId);\n };\n },\n resolve<H>(target: ItemTarget): ItemHit<H> | null {\n const source = sources.get(target.containerId);\n if (!source) return null;\n try {\n return (source(target) as ItemHit<H> | null) ?? null;\n } catch (error) {\n onError?.(error, target);\n return null;\n }\n },\n has: (containerId) => sources.has(containerId),\n };\n}\n\n/** THE item-source registry of this JS realm. */\nexport const itemSources: ItemSourceRegistry = createItemSources((error, target) => {\n // Loud, never silent: a source that throws leaves the menu without its item and says why.\n console.error(`[alchemy items] the source for \"${target.containerId}\" threw resolving ${target.level}`, error);\n});\n"],"mappings":"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","names":["fail"]}