@open-flow/ui 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +94 -0
- package/README.md +40 -0
- package/dist/app.d.ts +10 -0
- package/dist/app.js +1 -0
- package/dist/component-preview.d.ts +25 -0
- package/dist/component-preview.js +1 -0
- package/dist/config-context.d.ts +8 -0
- package/dist/config-context.js +1 -0
- package/dist/cx.d.ts +1 -0
- package/dist/cx.js +1 -0
- package/dist/demo.d.ts +18 -0
- package/dist/demo.js +1 -0
- package/dist/dev-actions.d.ts +9 -0
- package/dist/dev-actions.js +1 -0
- package/dist/dev-actions.noop.d.ts +3 -0
- package/dist/dev-actions.noop.js +1 -0
- package/dist/dom-realm.d.ts +4 -0
- package/dist/dom-realm.js +1 -0
- package/dist/edit-mode.d.ts +7 -0
- package/dist/edit-mode.js +1 -0
- package/dist/edit-session.d.ts +23 -0
- package/dist/edit-session.js +1 -0
- package/dist/error-boundary.d.ts +17 -0
- package/dist/error-boundary.js +1 -0
- package/dist/frame-view.d.ts +11 -0
- package/dist/frame-view.js +1 -0
- package/dist/frame.d.ts +29 -0
- package/dist/frame.js +1 -0
- package/dist/hover-inspect.d.ts +17 -0
- package/dist/hover-inspect.js +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -0
- package/dist/manifest.d.ts +19 -0
- package/dist/manifest.js +1 -0
- package/dist/manifest.types.d.ts +169 -0
- package/dist/manifest.types.js +1 -0
- package/dist/mirror.d.ts +7 -0
- package/dist/mirror.js +1 -0
- package/dist/overlay.d.ts +6 -0
- package/dist/overlay.js +1 -0
- package/dist/overlay.noop.d.ts +4 -0
- package/dist/overlay.noop.js +1 -0
- package/dist/panels/components.d.ts +22 -0
- package/dist/panels/components.js +1 -0
- package/dist/panels/elements.d.ts +1 -0
- package/dist/panels/elements.js +1 -0
- package/dist/panels/flows.d.ts +20 -0
- package/dist/panels/flows.js +1 -0
- package/dist/panels/surfaces.d.ts +6 -0
- package/dist/panels/surfaces.js +1 -0
- package/dist/parse-manifest.d.ts +3 -0
- package/dist/parse-manifest.js +1 -0
- package/dist/pick-box.d.ts +7 -0
- package/dist/pick-box.js +1 -0
- package/dist/pick-highlight.d.ts +20 -0
- package/dist/pick-highlight.js +1 -0
- package/dist/pin.d.ts +39 -0
- package/dist/pin.js +0 -0
- package/dist/registry.d.ts +24 -0
- package/dist/registry.js +1 -0
- package/dist/runtime-errors.d.ts +3 -0
- package/dist/runtime-errors.js +1 -0
- package/dist/screen-frame.d.ts +18 -0
- package/dist/screen-frame.js +1 -0
- package/dist/screen-toolbar.d.ts +34 -0
- package/dist/screen-toolbar.js +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +1 -0
- package/dist/ticket-drawer.d.ts +17 -0
- package/dist/ticket-drawer.js +1 -0
- package/dist/workbench-app.d.ts +22 -0
- package/dist/workbench-app.js +1 -0
- package/package.json +79 -0
package/dist/mirror.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";const f=500,T=8e3,h=3e4,d=2e6;function a(t,s,c){const o=t.documentElement;if(!o)throw new Error("documento sin ra\xEDz");const e=o.cloneNode(!0);for(const n of Array.from(e.querySelectorAll("script, noscript, base")))n.remove();for(const n of[e,...Array.from(e.querySelectorAll("*"))])for(const l of Array.from(n.attributes))l.name.toLowerCase().startsWith("on")&&n.removeAttribute(l.name);const r=t.createElement("base");r.setAttribute("href",new URL(s,c).href);const i=e.querySelector("head");return i?i.insertBefore(r,i.firstChild):e.insertBefore(r,e.firstChild),`${t.doctype?`<!DOCTYPE ${t.doctype.name}>`:"<!DOCTYPE html>"}${e.outerHTML}`}function m(t,s=500,c=8e3){return new Promise(o=>{let e,r;const i=new MutationObserver(()=>{clearTimeout(e),e=setTimeout(()=>u("quiet"),s)}),u=l=>{i.disconnect(),clearTimeout(e),clearTimeout(r),o(l)},n=t.documentElement;if(!n){o("restless");return}i.observe(n,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),e=setTimeout(()=>u("quiet"),s),r=setTimeout(()=>u("restless"),c)})}async function p(t,s){try{const c=t.contentDocument;if(!c||await m(c)==="restless")return null;const o=t.contentDocument;if(!o)return null;const e=t.contentWindow?.location.pathname??s,r=a(o,e,window.location.origin);return r.length>2e6?null:r}catch{return null}}export{T as CAPTURE_MAX_MS,h as CAPTURE_TOTAL_MS,d as MIRROR_MAX_BYTES,f as QUIET_MS,p as captureMirror,a as serializeMirror,m as whenQuiet};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NewTicketInput } from "./pin";
|
|
2
|
+
import { type CreateResult } from "./ticket-drawer";
|
|
3
|
+
export declare function WorkbenchOverlay({ manifest: raw, onCreateTicket, }: {
|
|
4
|
+
manifest: unknown;
|
|
5
|
+
onCreateTicket?: (input: NewTicketInput) => Promise<CreateResult>;
|
|
6
|
+
}): import("react").JSX.Element | null;
|
package/dist/overlay.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as i,jsxs as d}from"react/jsx-runtime";import{useCallback as y,useEffect as m,useMemo as c,useState as g,useSyncExternalStore as k}from"react";import{usePathname as w}from"next/navigation";import{cx as v}from"./cx";import{useInspect as S}from"./edit-mode";import{EditSessionOverlay as z,useEditSession as C}from"./edit-session";import{buildComponentIndex as E}from"./hover-inspect";import{surfaceForRoute as P}from"./manifest";import{parseOverlayManifest as A}from"./parse-manifest";import{BOX_ATTR as N}from"./pick-box";import{createTicket as O}from"./dev-actions";import{TicketDrawer as j}from"./ticket-drawer";function X({manifest:l,onCreateTicket:p=O}){const o=c(()=>A(l),[l]),n=w(),e=C(),[f,u]=g(!1),b=k(()=>()=>{},()=>window.self!==window.top,()=>!1),r=n.startsWith(o.config.mountPath)||b,h=c(()=>E(o.components),[o.components]),a=c(()=>P(o.routes,n),[o.routes,n]);return m(()=>{const t=s=>{s.altKey&&(s.key==="p"||s.key==="\u03C0")&&(s.preventDefault(),u(x=>!x))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[]),m(()=>{if(r)return;const t=N;return e.editing?document.body.setAttribute(t,""):document.body.removeAttribute(t),()=>document.body.removeAttribute(t)},[e.editing,r]),S(e.editing&&!r,y(()=>document.body,[]),h,{onPin:t=>e.addPin({...t,node:t.node??(a?{component:"",file:null,surface:a}:null)}),onHover:t=>e.setHovering(t&&{...t,node:{...t.node,surface:t.node.surface??a}})},n),r||!f&&!e.editing?r?null:i("button",{type:"button",onClick:()=>u(!0),"data-workbench-live":"",className:"fixed bottom-4 right-4 z-[2147483000] rounded-full bg-zinc-900/80 px-3 py-1.5 text-[11px] font-medium text-white shadow-lg backdrop-blur hover:bg-zinc-900 dark:bg-zinc-100/80 dark:text-zinc-900",title:"Se\xF1alar un elemento (\u2325P)",children:"Se\xF1alar"}):d("div",{"data-workbench-live":"",children:[d("div",{className:"fixed bottom-4 right-4 z-[2147483000] flex items-center gap-2 rounded-full bg-zinc-900/90 px-2 py-1.5 text-[11px] text-white shadow-lg backdrop-blur dark:bg-zinc-100/90 dark:text-zinc-900",children:[i("button",{type:"button",onClick:e.toggleEditing,className:v("rounded-full px-2 py-0.5 font-medium",e.editing?"bg-amber-400 text-amber-950":"hover:bg-white/10"),children:e.editing?"Se\xF1alando \u25CF":"Se\xF1alar"}),d("button",{type:"button",onClick:e.openDrawer,className:"rounded-full px-2 py-0.5 hover:bg-white/10",children:["Solicitud",e.pins.length>0?` (${e.pins.length})`:""]}),i("button",{type:"button",onClick:()=>u(!1),className:"rounded-full px-1.5 py-0.5 opacity-60 hover:opacity-100",title:"Ocultar (\u2325P)",children:"\xD7"})]}),i(z,{session:e}),i(j,{session:e,surfaces:o.surfaces,route:n,onCreate:p})]})}export{X as WorkbenchOverlay};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function n(r){return null}export{n as WorkbenchOverlay};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ComponentIndex } from "../hover-inspect";
|
|
2
|
+
import type { ComponentEntry } from "../manifest.types";
|
|
3
|
+
import type { PickTarget } from "../pick-highlight";
|
|
4
|
+
import type { Pin } from "../pin";
|
|
5
|
+
import { type Zoom } from "../screen-frame";
|
|
6
|
+
import { type ThemeMode } from "../screen-toolbar";
|
|
7
|
+
import { type RegistryEntry } from "../registry";
|
|
8
|
+
export declare function ComponentsPanel({ entry, registry, componentIndex, editing, onPin, onHover, onToggleEdit, pinCount, onOpenRequest, showChrome, initialViewport, initialZoom, initialTheme, }: {
|
|
9
|
+
entry: ComponentEntry;
|
|
10
|
+
registry: RegistryEntry[];
|
|
11
|
+
componentIndex: ComponentIndex;
|
|
12
|
+
editing: boolean;
|
|
13
|
+
onPin: (pin: Pick<Pin, "element" | "node">) => void;
|
|
14
|
+
onHover: (target: PickTarget | null) => void;
|
|
15
|
+
onToggleEdit: () => void;
|
|
16
|
+
pinCount: number;
|
|
17
|
+
onOpenRequest: () => void;
|
|
18
|
+
showChrome: boolean;
|
|
19
|
+
initialViewport?: string;
|
|
20
|
+
initialZoom?: Zoom;
|
|
21
|
+
initialTheme?: ThemeMode;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as s}from"react/jsx-runtime";import{useCallback as F,useRef as D,useState as d}from"react";import{ComponentPreview as H,ComponentScenarios as G,VariantScenarios as J,VerdictBadge as K}from"../component-preview";import{useManifest as Q}from"../config-context";import{useInspect as W}from"../edit-mode";import{InlineSurface as X,RouteFrame as T}from"../frame";import{frameUrl as Y,viewportById as E}from"../manifest";import{FRAME_CHROME as ee,ScreenFrame as j,useScale as te}from"../screen-frame";import{AUTO as I,ScreenToolbar as ie}from"../screen-toolbar";import{indexRegistry as ne}from"../registry";function ae({src:t,title:m,viewport:o,scale:c,editing:x,onLoaded:u}){const[g,b]=d(!1);return e(j,{viewport:o,scale:c,label:m,editing:x,children:g?e(T,{src:t,title:m,width:o.width,height:o.height,onLoad:u}):s("div",{className:"flex flex-col items-center justify-center gap-6 bg-zinc-50 dark:bg-zinc-900",style:{width:o.width,height:o.height},children:[e("p",{className:"max-w-lg px-10 text-center text-2xl leading-relaxed text-zinc-400 dark:text-zinc-500",children:"Cada vista es un iframe de la p\xE1gina aislada; se cargan al pedirlas para no multiplicar cargas del servidor."}),e("button",{type:"button",onClick:()=>b(!0),className:"rounded-xl border border-zinc-300 px-8 py-4 text-2xl font-medium text-zinc-600 hover:bg-zinc-100 dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800",children:"Cargar esta vista"})]})})}function ge({entry:t,registry:m,componentIndex:o,editing:c,onPin:x,onHover:u,onToggleEdit:g,pinCount:b,onOpenRequest:V,showChrome:L,initialViewport:M,initialZoom:O,initialTheme:_}){const l=Q().config,[h,A]=d(M??I),[z,B]=d(O??"fit"),[p,q]=d(_??"light"),R=D(null),v=ne(m).get(t.id),f=h===I,a=f?null:E(l,h),{ref:P,scale:S}=te(z,a?.width??0,ee),k=p==="split"?["light","dark"]:[p],[U,Z]=d(0),y=F(()=>Z(i=>i+1),[]);W(c,F(()=>R.current,[]),o,{onPin:x,onHover:u},`${t.id}:${h}:${z}:${p}:${U}`);const w=(i,n)=>Y(l,{component:t.id,viewport:a?.id??l.viewports[0]?.id??"",theme:i,...n?{scenario:n}:{}}),N=(i,n,r)=>s("section",{className:"mb-8",children:[s("header",{className:"mb-2 flex items-baseline gap-3",children:[e("h3",{className:"text-sm font-semibold text-zinc-900 dark:text-zinc-100",children:i}),n&&e("p",{className:"text-[11px] text-zinc-500 dark:text-zinc-400",children:n})]}),r]}),$=(i,n,r)=>f?e(X,{theme:i,editing:c,children:n}):r?e(ae,{src:w(i,r),title:`${t.name} \xB7 ${r}`,viewport:a??E(l,void 0),scale:S,editing:c,onLoaded:y}):e(j,{viewport:a??E(l,void 0),scale:S,label:t.name,editing:c,children:e(T,{src:w(i),title:`${t.name} \xB7 ${a?.label??""}`,width:a?.width??0,height:a?.height??0},`${i}-${a?.id}`)});return s("div",{className:"flex h-full flex-col",children:[L&&e(ie,{viewport:h,onViewport:A,zoom:z,onZoom:B,theme:p,onTheme:q,zoomEnabled:!f,hint:f?"En Auto se dibuja en l\xEDnea: r\xE1pido, pero los breakpoints de Tailwind responden al ancho de la ventana, no al del cuadro.":`Dentro de un iframe a ${a?.width}px reales, as\xED que los breakpoints son de verdad.`,editing:c,onToggleEdit:g,pinCount:b,onOpenRequest:V,isolatedBase:{tab:"componentes",component:t.id}}),s("div",{ref:P,className:"min-h-0 flex-1 overflow-auto bg-zinc-50 p-6 dark:bg-zinc-950",children:[s("header",{className:"mb-5 max-w-2xl",children:[s("div",{className:"flex items-center gap-2",children:[e("h2",{className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:t.name}),e(K,{verdict:t.verdict})]}),e("p",{className:"mt-1 font-mono text-[11px] text-zinc-500 dark:text-zinc-400",children:t.file}),t.surface&&s("p",{className:"mt-1 text-[11px] text-zinc-500 dark:text-zinc-400",children:["Superficie: ",e("span",{className:"font-medium",children:t.surface})]})]}),e("div",{ref:R,className:"space-y-8",children:k.map(i=>s("div",{children:[k.length>1&&e("p",{className:"mb-2 text-[11px] font-medium uppercase tracking-wider text-zinc-500",children:i==="light"?"Claro":"Oscuro"}),N("Vista principal",void 0,$(i,e(H,{entry:t,registry:v}))),e(J,{entry:t,registry:v,render:(n,r,C)=>N(n,r,$(i,C,n))}),e(G,{entry:t,registry:v,render:(n,r,C)=>N(n,r,$(i,C,n))})]},i))}),e("a",{href:w(k[0]??"light"),target:"_blank",rel:"noreferrer",className:"text-[11px] text-zinc-500 underline underline-offset-2 hover:text-zinc-900 dark:hover:text-zinc-100",children:"abrir aislado \u2197"})]})]})}export{ge as ComponentsPanel};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function ElementsPanel(): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as n,Fragment as x}from"react/jsx-runtime";import{useState as p}from"react";import{useManifest as b}from"../config-context";import{cx as u}from"../cx";function d({value:t}){return t?e("span",{className:"inline-block h-6 w-10 rounded border border-zinc-300 dark:border-zinc-600",style:{background:t},title:t}):e("span",{className:"inline-block h-6 w-10 rounded border border-dashed border-zinc-300 dark:border-zinc-600",title:"Sin declarar en este tema"})}function f({token:t}){const a=t.light===null||t.dark===null;return n("tr",{className:"border-b border-zinc-100 last:border-0 dark:border-zinc-800",children:[n("td",{className:"py-1.5 pr-4 align-middle",children:[e("code",{className:"font-mono text-[11px] text-zinc-700 dark:text-zinc-300",children:t.name}),a&&e("span",{className:"ml-2 rounded bg-amber-100 px-1 py-0.5 text-[10px] text-amber-900 dark:bg-amber-950 dark:text-amber-200",title:"Declarado en un solo tema",children:"falta un tema"}),t.note&&e("p",{className:"mt-0.5 text-[11px] text-zinc-500 dark:text-zinc-400",children:t.note})]}),t.kind==="color"?n(x,{children:[e("td",{className:"py-1.5 pr-3",children:e(d,{value:t.light})}),e("td",{className:"py-1.5 pr-3",children:e(d,{value:t.dark})})]}):e("td",{colSpan:2,className:"py-1.5 pr-3",children:e("code",{className:"font-mono text-[11px] text-zinc-500 dark:text-zinc-400",children:t.light??t.dark})})]})}function k({group:t}){return n("section",{id:`token-${t.id}`,className:"mb-8",children:[n("h3",{className:"mb-2 text-sm font-semibold text-zinc-900 dark:text-zinc-100",children:[t.label,e("span",{className:"ml-2 text-[11px] font-normal text-zinc-400",children:t.tokens.length})]}),n("table",{className:"w-full max-w-3xl border-collapse text-left",children:[e("thead",{children:n("tr",{className:"text-[10px] uppercase tracking-wider text-zinc-400",children:[e("th",{className:"pb-1 font-medium",children:"Token"}),e("th",{className:"pb-1 font-medium",children:"Claro"}),e("th",{className:"pb-1 font-medium",children:"Oscuro"})]})}),e("tbody",{children:t.tokens.map(a=>e(f,{token:a},a.name))})]})]})}function y(){const{tokens:t,config:a,stats:l}=b(),[o,m]=p(""),s=o.trim().toLowerCase(),i=s?t.map(r=>({...r,tokens:r.tokens.filter(c=>c.name.toLowerCase().includes(s))})).filter(r=>r.tokens.length>0):t,h=i.reduce((r,c)=>r+c.tokens.length,0);return n("div",{className:"flex h-full flex-col",children:[n("div",{className:"flex flex-wrap items-center gap-3 border-b border-zinc-200 bg-white px-6 py-2 dark:border-zinc-700 dark:bg-zinc-900",children:[e("input",{value:o,onChange:r=>m(r.target.value),placeholder:"Filtrar tokens\u2026",className:"w-56 rounded-md border border-zinc-300 px-2 py-1 text-[12px] text-zinc-800 placeholder:text-zinc-400 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100"}),n("span",{className:"text-[11px] text-zinc-500 dark:text-zinc-400",children:[h," tokens \xB7 ",a.title]})]}),e("div",{className:u("min-h-0 flex-1 overflow-auto bg-zinc-50 p-6 dark:bg-zinc-950"),children:t.length===0?l.missingStylesheet?n("p",{className:"max-w-lg text-sm text-zinc-600 dark:text-zinc-400",children:["El escaneo no encontr\xF3 la hoja de estilos"," ",e("code",{className:"font-mono",children:l.missingStylesheet}),", as\xED que no hay tokens que mostrar. Apunta ",e("code",{children:"themeSource"})," en",e("code",{className:"mx-1 font-mono",children:"workbench.config.json"})," al archivo con el bloque"," ",e("code",{children:"@theme"})," o ",e("code",{children:":root"}),"."]}):n("p",{className:"max-w-lg text-sm text-zinc-600 dark:text-zinc-400",children:["No se encontr\xF3 ning\xFAn token. Revisa ",e("code",{children:"themeSource"})," en",e("code",{className:"mx-1 font-mono",children:"workbench.config.json"}),": debe apuntar a la hoja de estilos con el bloque ",e("code",{children:"@theme"})," o ",e("code",{children:":root"}),"."]}):i.map(r=>e(k,{group:r},r.id))})]})}export{y as ElementsPanel};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ComponentIndex } from "../hover-inspect";
|
|
2
|
+
import type { Flow } from "../manifest.types";
|
|
3
|
+
import type { PickTarget } from "../pick-highlight";
|
|
4
|
+
import type { Pin } from "../pin";
|
|
5
|
+
import { type Zoom } from "../screen-frame";
|
|
6
|
+
import { type ThemeMode } from "../screen-toolbar";
|
|
7
|
+
export declare function FlowsPanel({ flow, componentIndex, editing, onPin, onHover, onToggleEdit, pinCount, onOpenRequest, showChrome, initialViewport, initialZoom, initialTheme, }: {
|
|
8
|
+
flow: Flow;
|
|
9
|
+
componentIndex: ComponentIndex;
|
|
10
|
+
editing: boolean;
|
|
11
|
+
onPin: (pin: Pick<Pin, "element" | "node">) => void;
|
|
12
|
+
onHover: (target: PickTarget | null) => void;
|
|
13
|
+
onToggleEdit: () => void;
|
|
14
|
+
pinCount: number;
|
|
15
|
+
onOpenRequest: () => void;
|
|
16
|
+
showChrome: boolean;
|
|
17
|
+
initialViewport?: string;
|
|
18
|
+
initialZoom?: Zoom;
|
|
19
|
+
initialTheme?: ThemeMode;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as t,Fragment as V,jsxs as c}from"react/jsx-runtime";import{Fragment as ue,useCallback as b,useEffect as W,useRef as Z,useState as v}from"react";import{useManifest as Y}from"../config-context";import{useInspect as me}from"../edit-mode";import{MirrorFrame as pe,RouteFrame as he}from"../frame";import{frameUrl as ge,viewportById as ee}from"../manifest";import{CAPTURE_TOTAL_MS as xe,captureMirror as fe,serializeMirror as ke}from"../mirror";import{FRAME_CHROME as be,ScreenFrame as ve,STEP_GUTTER as ze,useScale as Ne}from"../screen-frame";import{AUTO as G,CHIP as T,ScreenToolbar as $e}from"../screen-toolbar";const M={kind:"queued"};function je(n){return new Date(n).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}function Ee({flow:n,steps:F,scale:p,theme:z,nonce:D,editing:q,slot:h,frames:_,active:N,onCapture:S,onActivate:L,onRefresh:R,onDemote:A,registerLiveFrame:x}){const{config:$}=Y();return t("div",{children:t("ol",{className:"flex items-start gap-4",children:F.map(({step:l,viewport:i},d)=>{const o=_[d]??M,j=N!==null&&N.step===d&&N.slot===h,m=o.kind==="capturing"&&h===0,U=j||o.kind==="restless"&&h===0||m;return c(ue,{children:[c("li",{className:"shrink-0",children:[t(ve,{viewport:i,scale:p,label:`${d+1}. ${l.label}`,editing:q,children:U?t(he,{src:l.route,title:`${n.title} \xB7 ${l.label}`,width:i.width,height:i.height,theme:z,frameRef:f=>x(d,h,f),onLoad:m?f=>S(d,f):void 0},D):o.kind==="mirrored"?t(pe,{srcdoc:o.srcdoc,title:`${n.title} \xB7 ${l.label} (espejo)`,width:i.width,height:i.height,theme:z}):t("div",{className:"flex items-center justify-center bg-zinc-50 dark:bg-zinc-900",style:{width:i.width,height:i.height},children:t("p",{className:"max-w-lg px-10 text-center text-2xl leading-relaxed text-zinc-400 dark:text-zinc-500",children:o.kind==="capturing"?"Cargando la ruta real\u2026":o.kind==="restless"?"Sin espejo \u2014 el paso sigue en vivo en el tablero claro.":"En cola \u2014 cada paso se carga una sola vez y queda como espejo."})})}),(j||o.kind==="mirrored"||o.kind==="restless"||m)&&t("div",{className:"mt-2 flex flex-wrap items-center gap-2",style:{width:Math.floor(i.width*p)},children:j?c(V,{children:[t("span",{className:"text-[11px] font-medium text-emerald-600 dark:text-emerald-400",children:"En vivo"}),t("button",{type:"button",className:T,onClick:A,children:"Volver a espejo"})]}):o.kind==="mirrored"?c(V,{children:[c("span",{className:"text-[11px] text-zinc-500 dark:text-zinc-400",title:"Espejo est\xE1tico de la p\xE1gina real \u2014 sin peticiones al servidor.",children:["Espejo \xB7 ",je(o.capturedAt)]}),t("button",{type:"button",className:T,onClick:()=>L(d,h),title:"Monta la p\xE1gina real para interactuar con ella.",children:"Activar"}),t("button",{type:"button",className:T,onClick:()=>R(d),title:"Vuelve a cargar la ruta y captura un espejo nuevo.",children:"Actualizar"})]}):o.kind==="restless"?c(V,{children:[t("span",{className:"text-[11px] text-amber-600 dark:text-amber-400",title:"La p\xE1gina no termin\xF3 de asentarse, as\xED que el cuadro sigue en vivo.",children:"En vivo \u2014 sin espejo"}),t("button",{type:"button",className:T,onClick:()=>R(d),children:"Reintentar espejo"})]}):t("span",{className:"text-[11px] text-zinc-500 dark:text-zinc-400",children:"Cargando\u2026"})}),c("div",{className:"mt-2 flex items-start justify-between gap-2",style:{width:Math.floor(i.width*p)},children:[l.note&&t("p",{className:"text-[11px] leading-snug text-zinc-500 dark:text-zinc-400",children:l.note}),c("span",{className:"ml-auto flex shrink-0 items-center gap-2",children:[c("a",{href:l.route,target:"_blank",rel:"noreferrer",className:"font-mono text-[11px] text-zinc-500 underline underline-offset-2 hover:text-zinc-900 dark:hover:text-zinc-100",children:[l.route," \u2197"]}),t("a",{href:ge($,{route:l.route,viewport:i.id,theme:z}),target:"_blank",rel:"noreferrer",className:"text-[11px] text-zinc-500 underline underline-offset-2 hover:text-zinc-900 dark:hover:text-zinc-100",children:"aislado \u2197"})]})]})]}),d<F.length-1&&t("li",{"aria-hidden":!0,className:"shrink-0 self-center text-xl text-zinc-400 dark:text-zinc-600",children:"\u2192"})]},`${n.id}-${d}-${l.route}`)})})})}function qe({flow:n,componentIndex:F,editing:p,onPin:z,onHover:D,onToggleEdit:q,pinCount:h,onOpenRequest:_,showChrome:N,initialViewport:S,initialZoom:L,initialTheme:R}){const{config:A,stats:x}=Y(),[$,l]=v(0),[i,d]=v(S??G),[o,j]=v(L??"fit"),[m,U]=v(R??"light"),f=Z(null),[g,k]=v(()=>n.steps.map(()=>M)),[u,H]=v(null),I=Z(new Map);W(()=>{k(n.steps.map(()=>M)),H(null)},[$]);const Q=Z(1);W(()=>{g.some(e=>e.kind==="capturing")||g.some(e=>e.kind==="queued")&&k(e=>{if(e.some(a=>a.kind==="capturing"))return e;const r=e.findIndex(a=>a.kind==="queued");if(r===-1)return e;const s=Q.current;return Q.current+=1,e.map((a,w)=>w===r?{kind:"capturing",ticket:s}:a)})},[g]);const E=g.findIndex(e=>e.kind==="capturing"),J=E===-1?null:g[E],O=J?.kind==="capturing"?J.ticket:null;W(()=>{if(E===-1||O===null)return;const e=setTimeout(()=>{k(r=>r.map((s,a)=>a===E&&s.kind==="capturing"&&s.ticket===O?{kind:"restless"}:s))},xe);return()=>clearTimeout(e)},[E,O]);const te=b((e,r)=>{const s=n.steps[e]?.route;s&&fe(r,s).then(a=>{k(w=>w.map((C,P)=>P!==e||C.kind!=="capturing"?C:a?{kind:"mirrored",srcdoc:a,capturedAt:Date.now()}:{kind:"restless"}))}).catch(()=>{})},[n]),B=b(()=>{if(!u)return;const e=I.current.get(`${u.slot}:${u.step}`),r=n.steps[u.step]?.route;if(e&&r)try{const s=e.contentDocument;if(s){const a=e.contentWindow?.location.pathname??r,w=ke(s,a,window.location.origin),C=Date.now(),P=u.step;k(oe=>oe.map((le,de)=>de===P?{kind:"mirrored",srcdoc:w,capturedAt:C}:le))}}catch{}H(null)},[u,n]),ne=b((e,r)=>{B(),H({step:e,slot:r})},[B]),re=b(e=>{k(r=>r.map((s,a)=>a===e?M:s))},[]),ae=b((e,r,s)=>{const a=`${r}:${e}`;s?I.current.set(a,s):I.current.delete(a)},[]),K=i===G?null:ee(A,i),y=n.steps.map(e=>({step:e,viewport:K??ee(A,e.viewport)})),ie=y.reduce((e,{viewport:r})=>e+r.width,0),{ref:se,scale:ce}=Ne(o,ie,y.length*be+Math.max(0,y.length-1)*ze),X=m==="split"?["light","dark"]:[m];return me(p,b(()=>f.current,[]),F,{onPin:z,onHover:D},`${n.id}:${$}:${i}:${o}:${m}:${g.map(e=>e.kind.charAt(0)).join("")}:${u?`${u.slot}.${u.step}`:"-"}`),c("div",{className:"flex h-full flex-col",children:[N&&t($e,{viewport:i,onViewport:d,zoom:o,onZoom:j,theme:m,onTheme:U,actions:t("button",{type:"button",onClick:()=>l(e=>e+1),className:T,children:"Recargar cuadros"}),hint:i===G?"Rutas reales, cargadas de una en una y congeladas como espejos; activa un paso para interactuar. Las pantallas con sesi\xF3n requieren haber iniciado sesi\xF3n aqu\xED.":`Rutas reales, los ${y.length} pasos a ${K?.width}px, congeladas como espejos.`,editing:p,onToggleEdit:q,pinCount:h,onOpenRequest:_,isolatedBase:{tab:"flujos",flow:n.id}}),c("div",{ref:se,className:"min-h-0 flex-1 overflow-auto bg-zinc-50 p-6 dark:bg-zinc-950",children:[c("header",{className:"mb-5 max-w-2xl",children:[c("div",{className:"flex items-center gap-2",children:[t("h2",{className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:n.title}),n.origin==="spider"&&t("span",{className:"rounded bg-zinc-100 px-1.5 py-0.5 text-[10px] font-medium text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300",title:"Descubierto siguiendo los enlaces reales de la app. Declara el recorrido en workbench.config.json para darle nombre y notas.",children:"descubierto"})]}),n.description&&t("p",{className:"mt-1 text-sm text-zinc-600 dark:text-zinc-400",children:n.description}),x.untraceableHrefs>0&&c("p",{className:"mt-1 text-[11px] text-zinc-500 dark:text-zinc-400",children:[x.untraceableHrefs," enlaces con destino calculado no se pudieron rastrear, as\xED que puede faltar alg\xFAn paso."]}),x.droppedFlows>0&&c("p",{className:"mt-1 text-[11px] text-zinc-500 dark:text-zinc-400",children:[x.droppedFlows," recorridos adicionales encontrados y no mostrados; declara los que importen en workbench.config.json."]})]}),t("div",{ref:f,children:t("div",{className:"space-y-8",children:X.map((e,r)=>c("div",{children:[X.length>1&&t("p",{className:"mb-2 text-[11px] font-medium uppercase tracking-wider text-zinc-500",children:e==="light"?"Claro":"Oscuro"}),t(Ee,{flow:n,steps:y,scale:ce,theme:e,nonce:$,editing:p,slot:r,frames:g,active:u,onCapture:te,onActivate:ne,onRefresh:re,onDemote:B,registerLiveFrame:ae})]},r===0?"a":"b"))})})]})]})}export{qe as FlowsPanel};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as a,jsxs as i}from"react/jsx-runtime";import{useManifest as o}from"../config-context";import{cx as d}from"../cx";function n({title:e,items:l,tone:c,mono:s=!0}){return l.length===0?null:i("section",{className:"mb-5",children:[i("h4",{className:"mb-1 text-[10px] font-medium uppercase tracking-wider text-zinc-400",children:[e," ",a("span",{className:"text-zinc-300 dark:text-zinc-600",children:l.length})]}),a("ul",{className:d("space-y-0.5 text-[11px]",s&&"font-mono",c??"text-zinc-600 dark:text-zinc-400"),children:l.map(r=>a("li",{children:r},r))})]})}function b({surface:e,tickets:l}){const{components:c}=o(),s=l.filter(t=>t.surface===e.id),r=new Set(e.components),m=c.filter(t=>t.surface===e.id&&!r.has(t.id));return i("div",{className:"min-h-0 flex-1 overflow-auto bg-zinc-50 p-6 dark:bg-zinc-950",children:[i("header",{className:"mb-6 max-w-2xl",children:[i("div",{className:"flex flex-wrap items-center gap-2",children:[a("h2",{className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:e.label}),a("code",{className:"rounded bg-zinc-100 px-1.5 py-0.5 font-mono text-[11px] text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300",children:e.id}),a("span",{className:d("rounded px-1.5 py-0.5 text-[10px] font-medium",e.weight==="quick"?"bg-emerald-100 text-emerald-900 dark:bg-emerald-950 dark:text-emerald-200":"bg-amber-100 text-amber-900 dark:bg-amber-950 dark:text-amber-200"),title:e.weight==="quick"?"Un cambio aqu\xED es corto: qu\xE9 y validar, nada m\xE1s.":"Un cambio aqu\xED toca varios archivos o variantes: estrategia, plan, ejecutar, validar.",children:e.weight==="quick"?"cambio corto":"cambio amplio"}),e.origin==="spider"&&a("span",{className:"rounded bg-zinc-100 px-1.5 py-0.5 text-[10px] font-medium text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300",title:"Propuesta por el rastreador. Dale nombre en workbench.surfaces.json y pasa a ser tuya.",children:"descubierta"})]}),e.description&&a("p",{className:"mt-1 text-sm text-zinc-600 dark:text-zinc-400",children:e.description}),e.main&&i("p",{className:"mt-2 text-[11px] text-zinc-500 dark:text-zinc-400",children:["Empieza aqu\xED:"," ",a("code",{className:"font-mono text-zinc-700 dark:text-zinc-300",children:e.main})]})]}),e.gotchas.length>0&&i("div",{className:"mb-6 max-w-2xl rounded-lg border border-amber-300 bg-amber-50 p-3 dark:border-amber-800 dark:bg-amber-950",children:[a("h4",{className:"text-[10px] font-medium uppercase tracking-wider text-amber-800 dark:text-amber-200",children:"Ojo"}),a("ul",{className:"mt-1 space-y-1 text-[12px] text-amber-900 dark:text-amber-100",children:e.gotchas.map(t=>i("li",{children:["\u2014 ",t]},t))})]}),i("div",{className:"grid max-w-5xl gap-x-10 md:grid-cols-2",children:[i("div",{children:[a(n,{title:"Variantes \u2014 cambiar una sola las descuadra",items:e.files.anchors}),a(n,{title:"Partes",items:e.files.members}),a(n,{title:"Aprendido de tickets",items:e.files.learned.map(t=>t.ticket?`${t.file} \xB7 ${t.ticket}`:t.file)}),a(n,{title:"Se monta en",items:e.files.mounts}),a(n,{title:"Rutas",items:e.routes})]}),i("div",{children:[e.absent.length>0&&i("section",{className:"mb-5",children:[a("h4",{className:"mb-1 text-[10px] font-medium uppercase tracking-wider text-zinc-400",children:"No existe en"}),a("p",{className:"font-mono text-[11px] text-zinc-600 dark:text-zinc-400",children:e.absent.join(" ")})]}),e.tokens.length>0&&i("section",{className:"mb-5",children:[a("h4",{className:"mb-1 text-[10px] font-medium uppercase tracking-wider text-zinc-400",children:"Colores que lo pintan"}),a("ul",{className:"space-y-0.5 font-mono text-[11px] text-zinc-600 dark:text-zinc-400",children:e.tokens.map(t=>i("li",{children:[t.token," ",i("span",{className:"text-zinc-400",children:["\xD7",t.uses]})]},t.token))})]}),e.hardcodedColors.length>0&&i("section",{className:"mb-5",children:[a("h4",{className:"mb-1 text-[10px] font-medium uppercase tracking-wider text-amber-600 dark:text-amber-400",children:"Colores literales \u2014 se saltan el token"}),a("ul",{className:"space-y-0.5 font-mono text-[11px] text-amber-700 dark:text-amber-300",children:e.hardcodedColors.map(t=>i("li",{children:[t.file," \u2014 ",t.values.join(" ")]},t.file))})]}),a(n,{title:"Primitivos compartidos \u2014 no editar a la ligera",items:e.shared}),a(n,{title:"L\xF3gica que llama",items:e.logic}),a(n,{title:"Componentes en el taller",items:e.components,mono:!1}),m.length>0&&a(n,{title:"Sin cubrir",items:m.map(t=>`${t.name} (${t.verdict})`),mono:!1,tone:"text-zinc-500 dark:text-zinc-500"})]})]}),s.length>0&&i("section",{className:"mt-6 max-w-2xl",children:[a("h4",{className:"mb-1 text-[10px] font-medium uppercase tracking-wider text-zinc-400",children:"Tickets"}),a("ul",{className:"space-y-1 text-[12px]",children:s.map(t=>i("li",{className:"flex items-baseline gap-2",children:[a("code",{className:"font-mono text-[11px] text-zinc-500",children:t.id}),a("span",{className:"text-zinc-700 dark:text-zinc-300",children:t.title}),i("span",{className:"text-[10px] text-zinc-400",children:[t.status,t.misses>0&&` \xB7 ense\xF1\xF3 ${t.misses}`]})]},t.id))})]})]})}export{b as SurfacesPanel};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{MANIFEST_VERSION as o}from"./manifest.types";function w(e){if(typeof e!="object"||e===null)throw new Error("No se pudo leer .workbench/manifest.json. Ejecuta `workbench scan`.");const n=Reflect.get(e,"version");if(typeof n!="number")throw new Error("El manifiesto no declara versi\xF3n. Fue escrito por otra herramienta, o est\xE1 a medias \u2014 ejecuta `workbench scan`.");if(n!==o)throw new Error(`El manifiesto es de la versi\xF3n ${n} y este visor lee la ${o}. Ejecuta \`workbench scan\` con la misma versi\xF3n del paquete que tienes instalada.`);const r=t.filter(s=>Reflect.get(e,s)===void 0);if(r.length>0)throw new Error(`Al manifiesto le falta ${r.join(", ")}. Ejecuta \`workbench scan\`.`);if(!i(e))throw new Error("El manifiesto est\xE1 incompleto. Ejecuta `workbench scan`.");return e}const t=["config","tokens","components","routes","flows","surfaces","stats"];function i(e){return t.every(n=>Reflect.get(e,n)!==void 0)}const c=["config","components","routes","surfaces"];function l(e){return c.every(n=>Reflect.get(e,n)!==void 0)}let a=!1;function u(e){if(typeof e!="object"||e===null)throw new Error("No se pudo leer .workbench/overlay.json. Ejecuta `workbench scan`.");const n=Reflect.get(e,"version");if(n!==o)throw new Error(`El overlay es de la versi\xF3n ${String(n)} y este visor lee la ${o}. Ejecuta \`workbench scan\` con la misma versi\xF3n del paquete que tienes instalada.`);if(!l(e))throw new Error("Al overlay le faltan campos. Ejecuta `workbench scan`.");return!a&&(Reflect.get(e,"flows")!==void 0||Reflect.get(e,"tokens")!==void 0)&&(a=!0,console.warn("[workbench] El overlay recibi\xF3 el manifiesto completo. Importa `.workbench/overlay.json` en el layout \u2014 `workbench scan` ya lo genera y pesa una quinta parte del mapa completo, que ahora mismo viaja en el payload de cada ruta.")),e}export{w as parseManifest,u as parseOverlayManifest};
|
package/dist/pick-box.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as s}from"react/jsx-runtime";import{cx as c}from"./cx";const n="data-workbench-box";function x({enabled:r,children:o,className:i}){return s("div",{...r?{[n]:""}:{},className:c(i,r&&"cursor-crosshair ring-2 ring-amber-400 ring-inset"),children:o})}export{n as BOX_ATTR,x as PickBox};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ResolvedNode } from "./hover-inspect";
|
|
2
|
+
export interface PickTarget {
|
|
3
|
+
rect: {
|
|
4
|
+
top: number;
|
|
5
|
+
left: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
};
|
|
9
|
+
node: ResolvedNode;
|
|
10
|
+
}
|
|
11
|
+
export declare function mapRect(element: Element, frame: HTMLIFrameElement | null): {
|
|
12
|
+
top: number;
|
|
13
|
+
left: number;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
export declare function describeNode(node: ResolvedNode): string;
|
|
18
|
+
export declare function PickHighlight({ target }: {
|
|
19
|
+
target: PickTarget | null;
|
|
20
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as c,jsxs as a}from"react/jsx-runtime";import{SCALE_ATTR as p}from"./screen-frame";const r=20;function u(e,o){const t=e.getBoundingClientRect();if(!o)return{top:t.top,left:t.left,width:t.width,height:t.height};const n=o.closest(`[${p}]`)?.getAttribute(p),s=Number(n),i=Number.isFinite(s)&&s>0?s:1,l=o.getBoundingClientRect();return{top:l.top+t.top*i,left:l.left+t.left*i,width:t.width*i,height:t.height*i}}function h(e){const o=e.component??`<${e.tag}>`,t=e.component&&e.file?e.file.split("/").pop():null;return[o,t,e.surface].filter(Boolean).join(" \xB7 ")}function m({target:e}){if(!e)return null;const{rect:o,node:t}=e,n=o.top>r+4;return a("div",{"aria-hidden":!0,className:"pointer-events-none fixed z-[2147483000]",style:{top:o.top,left:o.left,width:o.width,height:o.height},children:[c("div",{className:"absolute inset-0 border border-amber-400"}),c("span",{className:"absolute left-0 whitespace-nowrap rounded-sm bg-amber-400 px-1.5 py-0.5 font-mono text-[10px] leading-none text-amber-950 shadow-sm",style:n?{top:-r}:{bottom:-r},children:h(t)})]})}export{m as PickHighlight,h as describeNode,u as mapRect};
|
package/dist/pin.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface Pin {
|
|
2
|
+
note: string;
|
|
3
|
+
element: {
|
|
4
|
+
tag: string;
|
|
5
|
+
classes: string;
|
|
6
|
+
text: string;
|
|
7
|
+
path: string;
|
|
8
|
+
};
|
|
9
|
+
node: {
|
|
10
|
+
component: string;
|
|
11
|
+
file: string | null;
|
|
12
|
+
surface: string | null;
|
|
13
|
+
} | null;
|
|
14
|
+
}
|
|
15
|
+
export interface RuntimeError {
|
|
16
|
+
message: string;
|
|
17
|
+
component: string | null;
|
|
18
|
+
file: string | null;
|
|
19
|
+
route: string | null;
|
|
20
|
+
at: string;
|
|
21
|
+
}
|
|
22
|
+
export interface NewTicketInput {
|
|
23
|
+
surface: string;
|
|
24
|
+
title: string;
|
|
25
|
+
intent: string;
|
|
26
|
+
acceptance: string;
|
|
27
|
+
pins: Pin[];
|
|
28
|
+
errors: RuntimeError[];
|
|
29
|
+
route?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface TicketSummary {
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
surface: string | null;
|
|
35
|
+
status: string;
|
|
36
|
+
created: string | null;
|
|
37
|
+
misses: number;
|
|
38
|
+
file: string;
|
|
39
|
+
}
|
package/dist/pin.js
ADDED
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ComponentType, type ReactNode } from "react";
|
|
2
|
+
import type { Demo, DemoModule } from "./demo";
|
|
3
|
+
import type { ComponentEntry, PropSpec } from "./manifest.types";
|
|
4
|
+
export interface RegistryEntry {
|
|
5
|
+
id: string;
|
|
6
|
+
load: () => Promise<Record<string, unknown>>;
|
|
7
|
+
exportName?: string;
|
|
8
|
+
demo?: () => Promise<{
|
|
9
|
+
default: unknown;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export interface Loaded {
|
|
13
|
+
Component: ComponentType<Record<string, unknown>> | null;
|
|
14
|
+
demo: Demo | null;
|
|
15
|
+
error: string | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function useComponentModule(entry: RegistryEntry): Loaded;
|
|
18
|
+
export declare function sampleProps(specs: PropSpec[]): {
|
|
19
|
+
props: Record<string, unknown>;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
};
|
|
22
|
+
export declare function indexRegistry(registry: RegistryEntry[]): Map<string, RegistryEntry>;
|
|
23
|
+
export type { Demo, DemoModule };
|
|
24
|
+
export type { ComponentEntry };
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{use as c}from"react";const r=new Map;function l(e){return typeof e=="function"?!0:typeof e=="object"&&e!==null&&"$$typeof"in e}function u(e){return typeof e=="object"&&e!==null&&"render"in e&&typeof Reflect.get(e,"render")=="function"}async function p(e){let o=null;if(e.demo){const t=await e.demo();u(t.default)&&(o=t.default)}const i=await e.load(),n=e.exportName?i[e.exportName]:i.default;return l(n)?{Component:n,demo:o,error:null}:{Component:null,demo:o,error:e.exportName?`El m\xF3dulo no exporta un componente llamado ${e.exportName}.`:"El m\xF3dulo no tiene una exportaci\xF3n por defecto que sea un componente."}}function m(e){let o=r.get(e.id);return o||(o=p(e),o.catch(()=>r.delete(e.id)),r.set(e.id,o)),c(o)}const a=()=>{};function d(e){const o={};let i=null;for(const n of e){if(!n.sample)continue;if(n.sample.kind==="callback"){o[n.name]=a;continue}const t=n.sample.value;if(n.name==="children"){i=typeof t=="boolean"?String(t):t;continue}o[n.name]=t}return{props:o,children:i}}function s(e){return new Map(e.map(o=>[o.id,o]))}export{s as indexRegistry,d as sampleProps,m as useComponentModule};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";const i=20;let t=[];const s=new Set;function o(){for(const e of s)e(t)}function c(e){const n={...e,at:new Date().toISOString()},r=t[0];r&&r.message===n.message&&r.file===n.file||(t=[n,...t].slice(0,20),o())}function u(e){return s.add(e),()=>{s.delete(e)}}export{c as reportRuntimeError,u as subscribeRuntimeErrors};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { Viewport } from "./manifest.types";
|
|
3
|
+
export declare const SCALE_ATTR = "data-workbench-scale";
|
|
4
|
+
export type Zoom = "fit" | 0.5 | 0.75 | 1;
|
|
5
|
+
export declare const FRAME_CHROME = 24;
|
|
6
|
+
export declare const STEP_GUTTER = 50;
|
|
7
|
+
export declare function fitScale(available: number, naturalWidth: number, gutters: number): number;
|
|
8
|
+
export declare function useScale(zoom: Zoom, naturalWidth: number, gutters: number): {
|
|
9
|
+
ref: import("react").RefObject<HTMLDivElement | null>;
|
|
10
|
+
scale: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function ScreenFrame({ viewport, scale, label, children, editing, }: {
|
|
13
|
+
viewport: Viewport;
|
|
14
|
+
scale: number;
|
|
15
|
+
label?: ReactNode;
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
editing?: boolean;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as n}from"react/jsx-runtime";import{useEffect as f,useRef as m,useState as u}from"react";import{FrameShell as b}from"./frame";import{PickBox as g}from"./pick-box";const x="data-workbench-scale",h=.15,S=24,T=50,p=8;function M(e,t,i){if(t<=0)return 1;const r=e-i-p;return r<=0?h:Math.min(1,Math.max(h,r/t))}function _(e,t,i){const r=m(null),[s,o]=u(0);f(()=>{const a=r.current;if(!a)return;const l=new ResizeObserver(d=>{o(d[0]?.contentRect.width??0)});return l.observe(a),()=>l.disconnect()},[]);const c=e==="fit"?M(s,t,i):e;return{ref:r,scale:c}}function w({viewport:e,scale:t,label:i,children:r,editing:s}){const o=Math.floor(e.width*t),c=Math.floor(e.height*t);return n("div",{style:{width:o+S},children:n(b,{label:i,meta:`${e.width}\xD7${e.height} \xB7 ${Math.round(t*100)}%`,children:n("div",{className:"bg-zinc-100 p-3 dark:bg-zinc-800",children:n(g,{enabled:s,children:n("div",{[x]:String(t),className:"relative overflow-hidden",style:{width:o,height:c},children:n("div",{className:"absolute left-0 top-0",style:{width:e.width,height:e.height,transform:`scale(${t})`,transformOrigin:"top left"},children:r})})})})})})}export{S as FRAME_CHROME,x as SCALE_ATTR,T as STEP_GUTTER,w as ScreenFrame,M as fitScale,_ as useScale};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { Zoom } from "./screen-frame";
|
|
3
|
+
export declare const CHIP = "rounded-md border border-zinc-300 px-2 py-1 text-[11px] font-medium text-zinc-600 hover:bg-zinc-100 dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800";
|
|
4
|
+
export declare const AUTO = "auto";
|
|
5
|
+
export type ThemeMode = "light" | "dark" | "split";
|
|
6
|
+
export declare function SegmentedControl<T extends string | number>({ options, value, onChange, disabled, disabledReason, }: {
|
|
7
|
+
options: Array<{
|
|
8
|
+
id: T;
|
|
9
|
+
label: string;
|
|
10
|
+
note?: string | null;
|
|
11
|
+
}>;
|
|
12
|
+
value: T;
|
|
13
|
+
onChange: (next: T) => void;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
disabledReason?: string;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
export declare function ScreenToolbar({ viewport, onViewport, zoom, onZoom, theme, onTheme, hint, actions, identity, backHref, zoomEnabled, editing, onToggleEdit, pinCount, onOpenRequest, isolatedBase, }: {
|
|
18
|
+
viewport: string;
|
|
19
|
+
onViewport: (next: string) => void;
|
|
20
|
+
zoom: Zoom;
|
|
21
|
+
onZoom: (next: Zoom) => void;
|
|
22
|
+
theme: ThemeMode;
|
|
23
|
+
onTheme: (next: ThemeMode) => void;
|
|
24
|
+
hint?: ReactNode;
|
|
25
|
+
actions?: ReactNode;
|
|
26
|
+
identity?: ReactNode;
|
|
27
|
+
backHref?: string;
|
|
28
|
+
zoomEnabled?: boolean;
|
|
29
|
+
editing?: boolean;
|
|
30
|
+
onToggleEdit?: () => void;
|
|
31
|
+
pinCount?: number;
|
|
32
|
+
onOpenRequest?: () => void;
|
|
33
|
+
isolatedBase?: Record<string, string>;
|
|
34
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as c}from"react/jsx-runtime";import{useViewerConfig as C}from"./config-context";import{cx as d}from"./cx";import{workbenchUrl as w}from"./manifest";const N="rounded-md border border-zinc-300 px-2 py-1 text-[11px] font-medium text-zinc-600 hover:bg-zinc-100 dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800",j="auto";function s({options:n,value:a,onChange:o,disabled:t=!1,disabledReason:i}){return e("div",{className:d("flex rounded-md border border-zinc-300 p-0.5 dark:border-zinc-700",t&&"opacity-40"),title:t?i:void 0,children:n.map(r=>e("button",{type:"button",disabled:t,onClick:()=>o(r.id),title:t?i:r.note??void 0,className:d("rounded px-2 py-1 text-[11px] font-medium transition-colors",r.id===a?"bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900":"text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"),children:r.label},String(r.id)))})}function b({label:n,children:a}){return c("span",{className:"flex items-center gap-1.5",children:[e("span",{className:"text-[10px] font-medium uppercase tracking-wider text-zinc-400 dark:text-zinc-500",children:n}),a]})}const A=[{id:"fit",label:"Ajustar"},{id:.5,label:"50%"},{id:.75,label:"75%"},{id:1,label:"100%"}],E=[{id:"light",label:"Claro"},{id:"dark",label:"Oscuro"},{id:"split",label:"Ambos"}];function _({viewport:n,onViewport:a,zoom:o,onZoom:t,theme:i,onTheme:r,hint:m,actions:y,identity:x,backHref:u,zoomEnabled:S=!0,editing:p,onToggleEdit:z,pinCount:h,onOpenRequest:f,isolatedBase:g}){const k=C(),v=g?w(k,"",new URLSearchParams({...g,vp:n,zoom:String(o),theme:i,chrome:"off"})):null;return c("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-2 border-b border-zinc-200 bg-white px-6 py-2 dark:border-zinc-700 dark:bg-zinc-900",children:[u&&e("a",{href:u,className:"rounded-md px-2 py-1 text-[11px] font-medium text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900 dark:hover:bg-zinc-800 dark:hover:text-zinc-100",children:"\u2190 Taller"}),x&&e("span",{className:"max-w-[16rem] truncate rounded bg-zinc-100 px-2 py-1 font-mono text-[11px] text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300",children:x}),e(b,{label:"Tama\xF1o",children:e(s,{value:n,onChange:a,options:[{id:j,label:"Auto"},...k.viewports.map(l=>({id:l.id,label:l.label,note:l.note}))]})}),e(b,{label:"Zoom",children:e(s,{value:o,onChange:t,options:A,disabled:!S,disabledReason:"En Auto el componente se dibuja en l\xEDnea, sin cuadro que escalar."})}),e(b,{label:"Tema",children:e(s,{value:i,onChange:r,options:E})}),y,c("span",{className:"ml-auto flex items-center gap-2",children:[z&&e("button",{type:"button",onClick:z,className:d("rounded-md px-2 py-1 text-[11px] font-medium transition-colors",p?"bg-amber-400 text-amber-950":"border border-zinc-300 text-zinc-600 hover:bg-zinc-100 dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800"),title:"Se\xF1alar elementos (E)",children:p?"Editando \u25CF":"Editar"}),f&&c("button",{type:"button",onClick:f,className:N,children:["Solicitud",(h??0)>0?` (${h})`:""]}),v&&e("a",{href:v,target:"_blank",rel:"noreferrer",className:N,title:"Sin cromo, en una pesta\xF1a nueva",children:"Abrir aislado \u2197"})]}),m&&e("p",{className:"basis-full text-[11px] leading-snug text-zinc-500 dark:text-zinc-400",children:m})]})}export{j as AUTO,N as CHIP,_ as ScreenToolbar,s as SegmentedControl};
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NewTicketInput, TicketSummary } from "./pin";
|
|
2
|
+
export declare function readTickets(): Promise<TicketSummary[]>;
|
|
3
|
+
export declare function writeTicket(input: NewTicketInput): Promise<{
|
|
4
|
+
ok: boolean;
|
|
5
|
+
id?: string;
|
|
6
|
+
file?: string;
|
|
7
|
+
prompt?: string;
|
|
8
|
+
error?: string;
|
|
9
|
+
}>;
|
package/dist/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{execFile as k}from"node:child_process";import{promisify as y}from"node:util";const i=y(k),w=120,l=4e3,g=50,f=3e4,u=16*1024*1024;function m(){return!1}function _(){if(!m())throw new Error("El taller s\xF3lo escribe tickets en desarrollo.")}function r(t,n){return(t??"").slice(0,n).trim()}function d(){return"workbench"}function T(t){return typeof t=="object"&&t!==null&&"id"in t&&"path"in t}async function S(){if(!m())return[];try{const{stdout:t}=await i(d(),["tickets"],{cwd:process.cwd(),timeout:f,maxBuffer:u}),n=JSON.parse(t);return Array.isArray(n)?n:[]}catch{return[]}}async function X(t){_();const n=r(t.title,w);if(n.length===0)return{ok:!1,error:"Falta el t\xEDtulo."};const o=r(t.surface,100);if(o.length===0)return{ok:!1,error:"Falta la superficie."};const p=JSON.stringify({intent:r(t.intent,l),acceptance:r(t.acceptance,l),route:r(t.route,200),pins:(t.pins??[]).slice(0,g).map(e=>({note:r(e.note,500),element:{tag:r(e.element.tag,40),classes:r(e.element.classes,300),text:r(e.element.text,120),path:r(e.element.path,300)},node:e.node})),errors:(t.errors??[]).slice(0,20).map(e=>({message:r(e.message,500),component:e.component,file:e.file,route:e.route}))});try{const e=i(d(),["ticket",o,n,"--json"],{cwd:process.cwd(),timeout:f,maxBuffer:u});e.child.stdin?.on("error",()=>{}),e.child.stdin?.end(p);const{stdout:h}=await e,c=JSON.parse(h.trim());if(!T(c))return{ok:!0};const s=String(c.id),a=String(c.path).replace(`${process.cwd()}/`,""),E=`Lee ${a} y ejec\xFAtalo. Es un ticket del taller contra la superficie "${o}"; el mapa de archivos ya est\xE1 dentro. Al terminar: commit con ${s} en el mensaje, luego \`workbench validate ${s}\`.`;return{ok:!0,id:s,file:a,prompt:E}}catch(e){return{ok:!1,error:e instanceof Error?e.message:"Fall\xF3 la escritura."}}}export{S as readTickets,X as writeTicket};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EditSession } from "./edit-session";
|
|
2
|
+
import type { OverlaySurface } from "./manifest.types";
|
|
3
|
+
import type { NewTicketInput } from "./pin";
|
|
4
|
+
export type DrawerSurface = OverlaySurface;
|
|
5
|
+
export interface CreateResult {
|
|
6
|
+
ok: boolean;
|
|
7
|
+
id?: string;
|
|
8
|
+
file?: string;
|
|
9
|
+
prompt?: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function TicketDrawer({ session, surfaces, route, onCreate, }: {
|
|
13
|
+
session: EditSession;
|
|
14
|
+
surfaces: DrawerSurface[];
|
|
15
|
+
route?: string;
|
|
16
|
+
onCreate: (input: NewTicketInput) => Promise<CreateResult>;
|
|
17
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as r,Fragment as u,jsxs as t}from"react/jsx-runtime";import{useState as l}from"react";import{cx as j}from"./cx";import{surfaceFromPins as B}from"./manifest";function U({session:a,surfaces:o,route:p,onCreate:v}){const[n,b]=l(""),[x,h]=l(""),[k,g]=l(""),[f,y]=l(!0),[s,z]=l(!1),[c,N]=l(null),[E,C]=l(null);if(!a.drawerOpen)return null;const F=o[0]?.id??"",$=B(a.pins,F),m=E??$,i=o.find(e=>e.id===m),w=new Set(a.pins.map(e=>e.node?.surface).filter(e=>!!e)),D=w.size>1,q=async()=>{if(!n.trim()||s)return;z(!0);const e=f?a.errors:[];try{const d=await v({surface:m,title:n.trim(),intent:x,acceptance:k,pins:a.pins,errors:e,...p?{route:p}:{}});N(d),d.ok&&(b(""),h(""),g(""),a.clearPins())}catch(d){N({ok:!1,error:d instanceof Error?d.message:"Fall\xF3 la escritura."})}finally{z(!1)}};return t("aside",{role:"dialog","aria-modal":"true","aria-labelledby":"workbench-drawer-title",onKeyDown:e=>{e.key==="Escape"&&a.closeDrawer()},className:"fixed right-0 top-0 z-[2147483100] flex h-full w-[26rem] flex-col border-l border-zinc-200 bg-white shadow-xl dark:border-zinc-700 dark:bg-zinc-900",children:[t("header",{className:"flex items-center justify-between border-b border-zinc-200 px-4 py-3 dark:border-zinc-700",children:[t("div",{children:[r("h2",{id:"workbench-drawer-title",className:"text-sm font-semibold text-zinc-900 dark:text-zinc-100",children:"Solicitud de cambio"}),r("p",{className:"mt-0.5 text-[11px] text-zinc-500 dark:text-zinc-400",children:i?t(u,{children:[i.label," \xB7 ",i.weight==="quick"?"ticket corto":"ticket completo"," ","\xB7 ",i.predictedFileCount," archivos predichos"]}):"Sin superficie"})]}),r("button",{type:"button",onClick:a.closeDrawer,className:"rounded px-2 py-1 text-[11px] text-zinc-500 hover:bg-zinc-100 dark:hover:bg-zinc-800",children:"Cerrar"})]}),t("div",{className:"min-h-0 flex-1 space-y-4 overflow-auto p-4",children:[D&&t("div",{className:"rounded-md border border-amber-300 bg-amber-50 p-2 text-[11px] dark:border-amber-800 dark:bg-amber-950",children:[r("p",{className:"text-amber-900 dark:text-amber-100",children:"Se\xF1alaste elementos de m\xE1s de una superficie."}),r("select",{value:m,onChange:e=>C(e.target.value),className:"mt-1 w-full rounded border border-amber-300 bg-white px-1 py-0.5 text-[11px] dark:border-amber-800 dark:bg-zinc-900",children:[...w].map(e=>r("option",{value:e,children:o.find(d=>d.id===e)?.label??e},e))})]}),t("label",{className:"block",children:[r("span",{className:"text-[11px] font-medium uppercase tracking-wider text-zinc-400",children:"T\xEDtulo"}),r("input",{value:n,onChange:e=>b(e.target.value),placeholder:"Unificar el gris de la barra superior",autoFocus:!0,className:"mt-1 w-full rounded-md border border-zinc-300 px-2 py-1.5 text-[13px] dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100"})]}),t("label",{className:"block",children:[r("span",{className:"text-[11px] font-medium uppercase tracking-wider text-zinc-400",children:"Qu\xE9 cambia"}),r("textarea",{value:x,onChange:e=>h(e.target.value),rows:3,placeholder:"Una o dos l\xEDneas. Qu\xE9 est\xE1 mal y qu\xE9 deber\xEDa pasar.",className:"mt-1 w-full rounded-md border border-zinc-300 px-2 py-1.5 text-[13px] dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100"})]}),t("label",{className:"block",children:[r("span",{className:"text-[11px] font-medium uppercase tracking-wider text-zinc-400",children:"C\xF3mo se valida"}),r("textarea",{value:k,onChange:e=>g(e.target.value),rows:3,placeholder:"Una l\xEDnea por criterio.\nSe vuelve una lista que `workbench validate` cuenta.",className:"mt-1 w-full rounded-md border border-zinc-300 px-2 py-1.5 text-[13px] dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100"})]}),t("section",{children:[t("h3",{className:"text-[11px] font-medium uppercase tracking-wider text-zinc-400",children:["Se\xF1alado ",a.pins.length>0&&`(${a.pins.length})`]}),a.pins.length===0?t("p",{className:"mt-1 text-[11px] text-zinc-500 dark:text-zinc-400",children:["Activa ",r("strong",{children:"Editar"})," y haz clic en lo que quieres cambiar. Cada clic guarda el componente y su archivo, no una descripci\xF3n."]}):r("ul",{className:"mt-1 space-y-2",children:a.pins.map((e,d)=>t("li",{className:"rounded-md border border-zinc-200 p-2 dark:border-zinc-700",children:[r("p",{className:"font-mono text-[10px] text-zinc-500 dark:text-zinc-400",children:e.node?`${e.node.component}${e.node.file?` \xB7 ${e.node.file}`:""}`:`<${e.element.tag}>`}),e.element.text&&t("p",{className:"mt-0.5 truncate text-[11px] text-zinc-600 dark:text-zinc-300",children:["\u201C",e.element.text,"\u201D"]}),t("div",{className:"mt-1 flex gap-2",children:[r("input",{value:e.note,onChange:S=>a.updatePin(d,S.target.value),placeholder:"qu\xE9 le pasa a esto",className:"w-full rounded border border-zinc-200 px-1.5 py-1 text-[11px] dark:border-zinc-700 dark:bg-zinc-800"}),r("button",{type:"button",onClick:()=>a.removePin(d),className:"shrink-0 rounded px-1.5 text-[11px] text-zinc-400 hover:text-zinc-900 dark:hover:text-zinc-100",children:"quitar"})]})]},`${e.element.path}-${d}`))})]}),a.errors.length>0&&t("section",{className:"rounded-md border border-red-200 bg-red-50 p-2 dark:border-red-900 dark:bg-red-950",children:[t("label",{className:"flex items-center gap-2 text-[11px] text-red-900 dark:text-red-200",children:[r("input",{type:"checkbox",checked:f,onChange:e=>y(e.target.checked)}),"Adjuntar ",a.errors.length," error",a.errors.length===1?"":"es"," de runtime"]}),r("ul",{className:"mt-1 space-y-0.5 font-mono text-[10px] text-red-800 dark:text-red-300",children:a.errors.slice(0,3).map(e=>t("li",{className:"truncate",children:[e.file??e.route??"?"," \u2014 ",e.message]},`${e.at}-${e.message}`))})]}),c&&r("div",{className:j("rounded-md border p-2 text-[11px]",c.ok?"border-emerald-300 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-950":"border-red-300 bg-red-50 dark:border-red-800 dark:bg-red-950"),children:c.ok?t(u,{children:[t("p",{className:"font-medium text-emerald-900 dark:text-emerald-100",children:[c.id," \xB7 ",c.file]}),c.prompt&&t(u,{children:[r("p",{className:"mt-1 text-emerald-800 dark:text-emerald-200",children:"P\xE1sale esto al agente:"}),r("textarea",{readOnly:!0,value:c.prompt,rows:4,onFocus:e=>e.currentTarget.select(),className:"mt-1 w-full rounded border border-emerald-300 bg-white p-1 font-mono text-[10px] dark:border-emerald-800 dark:bg-zinc-900"})]})]}):r("p",{className:"text-red-900 dark:text-red-100",children:c.error})})]}),r("footer",{className:"border-t border-zinc-200 p-3 dark:border-zinc-700",children:r("button",{type:"button",onClick:q,disabled:!n.trim()||s,className:"w-full rounded-md bg-zinc-900 px-3 py-2 text-[12px] font-medium text-white disabled:opacity-40 dark:bg-zinc-100 dark:text-zinc-900",children:s?"Escribiendo\u2026":"Escribir el ticket"})})]})}export{U as TicketDrawer};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Manifest } from "./manifest.types";
|
|
2
|
+
import type { NewTicketInput, TicketSummary } from "./pin";
|
|
3
|
+
import type { RegistryEntry } from "./registry";
|
|
4
|
+
import { type CreateResult } from "./ticket-drawer";
|
|
5
|
+
export type Tab = "elementos" | "componentes" | "flujos" | "superficies";
|
|
6
|
+
export interface WorkbenchView {
|
|
7
|
+
tab?: string;
|
|
8
|
+
component?: string;
|
|
9
|
+
flow?: string;
|
|
10
|
+
surface?: string;
|
|
11
|
+
vp?: string;
|
|
12
|
+
zoom?: string;
|
|
13
|
+
theme?: string;
|
|
14
|
+
chrome?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function WorkbenchApp({ manifest, registry, tickets, view, onCreateTicket, }: {
|
|
17
|
+
manifest: Manifest;
|
|
18
|
+
registry: RegistryEntry[];
|
|
19
|
+
tickets: TicketSummary[];
|
|
20
|
+
view: WorkbenchView;
|
|
21
|
+
onCreateTicket: (input: NewTicketInput) => Promise<CreateResult>;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as n,jsxs as o,Fragment as R}from"react/jsx-runtime";import{useMemo as x,useState as d}from"react";import{ManifestProvider as _}from"./config-context";import{cx as m}from"./cx";import{EditSessionOverlay as A,useEditSession as D}from"./edit-session";import{buildComponentIndex as H}from"./hover-inspect";import{byGroup as O,flowById as V,groupLabel as Z}from"./manifest";import{ComponentsPanel as q}from"./panels/components";import{ElementsPanel as G}from"./panels/elements";import{FlowsPanel as K}from"./panels/flows";import{SurfacesPanel as W}from"./panels/surfaces";import{TicketDrawer as $}from"./ticket-drawer";import{VerdictBadge as J}from"./component-preview";const w=[{id:"elementos",label:"Elementos"},{id:"componentes",label:"Componentes"},{id:"flujos",label:"Flujos"},{id:"superficies",label:"Superficies"}];function Q(e){return w.some(r=>r.id===e)&&e?e:"componentes"}function U(e){if(e==="fit")return"fit";const r=Number(e);return r===.5||r===.75||r===1?r:void 0}function X(e){return e==="light"||e==="dark"||e==="split"?e:void 0}function me({manifest:e,registry:r,tickets:N,view:i,onCreateTicket:C}){const[s,v]=d(Q(i.tab)),[F,j]=d(i.component??e.components[0]?.id),[E,I]=d(i.flow??e.flows[0]?.id),[S,P]=d(i.surface??e.surfaces[0]?.id),[h,T]=d(""),c=D({bareKeys:!0}),B=x(()=>H(e.components),[e.components]),g=i.chrome!=="off",u=e.components.find(t=>t.id===F)??e.components[0],l=V(e.flows,E),b=e.surfaces.find(t=>t.id===S)??e.surfaces[0],z={componentIndex:B,editing:c.editing,onPin:c.addPin,onHover:c.setHovering,onToggleEdit:c.toggleEditing,pinCount:c.pins.length,onOpenRequest:c.openDrawer,showChrome:g,initialViewport:i.vp,initialZoom:U(i.zoom),initialTheme:X(i.theme)},p=h.trim().toLowerCase(),k=x(()=>p?e.components.filter(t=>t.name.toLowerCase().includes(p)||t.file.toLowerCase().includes(p)):e.components,[e.components,p]),y=x(()=>O(k),[k]),L=s==="elementos"?n(G,{}):s==="flujos"?l?n(K,{flow:l,...z},l.id):n(f,{what:"recorridos",hint:"El rastreador no encontr\xF3 enlaces entre p\xE1ginas."}):s==="superficies"?b?n(W,{surface:b,tickets:N}):n(f,{what:"superficies",hint:"Nada bajo el directorio de la app importa una cabecera, un rail o una barra lateral."}):u?n(q,{entry:u,registry:r,...z}):n(f,{what:"componentes",hint:"Revisa `componentRoots` en workbench.config.json."});return o(_,{manifest:e,children:[o("div",{className:"fixed inset-0 flex bg-white text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100",children:[g&&o("nav",{className:"flex w-64 shrink-0 flex-col border-r border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900",children:[o("header",{className:"border-b border-zinc-200 px-4 py-3 dark:border-zinc-700",children:[n("h1",{className:"text-sm font-semibold",children:e.config.title}),n("p",{className:"mt-0.5 text-[11px] leading-snug text-zinc-500 dark:text-zinc-400",children:e.config.subtitle})]}),n("div",{className:"flex flex-wrap gap-1 border-b border-zinc-200 p-2 dark:border-zinc-700",children:w.map(t=>n("button",{type:"button",onClick:()=>v(t.id),className:m("rounded px-2 py-1 text-[11px] font-medium",t.id===s?"bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900":"text-zinc-600 hover:bg-zinc-200 dark:text-zinc-300 dark:hover:bg-zinc-800"),children:t.label},t.id))}),o("div",{className:"min-h-0 flex-1 overflow-auto p-2",children:[s==="componentes"&&o(R,{children:[n("input",{value:h,onChange:t=>T(t.target.value),placeholder:`Filtrar ${e.components.length}\u2026`,className:"mb-2 w-full rounded border border-zinc-300 px-2 py-1 text-[11px] dark:border-zinc-700 dark:bg-zinc-800"}),y.map(([t,M])=>o("section",{className:"mb-3",children:[n("h2",{className:"px-1 pb-1 text-[10px] font-medium uppercase tracking-wider text-zinc-400",children:Z(e.config,t)}),M.map(a=>o("button",{type:"button",onClick:()=>j(a.id),className:m("flex w-full items-center gap-1.5 rounded px-2 py-1 text-left text-[12px]",a.id===u?.id?"bg-zinc-200 font-medium dark:bg-zinc-800":"text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"),children:[n("span",{className:"truncate",children:a.name}),a.verdict!=="auto"&&n("span",{className:"ml-auto shrink-0",children:n(J,{verdict:a.verdict})})]},a.id))]},t))]}),s==="flujos"&&e.flows.map(t=>n("button",{type:"button",onClick:()=>I(t.id),className:m("block w-full truncate rounded px-2 py-1 text-left text-[12px]",t.id===l?.id?"bg-zinc-200 font-medium dark:bg-zinc-800":"text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"),children:t.title},t.id)),s==="superficies"&&e.surfaces.map(t=>n("button",{type:"button",onClick:()=>P(t.id),className:m("block w-full truncate rounded px-2 py-1 text-left text-[12px]",t.id===b?.id?"bg-zinc-200 font-medium dark:bg-zinc-800":"text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"),children:t.label},t.id))]}),o("footer",{className:"border-t border-zinc-200 px-3 py-2 text-[10px] text-zinc-400 dark:border-zinc-700",children:[e.stats.filesScanned," archivos \xB7 ",e.stats.elapsedMs," ms \xB7"," ",e.generatedBy,e.stats.parseFailures.length>0&&o("span",{className:"block text-amber-600 dark:text-amber-400",children:[e.stats.parseFailures.length," archivos no se analizaron"]})]})]}),n("main",{className:"min-w-0 flex-1",children:L})]}),n(A,{session:c}),n($,{session:c,surfaces:e.surfaces.map(t=>({id:t.id,label:t.label,weight:t.weight,predictedFileCount:t.predictedFiles.length})),onCreate:C})]})}function f({what:e,hint:r}){return n("div",{className:"flex h-full items-center justify-center p-10",children:o("p",{className:"max-w-sm text-center text-sm text-zinc-500 dark:text-zinc-400",children:["No se encontraron ",e,". ",r]})})}export{me as WorkbenchApp};
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@open-flow/ui",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "El visor de workbench \u2014 la mitad UI/UX, p\u00fablica. El motor de escaneo se distribuye por separado y requiere autorizaci\u00f3n.",
|
|
5
|
+
"license": "Elastic-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Ecorona-LLC/open-flow.git"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./app": {
|
|
18
|
+
"types": "./dist/app.d.ts",
|
|
19
|
+
"default": "./dist/app.js"
|
|
20
|
+
},
|
|
21
|
+
"./actions": {
|
|
22
|
+
"types": "./dist/dev-actions.d.ts",
|
|
23
|
+
"development": "./dist/dev-actions.js",
|
|
24
|
+
"default": "./dist/dev-actions.noop.js"
|
|
25
|
+
},
|
|
26
|
+
"./demo": {
|
|
27
|
+
"types": "./dist/demo.d.ts",
|
|
28
|
+
"default": "./dist/demo.js"
|
|
29
|
+
},
|
|
30
|
+
"./server": {
|
|
31
|
+
"types": "./dist/server.d.ts",
|
|
32
|
+
"default": "./dist/server.js"
|
|
33
|
+
},
|
|
34
|
+
"./overlay": {
|
|
35
|
+
"types": "./dist/overlay.d.ts",
|
|
36
|
+
"development": "./dist/overlay.js",
|
|
37
|
+
"default": "./dist/overlay.noop.js"
|
|
38
|
+
},
|
|
39
|
+
"./overlay/noop": {
|
|
40
|
+
"types": "./dist/overlay.noop.d.ts",
|
|
41
|
+
"default": "./dist/overlay.noop.js"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"bin",
|
|
47
|
+
"README.md",
|
|
48
|
+
"LICENSE"
|
|
49
|
+
],
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/minify.mjs",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"test": "vitest run --passWithNoTests",
|
|
54
|
+
"test:watch": "vitest",
|
|
55
|
+
"clean": "rm -rf dist"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"next": ">=15",
|
|
59
|
+
"react": ">=19",
|
|
60
|
+
"react-dom": ">=19"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/node": "^22.10.2",
|
|
64
|
+
"@types/react": "^19.2.18",
|
|
65
|
+
"@types/react-dom": "^19.2.5",
|
|
66
|
+
"esbuild": "^0.28.2",
|
|
67
|
+
"happy-dom": "^20.11.10",
|
|
68
|
+
"next": "^16.3.3",
|
|
69
|
+
"react": "^19.2.8",
|
|
70
|
+
"react-dom": "^19.2.8",
|
|
71
|
+
"typescript": "^5.9.0",
|
|
72
|
+
"vitest": "^3.2.0"
|
|
73
|
+
},
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public"
|
|
76
|
+
},
|
|
77
|
+
"packageManager": "pnpm@10.6.2",
|
|
78
|
+
"homepage": "https://github.com/Ecorona-LLC/open-flow"
|
|
79
|
+
}
|