@fabrika/builder 0.4.2 → 0.4.4
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.
|
@@ -7,7 +7,7 @@ provides: [authentication, authorization, proxy-enforcement]
|
|
|
7
7
|
requires: [zerops-platform]
|
|
8
8
|
recommends: []
|
|
9
9
|
conflicts: [propustka, cloudflare-access, auth-password-kv]
|
|
10
|
-
npm: ["@fabrika/app@^0.
|
|
10
|
+
npm: ["@fabrika/app@^0.4.4", "@fabrika/db@^0.4.4", "zod@^3.25.76"]
|
|
11
11
|
status: wip
|
|
12
12
|
sources:
|
|
13
13
|
- where: "packages/app/skill/SKILL.md in fabrika-platform (the `fabrika-app` skill)"
|
|
@@ -7,7 +7,7 @@ provides: [platform, private-services, managed-deploy]
|
|
|
7
7
|
requires: [bun, postgres]
|
|
8
8
|
recommends: []
|
|
9
9
|
conflicts: [cloudflare]
|
|
10
|
-
npm: ["@fabrika/provider-zerops@^0.
|
|
10
|
+
npm: ["@fabrika/provider-zerops@^0.4.4", "@fabrika/app@^0.4.4", "@fabrika/cli@^0.4.4"]
|
|
11
11
|
status: wip
|
|
12
12
|
sources:
|
|
13
13
|
- where: "examples/zerops-app/fabrika.config.ts + zerops.yaml in fabrika-platform"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabrika/builder",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Local-first guided application design and agent-assisted implementation.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"zod": "^3.25.76",
|
|
50
|
-
"@fabrika/annotations": "^0.4.
|
|
51
|
-
"@fabrika/app": "^0.4.
|
|
52
|
-
"@fabrika/auth-core": "^0.4.
|
|
53
|
-
"@fabrika/canvas-kernel": "^0.4.
|
|
54
|
-
"@fabrika/control-contract": "^0.4.
|
|
55
|
-
"@fabrika/daemon-kit": "^0.4.
|
|
56
|
-
"@fabrika/provider-zerops": "^0.4.
|
|
50
|
+
"@fabrika/annotations": "^0.4.4",
|
|
51
|
+
"@fabrika/app": "^0.4.4",
|
|
52
|
+
"@fabrika/auth-core": "^0.4.4",
|
|
53
|
+
"@fabrika/canvas-kernel": "^0.4.4",
|
|
54
|
+
"@fabrika/control-contract": "^0.4.4",
|
|
55
|
+
"@fabrika/daemon-kit": "^0.4.4",
|
|
56
|
+
"@fabrika/provider-zerops": "^0.4.4",
|
|
57
57
|
"preact": "^10.25.0"
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -66,7 +66,7 @@ ${this.parser.parse($)}</blockquote>
|
|
|
66
66
|
${$}</tr>
|
|
67
67
|
`}tablecell($){let f=this.parser.parseInline($.tokens),w=$.header?"th":"td";return($.align?`<${w} align="${$.align}">`:`<${w}>`)+f+`</${w}>
|
|
68
68
|
`}strong({tokens:$}){return`<strong>${this.parser.parseInline($)}</strong>`}em({tokens:$}){return`<em>${this.parser.parseInline($)}</em>`}codespan({text:$}){return`<code>${u0($,!0)}</code>`}br($){return"<br>"}del({tokens:$}){return`<del>${this.parser.parseInline($)}</del>`}link({href:$,title:f,tokens:w}){let X=this.parser.parseInline(w),J=Kf($);if(J===null)return X;$=J;let W='<a href="'+$+'"';return f&&(W+=' title="'+u0(f)+'"'),W+=">"+X+"</a>",W}image({href:$,title:f,text:w,tokens:X}){X&&(w=this.parser.parseInline(X,this.parser.textRenderer));let J=Kf($);if(J===null)return u0(w);$=J;let W=`<img src="${$}" alt="${u0(w)}"`;return f&&(W+=` title="${u0(f)}"`),W+=">",W}text($){return"tokens"in $&&$.tokens?this.parser.parseInline($.tokens):("escaped"in $)&&$.escaped?$.text:u0($.text)}},N5=class{strong({text:$}){return $}em({text:$}){return $}codespan({text:$}){return $}del({text:$}){return $}html({text:$}){return $}text({text:$}){return $}link({text:$}){return""+$}image({text:$}){return""+$}br(){return""}checkbox({raw:$}){return $}},I0=class ${options;renderer;textRenderer;constructor(f){this.options=f||z1,this.options.renderer=this.options.renderer||new X$,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new N5}static parse(f,w){return new $(w).parse(f)}static parseInline(f,w){return new $(w).parseInline(f)}parse(f){this.renderer.parser=this;let w="";for(let X=0;X<f.length;X++){let J=f[X];if(this.options.extensions?.renderers?.[J.type]){let q=J,Y=this.options.extensions.renderers[q.type].call({parser:this},q);if(Y!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(q.type)){w+=Y||"";continue}}let W=J;switch(W.type){case"space":{w+=this.renderer.space(W);break}case"hr":{w+=this.renderer.hr(W);break}case"heading":{w+=this.renderer.heading(W);break}case"code":{w+=this.renderer.code(W);break}case"table":{w+=this.renderer.table(W);break}case"blockquote":{w+=this.renderer.blockquote(W);break}case"list":{w+=this.renderer.list(W);break}case"checkbox":{w+=this.renderer.checkbox(W);break}case"html":{w+=this.renderer.html(W);break}case"def":{w+=this.renderer.def(W);break}case"paragraph":{w+=this.renderer.paragraph(W);break}case"text":{w+=this.renderer.text(W);break}default:{let q='Token with "'+W.type+'" type was not found.';if(this.options.silent)return console.error(q),"";throw Error(q)}}}return w}parseInline(f,w=this.renderer){this.renderer.parser=this;let X="";for(let J=0;J<f.length;J++){let W=f[J];if(this.options.extensions?.renderers?.[W.type]){let Y=this.options.extensions.renderers[W.type].call({parser:this},W);if(Y!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(W.type)){X+=Y||"";continue}}let q=W;switch(q.type){case"escape":{X+=w.text(q);break}case"html":{X+=w.html(q);break}case"link":{X+=w.link(q);break}case"image":{X+=w.image(q);break}case"checkbox":{X+=w.checkbox(q);break}case"strong":{X+=w.strong(q);break}case"em":{X+=w.em(q);break}case"codespan":{X+=w.codespan(q);break}case"br":{X+=w.br(q);break}case"del":{X+=w.del(q);break}case"text":{X+=w.text(q);break}default:{let Y='Token with "'+q.type+'" type was not found.';if(this.options.silent)return console.error(Y),"";throw Error(Y)}}}return X}},A2=class{options;block;constructor($){this.options=$||z1}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess($){return $}postprocess($){return $}processAllTokens($){return $}emStrongMask($){return $}provideLexer($=this.block){return $?j0.lex:j0.lexInline}provideParser($=this.block){return $?I0.parse:I0.parseInline}},P6=class{defaults=J5();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=I0;Renderer=X$;TextRenderer=N5;Lexer=j0;Tokenizer=J$;Hooks=A2;constructor(...$){this.use(...$)}walkTokens($,f){let w=[];for(let X of $)switch(w=w.concat(f.call(this,X)),X.type){case"table":{let J=X;for(let W of J.header)w=w.concat(this.walkTokens(W.tokens,f));for(let W of J.rows)for(let q of W)w=w.concat(this.walkTokens(q.tokens,f));break}case"list":{let J=X;w=w.concat(this.walkTokens(J.items,f));break}default:{let J=X;this.defaults.extensions?.childTokens?.[J.type]?this.defaults.extensions.childTokens[J.type].forEach((W)=>{let q=J[W].flat(1/0);w=w.concat(this.walkTokens(q,f))}):J.tokens&&(w=w.concat(this.walkTokens(J.tokens,f)))}}return w}use(...$){let f=this.defaults.extensions||{renderers:{},childTokens:{}};return $.forEach((w)=>{let X={...w};if(X.async=this.defaults.async||X.async||!1,w.extensions&&(w.extensions.forEach((J)=>{if(!J.name)throw Error("extension name required");if("renderer"in J){let W=f.renderers[J.name];W?f.renderers[J.name]=function(...q){let Y=J.renderer.apply(this,q);return Y===!1&&(Y=W.apply(this,q)),Y}:f.renderers[J.name]=J.renderer}if("tokenizer"in J){if(!J.level||J.level!=="block"&&J.level!=="inline")throw Error("extension level must be 'block' or 'inline'");let W=f[J.level];W?W.unshift(J.tokenizer):f[J.level]=[J.tokenizer],J.start&&(J.level==="block"?f.startBlock?f.startBlock.push(J.start):f.startBlock=[J.start]:J.level==="inline"&&(f.startInline?f.startInline.push(J.start):f.startInline=[J.start]))}"childTokens"in J&&J.childTokens&&(f.childTokens[J.name]=J.childTokens)}),X.extensions=f),w.renderer){let J=this.defaults.renderer||new X$(this.defaults);for(let W in w.renderer){if(!(W in J))throw Error(`renderer '${W}' does not exist`);if(["options","parser"].includes(W))continue;let q=W,Y=w.renderer[q],Q=J[q];J[q]=(..._)=>{let N=Y.apply(J,_);return N===!1&&(N=Q.apply(J,_)),N||""}}X.renderer=J}if(w.tokenizer){let J=this.defaults.tokenizer||new J$(this.defaults);for(let W in w.tokenizer){if(!(W in J))throw Error(`tokenizer '${W}' does not exist`);if(["options","rules","lexer"].includes(W))continue;let q=W,Y=w.tokenizer[q],Q=J[q];J[q]=(..._)=>{let N=Y.apply(J,_);return N===!1&&(N=Q.apply(J,_)),N}}X.tokenizer=J}if(w.hooks){let J=this.defaults.hooks||new A2;for(let W in w.hooks){if(!(W in J))throw Error(`hook '${W}' does not exist`);if(["options","block"].includes(W))continue;let q=W,Y=w.hooks[q],Q=J[q];A2.passThroughHooks.has(W)?J[q]=(_)=>{if(this.defaults.async&&A2.passThroughHooksRespectAsync.has(W))return(async()=>{let U=await Y.call(J,_);return Q.call(J,U)})();let N=Y.call(J,_);return Q.call(J,N)}:J[q]=(..._)=>{if(this.defaults.async)return(async()=>{let U=await Y.apply(J,_);return U===!1&&(U=await Q.apply(J,_)),U})();let N=Y.apply(J,_);return N===!1&&(N=Q.apply(J,_)),N}}X.hooks=J}if(w.walkTokens){let J=this.defaults.walkTokens,W=w.walkTokens;X.walkTokens=function(q){let Y=[];return Y.push(W.call(this,q)),J&&(Y=Y.concat(J.call(this,q))),Y}}this.defaults={...this.defaults,...X}}),this}setOptions($){return this.defaults={...this.defaults,...$},this}lexer($,f){return j0.lex($,f??this.defaults)}parser($,f){return I0.parse($,f??this.defaults)}parseMarkdown($){return(f,w)=>{let X={...w},J={...this.defaults,...X},W=this.onError(!!J.silent,!!J.async);if(this.defaults.async===!0&&X.async===!1)return W(Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof f>"u"||f===null)return W(Error("marked(): input parameter is undefined or null"));if(typeof f!="string")return W(Error("marked(): input parameter is of type "+Object.prototype.toString.call(f)+", string expected"));if(J.hooks&&(J.hooks.options=J,J.hooks.block=$),J.async)return(async()=>{let q=J.hooks?await J.hooks.preprocess(f):f,Y=await(J.hooks?await J.hooks.provideLexer($):$?j0.lex:j0.lexInline)(q,J),Q=J.hooks?await J.hooks.processAllTokens(Y):Y;J.walkTokens&&await Promise.all(this.walkTokens(Q,J.walkTokens));let _=await(J.hooks?await J.hooks.provideParser($):$?I0.parse:I0.parseInline)(Q,J);return J.hooks?await J.hooks.postprocess(_):_})().catch(W);try{J.hooks&&(f=J.hooks.preprocess(f));let q=(J.hooks?J.hooks.provideLexer($):$?j0.lex:j0.lexInline)(f,J);J.hooks&&(q=J.hooks.processAllTokens(q)),J.walkTokens&&this.walkTokens(q,J.walkTokens);let Y=(J.hooks?J.hooks.provideParser($):$?I0.parse:I0.parseInline)(q,J);return J.hooks&&(Y=J.hooks.postprocess(Y)),Y}catch(q){return W(q)}}}onError($,f){return(w)=>{if(w.message+=`
|
|
69
|
-
Please report this to https://github.com/markedjs/marked.`,$){let X="<p>An error occurred:</p><pre>"+u0(w.message+"",!0)+"</pre>";return f?Promise.resolve(X):X}if(f)return Promise.reject(w);throw w}}},S1=new P6;function t($,f){return S1.parse($,f)}t.options=t.setOptions=function($){return S1.setOptions($),t.defaults=S1.defaults,zf(t.defaults),t};t.getDefaults=J5;t.defaults=z1;t.use=function(...$){return S1.use(...$),t.defaults=S1.defaults,zf(t.defaults),t};t.walkTokens=function($,f){return S1.walkTokens($,f)};t.parseInline=S1.parseInline;t.Parser=I0;t.parser=I0.parse;t.Renderer=X$;t.TextRenderer=N5;t.Lexer=j0;t.lexer=j0.lex;t.Tokenizer=J$;t.Hooks=A2;t.parse=t;var{options:i7,setOptions:d7,use:o7,walkTokens:n7,parseInline:t7}=t;var a7=I0.parse,s7=j0.lex;import{useEffect as gf,useMemo as H5,useRef as v6,useState as P2}from"react";import{jsxDEV as b0}from"react/jsx-dev-runtime";function b5({open:$,onClose:f,onSubmit:w,includedRemoteIds:X,onToggleRemoteId:J}){let{annotations:W,generalNote:q,submittableResponses:Y,feedbackEntries:Q}=O1(),[_,N]=P2(""),[U,B]=P2(!1),[H,b]=P2(!1),[z,L]=P2(null),R=v6(null),[F,M]=P2(!1),T=H5(()=>W.filter((E)=>E.source==="remote"),[W]);if($&&!F)B(!1),b(!1),L(null);if(!$&&F)B(!1),b(!1),L(null);if($!==F)M($);let h=H5(()=>i1(W,q,Y,Q,X),[W,q,Y,Q,X]),Z=U?_:h;if(gf(()=>{if($&&H&&R.current)R.current.focus()},[$,H]),gf(()=>{if(!$)return;let E=(u)=>{if(u.key==="Escape")f()};return window.addEventListener("keydown",E),()=>window.removeEventListener("keydown",E)},[$,f]),!$)return null;let j=Z.trim().length>0;return b0("div",{className:"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm flex items-center justify-center p-8",onClick:f,children:b0("div",{className:"bg-bg-surface border border-border-medium rounded-xl shadow-lg w-full max-w-2xl flex flex-col",style:{height:"80vh"},onClick:(E)=>E.stopPropagation(),children:[b0("div",{className:"flex items-center justify-between px-5 py-3 border-b border-border-subtle flex-shrink-0",children:[b0("div",{className:"flex items-center gap-3",children:[b0("span",{className:"text-[13px] font-medium text-text-primary font-body",children:"Response preview"},void 0,!1,void 0,this),U&&b0("button",{onClick:()=>{B(!1),b(!1)},className:"text-[11px] text-text-tertiary hover:text-text-secondary font-body",children:"Reset"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b0("div",{className:"flex items-center gap-2",children:[b0("div",{className:"flex items-center bg-bg-base rounded-md p-0.5",children:[b0("button",{onClick:()=>b(!1),className:`px-2.5 py-1 rounded text-[11px] font-body font-medium transition-colors ${!H?"bg-bg-elevated text-text-primary shadow-sm":"text-text-tertiary hover:text-text-secondary"}`,children:"Preview"},void 0,!1,void 0,this),b0("button",{onClick:()=>b(!0),className:`px-2.5 py-1 rounded text-[11px] font-body font-medium transition-colors ${H?"bg-bg-elevated text-text-primary shadow-sm":"text-text-tertiary hover:text-text-secondary"}`,children:"Edit"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b0("button",{onClick:f,className:"text-text-tertiary hover:text-text-secondary w-7 h-7 flex items-center justify-center rounded-md hover:bg-border-subtle transition-colors",children:"✕"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),H?b0("textarea",{ref:R,value:Z,onChange:(E)=>{N(E.currentTarget.value),B(!0)},className:"flex-1 w-full bg-bg-base p-5 text-[13px] font-mono text-text-code resize-none focus:outline-none leading-relaxed placeholder:text-text-disabled",placeholder:"Your feedback will appear here..."},void 0,!1,void 0,this):b0("div",{className:"flex-1 overflow-y-auto p-5",children:b0(Q$,{text:Z},void 0,!1,void 0,this)},void 0,!1,void 0,this),T.length>0&&b0("div",{className:"px-5 py-2 border-t border-border-subtle flex-shrink-0",children:b0("span",{className:"text-[12px] text-text-secondary font-body",children:["Reviewer feedback: ",X.size,"/",T.length," included"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),z&&b0("div",{className:"px-5 py-2 text-[12px] text-accent-red font-body border-t border-border-subtle flex-shrink-0 flex items-center justify-between gap-2",children:[b0("span",{children:z},void 0,!1,void 0,this),b0("button",{onClick:()=>{L(null),w(Z)},className:"text-[11px] text-text-tertiary hover:text-text-secondary font-body whitespace-nowrap underline",children:"Submit anyway"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b0("div",{className:"flex justify-end gap-2 px-5 py-3 border-t border-border-subtle flex-shrink-0",children:[b0("button",{onClick:f,className:"px-4 py-2 rounded-lg text-[13px] font-body text-text-tertiary hover:text-text-secondary transition-colors",children:"Cancel"},void 0,!1,void 0,this),b0("button",{onClick:()=>{let E=d1(Y,Q);if(E.length>0){L(`Please answer: ${E.join(", ")}`);return}L(null),w(Z)},disabled:!j,className:`px-6 py-2 rounded-lg font-body text-[13px] font-medium transition-all ${j?"bg-btn-primary text-btn-primary-text hover:opacity-90":"bg-bg-input text-text-disabled cursor-default"}`,children:"Submit feedback"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}var m6=/!\[([^\]]*)\]\((\/tmp\/agent-canvas\/uploads\/([^)]+))\)/g;function k6($){return $.replace(m6,(f,w,X,J)=>``)}function Q$({text:$}){let f=H5(()=>t.parse(k6($),{async:!1}),[$]);return b0("div",{className:"prose-canvas font-body text-body text-text-primary leading-relaxed",dangerouslySetInnerHTML:{__html:f}},void 0,!1,void 0,this)}import{jsxDEV as y,Fragment as Y$}from"react/jsx-dev-runtime";function G$({onSubmit:$,collapseButton:f}){let{isReadOnly:w,selectedRevision:X,currentRevision:J,revisions:W,agentWatching:q}=B5(s1),Y=B5(C6),Q=W.find((B)=>B.revision===X),_=w&&X===J,N=!!Q?.feedbackConsumed,U=Q?.label||`Round ${X}`;if(w)return y(g6,{sessionId:Y,revision:X,label:U,waitingForUpdate:_,feedbackConsumed:N,agentWatching:q,collapseButton:f},void 0,!1,void 0,this);return y(j6,{onSubmit:$,agentWatching:q,collapseButton:f},void 0,!1,void 0,this)}function T6({sessionId:$,revision:f,label:w,waitingForUpdate:X,feedbackConsumed:J,agentWatching:W,collapseButton:q}){let Q=n0().isShared;return y("div",{className:"flex flex-col h-full",children:[y("div",{className:"px-4 py-3 flex items-center justify-between flex-shrink-0",children:[y("span",{className:"text-[11px] font-medium uppercase tracking-widest text-text-tertiary font-body",children:X?"Feedback sent":`Feedback — ${w}`},void 0,!1,void 0,this),q]},void 0,!0,void 0,this),X&&!Q&&y(If,{feedbackConsumed:J,agentWatching:W},void 0,!1,void 0,this),y(Vf,{sessionId:$,revision:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function If({feedbackConsumed:$,agentWatching:f}){if($)return y("div",{className:"mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-green-muted flex items-center gap-2 flex-shrink-0",children:[y("span",{className:"w-2 h-2 rounded-full bg-accent-green animate-pulse"},void 0,!1,void 0,this),y("span",{className:"text-[12px] font-body text-accent-green",children:"Feedback received — waiting for next revision..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(f)return y("div",{className:"mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-blue-muted flex items-center gap-2 flex-shrink-0",children:[y("span",{className:"w-2 h-2 rounded-full bg-accent-blue animate-pulse"},void 0,!1,void 0,this),y("span",{className:"text-[12px] font-body text-accent-blue",children:"Waiting for agent to pick up feedback..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return y("div",{className:"mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-amber-muted flex items-center gap-2 flex-shrink-0",children:[y("span",{className:"w-2 h-2 rounded-full bg-accent-amber"},void 0,!1,void 0,this),y("span",{className:"text-[12px] font-body text-accent-amber",children:"Agent disconnected — tell Claude to check feedback"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function g6({sessionId:$,revision:f,label:w,waitingForUpdate:X,feedbackConsumed:J,agentWatching:W,collapseButton:q}){let{annotations:Y,generalNote:Q}=O1(),_=Y.length>0||Q.trim().length>0,[N,U]=$2("feedback");if(!_)return y(T6,{sessionId:$,revision:f,label:w,waitingForUpdate:X,feedbackConsumed:J,agentWatching:W,collapseButton:q},void 0,!1,void 0,this);return y("div",{className:"flex flex-col h-full",children:[y("div",{className:"px-4 py-3 flex items-center justify-between flex-shrink-0",children:[y("div",{className:"flex items-center gap-1 bg-bg-input rounded-md p-0.5",children:[y("button",{onClick:()=>U("feedback"),className:`px-2.5 py-1 rounded text-[11px] font-medium font-body transition-colors ${N==="feedback"?"bg-bg-elevated text-text-primary shadow-sm":"text-text-tertiary hover:text-text-secondary"}`,children:"Feedback"},void 0,!1,void 0,this),y("button",{onClick:()=>U("annotations"),className:`px-2.5 py-1 rounded text-[11px] font-medium font-body transition-colors flex items-center gap-1.5 ${N==="annotations"?"bg-bg-elevated text-text-primary shadow-sm":"text-text-tertiary hover:text-text-secondary"}`,children:["Annotations",y("span",{className:"inline-flex items-center justify-center min-w-[16px] h-[16px] px-1 rounded-full bg-border-subtle text-[10px] font-medium",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q]},void 0,!0,void 0,this),X&&y(If,{feedbackConsumed:J,agentWatching:W},void 0,!1,void 0,this),N==="feedback"?y(Vf,{sessionId:$,revision:f},void 0,!1,void 0,this):y(Y$,{children:[y("div",{className:"flex-1 overflow-y-auto",children:y(Df,{annotations:Y,readOnly:!0},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q.trim()&&y("div",{className:"border-t border-border-subtle px-4 py-3 flex-shrink-0",children:y("div",{className:"text-[13px] font-body text-text-primary leading-relaxed",children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Vf({sessionId:$,revision:f}){let w=n0(),[X,J]=$2(null),[W,q]=$2(!0);return jf(()=>{if(q(!0),!w.fsAvailable){J(null),q(!1);return}fetch(`/api/session/${$}/revision/${f}/feedback`).then((Y)=>Y.json()).then((Y)=>{J(Nf.parse(Y).feedback||null),q(!1)}).catch(()=>{J(null),q(!1)})},[$,f]),y("div",{className:"flex-1 overflow-y-auto px-4",children:W?y("p",{className:"text-[12px] text-text-tertiary font-body py-4",children:"Loading..."},void 0,!1,void 0,this):X?y(Q$,{text:X},void 0,!1,void 0,this):y("p",{className:"text-[12px] text-text-tertiary font-body py-4",children:"No feedback was submitted for this revision."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function h6($){let f=$.filter((q)=>q.filePath===l1),w=$.filter((q)=>!q.filePath),X=$.filter((q)=>b1(q)!==void 0),J={};for(let q of X){let Y=b1(q);if(!Y)continue;let Q=J[Y];if(Q)Q.push(q);else J[Y]=[q]}let W=[f,w,X].filter((q)=>q.length>0).length>1;return{response:f,plan:w,fileGroups:J,hasMultipleGroups:W}}function hf({children:$}){return y("div",{className:"text-[10px] uppercase tracking-widest text-text-tertiary font-body px-3 mb-1 mt-1",children:$},void 0,!1,void 0,this)}function Df({annotations:$,readOnly:f,includedRemoteIds:w,onToggleRemoteId:X}){let{setActiveView:J}=B5(a1),{response:W,plan:q,fileGroups:Y,hasMultipleGroups:Q}=h6($),_=U5((B)=>{let H=b1(B);if(!H)return;J({type:"file",path:H}),setTimeout(()=>{let b=F2(B);if(b)b.scrollIntoView({behavior:"smooth",block:"center"})},150)},[J]),N=U5((B)=>$5(B,J),[J]),U={readOnly:f,onSelect:_,onReveal:N,includedRemoteIds:w,onToggleRemoteId:X};return y(Y$,{children:[W.length>0&&y(Y$,{children:[Q&&y(hf,{children:"Agent Response"},void 0,!1,void 0,this),y(L2,{annotations:W,...U},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q.length>0&&y(Y$,{children:[Q&&y(hf,{children:"Canvas"},void 0,!1,void 0,this),y(L2,{annotations:q,...U},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Object.entries(Y).map(([B,H])=>y("div",{children:[y("button",{onClick:()=>J({type:"file",path:B}),className:"flex items-center gap-1.5 text-[10px] uppercase tracking-widest text-text-tertiary hover:text-text-secondary font-body px-3 pt-3 pb-1 truncate transition-colors w-full text-left",title:B,children:[y(f5,{name:B.split("/").pop()||B,type:"file"},void 0,!1,void 0,this),y("span",{className:"truncate",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(L2,{annotations:H,...U},void 0,!1,void 0,this)]},B,!0,void 0,this))]},void 0,!0,void 0,this)}function j6({onSubmit:$,agentWatching:f,collapseButton:w}){let X=n0(),[J,W]=$2(!1),{annotations:q,generalNote:Y,submittableResponses:Q,feedbackEntries:_}=O1(),N=y6(()=>q.filter((T)=>T.source==="remote"),[q]),[U,B]=$2(()=>new Set);jf(()=>{if(N.length===0)return;B((T)=>{let h=new Set(T);for(let Z of N)h.add(Z.id);return h.size===T.size?T:h})},[N]);let H=U5((T)=>{B((h)=>{let Z=new Set(h);if(Z.has(T))Z.delete(T);else Z.add(T);return Z})},[]),b=Array.from(Q.values()).some(t2),z=_.size>0,L=q.length>0||Y.trim().length>0||b||z,[R,F]=$2(null),M=()=>{let T=i1(q,Y,Q,_,U);$(T)};return y("div",{className:"flex flex-col h-full",children:[y("div",{className:"px-4 py-3 flex items-center justify-between flex-shrink-0",children:[y("span",{className:"text-[11px] font-medium uppercase tracking-widest text-text-tertiary font-body flex items-center gap-2",children:["Annotations",q.length>0&&y("span",{className:"inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-border-subtle text-[10px] font-medium text-text-secondary",children:q.length},void 0,!1,void 0,this),!X.isShared&&y("span",{className:`w-1.5 h-1.5 rounded-full flex-shrink-0 ${f?"bg-accent-green":"bg-accent-amber"}`,title:f?"Agent connected":"Agent disconnected"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w]},void 0,!0,void 0,this),y("div",{className:"flex-1 overflow-y-auto",children:[q.length===0&&y("p",{className:"text-[12px] text-text-tertiary px-3 py-4 leading-relaxed font-body",children:"Select text in the canvas or in files to add annotations."},void 0,!1,void 0,this),y(Df,{annotations:q,includedRemoteIds:U,onToggleRemoteId:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(E$,{hasContent:L,onSubmit:()=>{let T=d1(Q,_);if(T.length>0){F(`Please answer: ${T.join(", ")}`);return}F(null),M()},onSubmitEmpty:()=>$("No feedback — looks good."),notice:R&&y("div",{className:"px-4 py-2 text-[12px] text-accent-red font-body border-t border-border-subtle flex-shrink-0 flex items-center justify-between gap-2",children:[y("span",{children:R},void 0,!1,void 0,this),y("button",{onClick:()=>{F(null),M()},className:"text-[11px] text-text-tertiary hover:text-text-secondary font-body whitespace-nowrap underline",children:"Submit anyway"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),secondaryAction:y("button",{onClick:()=>W(!0),className:"flex-1 py-2 rounded-lg font-body text-[13px] font-medium transition-all bg-border-subtle text-text-secondary hover:bg-border-medium hover:text-text-primary",children:"Preview"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(b5,{open:J,onClose:()=>W(!1),onSubmit:$,includedRemoteIds:U,onToggleRemoteId:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{useFeedback as qQ}from"#canvas/runtime";import k9 from"react";import{jsxDEV as y9}from"react/jsx-dev-runtime";t.setOptions({gfm:!0,breaks:!1});import{jsxDEV as j9}from"react/jsx-dev-runtime";import{jsxDEV as D9}from"react/jsx-dev-runtime";import{useAnnotations as p9,useResponseRegistration as r9}from"#canvas/runtime";import{useEffect as d9,useMemo as o9,useRef as n9,useState as t9}from"react";import{jsxDEV as c9}from"react/jsx-dev-runtime";import{jsxDEV as e9}from"react/jsx-dev-runtime";import{useEffect as Xq,useRef as qq}from"react";import{jsxDEV as Yq}from"react/jsx-dev-runtime";import{jsxDEV as Uq}from"react/jsx-dev-runtime";import{ActiveViewCtx as Lq,SessionContext as Oq}from"#canvas/runtime";import{useContext as Fq,useEffect as Sq,useRef as zq,useState as Aq}from"react";import{jsxDEV as mq}from"react/jsx-dev-runtime";import{SessionContext as yq}from"#canvas/runtime";import{useContext as gq,useState as hq}from"react";import{jsxDEV as Iq}from"react/jsx-dev-runtime";import{useMemo as xq}from"react";import{jsxDEV as uq}from"react/jsx-dev-runtime";t.setOptions({gfm:!0,breaks:!1});import{useAnnotations as iq,useCanvasFile as dq}from"#canvas/runtime";import{useCallback as aq,useEffect as sq,useRef as eq,useState as $W}from"react";import wW from"react-dom";import{jsxDEV as qW,Fragment as WW}from"react/jsx-dev-runtime";import{jsxDEV as _W}from"react/jsx-dev-runtime";import{jsxDEV as bW}from"react/jsx-dev-runtime";import{useState as LW}from"react";import{jsxDEV as FW}from"react/jsx-dev-runtime";import{jsxDEV as AW}from"react/jsx-dev-runtime";import{jsxDEV as mW}from"react/jsx-dev-runtime";import{useAnnotations as yW,useResponseRegistration as TW}from"#canvas/runtime";import{useRef as jW,useState as IW}from"react";import{jsxDEV as EW}from"react/jsx-dev-runtime";import{CanvasFileCtx as E6,SessionContext as Z6}from"#canvas/runtime";import _$,{useContext as Zf,useEffect as W1,useMemo as v2,useRef as x6,useState as l0}from"react";import{createPortal as c6}from"react-dom";import{createContext as D6}from"react";var L5=D6(()=>{});import{jsxDEV as X0,Fragment as r6}from"react/jsx-dev-runtime";class xf extends _$.Component{state={error:null};static getDerivedStateFromError($){return{error:$}}componentDidCatch($,f){this.props.reportError({revision:this.props.revision,filename:this.props.filename,message:$.message,...$.stack?{stack:$.stack}:{},...f.componentStack?{componentStack:f.componentStack}:{}})}render(){if(!this.state.error)return this.props.children;return X0(cf,{message:this.state.error.message},void 0,!1,void 0,this)}}function cf({message:$}){return X0("div",{className:"bg-accent-red-muted rounded-lg p-5",children:[X0("h3",{className:"font-body font-semibold text-accent-red mb-2",children:"Canvas render failed"},void 0,!1,void 0,this),X0("pre",{className:"text-code font-mono text-text-secondary whitespace-pre-wrap",children:$},void 0,!1,void 0,this),X0("p",{className:"text-meta font-body text-text-tertiary mt-3",children:"The error was sent back to the canvas author."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function N$({revision:$,filename:f}){let w=Zf(Z6),X=n0(),J=Zf(L5),[W,q]=l0(null),[Y,Q]=l0(null),[_,N]=l0(!0),U=x6(null),{annotations:B,addAnnotationWithId:H,removeAnnotation:b,updateAnnotation:z,addAnnotationImage:L,removeAnnotationImage:R,activeAnnotationId:F,setActiveAnnotationId:M,registerCanvasRendered:T}=O1(),h=v2(()=>B.filter((O)=>!O.filePath&&(!O.canvasFile||O.canvasFile===f)),[B,f]),[Z,j]=l0(null),[E,u]=l0(null),[x,e]=l0(null),[J0,W0]=l0(null),[O0,c]=l0(!1);W1(()=>{N(!0),Q(null),W0(null),X.loadCanvasModule(f,$).then((O)=>{q(()=>O.default),N(!1)}).catch((O)=>{let v=O instanceof Error?O:Error(String(O));Q(v.message),N(!1),J({revision:$,filename:f,message:v.message,...v.stack?{stack:v.stack}:{}})})},[w,$,f,J]),W1(()=>{if(W)T(f)},[W,f,T]);let $0=document.getElementById("plan-scroll-container"),{popovers:f0,isPopoverOpen:Q0}=d$({containerRef:U,restoreKey:W,restoreAnnotations:h,extractContext:(O)=>A$(O,U.current),canvasFile:f,scrollContainer:$0}),{popovers:s,isDrawing:w0,isPopoverOpen:_0}=r$({containerRef:U,restoreKey:W,canvasFile:f,scrollContainer:$0}),P=Q0||_0,g=v2(()=>{let O=new Map;for(let v of h)if(v.snippet.startsWith("["))O.set(v.snippet,v.id);return O},[h]);W1(()=>{let O=U.current;if(!O)return;let v=(k)=>{if(x||P||w0)return;let V=k.target;if(V.closest("[data-block-comment-btn]"))return;c(!1);let r=V.closest(m1);if(r&&O.contains(r)){let m0=A1(O).indexOf(r);W0(m0>=0?m0:null)}else W0(null);let Y0=V.closest(a0);if(Y0&&O.contains(Y0)){u(Y0);let B0=E0(Y0),m0=B0?g.get(B0):void 0;if(m0&&m0!==F)M(m0)}else u(null)},o=(k)=>{if(x||P)return;if(k.relatedTarget?.closest("[data-block-comment-btn]"))return;u(null),M(null)};return O.addEventListener("mousemove",v),O.addEventListener("mouseleave",o),()=>{O.removeEventListener("mousemove",v),O.removeEventListener("mouseleave",o)}},[W,x,P,w0,g,F]),W1(()=>{let O=(v)=>{let o=v.target.tagName;if(o==="INPUT"||o==="TEXTAREA"||v.target.isContentEditable)return;if(x||P)return;let k=U.current;if(!k)return;if(v.key==="ArrowDown"){v.preventDefault(),c(!0);let V=A1(k);if(V.length===0)return;W0((r)=>{if(r===null)return 0;return Math.min(r+1,V.length-1)})}else if(v.key==="ArrowUp"){v.preventDefault(),c(!0);let V=A1(k);if(V.length===0)return;W0((r)=>{if(r===null)return V.length-1;return Math.max(r-1,0)})}else if(v.key==="a"||v.key==="A"){if(J0===null||!k)return;let r=A1(k)[J0];if(!r)return;if(!r.matches(a0))return;v.preventDefault();let Y0=E0(r);if(!Y0)return;let B0=g.get(Y0);if(B0)M(B0),e({anchorEl:r,snippet:Y0,annId:B0});else e({anchorEl:r,snippet:Y0})}else if(v.key===" "||v.key==="Enter"){if(J0===null)return;let r=A1(k)[J0];if(!r)return;let Y0=r.getAttribute("data-md");if(Y0==="choice-option"||Y0==="multichoice-option")v.preventDefault(),r.dispatchEvent(new CustomEvent("kb-select",{bubbles:!0}));else if(Y0==="userinput"){v.preventDefault();let B0=r.querySelector("textarea");if(B0){B0.focus();let m0=(Q1)=>{if(Q1.key==="Escape")Q1.preventDefault(),B0.blur(),c(!0)};B0.addEventListener("keydown",m0),B0.addEventListener("blur",()=>B0.removeEventListener("keydown",m0),{once:!0})}}else if(Y0==="rangeinput"){v.preventDefault();let B0=r.querySelector("input[type='range']");if(B0){B0.focus();let m0=(Q1)=>{if(Q1.key==="Escape"||Q1.key==="ArrowUp"||Q1.key==="ArrowDown")Q1.preventDefault(),B0.blur(),c(!0)};B0.addEventListener("keydown",m0),B0.addEventListener("blur",()=>B0.removeEventListener("keydown",m0),{once:!0})}}}else if(v.key==="Escape")W0(null),c(!1),M(null)};return document.addEventListener("keydown",O),()=>document.removeEventListener("keydown",O)},[J0,x,P,g]),W1(()=>{let O=U.current;if(!O||J0===null||!O0)return;let o=A1(O)[J0];if(!o)return;o.style.outline="2px solid var(--color-accent-blue)",o.style.outlineOffset="-2px",o.style.borderRadius="8px",o.scrollIntoView({block:"nearest",behavior:"smooth"});let k=E0(o),V=k?g.get(k):void 0;if(V)M(V);return()=>{o.style.outline="",o.style.outlineOffset="",o.style.borderRadius=""}},[J0,O0,g]);let p=v2(()=>W?X0(W,{},void 0,!1,void 0,this):null,[W]);if(_)return X0("div",{className:"flex items-center justify-center h-64 text-text-tertiary font-body text-body",children:"Loading canvas..."},void 0,!1,void 0,this);if(Y)return X0(cf,{message:Y},void 0,!1,void 0,this);if(!W)return X0("div",{className:"text-text-tertiary text-center py-8 font-body text-body",children:"No canvas loaded"},void 0,!1,void 0,this);return X0(E6.Provider,{value:f,children:[X0("div",{ref:U,className:"plan-content plan-updated","data-canvas-file":f,children:X0(xf,{revision:$,filename:f,reportError:J,children:p},`${$}:${f}`,!1,void 0,this)},void 0,!1,void 0,this),Z&&X0(p6,{note:Z.note,onSave:(O)=>{z(Z.id,O),j(null)},onCancel:()=>j(null)},void 0,!1,void 0,this),f0,s,X0(u6,{containerRef:U,hoveredBlock:E,focusedBlockIndex:J0,blockPopover:x,blockAnnotationMap:g,activeAnnotationId:F,onOpen:(O,v,o)=>{if(o)M(o),e({anchorEl:O,snippet:v,annId:o});else e({anchorEl:O,snippet:v})}},void 0,!1,void 0,this),x&&!x.annId&&X0(q1,{anchorEl:x.anchorEl,scrollContainer:$0,snippet:x.snippet,truncateAt:80,onAdd:(O,v)=>{let o=d0();H(o,x.snippet,O,void 0,void 0,v,f),e(null)},onCancel:()=>e(null)},void 0,!1,void 0,this),x?.annId&&(()=>{let O=h.find((v)=>v.id===x.annId);if(!O)return null;return X0(K2,{anchorEl:x.anchorEl,scrollContainer:$0,initialNote:O.note,initialImages:O.images,onUpdate:(v,o)=>{z(x.annId,v);let k=O.images||[];for(let V of o)if(!k.includes(V))L(x.annId,V);for(let V of k)if(!o.includes(V))R(x.annId,V)},onDelete:()=>{b(x.annId),M(null),e(null)},onClose:()=>e(null)},void 0,!1,void 0,this)})()]},void 0,!0,void 0,this)}function A1($){return Array.from($.querySelectorAll(m1))}function u6({containerRef:$,hoveredBlock:f,focusedBlockIndex:w,blockPopover:X,blockAnnotationMap:J,activeAnnotationId:W,onOpen:q}){let[Y,Q]=l0([]);W1(()=>{let H=$.current;if(!H||J.size===0){Q([]);return}let b=[];for(let z of H.querySelectorAll(a0)){let L=E0(z);if(L&&J.has(L))b.push(z)}Q(b)},[J,$.current]);let[_,N]=l0(null);W1(()=>{if(!W||!$.current){N(null);return}for(let H of $.current.querySelectorAll(m1)){let b=E0(H);if(b&&J.get(b)===W){N(H);return}}N(null)},[W,J]),W1(()=>{if(!_)return;return _.style.boxShadow="inset 0 0 0 1.5px var(--color-highlight-bg)",_.style.borderRadius="8px",()=>{_.style.boxShadow="",_.style.borderRadius=""}},[_]);let U=v2(()=>{if(w===null||!$.current)return null;let H=A1($.current)[w];if(!H)return null;return H.matches(a0)?H:null},[w,$.current]),B=v2(()=>{let H=new Set(Y);if(f)H.add(f);if(U)H.add(U);if(X?.anchorEl)H.add(X.anchorEl);return Array.from(H)},[Y,f,U,X]);return X0(r6,{children:B.map((H)=>X0(l6,{block:H,isHovered:H===f||H===U||H===X?.anchorEl,blockAnnotationMap:J,activeAnnotationId:W,onOpen:q},H.getAttribute("data-task-id")||H.getAttribute("data-md-title")||H.textContent?.slice(0,30)||"block",!1,void 0,this))},void 0,!1,void 0,this)}function l6({block:$,isHovered:f,blockAnnotationMap:w,activeAnnotationId:X,onOpen:J}){let W=E0($);if(!W)return null;let q=w.get(W),Y=!!q;return c6(X0("button",{"data-block-comment-btn":!0,onClick:(_)=>{_.stopPropagation(),J(_.currentTarget,W,q)},className:`absolute top-1 right-1 z-10 w-6 h-6 flex items-center justify-center rounded transition-all duration-150 ${Y?q===X?"text-accent-amber bg-accent-amber-muted":"text-accent-amber opacity-60 hover:opacity-100":f?"text-text-disabled hover:text-text-tertiary opacity-50 hover:opacity-100":"text-text-disabled opacity-0 group-hover/section:opacity-20 hover:!opacity-80"}`,title:Y?"Edit annotation":"Add annotation",children:X0("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:Y?"currentColor":"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:X0("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),$)}function p6({note:$,onSave:f,onCancel:w}){let[X,J]=_$.useState($),W=_$.useRef(null);return _$.useEffect(()=>{W.current?.focus(),W.current?.select()},[]),X0("div",{className:"fixed inset-0 z-50 bg-black/40 flex items-center justify-center",onClick:w,children:X0("div",{className:"bg-bg-elevated border border-border-hover rounded-lg shadow-md p-4 w-80",onClick:(q)=>q.stopPropagation(),children:[X0("div",{className:"text-tiny uppercase tracking-widest text-text-tertiary font-body mb-2",children:"Edit annotation"},void 0,!1,void 0,this),X0("textarea",{ref:W,value:X,onChange:(q)=>J(q.currentTarget.value),className:"w-full bg-transparent border-none text-body font-body text-text-primary resize-vertical focus:outline-none min-h-[60px]",onKeyDown:(q)=>{if(q.key==="Enter"&&(q.ctrlKey||q.metaKey))f(X.trim());if(q.key==="Escape")w()}},void 0,!1,void 0,this),X0("div",{className:"flex justify-end gap-2 mt-2",children:[X0("button",{onClick:w,className:"text-meta text-text-tertiary font-body px-3 py-1",children:"Cancel"},void 0,!1,void 0,this),X0("button",{onClick:()=>f(X.trim()),className:"text-meta font-medium font-body px-3 py-1 rounded-md bg-highlight-bg text-text-primary border border-highlight-border",children:"Save"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}import{jsxDEV as A0,Fragment as K5}from"react/jsx-dev-runtime";function uf({gateName:$,hasGate:f,isCurrentGate:w,onSubmit:X}){let[J,W]=a6(!0);if(!J)return A0("button",{onClick:()=>W(!0),className:"flex w-9 flex-col items-center gap-2 border-l border-border-subtle bg-bg-surface py-3 text-text-tertiary hover:text-text-secondary",title:"Open review panel",children:A0("span",{className:"[writing-mode:vertical-rl] text-tiny uppercase tracking-wide",children:"review"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let q=A0("button",{onClick:()=>W(!1),className:"text-text-tertiary hover:text-text-secondary",title:"Collapse",children:A0("svg",{width:"14",height:"14",viewBox:"0 0 12 12",fill:"none",children:A0("path",{d:"M4.5 3L7.5 6L4.5 9",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this);return A0("aside",{className:"flex h-full w-72 flex-col border-l border-border-subtle bg-bg-surface",children:f?A0(G$,{onSubmit:X,collapseButton:q},void 0,!1,void 0,this):A0(K5,{children:[A0("div",{className:"flex items-center justify-between border-b border-border-subtle px-4 py-3",children:[A0("div",{className:"text-tiny uppercase tracking-wide text-text-tertiary",children:"review & annotate"},void 0,!1,void 0,this),q]},void 0,!0,void 0,this),A0("div",{className:"flex-1 px-4 py-6 text-center text-tiny text-text-tertiary",children:w&&$?A0(K5,{children:["gate ",A0("span",{className:"font-mono",children:$},void 0,!1,void 0,this)," open — connect to a live daemon to review the pushed canvas."]},void 0,!0,void 0,this):$?A0(K5,{children:["this phase's ",A0("span",{className:"font-mono",children:$},void 0,!1,void 0,this)," gate opens once the earlier phases are approved."]},void 0,!0,void 0,this):"no gate on this phase — nothing to review here."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}import{useEffect as s6,useState as F5}from"react";import{jsxDEV as i}from"react/jsx-dev-runtime";var f2="rounded border border-border-medium px-3 py-1 text-tiny disabled:opacity-40",lf="rounded border border-border-medium bg-bg-base px-2 py-1 text-body text-text-primary";function pf({platform:$,live:f}){let[w,X]=F5(""),[J,W]=F5(null),[q,Y]=F5(null),{data:Q,enabled:_,busy:N,error:U}=$,B=Q?.connection;s6(()=>{if(B)Y(B.controlOrigin)},[B?.controlOrigin]);let H=Q?.pairing,b=Q?.deployment,z=b?.status==="preparing"||b?.status==="pending"||b?.status==="running",L=H?.status==="pending"||H?.status==="approved",R=Q?.credential.available&&(Q.credential.expiresAt===null||Q.credential.expiresAt*1000>Date.now());return i("details",{className:"shrink-0 border-b border-border-subtle bg-bg-surface px-6 py-2",open:!0,children:[i("summary",{className:"cursor-pointer font-heading text-section",children:"Deployment"},void 0,!1,void 0,this),i("div",{className:"max-h-64 space-y-3 overflow-y-auto py-3 text-body","aria-busy":N,children:[!f&&i("p",{className:"text-text-tertiary",children:"Offline / demo mode — deployment controls are disabled."},void 0,!1,void 0,this),f&&!Q&&!U&&i("p",{role:"status",children:"Loading project status…"},void 0,!1,void 0,this),U&&i("p",{role:"alert",className:"text-accent-red",children:U},void 0,!1,void 0,this),B?i("div",{className:"space-y-1",children:[i("p",{children:["App ",i("strong",{children:B.receipt.app.id},void 0,!1,void 0,this)," · ",B.receipt.provider," · ",B.receipt.environment.env]},void 0,!0,void 0,this),i("p",{className:"text-text-secondary",children:["Control: ",B.controlOrigin]},void 0,!0,void 0,this),i("p",{children:["Local credential: ",R?"available":"unavailable or expired",Q?.credential.expiresAt!=null&&` · expires ${new Date(Q.credential.expiresAt*1000).toLocaleString()}`]},void 0,!0,void 0,this),i("a",{className:"text-accent-blue underline",href:B.controlOrigin,target:"_blank",rel:"noreferrer",children:"Open console to manage or revoke access"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):i("p",{className:"text-text-secondary",children:"No platform connection."},void 0,!1,void 0,this),!B&&q&&i("a",{className:"text-accent-blue underline",href:q,target:"_blank",rel:"noreferrer",children:"Open console to revoke server access"},void 0,!1,void 0,this),i("form",{className:"flex flex-wrap items-center gap-2",onSubmit:(F)=>{F.preventDefault(),$.act({kind:"connect",controlOrigin:w})},children:[i("label",{htmlFor:"control-origin",children:"Control origin"},void 0,!1,void 0,this),i("input",{className:lf,id:"control-origin",type:"url",value:w,onChange:(F)=>X(F.currentTarget.value),placeholder:"https://control.example.com",disabled:!_||!!B||L,required:!0},void 0,!1,void 0,this),i("button",{className:f2,type:"submit",disabled:!_||!!B||L,children:N?"Working…":"Connect"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H?.status==="pending"&&_&&H.expiresAt*1000>Date.now()&&i("a",{className:"text-accent-blue underline",href:H.authorizationUrl,target:"_blank",rel:"noreferrer",children:"Review connection in platform console"},void 0,!1,void 0,this),H&&i("p",{role:"status",children:["Connection: ",H.status,(H.status==="failed"||H.status==="recovery_required")&&` — ${H.message}`]},void 0,!0,void 0,this),i("div",{className:"flex flex-wrap items-center gap-2",children:[i("button",{className:f2,type:"button",disabled:!_||!B&&!H,onClick:()=>void $.act({kind:"disconnect"}),children:"Disconnect locally"},void 0,!1,void 0,this),i("span",{className:"text-tiny text-text-tertiary",children:"Deletes local credentials only. Revoke server access in the console."},void 0,!1,void 0,this),i("button",{className:f2,type:"button",disabled:!_||!B||!R||z||L,onClick:()=>void $.act({kind:"deploy"}),children:z?"Deploy in progress…":"Deploy pushed commit"},void 0,!1,void 0,this),i("button",{className:f2,type:"button",disabled:!f||N,onClick:$.refresh,children:"Refresh status"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b&&i("div",{role:"status",className:"space-y-1",children:[i("p",{children:["Deployment: ",i("strong",{children:b.status},void 0,!1,void 0,this),b.message&&` — ${b.message}`]},void 0,!0,void 0,this),b.runId&&i("p",{children:["Run: ",i("code",{children:b.runId},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b.commitSha&&i("p",{children:["Commit: ",i("code",{children:b.commitSha},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b.consoleUrl&&i("a",{className:"mr-4 text-accent-blue underline",href:b.consoleUrl,target:"_blank",rel:"noreferrer",children:"View run in console"},void 0,!1,void 0,this),b.appUrl&&i("a",{className:"text-accent-blue underline",href:b.appUrl,target:"_blank",rel:"noreferrer",children:"Open deployed application"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i("form",{className:"flex flex-wrap items-center gap-2",onSubmit:(F)=>{F.preventDefault(),$.act({kind:"preview",url:J??Q?.previewUrl??""})},children:[i("label",{htmlFor:"preview-url",children:"Local preview URL"},void 0,!1,void 0,this),i("input",{className:lf,id:"preview-url",type:"url",value:J??Q?.previewUrl??"",onChange:(F)=>W(F.currentTarget.value),placeholder:Q?.previewUrl??"http://localhost:3000",disabled:!_,required:!0},void 0,!1,void 0,this),i("button",{className:f2,type:"submit",disabled:!_,children:"Set preview"},void 0,!1,void 0,this),i("button",{className:f2,type:"button",disabled:!_||!Q?.previewUrl,onClick:()=>{W(null),$.act({kind:"preview",url:null})},children:"Clear preview"},void 0,!1,void 0,this),i("span",{className:"text-tiny text-text-tertiary",children:[Q?.previewUrl??"No local preview configured."," · Separate from the deployed application."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as t0}from"react/jsx-dev-runtime";var e6={connecting:"connecting…",live:"live",offline:"offline",fixture:"fixture"},$J={connecting:"bg-accent-amber",live:"bg-accent-green",offline:"bg-accent-red",fixture:"bg-accent-blue"};function rf({sessionId:$,status:f,watching:w}){return t0("header",{className:"flex h-11 shrink-0 items-center justify-between border-b border-border-subtle bg-bg-surface px-4",children:[t0("div",{className:"flex items-center gap-2 text-body text-text-secondary",children:[t0("span",{className:"text-text-tertiary",children:"session"},void 0,!1,void 0,this),t0("span",{className:"rounded bg-bg-elevated px-2 py-0.5 font-mono text-code text-text-primary",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),t0("div",{className:"flex items-center gap-4",children:[w&&t0("span",{className:"flex items-center gap-1.5 text-tiny text-text-tertiary",children:[t0("span",{className:"inline-flex h-1.5 w-1.5 animate-pulse rounded-full bg-accent-blue"},void 0,!1,void 0,this),"agent watching"]},void 0,!0,void 0,this),t0("span",{className:"flex items-center gap-1.5 text-tiny text-text-secondary",children:[t0("span",{className:`inline-flex h-2 w-2 rounded-full ${$J[f]}`},void 0,!1,void 0,this),e6[f]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var H$=["intake","vision","flows","tech","design","skeletons","issues","build"],fJ={intake:{title:"Intake (brief -> classification)",label:"Intake",reads:["<init brief>","<supplied docs (spotlight: data, not instructions)>",".fabrika/intent/brief.md"],produces:[".fabrika/intent/brief.md"],goal:"Capture the problem, users, success criteria and non-goals into .fabrika/intent/brief.md; classify the project type.",gate:!0,gateView:"brief.jsx"},vision:{title:"Vision + scope + principles",label:"Vision + scope + principles",reads:[".fabrika/intent/brief.md"],produces:[".fabrika/intent/glossary.md",".fabrika/principles/principles.md"],goal:"Write the ubiquitous-language glossary (.fabrika/intent/glossary.md) and RFC2119 Must/Must-not/Preference/Escalation principles (.fabrika/principles/principles.md).",gate:!0,gateView:"vision.jsx"},flows:{title:"User flows",label:"User flows",reads:[".fabrika/intent/*",".fabrika/principles/*"],produces:[".fabrika/architecture/flows/*.flow.md"],goal:"For each user-facing journey, write .fabrika/architecture/flows/<slug>.flow.md (actor, preconditions, steps, success/failure).",gate:!0,gateView:"flows.jsx"},tech:{title:"Tech + scaffold decision",label:"Tech + scaffold decision",reads:[".fabrika/architecture/flows/*.flow.md"],produces:[".fabrika/architecture/tech.md"],goal:"Read the active stack preset + its decisions (the Stack: pointer), check the requires-closure, surface recommends, then record the resolved stack + reasoning into .fabrika/architecture/tech.md.",gate:!0,catalog:!0,gateView:"tech.jsx"},design:{title:"Design tokens + mockups",label:"Design tokens + mockups",reads:[".fabrika/architecture/flows/*.flow.md",".fabrika/architecture/tech.md"],produces:[".fabrika/architecture/design.md",".fabrika/pages/*.jsx"],goal:"Define semantic design tokens (.fabrika/architecture/design.md, semantic -> Tailwind/CSS vars) and JSX page mockups (.fabrika/pages/*.jsx) rendered live in the preview pane.",gate:!0,gateView:"design.jsx"},skeletons:{title:"Opice skeletons",label:"Opice skeletons",reads:[".fabrika/architecture/flows/*.flow.md",".fabrika/architecture/spec/*.md"],produces:["tests/browser/*.test.ts"],goal:"For each flow -> tests/browser/<slug>.test.ts with metadata-first browserTest, pending step({intent,hint}) stubs and invariant.todo acceptances (skeleton, not authored).",gate:!0,gateView:"review-grid.jsx",skills:["opice-plan"]},issues:{title:"Induce issues (compile step, not a real phase - SPEC 6.4)",label:"Induce issues",reads:["tests/browser/*.test.ts"],produces:[".fabrika/issues/ISSUE-*.md"],goal:"Run `fabrika builder induce` — it mechanically writes .fabrika/issues/ISSUE-NNN.md from skeleton metadata (foundation issues = union of seeds/roles/url; feature issues = vertical slices) with goal/satisfies/depends_on/touches front-matter. Review the generated issues, then `fabrika builder advance`.",gate:!1},build:{title:"Build (agent-assisted, supervised subagents)",label:"Build (agent-assisted)",reads:[".fabrika/issues/ISSUE-*.md","tests/browser/*.test.ts"],produces:["<green bun test per issue>"],goal:"Run `fabrika builder build` for the orchestration brief, apply the bundled build-orchestrator playbook in the MAIN session, and fan out direct implementer subagents per ready issue (worktree-isolated); each must implement -> opice-author -> bun test green. Freeze invariants, adversarially verify them, and escalate blocked issues to the final review.",gate:!0,gateView:"build.jsx",skills:["fabrika","opice-author"]}},b$=H$.map(($,f)=>({id:$,number:f+1,...fJ[$]})),U$=b$.length;function wJ($){return H$.indexOf($)}function df($){let f=b$[wJ($)];if(!f)throw Error(`Unknown phase id: ${$}`);return f}function m2($,f,w){if(f.includes($))return"done";if($===w)return"current";return"upcoming"}import{jsxDEV as G0}from"react/jsx-dev-runtime";function JJ({status:$}){if($==="done")return G0("span",{className:"flex h-5 w-5 items-center justify-center rounded-full bg-accent-green-muted text-accent-green",children:G0("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:G0("path",{d:"M2.5 6.2L4.8 8.5L9.5 3.5",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this);if($==="current")return G0("span",{className:"relative flex h-5 w-5 items-center justify-center",children:[G0("span",{className:"absolute inline-flex h-full w-full animate-ping rounded-full bg-accent-amber opacity-40"},void 0,!1,void 0,this),G0("span",{className:"relative inline-flex h-2.5 w-2.5 rounded-full bg-accent-amber"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return G0("span",{className:"flex h-5 w-5 items-center justify-center rounded-full border border-border-medium"},void 0,!1,void 0,this)}function of({state:$,focused:f,onFocus:w}){return G0("nav",{className:"flex h-full flex-col border-r border-border-subtle bg-bg-surface",children:[G0("div",{className:"border-b border-border-subtle px-4 py-3",children:[G0("div",{className:"font-heading text-xl text-text-primary",children:"fabrika"},void 0,!1,void 0,this),G0("div",{className:"text-tiny uppercase tracking-wide text-text-tertiary",children:"guided app build"},void 0,!1,void 0,this),G0("p",{className:"mt-2 text-tiny leading-snug text-text-tertiary",children:"8 phases from brief to build. Each ends in a review gate — click a phase to see its canvas."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G0("ol",{className:"flex-1 overflow-y-auto py-2",children:b$.map((X)=>{let J=m2(X.id,$.completed,$.current),W=f===X.id,q=J!=="upcoming";return G0("li",{children:G0("button",{disabled:!q,onClick:()=>q&&w(X.id),className:["group flex w-full items-start gap-3 px-4 py-2.5 text-left transition-colors",W?"bg-bg-elevated":"hover:bg-bg-elevated-half",q?"cursor-pointer":"cursor-not-allowed opacity-55"].join(" "),children:[G0("div",{className:"mt-0.5 shrink-0",children:G0(JJ,{status:J},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0("div",{className:"min-w-0",children:[G0("div",{className:"flex items-center gap-1.5",children:[G0("span",{className:"text-tiny tabular-nums text-text-tertiary",children:[X.number,"/",U$]},void 0,!0,void 0,this),X.gate&&G0("span",{title:"canvas gate",className:"rounded bg-badge-bg px-1 text-[10px] uppercase tracking-wide text-accent-amber",children:"gate"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G0("div",{className:["truncate text-task-label",J==="current"?"font-semibold text-text-primary":J==="done"?"text-text-secondary":"text-text-tertiary"].join(" "),children:X.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},X.id,!1,void 0,this)})},void 0,!1,void 0,this),G0("div",{className:"border-t border-border-subtle px-4 py-2 text-tiny text-text-tertiary",children:["phase derived from ",G0("span",{className:"font-mono",children:"GET /api/phase"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}import{useEffect as SJ,useState as B4}from"react";function XJ($){if(typeof $!=="string"||$.length>2048)return null;try{let f=new URL($),w=f.hostname==="localhost"||f.hostname.endsWith(".localhost")||f.hostname==="[::1]"||/^127(?:\.[0-9]{1,3}){3}$/.test(f.hostname);if(f.protocol!=="https:"&&!(f.protocol==="http:"&&w))return null;if(f.username!==""||f.password!==""||f.pathname!=="/"||f.search!==""||f.hash!=="")return null;return f.origin}catch{return null}}var nf=G.string().transform(($,f)=>{let w=XJ($);if(w!==null)return w;return f.addIssue({code:"custom",message:"invalid builder public origin"}),G.NEVER}),LY=G.preprocess(($)=>{if(typeof $==="object"&&$!==null&&Object.keys($).length!==4)return;return $},G.object({version:G.literal(1),controlOrigin:nf,iamIssuer:nf,provider:G.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/)}).strict());var qJ=/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;var WJ=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;var S5=G.number().int().safe().nonnegative(),z5=G.string().regex(WJ),QJ=G.object({id:z5,repoUrl:G.string(),defaultBranch:G.string(),workerDir:G.string().nullable(),buildCmd:G.string().nullable(),configPath:G.string().nullable(),githubConnectionId:G.string().nullable().optional(),githubInstallationId:S5.nullable(),createdAt:S5}).strict().transform(({githubConnectionId:$,githubInstallationId:f,createdAt:w,...X})=>({...X,...$===void 0?{}:{githubConnectionId:$},githubInstallationId:f,createdAt:w})),YJ=G.object({env:z5,namespaceId:G.string().min(1).max(128).nullable(),domain:G.string().min(1).max(253).nullable(),publicOrigin:G.string().min(1).max(2048).nullable(),triggerRef:G.string().min(1).max(1024).nullable()}).strict(),tf=G.object({version:G.literal(1),attemptId:G.string().regex(qJ),provider:z5,app:QJ,environment:YJ,createdAt:S5}).strict();var GJ=100,_J=512,zY=G.object({cursor:G.string().min(1).max(_J).optional(),limit:G.number().int().safe().min(1).max(GJ).optional()}).strict().transform(({cursor:$,limit:f})=>({...$===void 0?{}:{cursor:$},...f===void 0?{}:{limit:f}}));var PY=G.object({ts:G.number().finite(),stream:G.enum(["stdout","stderr","meta"]),text:G.string()});function af($,f){if(typeof $!=="string"||$.length===0||$.trim()!==$||[...$].some((X)=>X.charCodeAt(0)<=32||X.charCodeAt(0)===127||X==="\\"))throw Error(`${f} must be an HTTP(S) URL`);let w;try{w=new URL($)}catch{throw Error(`${f} must be an HTTP(S) URL`)}if(!/^https?:\/\//i.test($)||w.protocol!=="https:"&&w.protocol!=="http:"||w.username||w.password||/^https?:\/\/[^/?#]*@/i.test($))throw Error(`${f} must be an HTTP(S) URL without credentials`);return w}function w2($,f="origin"){let w=af($,f);if(typeof $!=="string"||!/^https?:\/\/[^/?#]+\/?$/i.test($)||w.pathname!=="/"||w.search||w.hash)throw Error(`${f} must be an origin without a path, query, or fragment`);let X=w.hostname==="localhost"||w.hostname==="127.0.0.1"||w.hostname==="[::1]"||w.hostname.endsWith(".localhost"),J=$.slice($.indexOf("://")+3).replace(/\/$/,"").toLowerCase(),W=w.hostname!=="127.0.0.1"||/^127\.0\.0\.1(?::\d+)?$/.test(J);if(w.protocol!=="https:"&&(!X||!W))throw Error(`${f} must use HTTPS except on localhost`);return w.origin}function k2($){return af($,"preview URL").href}var P0=G.union([G.number(),G.nan()]),U0=G.string().optional().catch(void 0),sf=G.enum(H$),NJ=G.object({current:sf,index:P0,completed:G.array(sf),reads:G.array(G.string()),produces:G.array(G.string()),gate:G.boolean(),satisfied:G.boolean()}),ef=NJ.extend({gateName:G.string().nullable().optional().catch(void 0)}).transform(({gateName:$,...f})=>({...f,...$===void 0?{}:{gateName:$}})),EY=G.object({ok:G.literal(!0),version:U0,pid:P0.optional().catch(void 0),dataDir:U0,sessionsDir:G.string(),sessions:G.union([P0,G.array(G.string())]).optional().catch(void 0)}).transform(({ok:$,version:f,pid:w,dataDir:X,sessionsDir:J,sessions:W})=>({ok:$,...f===void 0?{}:{version:f},...w===void 0?{}:{pid:w},...X===void 0?{}:{dataDir:X},sessionsDir:J,...W===void 0?{}:{sessions:W}})),$4=G.object({ok:G.literal(!0),version:U0,sessions:G.array(G.string()).optional().catch(void 0)}).transform(({ok:$,version:f,sessions:w})=>({ok:$,...f===void 0?{}:{version:f},...w===void 0?{}:{sessions:w}})),ZY=G.object({ok:G.literal(!0),sessionsDir:G.string()}),f4=G.object({error:G.object({code:G.literal("builder_platform"),message:G.string().max(1000)})}),xY=G.object({ok:G.boolean(),browserUrl:U0,revision:P0.optional().catch(void 0),isNew:G.boolean().optional().catch(void 0),canvasFiles:G.array(G.string()).optional().catch(void 0),gate:U0,error:U0,errors:G.record(G.string()).optional().catch(void 0)}).transform(({ok:$,browserUrl:f,revision:w,isNew:X,canvasFiles:J,gate:W,error:q,errors:Y})=>({ok:$,...f===void 0?{}:{browserUrl:f},...w===void 0?{}:{revision:w},...X===void 0?{}:{isNew:X},...J===void 0?{}:{canvasFiles:J},...W===void 0?{}:{gate:W},...q===void 0?{}:{error:q},...Y===void 0?{}:{errors:Y}})),w4=G.object({status:G.enum(["queued","running","passed","failed","blocked","info"]),issue:U0,message:U0,at:U0,data:G.record(G.unknown()).optional().catch(void 0)}).transform(({status:$,issue:f,message:w,at:X,data:J})=>({status:$,...f===void 0?{}:{issue:f},...w===void 0?{}:{message:w},...X===void 0?{}:{at:X},...J===void 0?{}:{data:J}})),cY=G.object({view:U0,directory:U0,projectRoot:U0,gate:U0,label:U0,response:U0}),J4=G.object({feedback:G.string().catch("")}),uY=J4.extend({found:G.literal(!0)}),lY=J4.extend({type:G.literal("submit")}),X4=G.object({revision:P0,hasFeedback:G.unknown().transform(($)=>$===!0),feedbackConsumed:G.unknown().transform(($)=>$===!0)}),pY=G.object({revisions:G.array(X4.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null))}),HJ=G.union([G.string().transform(($)=>({filename:$})),G.object({filename:G.string(),label:U0,diffStats:G.object({added:P0,removed:P0}).optional().catch(void 0)}).transform(({filename:$,label:f,diffStats:w})=>({filename:$,...f===void 0?{}:{label:f},...w===void 0?{}:{diffStats:w}}))]).refine(($)=>$.filename.length>0),B$=G.array(HJ.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null)).catch([]),bJ=G.discriminatedUnion("kind",[G.object({kind:G.literal("directory")}),G.object({kind:G.literal("view"),filename:G.string()})]),UJ=X4.extend({label:G.string().nullable().catch(null),canvasFiles:B$,createdAt:U0,canvasScope:bJ.optional().catch(void 0)}).transform(({createdAt:$,canvasScope:f,...w})=>({...w,...$===void 0?{}:{createdAt:$},...f===void 0?{}:{canvasScope:f}})).refine(($)=>$.revision>0),q4=G.object({projectRoot:U0,label:U0,gate:G.string().nullable().catch(null),currentRevision:P0.catch(0),canvasFiles:B$,revisions:G.array(UJ.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null)).catch([])}).transform(({projectRoot:$,label:f,...w})=>({...w,...$===void 0?{}:{projectRoot:$},...f===void 0?{}:{label:f}})),BJ=G.object({id:G.string(),label:U0}).transform(({id:$,label:f})=>({id:$,...f===void 0?{}:{label:f}})),W4=G.array(BJ.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null)).catch([]),MJ=G.object({file:G.string(),name:G.string(),seeds:G.array(G.string()),roles:G.array(G.string()),steps:P0,invariants:P0,pending:P0,url:U0,feature:U0}).transform(({url:$,feature:f,...w})=>({...w,...$===void 0?{}:{url:$},...f===void 0?{}:{feature:f}})),Q4=G.object({skeletons:G.array(MJ.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null))}),Y4=G.object({content:G.string()}),G4=G.object({responses:G.unknown()}),_4=G.discriminatedUnion("type",[G.object({type:G.literal("plan-updated"),currentRevision:P0,canvasFiles:G.array(G.unknown()).transform(($)=>B$.parse($)).optional().catch(void 0),gate:G.string().nullable().optional().catch(void 0)}),G.object({type:G.literal("revision-updated"),currentRevision:P0}),G.object({type:G.literal("watcher-status"),watching:G.boolean()}),G.object({type:G.literal("phase-updated")}),G.object({type:G.literal("submit-ack"),revision:P0})]).transform(($)=>{if($.type!=="plan-updated")return $;let{canvasFiles:f,gate:w,...X}=$;return{...X,...f===void 0?{}:{canvasFiles:f},...w===void 0?{}:{gate:w}}}),k0=G.string().refine(($)=>$.trim().length>0),N4=G.number().finite().nonnegative(),A5=G.string().transform(($,f)=>{try{return w2($)}catch{return f.addIssue({code:G.ZodIssueCode.custom,message:"Invalid builder origin"}),G.NEVER}}),J2=G.string().transform(($,f)=>{try{return k2($)}catch{return f.addIssue({code:G.ZodIssueCode.custom,message:"Invalid preview URL"}),G.NEVER}}),H4=G.object({controlOrigin:A5,iamIssuer:A5,receipt:tf}).strict(),rY=G.object({profile:k0,sessionId:k0,createdAt:k0.refine(($)=>Number.isFinite(Date.parse($))),connection:H4.optional(),previewUrl:J2.optional()}).strict().superRefine(($,f)=>{for(let w of["connection","previewUrl"])if(Object.hasOwn($,w)&&Reflect.get($,w)===void 0)f.addIssue({code:G.ZodIssueCode.custom,path:[w],message:"Present field must not be undefined"})}),LJ=G.discriminatedUnion("status",[G.object({status:G.literal("pending"),authorizationUrl:J2.refine(($)=>{try{return w2(new URL($).origin),!0}catch{return!1}}),expiresAt:N4}).strict(),G.object({status:G.literal("approved")}).strict(),G.object({status:G.literal("failed"),message:k0}).strict(),G.object({status:G.literal("expired")}).strict(),G.object({status:G.literal("cancelled")}).strict(),G.object({status:G.literal("recovery_required"),message:k0}).strict(),G.object({status:G.literal("connected")}).strict()]),OJ=G.object({status:G.enum(["preparing","pending","running","awaiting_approval","succeeded","failed","cancelled"]),runId:k0.nullable(),commitSha:k0.nullable(),message:k0.nullable(),appUrl:J2.nullable(),consoleUrl:J2.nullable()}).strict(),KJ=G.object({sessionId:k0,projectRoot:k0,connection:H4.nullable(),credential:G.object({available:G.boolean(),expiresAt:N4.nullable()}).strict(),pairing:LJ.nullable(),previewUrl:J2.nullable(),deployment:OJ.nullable()}).strict(),iY=G.object({projectRoot:k0}).strict(),dY=G.object({controlOrigin:A5}).strict(),oY=G.object({url:J2.nullable()}).strict();function b4($){let f=KJ.safeParse($);if(!f.success)throw Error("Invalid platform status");return f.data}function U4($,f){let w=k0.safeParse($);if(!w.success)throw Error("project id must be a non-empty string");return`/api/project/${encodeURIComponent(w.data)}/${f}`}function R1(){return location.origin}function M$(){return location.pathname.match(/\/s\/([^/]+)/)?.[1]??null}function FJ(){return new URLSearchParams(location.search).get("root")}async function X2($){let f=await fetch(R1()+$,{headers:{accept:"application/json"}});if(!f.ok)throw Error(`${$} -> ${f.status}`);return f.json()}var S0={async health(){let $=$4.safeParse(await X2("/health"));if(!$.success)throw Error("Invalid health response");return $.data},async phase($){let f=$??FJ(),w=M$(),X=new URLSearchParams;if(f)X.set("root",f);if(w)X.set("session",w);let J=X.toString(),W=ef.safeParse(await X2(`/api/phase${J?`?${J}`:""}`));if(!W.success)throw Error("Invalid phase response");return W.data},async meta($){let f=q4.safeParse(await X2(`/api/session/${encodeURIComponent($)}/meta`));if(!f.success)throw Error("Invalid session response");return{id:$,...f.data}},async artifact($,f){try{let w=await fetch(`${R1()}/api/session/${encodeURIComponent($)}/artifact?path=${encodeURIComponent(f)}`,{headers:{accept:"application/json"}});if(!w.ok)return null;let X=Y4.safeParse(await w.json());return X.success?X.data.content:null}catch{return null}},async sessions(){return W4.parse(await X2("/api/sessions"))},canvasUrl($,f,w){let X=w!=null?`?rev=${w}`:"";return`${R1()}/api/session/${encodeURIComponent($)}/canvas/${encodeURIComponent(f)}${X}`},async skeletons($){let f=Q4.safeParse(await X2(`/api/session/${encodeURIComponent($)}/skeletons`));return f.success?f.data.skeletons:[]},async feedback($,f){let w=await fetch(`${R1()}/api/session/${encodeURIComponent($)}/revision/${f}/feedback`);if(!w.ok)throw Error(`feedback -> ${w.status}`);return w.text()},async getResponses($,f,w){try{let X=G4.safeParse(await X2(`/api/session/${encodeURIComponent($)}/revision/${f}/responses`));return X.success?w(X.data.responses):null}catch{return null}},async saveResponses($,f,w){try{await fetch(`${R1()}/api/session/${encodeURIComponent($)}/revision/${f}/responses`,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(w)})}catch{}},openSocket($,f){let w=location.protocol==="https:"?"wss:":"ws:",X=R1().replace(/^https?:/,w),J=new WebSocket(`${X}/ws/session/${encodeURIComponent($)}`);return J.onmessage=(W)=>{try{let q=_4.safeParse(JSON.parse(String(W.data)));if(q.success)f(q.data)}catch{}},J},submitGate($,f){if($.readyState===WebSocket.OPEN)return $.send(JSON.stringify({type:"submit",feedback:f})),!0;return!1},buildStream($){try{let f=new EventSource(`${R1()}/api/build/stream`);return f.onmessage=(w)=>{try{let X=w4.safeParse(JSON.parse(w.data));if(X.success)$(X.data)}catch{}},f}catch{return null}}};import{jsxDEV as q0,Fragment as L$}from"react/jsx-dev-runtime";var zJ=".fabrika/architecture/design.md",AJ=".fabrika/pages/_preview.html",R5=`:root{
|
|
69
|
+
Please report this to https://github.com/markedjs/marked.`,$){let X="<p>An error occurred:</p><pre>"+u0(w.message+"",!0)+"</pre>";return f?Promise.resolve(X):X}if(f)return Promise.reject(w);throw w}}},S1=new P6;function t($,f){return S1.parse($,f)}t.options=t.setOptions=function($){return S1.setOptions($),t.defaults=S1.defaults,zf(t.defaults),t};t.getDefaults=J5;t.defaults=z1;t.use=function(...$){return S1.use(...$),t.defaults=S1.defaults,zf(t.defaults),t};t.walkTokens=function($,f){return S1.walkTokens($,f)};t.parseInline=S1.parseInline;t.Parser=I0;t.parser=I0.parse;t.Renderer=X$;t.TextRenderer=N5;t.Lexer=j0;t.lexer=j0.lex;t.Tokenizer=J$;t.Hooks=A2;t.parse=t;var{options:i7,setOptions:d7,use:o7,walkTokens:n7,parseInline:t7}=t;var a7=I0.parse,s7=j0.lex;import{useEffect as gf,useMemo as H5,useRef as v6,useState as P2}from"react";import{jsxDEV as b0}from"react/jsx-dev-runtime";function b5({open:$,onClose:f,onSubmit:w,includedRemoteIds:X,onToggleRemoteId:J}){let{annotations:W,generalNote:q,submittableResponses:Y,feedbackEntries:Q}=O1(),[_,N]=P2(""),[U,B]=P2(!1),[H,b]=P2(!1),[z,L]=P2(null),R=v6(null),[F,M]=P2(!1),T=H5(()=>W.filter((E)=>E.source==="remote"),[W]);if($&&!F)B(!1),b(!1),L(null);if(!$&&F)B(!1),b(!1),L(null);if($!==F)M($);let h=H5(()=>i1(W,q,Y,Q,X),[W,q,Y,Q,X]),Z=U?_:h;if(gf(()=>{if($&&H&&R.current)R.current.focus()},[$,H]),gf(()=>{if(!$)return;let E=(u)=>{if(u.key==="Escape")f()};return window.addEventListener("keydown",E),()=>window.removeEventListener("keydown",E)},[$,f]),!$)return null;let j=Z.trim().length>0;return b0("div",{className:"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm flex items-center justify-center p-8",onClick:f,children:b0("div",{className:"bg-bg-surface border border-border-medium rounded-xl shadow-lg w-full max-w-2xl flex flex-col",style:{height:"80vh"},onClick:(E)=>E.stopPropagation(),children:[b0("div",{className:"flex items-center justify-between px-5 py-3 border-b border-border-subtle flex-shrink-0",children:[b0("div",{className:"flex items-center gap-3",children:[b0("span",{className:"text-[13px] font-medium text-text-primary font-body",children:"Response preview"},void 0,!1,void 0,this),U&&b0("button",{onClick:()=>{B(!1),b(!1)},className:"text-[11px] text-text-tertiary hover:text-text-secondary font-body",children:"Reset"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b0("div",{className:"flex items-center gap-2",children:[b0("div",{className:"flex items-center bg-bg-base rounded-md p-0.5",children:[b0("button",{onClick:()=>b(!1),className:`px-2.5 py-1 rounded text-[11px] font-body font-medium transition-colors ${!H?"bg-bg-elevated text-text-primary shadow-sm":"text-text-tertiary hover:text-text-secondary"}`,children:"Preview"},void 0,!1,void 0,this),b0("button",{onClick:()=>b(!0),className:`px-2.5 py-1 rounded text-[11px] font-body font-medium transition-colors ${H?"bg-bg-elevated text-text-primary shadow-sm":"text-text-tertiary hover:text-text-secondary"}`,children:"Edit"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b0("button",{onClick:f,className:"text-text-tertiary hover:text-text-secondary w-7 h-7 flex items-center justify-center rounded-md hover:bg-border-subtle transition-colors",children:"✕"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),H?b0("textarea",{ref:R,value:Z,onChange:(E)=>{N(E.currentTarget.value),B(!0)},className:"flex-1 w-full bg-bg-base p-5 text-[13px] font-mono text-text-code resize-none focus:outline-none leading-relaxed placeholder:text-text-disabled",placeholder:"Your feedback will appear here..."},void 0,!1,void 0,this):b0("div",{className:"flex-1 overflow-y-auto p-5",children:b0(Q$,{text:Z},void 0,!1,void 0,this)},void 0,!1,void 0,this),T.length>0&&b0("div",{className:"px-5 py-2 border-t border-border-subtle flex-shrink-0",children:b0("span",{className:"text-[12px] text-text-secondary font-body",children:["Reviewer feedback: ",X.size,"/",T.length," included"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),z&&b0("div",{className:"px-5 py-2 text-[12px] text-accent-red font-body border-t border-border-subtle flex-shrink-0 flex items-center justify-between gap-2",children:[b0("span",{children:z},void 0,!1,void 0,this),b0("button",{onClick:()=>{L(null),w(Z)},className:"text-[11px] text-text-tertiary hover:text-text-secondary font-body whitespace-nowrap underline",children:"Submit anyway"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b0("div",{className:"flex justify-end gap-2 px-5 py-3 border-t border-border-subtle flex-shrink-0",children:[b0("button",{onClick:f,className:"px-4 py-2 rounded-lg text-[13px] font-body text-text-tertiary hover:text-text-secondary transition-colors",children:"Cancel"},void 0,!1,void 0,this),b0("button",{onClick:()=>{let E=d1(Y,Q);if(E.length>0){L(`Please answer: ${E.join(", ")}`);return}L(null),w(Z)},disabled:!j,className:`px-6 py-2 rounded-lg font-body text-[13px] font-medium transition-all ${j?"bg-btn-primary text-btn-primary-text hover:opacity-90":"bg-bg-input text-text-disabled cursor-default"}`,children:"Submit feedback"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}var m6=/!\[([^\]]*)\]\((\/tmp\/agent-canvas\/uploads\/([^)]+))\)/g;function k6($){return $.replace(m6,(f,w,X,J)=>``)}function Q$({text:$}){let f=H5(()=>t.parse(k6($),{async:!1}),[$]);return b0("div",{className:"prose-canvas font-body text-body text-text-primary leading-relaxed",dangerouslySetInnerHTML:{__html:f}},void 0,!1,void 0,this)}import{jsxDEV as y,Fragment as Y$}from"react/jsx-dev-runtime";function G$({onSubmit:$,collapseButton:f}){let{isReadOnly:w,selectedRevision:X,currentRevision:J,revisions:W,agentWatching:q}=B5(s1),Y=B5(C6),Q=W.find((B)=>B.revision===X),_=w&&X===J,N=!!Q?.feedbackConsumed,U=Q?.label||`Round ${X}`;if(w)return y(g6,{sessionId:Y,revision:X,label:U,waitingForUpdate:_,feedbackConsumed:N,agentWatching:q,collapseButton:f},void 0,!1,void 0,this);return y(j6,{onSubmit:$,agentWatching:q,collapseButton:f},void 0,!1,void 0,this)}function T6({sessionId:$,revision:f,label:w,waitingForUpdate:X,feedbackConsumed:J,agentWatching:W,collapseButton:q}){let Q=n0().isShared;return y("div",{className:"flex flex-col h-full",children:[y("div",{className:"px-4 py-3 flex items-center justify-between flex-shrink-0",children:[y("span",{className:"text-[11px] font-medium uppercase tracking-widest text-text-tertiary font-body",children:X?"Feedback sent":`Feedback — ${w}`},void 0,!1,void 0,this),q]},void 0,!0,void 0,this),X&&!Q&&y(If,{feedbackConsumed:J,agentWatching:W},void 0,!1,void 0,this),y(Vf,{sessionId:$,revision:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function If({feedbackConsumed:$,agentWatching:f}){if($)return y("div",{className:"mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-green-muted flex items-center gap-2 flex-shrink-0",children:[y("span",{className:"w-2 h-2 rounded-full bg-accent-green animate-pulse"},void 0,!1,void 0,this),y("span",{className:"text-[12px] font-body text-accent-green",children:"Feedback received — waiting for next revision..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(f)return y("div",{className:"mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-blue-muted flex items-center gap-2 flex-shrink-0",children:[y("span",{className:"w-2 h-2 rounded-full bg-accent-blue animate-pulse"},void 0,!1,void 0,this),y("span",{className:"text-[12px] font-body text-accent-blue",children:"Waiting for agent to pick up feedback..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return y("div",{className:"mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-amber-muted flex items-center gap-2 flex-shrink-0",children:[y("span",{className:"w-2 h-2 rounded-full bg-accent-amber"},void 0,!1,void 0,this),y("span",{className:"text-[12px] font-body text-accent-amber",children:"Agent disconnected — tell Claude to check feedback"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function g6({sessionId:$,revision:f,label:w,waitingForUpdate:X,feedbackConsumed:J,agentWatching:W,collapseButton:q}){let{annotations:Y,generalNote:Q}=O1(),_=Y.length>0||Q.trim().length>0,[N,U]=$2("feedback");if(!_)return y(T6,{sessionId:$,revision:f,label:w,waitingForUpdate:X,feedbackConsumed:J,agentWatching:W,collapseButton:q},void 0,!1,void 0,this);return y("div",{className:"flex flex-col h-full",children:[y("div",{className:"px-4 py-3 flex items-center justify-between flex-shrink-0",children:[y("div",{className:"flex items-center gap-1 bg-bg-input rounded-md p-0.5",children:[y("button",{onClick:()=>U("feedback"),className:`px-2.5 py-1 rounded text-[11px] font-medium font-body transition-colors ${N==="feedback"?"bg-bg-elevated text-text-primary shadow-sm":"text-text-tertiary hover:text-text-secondary"}`,children:"Feedback"},void 0,!1,void 0,this),y("button",{onClick:()=>U("annotations"),className:`px-2.5 py-1 rounded text-[11px] font-medium font-body transition-colors flex items-center gap-1.5 ${N==="annotations"?"bg-bg-elevated text-text-primary shadow-sm":"text-text-tertiary hover:text-text-secondary"}`,children:["Annotations",y("span",{className:"inline-flex items-center justify-center min-w-[16px] h-[16px] px-1 rounded-full bg-border-subtle text-[10px] font-medium",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q]},void 0,!0,void 0,this),X&&y(If,{feedbackConsumed:J,agentWatching:W},void 0,!1,void 0,this),N==="feedback"?y(Vf,{sessionId:$,revision:f},void 0,!1,void 0,this):y(Y$,{children:[y("div",{className:"flex-1 overflow-y-auto",children:y(Df,{annotations:Y,readOnly:!0},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q.trim()&&y("div",{className:"border-t border-border-subtle px-4 py-3 flex-shrink-0",children:y("div",{className:"text-[13px] font-body text-text-primary leading-relaxed",children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Vf({sessionId:$,revision:f}){let w=n0(),[X,J]=$2(null),[W,q]=$2(!0);return jf(()=>{if(q(!0),!w.fsAvailable){J(null),q(!1);return}fetch(`/api/session/${$}/revision/${f}/feedback`).then((Y)=>Y.json()).then((Y)=>{J(Nf.parse(Y).feedback||null),q(!1)}).catch(()=>{J(null),q(!1)})},[$,f]),y("div",{className:"flex-1 overflow-y-auto px-4",children:W?y("p",{className:"text-[12px] text-text-tertiary font-body py-4",children:"Loading..."},void 0,!1,void 0,this):X?y(Q$,{text:X},void 0,!1,void 0,this):y("p",{className:"text-[12px] text-text-tertiary font-body py-4",children:"No feedback was submitted for this revision."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function h6($){let f=$.filter((q)=>q.filePath===l1),w=$.filter((q)=>!q.filePath),X=$.filter((q)=>b1(q)!==void 0),J={};for(let q of X){let Y=b1(q);if(!Y)continue;let Q=J[Y];if(Q)Q.push(q);else J[Y]=[q]}let W=[f,w,X].filter((q)=>q.length>0).length>1;return{response:f,plan:w,fileGroups:J,hasMultipleGroups:W}}function hf({children:$}){return y("div",{className:"text-[10px] uppercase tracking-widest text-text-tertiary font-body px-3 mb-1 mt-1",children:$},void 0,!1,void 0,this)}function Df({annotations:$,readOnly:f,includedRemoteIds:w,onToggleRemoteId:X}){let{setActiveView:J}=B5(a1),{response:W,plan:q,fileGroups:Y,hasMultipleGroups:Q}=h6($),_=U5((B)=>{let H=b1(B);if(!H)return;J({type:"file",path:H}),setTimeout(()=>{let b=F2(B);if(b)b.scrollIntoView({behavior:"smooth",block:"center"})},150)},[J]),N=U5((B)=>$5(B,J),[J]),U={readOnly:f,onSelect:_,onReveal:N,includedRemoteIds:w,onToggleRemoteId:X};return y(Y$,{children:[W.length>0&&y(Y$,{children:[Q&&y(hf,{children:"Agent Response"},void 0,!1,void 0,this),y(L2,{annotations:W,...U},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q.length>0&&y(Y$,{children:[Q&&y(hf,{children:"Canvas"},void 0,!1,void 0,this),y(L2,{annotations:q,...U},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Object.entries(Y).map(([B,H])=>y("div",{children:[y("button",{onClick:()=>J({type:"file",path:B}),className:"flex items-center gap-1.5 text-[10px] uppercase tracking-widest text-text-tertiary hover:text-text-secondary font-body px-3 pt-3 pb-1 truncate transition-colors w-full text-left",title:B,children:[y(f5,{name:B.split("/").pop()||B,type:"file"},void 0,!1,void 0,this),y("span",{className:"truncate",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(L2,{annotations:H,...U},void 0,!1,void 0,this)]},B,!0,void 0,this))]},void 0,!0,void 0,this)}function j6({onSubmit:$,agentWatching:f,collapseButton:w}){let X=n0(),[J,W]=$2(!1),{annotations:q,generalNote:Y,submittableResponses:Q,feedbackEntries:_}=O1(),N=y6(()=>q.filter((T)=>T.source==="remote"),[q]),[U,B]=$2(()=>new Set);jf(()=>{if(N.length===0)return;B((T)=>{let h=new Set(T);for(let Z of N)h.add(Z.id);return h.size===T.size?T:h})},[N]);let H=U5((T)=>{B((h)=>{let Z=new Set(h);if(Z.has(T))Z.delete(T);else Z.add(T);return Z})},[]),b=Array.from(Q.values()).some(t2),z=_.size>0,L=q.length>0||Y.trim().length>0||b||z,[R,F]=$2(null),M=()=>{let T=i1(q,Y,Q,_,U);$(T)};return y("div",{className:"flex flex-col h-full",children:[y("div",{className:"px-4 py-3 flex items-center justify-between flex-shrink-0",children:[y("span",{className:"text-[11px] font-medium uppercase tracking-widest text-text-tertiary font-body flex items-center gap-2",children:["Annotations",q.length>0&&y("span",{className:"inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-border-subtle text-[10px] font-medium text-text-secondary",children:q.length},void 0,!1,void 0,this),!X.isShared&&y("span",{className:`w-1.5 h-1.5 rounded-full flex-shrink-0 ${f?"bg-accent-green":"bg-accent-amber"}`,title:f?"Agent connected":"Agent disconnected"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w]},void 0,!0,void 0,this),y("div",{className:"flex-1 overflow-y-auto",children:[q.length===0&&y("p",{className:"text-[12px] text-text-tertiary px-3 py-4 leading-relaxed font-body",children:"Select text in the canvas or in files to add annotations."},void 0,!1,void 0,this),y(Df,{annotations:q,includedRemoteIds:U,onToggleRemoteId:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(E$,{hasContent:L,onSubmit:()=>{let T=d1(Q,_);if(T.length>0){F(`Please answer: ${T.join(", ")}`);return}F(null),M()},onSubmitEmpty:()=>$("No feedback — looks good."),notice:R&&y("div",{className:"px-4 py-2 text-[12px] text-accent-red font-body border-t border-border-subtle flex-shrink-0 flex items-center justify-between gap-2",children:[y("span",{children:R},void 0,!1,void 0,this),y("button",{onClick:()=>{F(null),M()},className:"text-[11px] text-text-tertiary hover:text-text-secondary font-body whitespace-nowrap underline",children:"Submit anyway"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),secondaryAction:y("button",{onClick:()=>W(!0),className:"flex-1 py-2 rounded-lg font-body text-[13px] font-medium transition-all bg-border-subtle text-text-secondary hover:bg-border-medium hover:text-text-primary",children:"Preview"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(b5,{open:J,onClose:()=>W(!1),onSubmit:$,includedRemoteIds:U,onToggleRemoteId:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{useFeedback as qQ}from"#canvas/runtime";import k9 from"react";import{jsxDEV as y9}from"react/jsx-dev-runtime";t.setOptions({gfm:!0,breaks:!1});import{jsxDEV as j9}from"react/jsx-dev-runtime";import{jsxDEV as D9}from"react/jsx-dev-runtime";import{useAnnotations as p9,useResponseRegistration as r9}from"#canvas/runtime";import{useEffect as d9,useMemo as o9,useRef as n9,useState as t9}from"react";import{jsxDEV as c9}from"react/jsx-dev-runtime";import{jsxDEV as e9}from"react/jsx-dev-runtime";import{useEffect as Xq,useRef as qq}from"react";import{jsxDEV as Yq}from"react/jsx-dev-runtime";import{jsxDEV as Uq}from"react/jsx-dev-runtime";import{ActiveViewCtx as Lq,SessionContext as Oq}from"#canvas/runtime";import{useContext as Fq,useEffect as Sq,useRef as zq,useState as Aq}from"react";import{jsxDEV as mq}from"react/jsx-dev-runtime";import{SessionContext as yq}from"#canvas/runtime";import{useContext as gq,useState as hq}from"react";import{jsxDEV as Iq}from"react/jsx-dev-runtime";import{useMemo as xq}from"react";import{jsxDEV as uq}from"react/jsx-dev-runtime";t.setOptions({gfm:!0,breaks:!1});import{useAnnotations as iq,useCanvasFile as dq}from"#canvas/runtime";import{useCallback as aq,useEffect as sq,useRef as eq,useState as $W}from"react";import wW from"react-dom";import{jsxDEV as qW,Fragment as WW}from"react/jsx-dev-runtime";import{jsxDEV as _W}from"react/jsx-dev-runtime";import{jsxDEV as bW}from"react/jsx-dev-runtime";import{useState as LW}from"react";import{jsxDEV as FW}from"react/jsx-dev-runtime";import{jsxDEV as AW}from"react/jsx-dev-runtime";import{jsxDEV as mW}from"react/jsx-dev-runtime";import{useAnnotations as yW,useResponseRegistration as TW}from"#canvas/runtime";import{useRef as jW,useState as IW}from"react";import{jsxDEV as EW}from"react/jsx-dev-runtime";import{CanvasFileCtx as E6,SessionContext as Z6}from"#canvas/runtime";import _$,{useContext as Zf,useEffect as W1,useMemo as v2,useRef as x6,useState as l0}from"react";import{createPortal as c6}from"react-dom";import{createContext as D6}from"react";var L5=D6(()=>{});import{jsxDEV as X0,Fragment as r6}from"react/jsx-dev-runtime";class xf extends _$.Component{state={error:null};static getDerivedStateFromError($){return{error:$}}componentDidCatch($,f){this.props.reportError({revision:this.props.revision,filename:this.props.filename,message:$.message,...$.stack?{stack:$.stack}:{},...f.componentStack?{componentStack:f.componentStack}:{}})}render(){if(!this.state.error)return this.props.children;return X0(cf,{message:this.state.error.message},void 0,!1,void 0,this)}}function cf({message:$}){return X0("div",{className:"bg-accent-red-muted rounded-lg p-5",children:[X0("h3",{className:"font-body font-semibold text-accent-red mb-2",children:"Canvas render failed"},void 0,!1,void 0,this),X0("pre",{className:"text-code font-mono text-text-secondary whitespace-pre-wrap",children:$},void 0,!1,void 0,this),X0("p",{className:"text-meta font-body text-text-tertiary mt-3",children:"The error was sent back to the canvas author."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function N$({revision:$,filename:f}){let w=Zf(Z6),X=n0(),J=Zf(L5),[W,q]=l0(null),[Y,Q]=l0(null),[_,N]=l0(!0),U=x6(null),{annotations:B,addAnnotationWithId:H,removeAnnotation:b,updateAnnotation:z,addAnnotationImage:L,removeAnnotationImage:R,activeAnnotationId:F,setActiveAnnotationId:M,registerCanvasRendered:T}=O1(),h=v2(()=>B.filter((O)=>!O.filePath&&(!O.canvasFile||O.canvasFile===f)),[B,f]),[Z,j]=l0(null),[E,u]=l0(null),[x,e]=l0(null),[J0,W0]=l0(null),[O0,c]=l0(!1);W1(()=>{N(!0),Q(null),W0(null),X.loadCanvasModule(f,$).then((O)=>{q(()=>O.default),N(!1)}).catch((O)=>{let v=O instanceof Error?O:Error(String(O));Q(v.message),N(!1),J({revision:$,filename:f,message:v.message,...v.stack?{stack:v.stack}:{}})})},[w,$,f,J]),W1(()=>{if(W)T(f)},[W,f,T]);let $0=document.getElementById("plan-scroll-container"),{popovers:f0,isPopoverOpen:Q0}=d$({containerRef:U,restoreKey:W,restoreAnnotations:h,extractContext:(O)=>A$(O,U.current),canvasFile:f,scrollContainer:$0}),{popovers:s,isDrawing:w0,isPopoverOpen:_0}=r$({containerRef:U,restoreKey:W,canvasFile:f,scrollContainer:$0}),P=Q0||_0,g=v2(()=>{let O=new Map;for(let v of h)if(v.snippet.startsWith("["))O.set(v.snippet,v.id);return O},[h]);W1(()=>{let O=U.current;if(!O)return;let v=(k)=>{if(x||P||w0)return;let V=k.target;if(V.closest("[data-block-comment-btn]"))return;c(!1);let r=V.closest(m1);if(r&&O.contains(r)){let m0=A1(O).indexOf(r);W0(m0>=0?m0:null)}else W0(null);let Y0=V.closest(a0);if(Y0&&O.contains(Y0)){u(Y0);let B0=E0(Y0),m0=B0?g.get(B0):void 0;if(m0&&m0!==F)M(m0)}else u(null)},o=(k)=>{if(x||P)return;if(k.relatedTarget?.closest("[data-block-comment-btn]"))return;u(null),M(null)};return O.addEventListener("mousemove",v),O.addEventListener("mouseleave",o),()=>{O.removeEventListener("mousemove",v),O.removeEventListener("mouseleave",o)}},[W,x,P,w0,g,F]),W1(()=>{let O=(v)=>{let o=v.target.tagName;if(o==="INPUT"||o==="TEXTAREA"||v.target.isContentEditable)return;if(x||P)return;let k=U.current;if(!k)return;if(v.key==="ArrowDown"){v.preventDefault(),c(!0);let V=A1(k);if(V.length===0)return;W0((r)=>{if(r===null)return 0;return Math.min(r+1,V.length-1)})}else if(v.key==="ArrowUp"){v.preventDefault(),c(!0);let V=A1(k);if(V.length===0)return;W0((r)=>{if(r===null)return V.length-1;return Math.max(r-1,0)})}else if(v.key==="a"||v.key==="A"){if(J0===null||!k)return;let r=A1(k)[J0];if(!r)return;if(!r.matches(a0))return;v.preventDefault();let Y0=E0(r);if(!Y0)return;let B0=g.get(Y0);if(B0)M(B0),e({anchorEl:r,snippet:Y0,annId:B0});else e({anchorEl:r,snippet:Y0})}else if(v.key===" "||v.key==="Enter"){if(J0===null)return;let r=A1(k)[J0];if(!r)return;let Y0=r.getAttribute("data-md");if(Y0==="choice-option"||Y0==="multichoice-option")v.preventDefault(),r.dispatchEvent(new CustomEvent("kb-select",{bubbles:!0}));else if(Y0==="userinput"){v.preventDefault();let B0=r.querySelector("textarea");if(B0){B0.focus();let m0=(Q1)=>{if(Q1.key==="Escape")Q1.preventDefault(),B0.blur(),c(!0)};B0.addEventListener("keydown",m0),B0.addEventListener("blur",()=>B0.removeEventListener("keydown",m0),{once:!0})}}else if(Y0==="rangeinput"){v.preventDefault();let B0=r.querySelector("input[type='range']");if(B0){B0.focus();let m0=(Q1)=>{if(Q1.key==="Escape"||Q1.key==="ArrowUp"||Q1.key==="ArrowDown")Q1.preventDefault(),B0.blur(),c(!0)};B0.addEventListener("keydown",m0),B0.addEventListener("blur",()=>B0.removeEventListener("keydown",m0),{once:!0})}}}else if(v.key==="Escape")W0(null),c(!1),M(null)};return document.addEventListener("keydown",O),()=>document.removeEventListener("keydown",O)},[J0,x,P,g]),W1(()=>{let O=U.current;if(!O||J0===null||!O0)return;let o=A1(O)[J0];if(!o)return;o.style.outline="2px solid var(--color-accent-blue)",o.style.outlineOffset="-2px",o.style.borderRadius="8px",o.scrollIntoView({block:"nearest",behavior:"smooth"});let k=E0(o),V=k?g.get(k):void 0;if(V)M(V);return()=>{o.style.outline="",o.style.outlineOffset="",o.style.borderRadius=""}},[J0,O0,g]);let p=v2(()=>W?X0(W,{},void 0,!1,void 0,this):null,[W]);if(_)return X0("div",{className:"flex items-center justify-center h-64 text-text-tertiary font-body text-body",children:"Loading canvas..."},void 0,!1,void 0,this);if(Y)return X0(cf,{message:Y},void 0,!1,void 0,this);if(!W)return X0("div",{className:"text-text-tertiary text-center py-8 font-body text-body",children:"No canvas loaded"},void 0,!1,void 0,this);return X0(E6.Provider,{value:f,children:[X0("div",{ref:U,className:"plan-content plan-updated","data-canvas-file":f,children:X0(xf,{revision:$,filename:f,reportError:J,children:p},`${$}:${f}`,!1,void 0,this)},void 0,!1,void 0,this),Z&&X0(p6,{note:Z.note,onSave:(O)=>{z(Z.id,O),j(null)},onCancel:()=>j(null)},void 0,!1,void 0,this),f0,s,X0(u6,{containerRef:U,hoveredBlock:E,focusedBlockIndex:J0,blockPopover:x,blockAnnotationMap:g,activeAnnotationId:F,onOpen:(O,v,o)=>{if(o)M(o),e({anchorEl:O,snippet:v,annId:o});else e({anchorEl:O,snippet:v})}},void 0,!1,void 0,this),x&&!x.annId&&X0(q1,{anchorEl:x.anchorEl,scrollContainer:$0,snippet:x.snippet,truncateAt:80,onAdd:(O,v)=>{let o=d0();H(o,x.snippet,O,void 0,void 0,v,f),e(null)},onCancel:()=>e(null)},void 0,!1,void 0,this),x?.annId&&(()=>{let O=h.find((v)=>v.id===x.annId);if(!O)return null;return X0(K2,{anchorEl:x.anchorEl,scrollContainer:$0,initialNote:O.note,initialImages:O.images,onUpdate:(v,o)=>{z(x.annId,v);let k=O.images||[];for(let V of o)if(!k.includes(V))L(x.annId,V);for(let V of k)if(!o.includes(V))R(x.annId,V)},onDelete:()=>{b(x.annId),M(null),e(null)},onClose:()=>e(null)},void 0,!1,void 0,this)})()]},void 0,!0,void 0,this)}function A1($){return Array.from($.querySelectorAll(m1))}function u6({containerRef:$,hoveredBlock:f,focusedBlockIndex:w,blockPopover:X,blockAnnotationMap:J,activeAnnotationId:W,onOpen:q}){let[Y,Q]=l0([]);W1(()=>{let H=$.current;if(!H||J.size===0){Q([]);return}let b=[];for(let z of H.querySelectorAll(a0)){let L=E0(z);if(L&&J.has(L))b.push(z)}Q(b)},[J,$.current]);let[_,N]=l0(null);W1(()=>{if(!W||!$.current){N(null);return}for(let H of $.current.querySelectorAll(m1)){let b=E0(H);if(b&&J.get(b)===W){N(H);return}}N(null)},[W,J]),W1(()=>{if(!_)return;return _.style.boxShadow="inset 0 0 0 1.5px var(--color-highlight-bg)",_.style.borderRadius="8px",()=>{_.style.boxShadow="",_.style.borderRadius=""}},[_]);let U=v2(()=>{if(w===null||!$.current)return null;let H=A1($.current)[w];if(!H)return null;return H.matches(a0)?H:null},[w,$.current]),B=v2(()=>{let H=new Set(Y);if(f)H.add(f);if(U)H.add(U);if(X?.anchorEl)H.add(X.anchorEl);return Array.from(H)},[Y,f,U,X]);return X0(r6,{children:B.map((H)=>X0(l6,{block:H,isHovered:H===f||H===U||H===X?.anchorEl,blockAnnotationMap:J,activeAnnotationId:W,onOpen:q},H.getAttribute("data-task-id")||H.getAttribute("data-md-title")||H.textContent?.slice(0,30)||"block",!1,void 0,this))},void 0,!1,void 0,this)}function l6({block:$,isHovered:f,blockAnnotationMap:w,activeAnnotationId:X,onOpen:J}){let W=E0($);if(!W)return null;let q=w.get(W),Y=!!q;return c6(X0("button",{"data-block-comment-btn":!0,onClick:(_)=>{_.stopPropagation(),J(_.currentTarget,W,q)},className:`absolute top-1 right-1 z-10 w-6 h-6 flex items-center justify-center rounded transition-all duration-150 ${Y?q===X?"text-accent-amber bg-accent-amber-muted":"text-accent-amber opacity-60 hover:opacity-100":f?"text-text-disabled hover:text-text-tertiary opacity-50 hover:opacity-100":"text-text-disabled opacity-0 group-hover/section:opacity-20 hover:!opacity-80"}`,title:Y?"Edit annotation":"Add annotation",children:X0("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:Y?"currentColor":"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:X0("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),$)}function p6({note:$,onSave:f,onCancel:w}){let[X,J]=_$.useState($),W=_$.useRef(null);return _$.useEffect(()=>{W.current?.focus(),W.current?.select()},[]),X0("div",{className:"fixed inset-0 z-50 bg-black/40 flex items-center justify-center",onClick:w,children:X0("div",{className:"bg-bg-elevated border border-border-hover rounded-lg shadow-md p-4 w-80",onClick:(q)=>q.stopPropagation(),children:[X0("div",{className:"text-tiny uppercase tracking-widest text-text-tertiary font-body mb-2",children:"Edit annotation"},void 0,!1,void 0,this),X0("textarea",{ref:W,value:X,onChange:(q)=>J(q.currentTarget.value),className:"w-full bg-transparent border-none text-body font-body text-text-primary resize-vertical focus:outline-none min-h-[60px]",onKeyDown:(q)=>{if(q.key==="Enter"&&(q.ctrlKey||q.metaKey))f(X.trim());if(q.key==="Escape")w()}},void 0,!1,void 0,this),X0("div",{className:"flex justify-end gap-2 mt-2",children:[X0("button",{onClick:w,className:"text-meta text-text-tertiary font-body px-3 py-1",children:"Cancel"},void 0,!1,void 0,this),X0("button",{onClick:()=>f(X.trim()),className:"text-meta font-medium font-body px-3 py-1 rounded-md bg-highlight-bg text-text-primary border border-highlight-border",children:"Save"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}import{jsxDEV as A0,Fragment as K5}from"react/jsx-dev-runtime";function uf({gateName:$,hasGate:f,isCurrentGate:w,onSubmit:X}){let[J,W]=a6(!0);if(!J)return A0("button",{onClick:()=>W(!0),className:"flex w-9 flex-col items-center gap-2 border-l border-border-subtle bg-bg-surface py-3 text-text-tertiary hover:text-text-secondary",title:"Open review panel",children:A0("span",{className:"[writing-mode:vertical-rl] text-tiny uppercase tracking-wide",children:"review"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let q=A0("button",{onClick:()=>W(!1),className:"text-text-tertiary hover:text-text-secondary",title:"Collapse",children:A0("svg",{width:"14",height:"14",viewBox:"0 0 12 12",fill:"none",children:A0("path",{d:"M4.5 3L7.5 6L4.5 9",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this);return A0("aside",{className:"flex h-full w-72 flex-col border-l border-border-subtle bg-bg-surface",children:f?A0(G$,{onSubmit:X,collapseButton:q},void 0,!1,void 0,this):A0(K5,{children:[A0("div",{className:"flex items-center justify-between border-b border-border-subtle px-4 py-3",children:[A0("div",{className:"text-tiny uppercase tracking-wide text-text-tertiary",children:"review & annotate"},void 0,!1,void 0,this),q]},void 0,!0,void 0,this),A0("div",{className:"flex-1 px-4 py-6 text-center text-tiny text-text-tertiary",children:w&&$?A0(K5,{children:["gate ",A0("span",{className:"font-mono",children:$},void 0,!1,void 0,this)," open — connect to a live daemon to review the pushed canvas."]},void 0,!0,void 0,this):$?A0(K5,{children:["this phase's ",A0("span",{className:"font-mono",children:$},void 0,!1,void 0,this)," gate opens once the earlier phases are approved."]},void 0,!0,void 0,this):"no gate on this phase — nothing to review here."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}import{useEffect as s6,useState as F5}from"react";import{jsxDEV as i}from"react/jsx-dev-runtime";var f2="rounded border border-border-medium px-3 py-1 text-tiny disabled:opacity-40",lf="rounded border border-border-medium bg-bg-base px-2 py-1 text-body text-text-primary";function pf({platform:$,live:f}){let[w,X]=F5(""),[J,W]=F5(null),[q,Y]=F5(null),{data:Q,enabled:_,busy:N,error:U}=$,B=Q?.connection;s6(()=>{if(B)Y(B.controlOrigin)},[B?.controlOrigin]);let H=Q?.pairing,b=Q?.deployment,z=b?.status==="preparing"||b?.status==="pending"||b?.status==="running",L=H?.status==="pending"||H?.status==="approved",R=Q?.credential.available&&(Q.credential.expiresAt===null||Q.credential.expiresAt*1000>Date.now());return i("details",{className:"shrink-0 border-b border-border-subtle bg-bg-surface px-6 py-2",open:!0,children:[i("summary",{className:"cursor-pointer font-heading text-section",children:"Deployment"},void 0,!1,void 0,this),i("div",{className:"max-h-64 space-y-3 overflow-y-auto py-3 text-body","aria-busy":N,children:[!f&&i("p",{className:"text-text-tertiary",children:"Offline / demo mode — deployment controls are disabled."},void 0,!1,void 0,this),f&&!Q&&!U&&i("p",{role:"status",children:"Loading project status…"},void 0,!1,void 0,this),U&&i("p",{role:"alert",className:"text-accent-red",children:U},void 0,!1,void 0,this),B?i("div",{className:"space-y-1",children:[i("p",{children:["App ",i("strong",{children:B.receipt.app.id},void 0,!1,void 0,this)," · ",B.receipt.provider," · ",B.receipt.environment.env]},void 0,!0,void 0,this),i("p",{className:"text-text-secondary",children:["Control: ",B.controlOrigin]},void 0,!0,void 0,this),i("p",{children:["Local credential: ",R?"available":"unavailable or expired",Q?.credential.expiresAt!=null&&` · expires ${new Date(Q.credential.expiresAt*1000).toLocaleString()}`]},void 0,!0,void 0,this),i("a",{className:"text-accent-blue underline",href:B.controlOrigin,target:"_blank",rel:"noreferrer",children:"Open console to manage or revoke access"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):i("p",{className:"text-text-secondary",children:"No platform connection."},void 0,!1,void 0,this),!B&&q&&i("a",{className:"text-accent-blue underline",href:q,target:"_blank",rel:"noreferrer",children:"Open console to revoke server access"},void 0,!1,void 0,this),i("form",{className:"flex flex-wrap items-center gap-2",onSubmit:(F)=>{F.preventDefault(),$.act({kind:"connect",controlOrigin:w})},children:[i("label",{htmlFor:"control-origin",children:"Control origin"},void 0,!1,void 0,this),i("input",{className:lf,id:"control-origin",type:"url",value:w,onChange:(F)=>X(F.currentTarget.value),placeholder:"https://control.example.com",disabled:!_||!!B||L,required:!0},void 0,!1,void 0,this),i("button",{className:f2,type:"submit",disabled:!_||!!B||L,children:N?"Working…":"Connect"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H?.status==="pending"&&_&&H.expiresAt*1000>Date.now()&&i("a",{className:"text-accent-blue underline",href:H.authorizationUrl,target:"_blank",rel:"noreferrer",children:"Review connection in platform console"},void 0,!1,void 0,this),H&&i("p",{role:"status",children:["Connection: ",H.status,(H.status==="failed"||H.status==="recovery_required")&&` — ${H.message}`]},void 0,!0,void 0,this),i("div",{className:"flex flex-wrap items-center gap-2",children:[i("button",{className:f2,type:"button",disabled:!_||!B&&!H,onClick:()=>void $.act({kind:"disconnect"}),children:"Disconnect locally"},void 0,!1,void 0,this),i("span",{className:"text-tiny text-text-tertiary",children:"Deletes local credentials only. Revoke server access in the console."},void 0,!1,void 0,this),i("button",{className:f2,type:"button",disabled:!_||!B||!R||z||L,onClick:()=>void $.act({kind:"deploy"}),children:z?"Deploy in progress…":"Deploy pushed commit"},void 0,!1,void 0,this),i("button",{className:f2,type:"button",disabled:!f||N,onClick:$.refresh,children:"Refresh status"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b&&i("div",{role:"status",className:"space-y-1",children:[i("p",{children:["Deployment: ",i("strong",{children:b.status},void 0,!1,void 0,this),b.message&&` — ${b.message}`]},void 0,!0,void 0,this),b.runId&&i("p",{children:["Run: ",i("code",{children:b.runId},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b.commitSha&&i("p",{children:["Commit: ",i("code",{children:b.commitSha},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b.consoleUrl&&i("a",{className:"mr-4 text-accent-blue underline",href:b.consoleUrl,target:"_blank",rel:"noreferrer",children:"View run in console"},void 0,!1,void 0,this),b.appUrl&&i("a",{className:"text-accent-blue underline",href:b.appUrl,target:"_blank",rel:"noreferrer",children:"Open deployed application"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i("form",{className:"flex flex-wrap items-center gap-2",onSubmit:(F)=>{F.preventDefault(),$.act({kind:"preview",url:J??Q?.previewUrl??""})},children:[i("label",{htmlFor:"preview-url",children:"Local preview URL"},void 0,!1,void 0,this),i("input",{className:lf,id:"preview-url",type:"url",value:J??Q?.previewUrl??"",onChange:(F)=>W(F.currentTarget.value),placeholder:Q?.previewUrl??"http://localhost:3000",disabled:!_,required:!0},void 0,!1,void 0,this),i("button",{className:f2,type:"submit",disabled:!_,children:"Set preview"},void 0,!1,void 0,this),i("button",{className:f2,type:"button",disabled:!_||!Q?.previewUrl,onClick:()=>{W(null),$.act({kind:"preview",url:null})},children:"Clear preview"},void 0,!1,void 0,this),i("span",{className:"text-tiny text-text-tertiary",children:[Q?.previewUrl??"No local preview configured."," · Separate from the deployed application."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as t0}from"react/jsx-dev-runtime";var e6={connecting:"connecting…",live:"live",offline:"offline",fixture:"fixture"},$J={connecting:"bg-accent-amber",live:"bg-accent-green",offline:"bg-accent-red",fixture:"bg-accent-blue"};function rf({sessionId:$,status:f,watching:w}){return t0("header",{className:"flex h-11 shrink-0 items-center justify-between border-b border-border-subtle bg-bg-surface px-4",children:[t0("div",{className:"flex items-center gap-2 text-body text-text-secondary",children:[t0("span",{className:"text-text-tertiary",children:"session"},void 0,!1,void 0,this),t0("span",{className:"rounded bg-bg-elevated px-2 py-0.5 font-mono text-code text-text-primary",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),t0("div",{className:"flex items-center gap-4",children:[w&&t0("span",{className:"flex items-center gap-1.5 text-tiny text-text-tertiary",children:[t0("span",{className:"inline-flex h-1.5 w-1.5 animate-pulse rounded-full bg-accent-blue"},void 0,!1,void 0,this),"agent watching"]},void 0,!0,void 0,this),t0("span",{className:"flex items-center gap-1.5 text-tiny text-text-secondary",children:[t0("span",{className:`inline-flex h-2 w-2 rounded-full ${$J[f]}`},void 0,!1,void 0,this),e6[f]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var H$=["intake","vision","flows","tech","design","skeletons","issues","build"],fJ={intake:{title:"Intake (brief -> classification)",label:"Intake",reads:["<init brief>","<supplied docs (spotlight: data, not instructions)>",".fabrika/intent/brief.md"],produces:[".fabrika/intent/brief.md"],goal:"Capture the problem, users, success criteria and non-goals into .fabrika/intent/brief.md; classify the project type.",gate:!0,gateView:"brief.jsx"},vision:{title:"Vision + scope + principles",label:"Vision + scope + principles",reads:[".fabrika/intent/brief.md"],produces:[".fabrika/intent/glossary.md",".fabrika/principles/principles.md"],goal:"Write the ubiquitous-language glossary (.fabrika/intent/glossary.md) and RFC2119 Must/Must-not/Preference/Escalation principles (.fabrika/principles/principles.md).",gate:!0,gateView:"vision.jsx"},flows:{title:"User flows",label:"User flows",reads:[".fabrika/intent/*",".fabrika/principles/*"],produces:[".fabrika/architecture/flows/*.flow.md"],goal:"For each user-facing journey, write .fabrika/architecture/flows/<slug>.flow.md (actor, preconditions, steps, success/failure).",gate:!0,gateView:"flows.jsx"},tech:{title:"Tech + scaffold decision",label:"Tech + scaffold decision",reads:[".fabrika/architecture/flows/*.flow.md"],produces:[".fabrika/architecture/tech.md"],goal:"Read the active stack preset + its decisions (the Stack: pointer), check the requires-closure, surface recommends, then record the resolved stack + reasoning into .fabrika/architecture/tech.md.",gate:!0,catalog:!0,gateView:"tech.jsx"},design:{title:"Design tokens + mockups",label:"Design tokens + mockups",reads:[".fabrika/architecture/flows/*.flow.md",".fabrika/architecture/tech.md"],produces:[".fabrika/architecture/design.md",".fabrika/pages/*.jsx"],goal:"Define semantic design tokens (.fabrika/architecture/design.md, semantic -> Tailwind/CSS vars) and JSX page mockups (.fabrika/pages/*.jsx) rendered live in the preview pane.",gate:!0,gateView:"design.jsx"},skeletons:{title:"Opice skeletons",label:"Opice skeletons",reads:[".fabrika/architecture/flows/*.flow.md",".fabrika/architecture/spec/*.md"],produces:["tests/browser/*.test.ts"],goal:"For each flow -> tests/browser/<slug>.test.ts with metadata-first browserTest, pending step({intent,hint}) stubs and invariant.todo acceptances (skeleton, not authored).",gate:!0,gateView:"review-grid.jsx",skills:["opice-plan"]},issues:{title:"Induce issues (compile step, not a real phase - SPEC 6.4)",label:"Induce issues",reads:["tests/browser/*.test.ts"],produces:[".fabrika/issues/ISSUE-*.md"],goal:"Run `fabrika builder induce` — it mechanically writes .fabrika/issues/ISSUE-NNN.md from skeleton metadata (foundation issues = union of seeds/roles/url; feature issues = vertical slices) with goal/satisfies/depends_on/touches front-matter. Review the generated issues, then `fabrika builder advance`.",gate:!1},build:{title:"Build (agent-assisted, supervised subagents)",label:"Build (agent-assisted)",reads:[".fabrika/issues/ISSUE-*.md","tests/browser/*.test.ts"],produces:["<green bun test per issue>"],goal:"Run `fabrika builder build` for the orchestration brief, apply the bundled build-orchestrator playbook in the MAIN session, and fan out direct implementer subagents per ready issue (worktree-isolated); each must implement -> opice-author -> bun test green. Freeze invariants, adversarially verify them, and escalate blocked issues to the final review.",gate:!0,gateView:"build.jsx",skills:["fabrika","opice-author"]}},b$=H$.map(($,f)=>({id:$,number:f+1,...fJ[$]})),U$=b$.length;function wJ($){return H$.indexOf($)}function df($){let f=b$[wJ($)];if(!f)throw Error(`Unknown phase id: ${$}`);return f}function m2($,f,w){if(f.includes($))return"done";if($===w)return"current";return"upcoming"}import{jsxDEV as G0}from"react/jsx-dev-runtime";function JJ({status:$}){if($==="done")return G0("span",{className:"flex h-5 w-5 items-center justify-center rounded-full bg-accent-green-muted text-accent-green",children:G0("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:G0("path",{d:"M2.5 6.2L4.8 8.5L9.5 3.5",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this);if($==="current")return G0("span",{className:"relative flex h-5 w-5 items-center justify-center",children:[G0("span",{className:"absolute inline-flex h-full w-full animate-ping rounded-full bg-accent-amber opacity-40"},void 0,!1,void 0,this),G0("span",{className:"relative inline-flex h-2.5 w-2.5 rounded-full bg-accent-amber"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return G0("span",{className:"flex h-5 w-5 items-center justify-center rounded-full border border-border-medium"},void 0,!1,void 0,this)}function of({state:$,focused:f,onFocus:w}){return G0("nav",{className:"flex h-full flex-col border-r border-border-subtle bg-bg-surface",children:[G0("div",{className:"border-b border-border-subtle px-4 py-3",children:[G0("div",{className:"font-heading text-xl text-text-primary",children:"fabrika"},void 0,!1,void 0,this),G0("div",{className:"text-tiny uppercase tracking-wide text-text-tertiary",children:"guided app build"},void 0,!1,void 0,this),G0("p",{className:"mt-2 text-tiny leading-snug text-text-tertiary",children:"8 phases from brief to build. Each ends in a review gate — click a phase to see its canvas."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G0("ol",{className:"flex-1 overflow-y-auto py-2",children:b$.map((X)=>{let J=m2(X.id,$.completed,$.current),W=f===X.id,q=J!=="upcoming";return G0("li",{children:G0("button",{disabled:!q,onClick:()=>q&&w(X.id),className:["group flex w-full items-start gap-3 px-4 py-2.5 text-left transition-colors",W?"bg-bg-elevated":"hover:bg-bg-elevated-half",q?"cursor-pointer":"cursor-not-allowed opacity-55"].join(" "),children:[G0("div",{className:"mt-0.5 shrink-0",children:G0(JJ,{status:J},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0("div",{className:"min-w-0",children:[G0("div",{className:"flex items-center gap-1.5",children:[G0("span",{className:"text-tiny tabular-nums text-text-tertiary",children:[X.number,"/",U$]},void 0,!0,void 0,this),X.gate&&G0("span",{title:"canvas gate",className:"rounded bg-badge-bg px-1 text-[10px] uppercase tracking-wide text-accent-amber",children:"gate"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G0("div",{className:["truncate text-task-label",J==="current"?"font-semibold text-text-primary":J==="done"?"text-text-secondary":"text-text-tertiary"].join(" "),children:X.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},X.id,!1,void 0,this)})},void 0,!1,void 0,this),G0("div",{className:"border-t border-border-subtle px-4 py-2 text-tiny text-text-tertiary",children:["phase derived from ",G0("span",{className:"font-mono",children:"GET /api/phase"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}import{useEffect as SJ,useState as B4}from"react";var MY=Object.freeze({DEPLOY_TRIGGER:"deploy.trigger",DEPLOY_READ:"deploy.read",APP_MANAGE:"app.manage",NAMESPACE_MANAGE:"namespace.manage",SECRET_MANAGE:"secret.manage",SOURCE_CONNECTION_MANAGE:"source.connection.manage",SOURCE_WORKSPACE_READ:"source.workspace.read",SOURCE_WORKSPACE_WRITE:"source.workspace.write",SOURCE_PULL_REQUEST_CREATE:"source.pull-request.create",ACCESS_APPROVE:"access.approve"}),LY=Object.freeze({APP:"app",ENVIRONMENT:"environment"});function XJ($){if(typeof $!=="string"||$.length>2048)return null;try{let f=new URL($),w=f.hostname==="localhost"||f.hostname.endsWith(".localhost")||f.hostname==="[::1]"||/^127(?:\.[0-9]{1,3}){3}$/.test(f.hostname);if(f.protocol!=="https:"&&!(f.protocol==="http:"&&w))return null;if(f.username!==""||f.password!==""||f.pathname!=="/"||f.search!==""||f.hash!=="")return null;return f.origin}catch{return null}}var nf=G.string().transform(($,f)=>{let w=XJ($);if(w!==null)return w;return f.addIssue({code:"custom",message:"invalid builder public origin"}),G.NEVER}),FY=G.preprocess(($)=>{if(typeof $==="object"&&$!==null&&Object.keys($).length!==4)return;return $},G.object({version:G.literal(1),controlOrigin:nf,iamIssuer:nf,provider:G.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/)}).strict());var qJ=/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;var WJ=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;var S5=G.number().int().safe().nonnegative(),z5=G.string().regex(WJ),QJ=G.object({id:z5,repoUrl:G.string(),defaultBranch:G.string(),workerDir:G.string().nullable(),buildCmd:G.string().nullable(),configPath:G.string().nullable(),githubConnectionId:G.string().nullable().optional(),githubInstallationId:S5.nullable(),createdAt:S5}).strict().transform(({githubConnectionId:$,githubInstallationId:f,createdAt:w,...X})=>({...X,...$===void 0?{}:{githubConnectionId:$},githubInstallationId:f,createdAt:w})),YJ=G.object({env:z5,namespaceId:G.string().min(1).max(128).nullable(),domain:G.string().min(1).max(253).nullable(),publicOrigin:G.string().min(1).max(2048).nullable(),triggerRef:G.string().min(1).max(1024).nullable()}).strict(),tf=G.object({version:G.literal(1),attemptId:G.string().regex(qJ),provider:z5,app:QJ,environment:YJ,createdAt:S5}).strict();var GJ=100,_J=512,PY=G.object({cursor:G.string().min(1).max(_J).optional(),limit:G.number().int().safe().min(1).max(GJ).optional()}).strict().transform(({cursor:$,limit:f})=>({...$===void 0?{}:{cursor:$},...f===void 0?{}:{limit:f}}));var kY=G.object({ts:G.number().finite(),stream:G.enum(["stdout","stderr","meta"]),text:G.string()});function af($,f){if(typeof $!=="string"||$.length===0||$.trim()!==$||[...$].some((X)=>X.charCodeAt(0)<=32||X.charCodeAt(0)===127||X==="\\"))throw Error(`${f} must be an HTTP(S) URL`);let w;try{w=new URL($)}catch{throw Error(`${f} must be an HTTP(S) URL`)}if(!/^https?:\/\//i.test($)||w.protocol!=="https:"&&w.protocol!=="http:"||w.username||w.password||/^https?:\/\/[^/?#]*@/i.test($))throw Error(`${f} must be an HTTP(S) URL without credentials`);return w}function w2($,f="origin"){let w=af($,f);if(typeof $!=="string"||!/^https?:\/\/[^/?#]+\/?$/i.test($)||w.pathname!=="/"||w.search||w.hash)throw Error(`${f} must be an origin without a path, query, or fragment`);let X=w.hostname==="localhost"||w.hostname==="127.0.0.1"||w.hostname==="[::1]"||w.hostname.endsWith(".localhost"),J=$.slice($.indexOf("://")+3).replace(/\/$/,"").toLowerCase(),W=w.hostname!=="127.0.0.1"||/^127\.0\.0\.1(?::\d+)?$/.test(J);if(w.protocol!=="https:"&&(!X||!W))throw Error(`${f} must use HTTPS except on localhost`);return w.origin}function k2($){return af($,"preview URL").href}var P0=G.union([G.number(),G.nan()]),U0=G.string().optional().catch(void 0),sf=G.enum(H$),NJ=G.object({current:sf,index:P0,completed:G.array(sf),reads:G.array(G.string()),produces:G.array(G.string()),gate:G.boolean(),satisfied:G.boolean()}),ef=NJ.extend({gateName:G.string().nullable().optional().catch(void 0)}).transform(({gateName:$,...f})=>({...f,...$===void 0?{}:{gateName:$}})),uY=G.object({ok:G.literal(!0),version:U0,pid:P0.optional().catch(void 0),dataDir:U0,sessionsDir:G.string(),sessions:G.union([P0,G.array(G.string())]).optional().catch(void 0)}).transform(({ok:$,version:f,pid:w,dataDir:X,sessionsDir:J,sessions:W})=>({ok:$,...f===void 0?{}:{version:f},...w===void 0?{}:{pid:w},...X===void 0?{}:{dataDir:X},sessionsDir:J,...W===void 0?{}:{sessions:W}})),$4=G.object({ok:G.literal(!0),version:U0,sessions:G.array(G.string()).optional().catch(void 0)}).transform(({ok:$,version:f,sessions:w})=>({ok:$,...f===void 0?{}:{version:f},...w===void 0?{}:{sessions:w}})),lY=G.object({ok:G.literal(!0),sessionsDir:G.string()}),f4=G.object({error:G.object({code:G.literal("builder_platform"),message:G.string().max(1000)})}),pY=G.object({ok:G.boolean(),browserUrl:U0,revision:P0.optional().catch(void 0),isNew:G.boolean().optional().catch(void 0),canvasFiles:G.array(G.string()).optional().catch(void 0),gate:U0,error:U0,errors:G.record(G.string()).optional().catch(void 0)}).transform(({ok:$,browserUrl:f,revision:w,isNew:X,canvasFiles:J,gate:W,error:q,errors:Y})=>({ok:$,...f===void 0?{}:{browserUrl:f},...w===void 0?{}:{revision:w},...X===void 0?{}:{isNew:X},...J===void 0?{}:{canvasFiles:J},...W===void 0?{}:{gate:W},...q===void 0?{}:{error:q},...Y===void 0?{}:{errors:Y}})),w4=G.object({status:G.enum(["queued","running","passed","failed","blocked","info"]),issue:U0,message:U0,at:U0,data:G.record(G.unknown()).optional().catch(void 0)}).transform(({status:$,issue:f,message:w,at:X,data:J})=>({status:$,...f===void 0?{}:{issue:f},...w===void 0?{}:{message:w},...X===void 0?{}:{at:X},...J===void 0?{}:{data:J}})),rY=G.object({view:U0,directory:U0,projectRoot:U0,gate:U0,label:U0,response:U0}),J4=G.object({feedback:G.string().catch("")}),iY=J4.extend({found:G.literal(!0)}),dY=J4.extend({type:G.literal("submit")}),X4=G.object({revision:P0,hasFeedback:G.unknown().transform(($)=>$===!0),feedbackConsumed:G.unknown().transform(($)=>$===!0)}),oY=G.object({revisions:G.array(X4.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null))}),HJ=G.union([G.string().transform(($)=>({filename:$})),G.object({filename:G.string(),label:U0,diffStats:G.object({added:P0,removed:P0}).optional().catch(void 0)}).transform(({filename:$,label:f,diffStats:w})=>({filename:$,...f===void 0?{}:{label:f},...w===void 0?{}:{diffStats:w}}))]).refine(($)=>$.filename.length>0),B$=G.array(HJ.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null)).catch([]),bJ=G.discriminatedUnion("kind",[G.object({kind:G.literal("directory")}),G.object({kind:G.literal("view"),filename:G.string()})]),UJ=X4.extend({label:G.string().nullable().catch(null),canvasFiles:B$,createdAt:U0,canvasScope:bJ.optional().catch(void 0)}).transform(({createdAt:$,canvasScope:f,...w})=>({...w,...$===void 0?{}:{createdAt:$},...f===void 0?{}:{canvasScope:f}})).refine(($)=>$.revision>0),q4=G.object({projectRoot:U0,label:U0,gate:G.string().nullable().catch(null),currentRevision:P0.catch(0),canvasFiles:B$,revisions:G.array(UJ.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null)).catch([])}).transform(({projectRoot:$,label:f,...w})=>({...w,...$===void 0?{}:{projectRoot:$},...f===void 0?{}:{label:f}})),BJ=G.object({id:G.string(),label:U0}).transform(({id:$,label:f})=>({id:$,...f===void 0?{}:{label:f}})),W4=G.array(BJ.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null)).catch([]),MJ=G.object({file:G.string(),name:G.string(),seeds:G.array(G.string()),roles:G.array(G.string()),steps:P0,invariants:P0,pending:P0,url:U0,feature:U0}).transform(({url:$,feature:f,...w})=>({...w,...$===void 0?{}:{url:$},...f===void 0?{}:{feature:f}})),Q4=G.object({skeletons:G.array(MJ.nullable().catch(null)).transform(($)=>$.filter((f)=>f!==null))}),Y4=G.object({content:G.string()}),G4=G.object({responses:G.unknown()}),_4=G.discriminatedUnion("type",[G.object({type:G.literal("plan-updated"),currentRevision:P0,canvasFiles:G.array(G.unknown()).transform(($)=>B$.parse($)).optional().catch(void 0),gate:G.string().nullable().optional().catch(void 0)}),G.object({type:G.literal("revision-updated"),currentRevision:P0}),G.object({type:G.literal("watcher-status"),watching:G.boolean()}),G.object({type:G.literal("phase-updated")}),G.object({type:G.literal("submit-ack"),revision:P0})]).transform(($)=>{if($.type!=="plan-updated")return $;let{canvasFiles:f,gate:w,...X}=$;return{...X,...f===void 0?{}:{canvasFiles:f},...w===void 0?{}:{gate:w}}}),k0=G.string().refine(($)=>$.trim().length>0),N4=G.number().finite().nonnegative(),A5=G.string().transform(($,f)=>{try{return w2($)}catch{return f.addIssue({code:G.ZodIssueCode.custom,message:"Invalid builder origin"}),G.NEVER}}),J2=G.string().transform(($,f)=>{try{return k2($)}catch{return f.addIssue({code:G.ZodIssueCode.custom,message:"Invalid preview URL"}),G.NEVER}}),H4=G.object({controlOrigin:A5,iamIssuer:A5,receipt:tf}).strict(),nY=G.object({profile:k0,sessionId:k0,createdAt:k0.refine(($)=>Number.isFinite(Date.parse($))),connection:H4.optional(),previewUrl:J2.optional()}).strict().superRefine(($,f)=>{for(let w of["connection","previewUrl"])if(Object.hasOwn($,w)&&Reflect.get($,w)===void 0)f.addIssue({code:G.ZodIssueCode.custom,path:[w],message:"Present field must not be undefined"})}),LJ=G.discriminatedUnion("status",[G.object({status:G.literal("pending"),authorizationUrl:J2.refine(($)=>{try{return w2(new URL($).origin),!0}catch{return!1}}),expiresAt:N4}).strict(),G.object({status:G.literal("approved")}).strict(),G.object({status:G.literal("failed"),message:k0}).strict(),G.object({status:G.literal("expired")}).strict(),G.object({status:G.literal("cancelled")}).strict(),G.object({status:G.literal("recovery_required"),message:k0}).strict(),G.object({status:G.literal("connected")}).strict()]),OJ=G.object({status:G.enum(["preparing","pending","running","awaiting_approval","succeeded","failed","cancelled"]),runId:k0.nullable(),commitSha:k0.nullable(),message:k0.nullable(),appUrl:J2.nullable(),consoleUrl:J2.nullable()}).strict(),KJ=G.object({sessionId:k0,projectRoot:k0,connection:H4.nullable(),credential:G.object({available:G.boolean(),expiresAt:N4.nullable()}).strict(),pairing:LJ.nullable(),previewUrl:J2.nullable(),deployment:OJ.nullable()}).strict(),tY=G.object({projectRoot:k0}).strict(),aY=G.object({controlOrigin:A5}).strict(),sY=G.object({url:J2.nullable()}).strict();function b4($){let f=KJ.safeParse($);if(!f.success)throw Error("Invalid platform status");return f.data}function U4($,f){let w=k0.safeParse($);if(!w.success)throw Error("project id must be a non-empty string");return`/api/project/${encodeURIComponent(w.data)}/${f}`}function R1(){return location.origin}function M$(){return location.pathname.match(/\/s\/([^/]+)/)?.[1]??null}function FJ(){return new URLSearchParams(location.search).get("root")}async function X2($){let f=await fetch(R1()+$,{headers:{accept:"application/json"}});if(!f.ok)throw Error(`${$} -> ${f.status}`);return f.json()}var S0={async health(){let $=$4.safeParse(await X2("/health"));if(!$.success)throw Error("Invalid health response");return $.data},async phase($){let f=$??FJ(),w=M$(),X=new URLSearchParams;if(f)X.set("root",f);if(w)X.set("session",w);let J=X.toString(),W=ef.safeParse(await X2(`/api/phase${J?`?${J}`:""}`));if(!W.success)throw Error("Invalid phase response");return W.data},async meta($){let f=q4.safeParse(await X2(`/api/session/${encodeURIComponent($)}/meta`));if(!f.success)throw Error("Invalid session response");return{id:$,...f.data}},async artifact($,f){try{let w=await fetch(`${R1()}/api/session/${encodeURIComponent($)}/artifact?path=${encodeURIComponent(f)}`,{headers:{accept:"application/json"}});if(!w.ok)return null;let X=Y4.safeParse(await w.json());return X.success?X.data.content:null}catch{return null}},async sessions(){return W4.parse(await X2("/api/sessions"))},canvasUrl($,f,w){let X=w!=null?`?rev=${w}`:"";return`${R1()}/api/session/${encodeURIComponent($)}/canvas/${encodeURIComponent(f)}${X}`},async skeletons($){let f=Q4.safeParse(await X2(`/api/session/${encodeURIComponent($)}/skeletons`));return f.success?f.data.skeletons:[]},async feedback($,f){let w=await fetch(`${R1()}/api/session/${encodeURIComponent($)}/revision/${f}/feedback`);if(!w.ok)throw Error(`feedback -> ${w.status}`);return w.text()},async getResponses($,f,w){try{let X=G4.safeParse(await X2(`/api/session/${encodeURIComponent($)}/revision/${f}/responses`));return X.success?w(X.data.responses):null}catch{return null}},async saveResponses($,f,w){try{await fetch(`${R1()}/api/session/${encodeURIComponent($)}/revision/${f}/responses`,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(w)})}catch{}},openSocket($,f){let w=location.protocol==="https:"?"wss:":"ws:",X=R1().replace(/^https?:/,w),J=new WebSocket(`${X}/ws/session/${encodeURIComponent($)}`);return J.onmessage=(W)=>{try{let q=_4.safeParse(JSON.parse(String(W.data)));if(q.success)f(q.data)}catch{}},J},submitGate($,f){if($.readyState===WebSocket.OPEN)return $.send(JSON.stringify({type:"submit",feedback:f})),!0;return!1},buildStream($){try{let f=new EventSource(`${R1()}/api/build/stream`);return f.onmessage=(w)=>{try{let X=w4.safeParse(JSON.parse(w.data));if(X.success)$(X.data)}catch{}},f}catch{return null}}};import{jsxDEV as q0,Fragment as L$}from"react/jsx-dev-runtime";var zJ=".fabrika/architecture/design.md",AJ=".fabrika/pages/_preview.html",R5=`:root{
|
|
70
70
|
--color-brand:#6f4e37; --color-brand-strong:#573c2a;
|
|
71
71
|
--color-surface:#fbf7f0; --color-surface-sunken:#f1e9dd;
|
|
72
72
|
--color-text:#2a1e16; --color-muted:#8a7866; --color-accent:#c8853a;
|