blnkfld 0.1.4 → 0.1.5

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/README.md CHANGED
@@ -22,6 +22,8 @@ node /absolute/path/to/blnkfld/cli/main.mjs /absolute/path/to/project
22
22
 
23
23
  The command analyzes the project, validates the report, saves `.blnkfld/report.json`, starts a loopback server, and opens your browser. The Three.js interface displays the generated report, with System Overview first and a separate System Architecture diagram. When WebGL is unavailable, an interactive isometric SVG view preserves the components, connections, action playback, and source inspection. Run it again to refresh the analysis. Press Ctrl+C to stop. Use `--no-open` for a terminal-only environment, `--port 4174` to choose a port, or `--report-only` to save the report and exit.
24
24
 
25
+ On startup, blnkfld asks npm for the latest release. If your cached copy is older, it reruns the same command with the latest version, so `npx blnkfld` always stays current. The check times out after two seconds and falls back to the installed version when offline. Set `BLNKFLD_NO_UPDATE=1` to skip it; it is also skipped when `CI` is set.
26
+
25
27
  ## What the agent produces
26
28
 
27
29
  - Project purpose, constraints, stack, and source-backed how-to-run instructions.
package/cli/main.mjs CHANGED
@@ -6,6 +6,7 @@ import { spawn } from 'node:child_process';
6
6
  import { selectAgent, analyze, run } from './agent.mjs';
7
7
  import { validateAnalysis, toViewReport } from './report.mjs';
8
8
  import { serve } from './server.mjs';
9
+ import { updateTarget, handoff } from './update.mjs';
9
10
 
10
11
  const ignored=new Set(['.git','.blnkfld','node_modules','dist','build','.next','coverage','.venv','venv','vendor']);
11
12
  async function inventory(root) {
@@ -26,6 +27,13 @@ async function main() {
26
27
  const {values,positionals}=parseArgs({options:{help:{type:'boolean',short:'h'},agent:{type:'string',default:'auto'},'no-open':{type:'boolean'},port:{type:'string'},'report-only':{type:'boolean'}},allowPositionals:true});
27
28
  if(values.help){console.log('Usage: blnkfld [project-directory] [--agent auto|codex|claude] [--no-open] [--port PORT] [--report-only]\n\nAnalyze a project with your signed-in coding agent and open its visual brief.\nRequires Node 22+ and a signed-in Codex or Claude Code CLI.\nThe analysis uses your agent account and may consume its usage allowance.\nReports are saved in .blnkfld/report.json. Ctrl+C stops the preview.');return;}
28
29
  if(positionals.length>1)throw new Error('Provide at most one project directory.');
30
+ const update=await updateTarget();
31
+ if(update){
32
+ console.log(`Updating blnkfld ${update.current} → ${update.latest}…`);
33
+ const code=await handoff(update.latest,process.argv.slice(2));
34
+ if(code!==null){process.exitCode=code;return;}
35
+ console.log(`Could not start blnkfld ${update.latest}; continuing with ${update.current}.`);
36
+ }
29
37
  if(!['auto','codex','claude'].includes(values.agent))throw new Error('Agent must be auto, codex, or claude.');
30
38
  const port=values.port===undefined?0:Number(values.port);
31
39
  if(!Number.isInteger(port)||port<0||port>65535)throw new Error('Port must be an integer from 0 to 65535.');
package/cli/update.mjs ADDED
@@ -0,0 +1,57 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { spawn } from 'node:child_process';
3
+
4
+ // `npx blnkfld` silently reuses a previously cached copy, so returning users can be
5
+ // stuck on an old release. On startup, ask the registry for the latest version and,
6
+ // if it is newer, hand off to it. Any failure falls back to the running version.
7
+ const REGISTRY = 'https://registry.npmjs.org/blnkfld/latest';
8
+ export const HANDOFF_ENV = 'BLNKFLD_UPDATED';
9
+ export const OPT_OUT_ENV = 'BLNKFLD_NO_UPDATE';
10
+
11
+ const parse = v => /^(\d+)\.(\d+)\.(\d+)$/.exec(String(v ?? '').trim())?.slice(1).map(Number);
12
+ export function isNewer(latest, current) {
13
+ const a = parse(latest), b = parse(current);
14
+ if(!a || !b) return false;
15
+ for(let i = 0; i < 3; i++) if(a[i] !== b[i]) return a[i] > b[i];
16
+ return false;
17
+ }
18
+
19
+ export async function currentVersion() {
20
+ return JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')).version;
21
+ }
22
+
23
+ export async function latestVersion({ fetchImpl = fetch, timeoutMs = 2000 } = {}) {
24
+ try {
25
+ const response = await fetchImpl(REGISTRY, { signal: AbortSignal.timeout(timeoutMs), headers: { accept: 'application/json' } });
26
+ if(!response.ok) return null;
27
+ return (await response.json()).version ?? null;
28
+ } catch { return null; }
29
+ }
30
+
31
+ export async function updateTarget({ env = process.env, current, fetchImpl, timeoutMs } = {}) {
32
+ if(env[HANDOFF_ENV] || env[OPT_OUT_ENV] || env.CI) return null;
33
+ current ??= await currentVersion();
34
+ const latest = await latestVersion({ fetchImpl, timeoutMs });
35
+ return isNewer(latest, current) ? { current, latest } : null;
36
+ }
37
+
38
+ // Re-run the same command with the latest release. Resolves with the exit code,
39
+ // or null if the newer version could not be started.
40
+ export function handoff(latest, args, { env = process.env } = {}) {
41
+ const windows = process.platform === 'win32';
42
+ const command = windows ? 'npx.cmd' : 'npx';
43
+ const argv = ['--yes', `blnkfld@${latest}`, ...args];
44
+ return new Promise(resolve => {
45
+ let child;
46
+ try {
47
+ child = spawn(command, windows ? argv.map(a => JSON.stringify(a)) : argv,
48
+ { stdio: 'inherit', shell: windows, env: { ...env, [HANDOFF_ENV]: latest } });
49
+ } catch { resolve(null); return; }
50
+ // Ctrl+C reaches the child directly through the terminal; keep this process alive until it exits.
51
+ const ignore = () => {};
52
+ process.on('SIGINT', ignore); process.on('SIGTERM', ignore);
53
+ const done = code => { process.off('SIGINT', ignore); process.off('SIGTERM', ignore); resolve(code); };
54
+ child.on('error', () => done(null));
55
+ child.on('close', (code, signal) => done(code ?? (signal ? 1 : 0)));
56
+ });
57
+ }
@@ -4290,4 +4290,4 @@ void main() {
4290
4290
  `));return`${t.join(`
4291
4291
 
4292
4292
  `)}
4293
- `}function FN({report:r}){const t=xe.useRef(null),i=xe.useMemo(()=>UN(r),[r]),e=xe.useMemo(()=>ON(i),[i]);return L.jsxs(L.Fragment,{children:[L.jsx("button",{className:"readme-trigger",type:"button","aria-haspopup":"dialog",onClick:()=>t.current.showModal(),children:"VIEW README ↗"}),L.jsxs("dialog",{ref:t,className:"changelog-drawer readme-drawer","aria-labelledby":"readme-heading",onClick:s=>{if(s.target===t.current){const o=t.current.getBoundingClientRect();(s.clientX<o.left||s.clientX>o.right||s.clientY<o.top||s.clientY>o.bottom)&&t.current.close()}},children:[L.jsxs("header",{children:[L.jsxs("div",{children:[L.jsxs("span",{className:"eyebrow",children:[r.traceStatus==="curated"?"CURATED EXAMPLE":r.analysisKind==="agent"?"AGENT BRIEF":"SOURCE MODEL"," / TEXT README"]}),L.jsx("h2",{id:"readme-heading",children:"README"})]}),L.jsx(Um,{label:"Close README",onClick:()=>t.current.close()})]}),L.jsx("div",{className:"readme-actions",children:L.jsx("a",{className:"readme-download",href:`data:text/markdown;charset=utf-8,${encodeURIComponent(e)}`,download:"README.md",children:"Download README.md ↓"})}),L.jsxs("article",{className:"readme-text","aria-label":"README preview",children:[L.jsx("h3",{children:i.title}),i.subtitle&&L.jsx("p",{className:"readme-subtitle",children:i.subtitle}),i.sections.map(s=>{const o=s.ordered?"ol":"ul";return L.jsxs("section",{children:[L.jsx("h4",{children:s.title}),s.paragraphs.map((c,h)=>L.jsx("p",{children:c},h)),s.items.length>0&&L.jsx(o,{children:s.items.map((c,h)=>L.jsx("li",{children:c},h))})]},s.title)})]})]})]})}function Om({children:r,className:t=""}){const i=xe.useRef(null),e=xe.useRef(null);return xe.useLayoutEffect(()=>{const s=i.current,o=e.current,c=()=>{const d=o.getBoundingClientRect().height;s.style.height=`${d}px`};c();const h=new ResizeObserver(c);return h.observe(o),()=>h.disconnect()},[]),L.jsx("div",{ref:i,className:`smooth-height ${t}`,children:L.jsx("div",{ref:e,className:"smooth-height-content",children:r})})}const BN="0.1.4",kN=[{version:"0.1.4",date:"2026-11-02",groups:[{title:"Fixed",changes:['Briefs no longer fail with "Missing evidence entry" when the agent appends its claim to a source citation.']},{title:"Changed",changes:["Use the rounded-outline mark without a visible wordmark across the app and website; retain the striped-circle design as a saved alternate.","Add Vercel Web Analytics to the website.","Center the homepage mark above a smaller tagline and add a linked project credit to the footer mark.","Refine docs labels, copy feedback, and app header spacing; match the app browser title to the homepage."]}]},{version:"0.1.3",date:"2026-10-07",groups:[{title:"Added",changes:["Switch the app between light, dark, and blue themes from the header.","The website includes a getting-started guide with animated troubleshooting answers.","Matching rounded-square favicons adapt to light and dark browser themes."]},{title:"Changed",changes:["A shared outlined logo and consistent serif wordmark align the app, homepage, and docs.","Section navigation sits in its own row below the app header, alongside the updated AN AGENTIC README label.","Numbered card labels use the orange accent, and the rounded repository selector closes when clicking outside it.","The homepage command and its underline use orange, with a theme-aware footer mark.","Documentation typography and spacing are more consistent, and copying the homepage command no longer highlights its text."]},{title:"Fixed",changes:["Haikus use italic serif text again.","Blue mode uses white secondary text and theme-aware logo colors."]}]},{version:"0.1.2",date:"2026-10-06",groups:[{title:"Changed",changes:["App and drawer text is smaller and lighter, with consistent 21px medium serif headings and upright typography throughout, including the haiku.","Quick Start headings use periods in place of slash separators.","Quick Start uses the published npm package instead of requiring a local blnkfld checkout and build."]}]},{version:"0.1.1",date:"2026-10-06",groups:[{title:"Changed",changes:["System Architecture and Trace one action now step through five, four, three, two, and one column as the window narrows, preserving selection and playback.","Newly generated IN ONE MINUTE summaries contain one to five sentences, with additional detail in the expanded summary.","The changelog groups release notes by version and date and shows only releases up to the running app's version.","The hosted interface uses Lora and Times New Roman as fallbacks when Iowan Old Style is unavailable."]}]},{version:"0.1.0",date:"2026-10-05",groups:[{title:"Added",changes:["Run npx blnkfld inside a project to generate a source-backed brief using your installed Codex or Claude Code CLI.","Explore the project's system overview, architecture, and an action trace, with source excerpts supporting the explanation.","Read a project summary and haiku, inspect setup instructions, and export the brief as a README.","View reports in a local browser interface with bundled Inter, Geist Mono, IBM Plex Mono, and Lora fonts. Serif text prefers Iowan Old Style when installed, then Lora and Times New Roman."]}]}],zN=new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric",year:"numeric",timeZone:"UTC"});function HN(){const r=xe.useRef(null);return L.jsxs(L.Fragment,{children:[L.jsx("button",{className:"changelog-trigger",type:"button","aria-haspopup":"dialog",onClick:()=>r.current.showModal(),children:"CHANGELOG"}),L.jsxs("dialog",{ref:r,className:"changelog-drawer release-notes-drawer","aria-labelledby":"changelog-title",onClick:t=>{if(t.target===r.current){const i=r.current.getBoundingClientRect();(t.clientX<i.left||t.clientX>i.right||t.clientY<i.top||t.clientY>i.bottom)&&r.current.close()}},children:[L.jsxs("header",{children:[L.jsxs("div",{children:[L.jsx("span",{className:"eyebrow",children:"BLNKFLD / RELEASE NOTES"}),L.jsx("h2",{id:"changelog-title",children:"Changelog"}),L.jsxs("p",{children:["What’s changed through v",BN,"."]})]}),L.jsx(Um,{label:"Close changelog",onClick:()=>r.current.close()})]}),L.jsx("div",{className:"changelog-list",children:kN.map(t=>L.jsxs("article",{className:"changelog-entry",children:[L.jsx("time",{className:"changelog-date",dateTime:t.date,children:zN.format(new Date(`${t.date}T00:00:00Z`))}),L.jsxs("div",{children:[L.jsxs("h3",{children:["v",t.version]}),t.groups.map(i=>L.jsxs("section",{className:"changelog-category",children:[L.jsx("h4",{children:i.title}),L.jsx("ul",{children:i.changes.map(e=>L.jsx("li",{children:e},e))})]},i.title))]})]},t.version))})]})]})}function VN({report:r,selected:t,onSelect:i,curated:e}){var v,_,A;const[s,o]=xe.useState(!1),[c,h]=xe.useState(null),d=S_(),f=xe.useMemo(()=>NN(r.system,r.connections,d),[r.system,r.connections,d]),g=f.edges[c];function x(b){h(null),i(b)}function y(b){h(b),i(r.system.findIndex(S=>S.id===f.edges[b].from))}return L.jsxs("div",{className:"connections architecture-connections",children:[L.jsxs("div",{className:"connection-toolbar",children:[L.jsx("span",{children:"ENTIRE ARCHITECTURE"}),L.jsx("button",{disabled:!r.system[t],"aria-pressed":s,onClick:()=>o(!s),children:s?"Show all connections equally":"Highlight selected component"})]}),L.jsx("p",{className:"connection-context",children:e?"Reference architecture · arrows describe the documented interaction.":r.analysisKind==="agent"?"Source-based explanation · arrows describe the reported relationship, not an observed execution.":"Static imports · arrows point from the importing file to its dependency, not the direction of runtime data."}),L.jsx(v_,{layout:f,selected:t,onSelect:x,focused:s,activeEdge:c,onEdge:y}),!f.edges.length&&L.jsx("p",{className:"connection-empty",children:"No connections were established in this report. Components remain available to inspect."}),L.jsx(Om,{children:g&&L.jsxs("section",{className:"architecture-evidence","aria-label":"Selected connection evidence",children:[L.jsxs("div",{children:[L.jsxs("span",{className:"eyebrow",children:["CONNECTION / ",String(g.index+1).padStart(2,"0")]}),L.jsx("button",{onClick:()=>h(null),"aria-label":"Close connection evidence",children:"×"})]}),L.jsxs("h3",{children:[(v=r.system.find(b=>b.id===g.from))==null?void 0:v.label," → ",(_=r.system.find(b=>b.id===g.to))==null?void 0:_.label]}),L.jsx("p",{children:g.labelText}),(A=g.evidence)==null?void 0:A.map(b=>{var S;return L.jsxs("div",{className:"source-file",children:[L.jsxs("span",{children:[b,g.line?` · line ${g.line}`:""]}),L.jsx("p",{children:((S=r.evidence.find(R=>R.path===b))==null?void 0:S.claim)||"Referenced by this relationship."})]},b)})]})})]})}function GN({nodes:r,selected:t,onSelect:i,connections:e,label:s}){const o=xe.useId().replaceAll(":",""),c=98*Xu/Jn,h=Math.max(360,(r.length-1)*c+210),d=r.map((y,v)=>105+v*c),f=e===void 0?r.slice(1).map((y,v)=>[v,v+1]):e.map(y=>[r.findIndex(v=>v.id===y.from),r.findIndex(v=>v.id===y.to)]).filter(([y,v])=>y>=0&&v>=0),g=(y,v,_,A,b,S)=>L.jsxs("g",{children:[L.jsx("polygon",{points:`${y-_},${v-b} ${y},${v+A-b} ${y},${v+A} ${y-_},${v}`,fill:"#cecece"}),L.jsx("polygon",{points:`${y},${v+A-b} ${y+_},${v-b} ${y+_},${v} ${y},${v+A}`,fill:"#b4b4b4"}),L.jsx("polygon",{points:`${y-_},${v-b} ${y},${v-A-b} ${y+_},${v-b} ${y},${v+A-b}`,fill:"#e9e9e9"})]},S);function x(y){return["browser","cli","input"].includes(y)?L.jsxs("g",{children:[g(0,120,18,8,4),L.jsx("path",{d:"M0 111V88",stroke:"#aaa",strokeWidth:"5"}),L.jsx("polygon",{points:"-28,54 28,78 28,111 -28,87",fill:"#aaa"}),L.jsx("polygon",{points:"-23,61 23,81 23,103 -23,83",fill:"#333"})]}):y==="react"?[0,1,2].map(v=>g(0,117-v*14,35-v*7,17-v*3,5,v)):y==="database"?L.jsx("g",{children:[0,1,2].map(v=>L.jsxs("g",{children:[L.jsx("path",{d:`M-25 ${110-v*16}v12c0 13 50 13 50 0v-12`,fill:"#bbb"}),L.jsx("ellipse",{cy:110-v*16,rx:"25",ry:"10",fill:"#ddd"})]},v))}):y==="api"?L.jsxs("g",{children:[g(-22,113,10,8,40),g(22,113,10,8,40),g(0,77,33,9,8)]}):y==="file"||y==="output"?L.jsxs("g",{children:[g(0,118,34,18,5),y==="output"&&L.jsx("path",{d:"M-20 110l28 13m-18-18l28 13m-18-18l28 13",stroke:"#777",strokeWidth:"2"})]}):y==="operation"?L.jsxs("g",{children:[L.jsx("path",{d:"M-25 90v28c0 14 50 14 50 0V90",fill:"#bbb"}),L.jsx("ellipse",{cy:"90",rx:"25",ry:"13",fill:"#ddd"})]}):y==="transfer"?g(0,104,27,18,15):g(0,119,29,16,36)}return L.jsxs("div",{className:"isometric-fallback",children:[L.jsx("span",{className:"fallback-caption",children:"ISOMETRIC COMPATIBILITY VIEW"}),L.jsxs("svg",{viewBox:`0 0 ${h} 220`,role:"group","aria-label":s.replace("three-dimensional","isometric"),children:[L.jsx("defs",{children:L.jsx("marker",{id:o,viewBox:"0 0 8 8",refX:"7",refY:"4",markerWidth:"5",markerHeight:"5",orient:"auto",children:L.jsx("path",{d:"M0 0 8 4 0 8Z",fill:"context-stroke"})})}),f.map(([y,v],_)=>L.jsx("path",{d:`M${d[y]} 148 V${175+_*5} H${d[v]} V148`,fill:"none",stroke:(t==null?void 0:t.index)===y||(t==null?void 0:t.index)===v?"var(--accent)":"#aaa",strokeWidth:"1.2",markerEnd:`url(#${o})`},_)),r.map((y,v)=>L.jsxs("g",{transform:`translate(${d[v]} 0)`,role:"button",tabIndex:"0","aria-label":`Select ${y.label}`,"aria-pressed":(t==null?void 0:t.index)===v,onClick:()=>i(v),onKeyDown:_=>{["Enter"," "].includes(_.key)&&(_.preventDefault(),i(v))},style:{cursor:"pointer"},children:[L.jsx("title",{children:y.label}),g(0,143,49,24.5,7),x(y.kind),L.jsx("path",{d:"M-32 143l19 9",stroke:(t==null?void 0:t.index)===v?"var(--accent)":"#777",strokeWidth:"3"}),L.jsx("text",{y:"210",textAnchor:"middle",fill:(t==null?void 0:t.index)===v?"var(--accent)":"#555",fontSize:"var(--mono-size)",fontFamily:"var(--mono)",fontWeight:"700",children:String(v+1).padStart(2,"0")})]},y.id||v))]})]})}function XN({nodes:r,selected:t,onSelect:i,connections:e,label:s="Interactive three-dimensional repository system"}){const o=xe.useRef(null),c=xe.useRef({selected:t,onSelect:i});c.current={selected:t,onSelect:i};const[h,d]=xe.useState(!1);return xe.useEffect(()=>{const f=o.current,g=getComputedStyle(f).getPropertyValue("--accent").trim();let x;try{x=new y_({antialias:!0,alpha:!0,preserveDrawingBuffer:!0})}catch{d(!0);return}x.setPixelRatio(Math.min(window.devicePixelRatio,2)),x.shadowMap.enabled=!0,x.shadowMap.type=PS,f.appendChild(x.domElement);const y=PM(r.length),v=new JS,_=new Gl(-9,9,7,-7,.1,100);_.position.set(5,13,20),_.lookAt(0,0,0),v.add(new E1(16777215,11908533,3));const A=new c_(16777215,4);A.position.set(-3,12,7),A.castShadow=!0,A.shadow.mapSize.set(2048,2048),Object.assign(A.shadow.camera,{left:-14,right:14,top:12,bottom:-12}),A.shadow.normalBias=.03,v.add(A);const b=[],S=[];function R(Et,Zt,me,Dt=0,fe=0,te=0){b.push(Et);const re=new o_({color:Zt,roughness:.75});S.push(re);const Pe=new Hn(Et,re);return Pe.position.set(Dt,fe,te),Pe.castShadow=!0,Pe.receiveShadow=!0,me.add(Pe),Pe}v.background=new Se(getComputedStyle(f).getPropertyValue("--paper").trim());const B=new g1({opacity:.12});S.push(B);const N=new Vl(200,200);b.push(N);const D=new Hn(N,B);D.position.y=-.005,D.rotation.x=-Math.PI/2,D.receiveShadow=!0,v.add(D);const I=new R1(y.gridSize,y.gridSize/Na,wM,CS);I.position.set(y.gridX,.002,y.gridZ),v.add(I);const O=[],M=[],w=[],z=[];r.forEach((Et,Zt)=>{const me=new co;me.position.set(y.centers[Zt],0,0),v.add(me),O.push(me);const Dt=new co;me.add(Dt),M.push(Dt),R(new yi(Jn,.18,Jn),"#d3d3d3",me,0,.09,0);const fe=R(new yi(.58,.025,.08),"#777777",me,-.65,.2,1);if(fe.material.dispose(),fe.material=new Zu({color:"#777777",toneMapped:!1}),S.push(fe.material),w.push(fe),Et.kind==="browser"||Et.kind==="input"||Et.kind==="cli")R(new yi(1.8,1.35,.15),"#555555",Dt,0,1.05,-.2),R(new yi(1.58,1.12,.025),"#252525",Dt,0,1.05,-.11),R(new yi(.1,.55,.12),"#818181",Dt,0,.45,-.2),R(new yi(1,.08,.55),"#adadad",Dt,0,.25,0);else if(Et.kind==="database")for(let te=0;te<3;te++)R(new Qu(.78,.78,.3,64),"#b9b9b9",Dt,0,.42+te*.36,0);else if(Et.kind==="output"){R(new yi(1.7,.14,1.5),"#eeeeee",Dt,0,.35,0);for(let te=0;te<3;te++)R(new yi(1.1,.03,.12),"#777777",Dt,0,.44,-.35+te*.3)}else if(Et.kind==="operation")R(new Qu(.7,.7,.65,8),"#bfbfbf",Dt,0,.6,0);else if(Et.kind==="transfer"){const te=R(new yi(1.25,.25,.9),"#bfbfbf",Dt,0,.7,0);te.rotation.y=Math.PI/4}else if(Et.kind==="react")for(let te=0;te<3;te++)R(new yi(1.8-te*.22,.22,1.5-te*.15),"#c1c1c1",Dt,0,.4+te*.35,0);else if(Et.kind==="step"||Et.kind==="file")R(new yi(1.65,.22,1.4),"#bfbfbf",Dt,0,.42,0);else if(Et.kind==="api")R(new yi(.35,1.3,1.25),"#b8b8b8",Dt,-.65,.85,0),R(new yi(.35,1.3,1.25),"#b8b8b8",Dt,.65,.85,0),R(new yi(1.65,.25,1.25),"#d8d8d8",Dt,0,1.5,0);else{R(new yi(1.65,1.3,1.4),"#bfbfbf",Dt,0,.85,0);for(let te=0;te<6;te++)R(new yi(.85,.035,.025),"#6b6b6b",Dt,0,.55+te*.13,.715)}me.traverse(te=>{te.isMesh&&(te.userData.index=Zt)}),!e&&Zt<r.length-1&&z.push(R(new yi(wS,.025,.045),"#999999",v,me.position.x+Xu/2,.03,0))}),e&&e.forEach((Et,Zt)=>{const me=r.findIndex(Le=>Le.id===Et.from),Dt=r.findIndex(Le=>Le.id===Et.to);if(me<0||Dt<0||me===Dt)return;const fe=O[me].position.x,te=O[Dt].position.x,re=-Jn/2-(Zt+1)*Na,Pe=[new J(fe,.03,-Jn/2),new J(fe,.03,re),new J(te,.03,re),new J(te,.03,-Jn/2)],ri=new m1;for(let Le=1;Le<Pe.length;Le++)ri.add(new s_(Pe[Le-1],Pe[Le]));const pi=R(new Lm(ri,24,.015,4,!1),"#999999",v);pi.userData.source=me,pi.userData.target=Dt,z.push(pi)}),z.forEach(Et=>{Et.material.dispose(),Et.material=new Zu({color:"#999999",toneMapped:!1}),S.push(Et.material)});const V=new N1,X=new le;function Q(Et){const Zt=f.getBoundingClientRect();return X.set((Et.clientX-Zt.left)/Zt.width*2-1,-(Et.clientY-Zt.top)/Zt.height*2+1),V.setFromCamera(X,_),V.intersectObjects(O,!0)[0]}function W(Et){const Zt=Q(Et);Zt&&c.current.onSelect(Zt.object.userData.index)}function tt(Et){f.style.cursor=Q(Et)?"pointer":"default"}f.addEventListener("click",W),f.addEventListener("pointermove",tt);let k=!0;const H=new ResizeObserver(()=>{const Et=f.clientWidth,Zt=f.clientHeight;x.setSize(Et,Zt);const me=Et/Zt,Dt=Math.max(4.5,(y.width/2+1.25)/me);_.left=-Dt*me,_.right=Dt*me,_.top=Dt,_.bottom=-Dt,_.updateProjectionMatrix(),k=!0});H.observe(f);const st=window.matchMedia("(prefers-reduced-motion: reduce)"),et=new Se(g),pt=new Se(g),U=new Se("#777777"),Y=new Se("#999999");let ft,At,Nt=0,zt=!1,ot=[],yt=[],wt=[];function ce(Et){var me;const Zt=(me=c.current.selected)==null?void 0:me.index;if((Zt!==At||At===void 0&&!ot.length)&&(ot=M.map(Dt=>Dt.position.y),yt=w.map(Dt=>Dt.material.color.clone()),wt=z.map(Dt=>Dt.material.color.clone()),At=Zt,Nt=Et,zt=!0),zt||k){const Dt=st.matches?1:Math.min((Et-Nt)/360,1),fe=1-Math.pow(1-Dt,3);O.forEach((te,re)=>{M[re].position.y=PA.lerp(ot[re],re===Zt?.22:0,fe),w[re].material.color.lerpColors(yt[re],re===Zt?pt:U,fe)}),z.forEach((te,re)=>{te.material.color.lerpColors(wt[re],(e?te.userData.target===Zt||te.userData.source===Zt:re===Zt-1)?et:Y,fe)}),x.render(v,_),zt=Dt<1,k=!1}ft=requestAnimationFrame(ce)}return ft=requestAnimationFrame(ce),()=>{cancelAnimationFrame(ft),H.disconnect(),f.removeEventListener("click",W),f.removeEventListener("pointermove",tt),b.forEach(Et=>Et.dispose()),S.forEach(Et=>Et.dispose()),I.geometry.dispose(),I.material.dispose(),x.dispose(),x.domElement.remove()}},[r,e]),L.jsx("div",{className:"instrument-scene",ref:o,"aria-label":s,children:h&&L.jsx(GN,{nodes:r,selected:t,onSelect:i,connections:e,label:s})})}function ap({path:r}){const t=r.split("/");return t.map((i,e)=>L.jsxs(xe.Fragment,{children:[i,e<t.length-1&&L.jsxs(L.Fragment,{children:["/",L.jsx("wbr",{})]})]},e))}function nS({report:r,curated:t,node:i,active:e,trace:s,step:o,mode:c,tab:h,setTab:d}){var g;const f=(s==null?void 0:s.evidence)||(i==null?void 0:i.evidence)||[];return L.jsxs("aside",{className:`instrument-inspector inspector-${c}`,"aria-label":c==="system"?"02 / Module details":"03 / Action details","data-tab":h,children:[L.jsx("div",{className:"inspector-tabs",children:["part","files","notes"].map(x=>L.jsx("button",{"aria-pressed":h===x,onClick:()=>d(x),children:x},x))}),L.jsxs(Om,{className:"inspector-content",children:[h==="part"?L.jsxs(L.Fragment,{children:[L.jsxs("span",{className:"eyebrow",children:[c==="trace"?s?`ACTION STEP / ${String(o+1).padStart(2,"0")}`:"ACTION OVERVIEW":`SELECTED MODULE / ${String(e+1).padStart(2,"0")}`," "]}),L.jsx("h2",{children:c==="trace"?(s==null?void 0:s.title)||r.traceTitle:(i==null?void 0:i.label)||"No source components"}),s&&i&&L.jsxs("p",{className:"inspection-context",children:["MODULE ",String(e+1).padStart(2,"0")," / ",i.label]}),L.jsx("p",{children:c==="trace"?(s==null?void 0:s.description)||r.traceSummary:(i==null?void 0:i.detail)||"No readable components were established."}),L.jsx("div",{className:"inspector-rule"}),L.jsx("span",{className:"eyebrow",children:f.length?"SUPPORTING FILES":"EVIDENCE STATUS"}),f.length?f.map(x=>{var y,v,_;return L.jsxs("div",{className:"source-file",children:[L.jsxs("span",{children:["↳ ",L.jsx(ap,{path:x})]}),L.jsx("p",{children:((y=r.evidence.find(A=>A.path===x))==null?void 0:y.claim)||"Referenced by this action step."}),((v=r.evidence.find(A=>A.path===x))==null?void 0:v.excerpt)&&L.jsxs("details",{children:[L.jsxs("summary",{children:["Read source excerpt",(_=r.evidence.find(A=>A.path===x))!=null&&_.startLine?` · lines ${r.evidence.find(A=>A.path===x).startLine}–${r.evidence.find(A=>A.path===x).endLine}`:""]}),L.jsx("pre",{children:r.evidence.find(A=>A.path===x).excerpt})]})]},x)}):L.jsx("p",{children:c==="trace"&&!s?"Select an action step to inspect its supporting files.":"No source references are attached to this selection."}),!t&&((g=r.connections)==null?void 0:g.filter(x=>x.from===(i==null?void 0:i.id)||x.to===(i==null?void 0:i.id)).map((x,y)=>L.jsxs("div",{className:"source-file",children:[L.jsxs("span",{children:[x.from," → ",x.to]}),L.jsx("p",{children:r.analysisKind==="agent"?x.label:`Import declared in ${x.from}:${x.line}.`})]},`edge-${y}`))),L.jsx("div",{className:"inspector-note",children:t?"Reference explanation. Playback illustrates the documented sequence; it is not a live execution.":r.analysisKind==="agent"?"Agent-authored source analysis. References are checked against local files; interpretations and runtime behavior are not independently verified.":"Source imports and direct calls only. This is a static reading, not a verified runtime or deployment graph."})]}):h==="files"?L.jsxs(L.Fragment,{children:[L.jsx("span",{className:"eyebrow",children:"REPOSITORY EVIDENCE"}),L.jsx("h2",{children:"Source index"}),r.evidence.map(x=>L.jsxs("div",{className:"source-file",children:[L.jsx("span",{children:L.jsx(ap,{path:x.path})}),L.jsx("p",{children:x.claim})]},x.path))]}):L.jsxs(L.Fragment,{children:[L.jsx("span",{className:"eyebrow",children:"OPERATOR NOTES"}),L.jsx("h2",{children:"What matters"}),L.jsx("p",{children:r.matters}),L.jsx("h3",{children:"Data & persistence"}),L.jsx("p",{children:r.dataSummary}),L.jsx("h3",{children:"Project map"}),r.projectMap.map(x=>L.jsxs("div",{className:"source-file",children:[L.jsx("span",{children:L.jsx(ap,{path:x.path})}),L.jsx("p",{children:x.description})]},x.path)),L.jsx("h3",{children:"Tech stack"}),L.jsx("p",{children:r.stack.join(" / ")}),r.decisions.map(x=>L.jsx("p",{children:x},x))]}),L.jsxs("div",{className:"inspector-footer",children:[r.fileCount," FILES / ",r.generatedAt,L.jsx("br",{}),"SOURCE: ",r.sourceLabel]})]})]})}function WN({initialReport:r=Da}){const[t,i]=xe.useState("light"),e=["light","dark","blue"],s=e[(e.indexOf(t)+1)%e.length];xe.useLayoutEffect(()=>(document.documentElement.dataset.theme=t,()=>{delete document.documentElement.dataset.theme}),[t]);const[o,c]=xe.useState(r),[h,d]=xe.useState(0),[f,g]=xe.useState(-1),[x,y]=xe.useState(!1),[v,_]=xe.useState("part"),[A,b]=xe.useState("part"),[S,R]=xe.useState(""),[B,N]=xe.useState(!1),[D,I]=xe.useState(""),[O,M]=xe.useState(!1),[w,z]=xe.useState("3d"),V=xe.useRef(null),X=xe.useRef(null),Q=xe.useRef(null);xe.useEffect(()=>{if(!O)return;function Y(At){var Nt,zt;!((Nt=X.current)!=null&&Nt.contains(At.target))&&!((zt=Q.current)!=null&&zt.contains(At.target))&&M(!1)}function ft(At){var Nt;At.key==="Escape"&&(M(!1),(Nt=Q.current)==null||Nt.focus())}return document.addEventListener("pointerdown",Y),document.addEventListener("keydown",ft),()=>{document.removeEventListener("pointerdown",Y),document.removeEventListener("keydown",ft)}},[O]);const W=o===Da,tt=f>=0?o.system.findIndex(Y=>{var ft;return Y.id===((ft=o.trace[f])==null?void 0:ft.nodeId)}):-1;function k(Y){g(Y),y(!1),b("part")}xe.useEffect(()=>{if(!x)return;const Y=setTimeout(()=>{if(f>=o.trace.length-1){y(!1);return}g(f+1)},1300);return()=>clearTimeout(Y)},[x,f,o]);function H(Y){d(Y),_("part")}async function st(Y){N(!0),I("");try{c(await Y()),d(0),g(-1),y(!1),_("part"),b("part"),M(!1)}catch(ft){I(ft.message)}finally{N(!1)}}const et=o.system[h],pt=o.system[tt],U=o.trace[f];return L.jsxs("main",{className:"instrument instrument-cards",children:[L.jsxs("header",{className:"instrument-header",children:[L.jsx("a",{className:"instrument-brand",href:"/","aria-label":"blnkfld home",children:L.jsx("span",{className:"wordmark blnkfld-lockup",children:L.jsx("span",{className:"blnkfld-mark","aria-hidden":"true"})})}),L.jsxs("button",{className:"app-theme-toggle","aria-label":`Theme: ${t}. Switch to ${s} theme`,onClick:()=>i(s),children:[L.jsx("span",{"aria-hidden":"true"}),"THEME"]})]}),L.jsxs("nav",{className:"instrument-header-right","aria-label":"Sections",children:[L.jsx("a",{href:"#repository",children:"01 / REPOSITORY"}),L.jsx("a",{href:"#system",children:"02 / SYSTEM"}),L.jsxs("a",{href:"#action",children:["03 / ",W||o.analysisKind==="agent"?"TRACE ONE ACTION":"SOURCE CALL PATH"]}),L.jsx("a",{href:"#how-to-run",children:"04 / GET STARTED"})]}),L.jsxs("div",{className:`instrument-body ${U?"inspecting-trace":"inspecting-system"}`,children:[L.jsxs("section",{className:"instrument-workspace",children:[L.jsxs("div",{id:"repository",className:"instrument-title",children:[L.jsxs("div",{children:[L.jsx("span",{className:"eyebrow",children:W?"01 / REFERENCE REPOSITORY":"01 / IMPORTED REPOSITORY"}),L.jsx("h1",{children:o.name}),L.jsx("p",{children:o.subtitle})]}),L.jsx(FN,{report:o})]}),L.jsxs("div",{className:"instrument-summary",children:[L.jsx("span",{className:"eyebrow",children:"IN ONE MINUTE"}),L.jsx("p",{children:o.summary}),Array.isArray(o.haiku)&&o.haiku.length===3&&L.jsxs(L.Fragment,{children:[L.jsx("span",{className:"eyebrow project-haiku-label",children:"A HAIKU"}),L.jsx("p",{className:"project-haiku","aria-label":"Project haiku",children:o.haiku.map((Y,ft)=>L.jsx("span",{children:Y},ft))})]})]}),L.jsx("hr",{className:"section-divider divider-system"}),L.jsxs("section",{id:"system",className:"scene-wrap","aria-labelledby":"system-heading",children:[L.jsxs("div",{className:"system-heading",children:[L.jsxs("div",{children:[L.jsxs("span",{className:"eyebrow",children:["02 / SYSTEM / ",String(o.system.length).padStart(2,"0")," COMPONENTS"]}),L.jsx("h2",{id:"system-heading",children:"How the parts work together"})]}),L.jsx("div",{className:"system-view","aria-label":"System view",children:["3d","connections"].map(Y=>L.jsx("button",{"aria-pressed":w===Y,onClick:()=>z(Y),children:Y==="3d"?"SYSTEM OVERVIEW":"SYSTEM ARCHITECTURE"},Y))})]}),L.jsx(Om,{children:L.jsxs("div",{className:"view-enter",children:[w==="3d"&&L.jsxs(L.Fragment,{children:[L.jsx(XN,{nodes:o.system,connections:W?void 0:o.connections,selected:{index:h},onSelect:H},t),L.jsx("div",{className:"module-controls",children:o.system.map((Y,ft)=>L.jsxs("button",{onClick:()=>H(ft),"aria-pressed":h===ft,children:[L.jsx("span",{children:String(ft+1).padStart(2,"0")}),L.jsx("strong",{children:Y.label})]},Y.id))})]}),w==="connections"&&L.jsx(VN,{report:o,selected:h,onSelect:H,curated:W},o.sourceLabel+o.generatedAt)]},w)})]}),o.analysisKind==="agent"&&L.jsxs("p",{className:"analysis-coverage",children:["Source references checked in ",o.evidence.length," files · ",o.fileCount," files inventoried · Static analysis by ",o.agent]}),o.analysisKind!=="agent"&&o.coverage&&L.jsxs("p",{className:"analysis-coverage",children:["Read ",o.coverage.readCount," of ",o.coverage.totalCount," files · Parsed ",o.coverage.parsedCount," JavaScript/TypeScript files",o.coverage.omittedCount>0?` · ${o.coverage.omittedCount} additional modules omitted from this view`:"",o.coverage.treeTruncated?" · GitHub tree is incomplete":"",". Other languages are not analyzed."]}),L.jsx("hr",{className:"section-divider divider-action"}),L.jsxs("section",{id:"action",className:"sequencer",children:[L.jsxs("div",{className:"sequence-heading",children:[L.jsxs("div",{children:[L.jsxs("span",{className:"eyebrow",children:["03 / ",W||o.analysisKind==="agent"?"TRACE ONE ACTION":"SOURCE CALL PATH"]}),L.jsx("h2",{children:o.traceTitle})]}),L.jsx("button",{className:"play-button","aria-label":x?"Pause action trace":"Play action trace",title:x?"Pause":"Play","aria-pressed":x,disabled:!o.trace.length,onClick:()=>{x?y(!1):((f<0||f===o.trace.length-1)&&g(0),y(!0),b("part"))},children:L.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:x?L.jsx("path",{d:"M9 6v12M15 6v12"}):L.jsx("path",{d:"m9 5 10 7-10 7Z"})})})]}),L.jsx("p",{className:"action-summary",children:o.traceSummary}),L.jsx(LN,{report:o,selected:f,onSelect:k})]}),L.jsx("hr",{className:"section-divider divider-run"}),L.jsxs("section",{id:"how-to-run",className:"instrument-run","aria-labelledby":"run-heading",children:[L.jsx("span",{className:"eyebrow",children:"04 / GET STARTED"}),L.jsx("h2",{id:"run-heading",children:"How to run"}),L.jsx("p",{children:o.howToRun}),L.jsxs("div",{className:"run-evidence",children:[L.jsx("span",{children:"EVIDENCE"}),(o.runEvidence||[]).map(Y=>L.jsx("span",{children:Y},Y))]})]})]}),L.jsx(nS,{report:o,curated:W,node:et,active:h,mode:"system",tab:v,setTab:_}),L.jsx(nS,{report:o,curated:W,node:pt,active:tt,trace:U,step:f,mode:"trace",tab:A,setTab:b}),["repository","system","action","run"].map(Y=>L.jsx("div",{className:`section-card-outline card-${Y}`,"aria-hidden":"true"},Y))]}),L.jsxs("footer",{className:"instrument-footer",children:[L.jsx("button",{ref:Q,"aria-expanded":O,"aria-controls":"repository-popover",onClick:()=>M(!O),children:"+ CHANGE REPOSITORY"}),L.jsx("span",{children:B?"ANALYZING…":o.sourceLabel}),L.jsxs("div",{className:"footer-links",children:[L.jsx(HN,{}),L.jsx("span",{"aria-hidden":"true",children:"/"}),L.jsx(IN,{})]})]}),O&&L.jsxs("form",{ref:X,id:"repository-popover",className:"repository-popover",onSubmit:Y=>{Y.preventDefault(),st(()=>CM(S))},children:[L.jsx("label",{htmlFor:"repo-url",children:"Public GitHub repository"}),L.jsx("input",{id:"repo-url",value:S,onChange:Y=>R(Y.target.value),placeholder:"https://github.com/owner/repository",required:!0}),L.jsx("button",{disabled:B,children:"Analyze repository ↗"}),L.jsx("button",{type:"button",disabled:B,onClick:()=>V.current.click(),children:"Choose local folder"}),D&&L.jsx("p",{role:"alert",children:D})]}),L.jsx("input",{ref:V,type:"file",webkitdirectory:"",multiple:!0,hidden:!0,onChange:Y=>{const ft=Array.from(Y.target.files);ft.length&&st(()=>AM(ft)),Y.target.value=""}})]})}const rp=Ob.createRoot(document.getElementById("root"));async function qN(){const r=new URLSearchParams(window.location.search);let t;if(r.get("local")==="1"||document.querySelector('meta[name="blnkfld-local"]')){rp.render(L.jsx("p",{style:{padding:36},children:"Opening your project brief…"}));try{const i=await fetch("/api/report");if(!i.ok)throw new Error("Could not load the local report. Open the link printed by blnkfld in your terminal.");if(t=await i.json(),!t.system||!t.evidence)throw new Error("The local report is invalid.");r.has("token")&&(r.delete("token"),window.history.replaceState(null,"","?"+r.toString()))}catch(i){rp.render(L.jsx("p",{role:"alert",style:{padding:36},children:i.message}));return}}rp.render(L.jsx(Pb.StrictMode,{children:L.jsx(WN,{initialReport:t})}))}qN();
4293
+ `}function FN({report:r}){const t=xe.useRef(null),i=xe.useMemo(()=>UN(r),[r]),e=xe.useMemo(()=>ON(i),[i]);return L.jsxs(L.Fragment,{children:[L.jsx("button",{className:"readme-trigger",type:"button","aria-haspopup":"dialog",onClick:()=>t.current.showModal(),children:"VIEW README ↗"}),L.jsxs("dialog",{ref:t,className:"changelog-drawer readme-drawer","aria-labelledby":"readme-heading",onClick:s=>{if(s.target===t.current){const o=t.current.getBoundingClientRect();(s.clientX<o.left||s.clientX>o.right||s.clientY<o.top||s.clientY>o.bottom)&&t.current.close()}},children:[L.jsxs("header",{children:[L.jsxs("div",{children:[L.jsxs("span",{className:"eyebrow",children:[r.traceStatus==="curated"?"CURATED EXAMPLE":r.analysisKind==="agent"?"AGENT BRIEF":"SOURCE MODEL"," / TEXT README"]}),L.jsx("h2",{id:"readme-heading",children:"README"})]}),L.jsx(Um,{label:"Close README",onClick:()=>t.current.close()})]}),L.jsx("div",{className:"readme-actions",children:L.jsx("a",{className:"readme-download",href:`data:text/markdown;charset=utf-8,${encodeURIComponent(e)}`,download:"README.md",children:"Download README.md ↓"})}),L.jsxs("article",{className:"readme-text","aria-label":"README preview",children:[L.jsx("h3",{children:i.title}),i.subtitle&&L.jsx("p",{className:"readme-subtitle",children:i.subtitle}),i.sections.map(s=>{const o=s.ordered?"ol":"ul";return L.jsxs("section",{children:[L.jsx("h4",{children:s.title}),s.paragraphs.map((c,h)=>L.jsx("p",{children:c},h)),s.items.length>0&&L.jsx(o,{children:s.items.map((c,h)=>L.jsx("li",{children:c},h))})]},s.title)})]})]})]})}function Om({children:r,className:t=""}){const i=xe.useRef(null),e=xe.useRef(null);return xe.useLayoutEffect(()=>{const s=i.current,o=e.current,c=()=>{const d=o.getBoundingClientRect().height;s.style.height=`${d}px`};c();const h=new ResizeObserver(c);return h.observe(o),()=>h.disconnect()},[]),L.jsx("div",{ref:i,className:`smooth-height ${t}`,children:L.jsx("div",{ref:e,className:"smooth-height-content",children:r})})}const BN="0.1.5",kN=[{version:"0.1.5",date:"2026-11-02",groups:[{title:"Added",changes:["npx blnkfld checks for a newer release on startup and runs it automatically, so returning users are no longer stuck on an old cached version. Set BLNKFLD_NO_UPDATE=1 to opt out."]}]},{version:"0.1.4",date:"2026-11-02",groups:[{title:"Fixed",changes:['Briefs no longer fail with "Missing evidence entry" when the agent appends its claim to a source citation.']},{title:"Changed",changes:["Use the rounded-outline mark without a visible wordmark across the app and website; retain the striped-circle design as a saved alternate.","Add Vercel Web Analytics to the website.","Center the homepage mark above a smaller tagline and add a linked project credit to the footer mark.","Refine docs labels, copy feedback, and app header spacing; match the app browser title to the homepage."]}]},{version:"0.1.3",date:"2026-10-07",groups:[{title:"Added",changes:["Switch the app between light, dark, and blue themes from the header.","The website includes a getting-started guide with animated troubleshooting answers.","Matching rounded-square favicons adapt to light and dark browser themes."]},{title:"Changed",changes:["A shared outlined logo and consistent serif wordmark align the app, homepage, and docs.","Section navigation sits in its own row below the app header, alongside the updated AN AGENTIC README label.","Numbered card labels use the orange accent, and the rounded repository selector closes when clicking outside it.","The homepage command and its underline use orange, with a theme-aware footer mark.","Documentation typography and spacing are more consistent, and copying the homepage command no longer highlights its text."]},{title:"Fixed",changes:["Haikus use italic serif text again.","Blue mode uses white secondary text and theme-aware logo colors."]}]},{version:"0.1.2",date:"2026-10-06",groups:[{title:"Changed",changes:["App and drawer text is smaller and lighter, with consistent 21px medium serif headings and upright typography throughout, including the haiku.","Quick Start headings use periods in place of slash separators.","Quick Start uses the published npm package instead of requiring a local blnkfld checkout and build."]}]},{version:"0.1.1",date:"2026-10-06",groups:[{title:"Changed",changes:["System Architecture and Trace one action now step through five, four, three, two, and one column as the window narrows, preserving selection and playback.","Newly generated IN ONE MINUTE summaries contain one to five sentences, with additional detail in the expanded summary.","The changelog groups release notes by version and date and shows only releases up to the running app's version.","The hosted interface uses Lora and Times New Roman as fallbacks when Iowan Old Style is unavailable."]}]},{version:"0.1.0",date:"2026-10-05",groups:[{title:"Added",changes:["Run npx blnkfld inside a project to generate a source-backed brief using your installed Codex or Claude Code CLI.","Explore the project's system overview, architecture, and an action trace, with source excerpts supporting the explanation.","Read a project summary and haiku, inspect setup instructions, and export the brief as a README.","View reports in a local browser interface with bundled Inter, Geist Mono, IBM Plex Mono, and Lora fonts. Serif text prefers Iowan Old Style when installed, then Lora and Times New Roman."]}]}],zN=new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric",year:"numeric",timeZone:"UTC"});function HN(){const r=xe.useRef(null);return L.jsxs(L.Fragment,{children:[L.jsx("button",{className:"changelog-trigger",type:"button","aria-haspopup":"dialog",onClick:()=>r.current.showModal(),children:"CHANGELOG"}),L.jsxs("dialog",{ref:r,className:"changelog-drawer release-notes-drawer","aria-labelledby":"changelog-title",onClick:t=>{if(t.target===r.current){const i=r.current.getBoundingClientRect();(t.clientX<i.left||t.clientX>i.right||t.clientY<i.top||t.clientY>i.bottom)&&r.current.close()}},children:[L.jsxs("header",{children:[L.jsxs("div",{children:[L.jsx("span",{className:"eyebrow",children:"BLNKFLD / RELEASE NOTES"}),L.jsx("h2",{id:"changelog-title",children:"Changelog"}),L.jsxs("p",{children:["What’s changed through v",BN,"."]})]}),L.jsx(Um,{label:"Close changelog",onClick:()=>r.current.close()})]}),L.jsx("div",{className:"changelog-list",children:kN.map(t=>L.jsxs("article",{className:"changelog-entry",children:[L.jsx("time",{className:"changelog-date",dateTime:t.date,children:zN.format(new Date(`${t.date}T00:00:00Z`))}),L.jsxs("div",{children:[L.jsxs("h3",{children:["v",t.version]}),t.groups.map(i=>L.jsxs("section",{className:"changelog-category",children:[L.jsx("h4",{children:i.title}),L.jsx("ul",{children:i.changes.map(e=>L.jsx("li",{children:e},e))})]},i.title))]})]},t.version))})]})]})}function VN({report:r,selected:t,onSelect:i,curated:e}){var v,_,A;const[s,o]=xe.useState(!1),[c,h]=xe.useState(null),d=S_(),f=xe.useMemo(()=>NN(r.system,r.connections,d),[r.system,r.connections,d]),g=f.edges[c];function x(b){h(null),i(b)}function y(b){h(b),i(r.system.findIndex(S=>S.id===f.edges[b].from))}return L.jsxs("div",{className:"connections architecture-connections",children:[L.jsxs("div",{className:"connection-toolbar",children:[L.jsx("span",{children:"ENTIRE ARCHITECTURE"}),L.jsx("button",{disabled:!r.system[t],"aria-pressed":s,onClick:()=>o(!s),children:s?"Show all connections equally":"Highlight selected component"})]}),L.jsx("p",{className:"connection-context",children:e?"Reference architecture · arrows describe the documented interaction.":r.analysisKind==="agent"?"Source-based explanation · arrows describe the reported relationship, not an observed execution.":"Static imports · arrows point from the importing file to its dependency, not the direction of runtime data."}),L.jsx(v_,{layout:f,selected:t,onSelect:x,focused:s,activeEdge:c,onEdge:y}),!f.edges.length&&L.jsx("p",{className:"connection-empty",children:"No connections were established in this report. Components remain available to inspect."}),L.jsx(Om,{children:g&&L.jsxs("section",{className:"architecture-evidence","aria-label":"Selected connection evidence",children:[L.jsxs("div",{children:[L.jsxs("span",{className:"eyebrow",children:["CONNECTION / ",String(g.index+1).padStart(2,"0")]}),L.jsx("button",{onClick:()=>h(null),"aria-label":"Close connection evidence",children:"×"})]}),L.jsxs("h3",{children:[(v=r.system.find(b=>b.id===g.from))==null?void 0:v.label," → ",(_=r.system.find(b=>b.id===g.to))==null?void 0:_.label]}),L.jsx("p",{children:g.labelText}),(A=g.evidence)==null?void 0:A.map(b=>{var S;return L.jsxs("div",{className:"source-file",children:[L.jsxs("span",{children:[b,g.line?` · line ${g.line}`:""]}),L.jsx("p",{children:((S=r.evidence.find(R=>R.path===b))==null?void 0:S.claim)||"Referenced by this relationship."})]},b)})]})})]})}function GN({nodes:r,selected:t,onSelect:i,connections:e,label:s}){const o=xe.useId().replaceAll(":",""),c=98*Xu/Jn,h=Math.max(360,(r.length-1)*c+210),d=r.map((y,v)=>105+v*c),f=e===void 0?r.slice(1).map((y,v)=>[v,v+1]):e.map(y=>[r.findIndex(v=>v.id===y.from),r.findIndex(v=>v.id===y.to)]).filter(([y,v])=>y>=0&&v>=0),g=(y,v,_,A,b,S)=>L.jsxs("g",{children:[L.jsx("polygon",{points:`${y-_},${v-b} ${y},${v+A-b} ${y},${v+A} ${y-_},${v}`,fill:"#cecece"}),L.jsx("polygon",{points:`${y},${v+A-b} ${y+_},${v-b} ${y+_},${v} ${y},${v+A}`,fill:"#b4b4b4"}),L.jsx("polygon",{points:`${y-_},${v-b} ${y},${v-A-b} ${y+_},${v-b} ${y},${v+A-b}`,fill:"#e9e9e9"})]},S);function x(y){return["browser","cli","input"].includes(y)?L.jsxs("g",{children:[g(0,120,18,8,4),L.jsx("path",{d:"M0 111V88",stroke:"#aaa",strokeWidth:"5"}),L.jsx("polygon",{points:"-28,54 28,78 28,111 -28,87",fill:"#aaa"}),L.jsx("polygon",{points:"-23,61 23,81 23,103 -23,83",fill:"#333"})]}):y==="react"?[0,1,2].map(v=>g(0,117-v*14,35-v*7,17-v*3,5,v)):y==="database"?L.jsx("g",{children:[0,1,2].map(v=>L.jsxs("g",{children:[L.jsx("path",{d:`M-25 ${110-v*16}v12c0 13 50 13 50 0v-12`,fill:"#bbb"}),L.jsx("ellipse",{cy:110-v*16,rx:"25",ry:"10",fill:"#ddd"})]},v))}):y==="api"?L.jsxs("g",{children:[g(-22,113,10,8,40),g(22,113,10,8,40),g(0,77,33,9,8)]}):y==="file"||y==="output"?L.jsxs("g",{children:[g(0,118,34,18,5),y==="output"&&L.jsx("path",{d:"M-20 110l28 13m-18-18l28 13m-18-18l28 13",stroke:"#777",strokeWidth:"2"})]}):y==="operation"?L.jsxs("g",{children:[L.jsx("path",{d:"M-25 90v28c0 14 50 14 50 0V90",fill:"#bbb"}),L.jsx("ellipse",{cy:"90",rx:"25",ry:"13",fill:"#ddd"})]}):y==="transfer"?g(0,104,27,18,15):g(0,119,29,16,36)}return L.jsxs("div",{className:"isometric-fallback",children:[L.jsx("span",{className:"fallback-caption",children:"ISOMETRIC COMPATIBILITY VIEW"}),L.jsxs("svg",{viewBox:`0 0 ${h} 220`,role:"group","aria-label":s.replace("three-dimensional","isometric"),children:[L.jsx("defs",{children:L.jsx("marker",{id:o,viewBox:"0 0 8 8",refX:"7",refY:"4",markerWidth:"5",markerHeight:"5",orient:"auto",children:L.jsx("path",{d:"M0 0 8 4 0 8Z",fill:"context-stroke"})})}),f.map(([y,v],_)=>L.jsx("path",{d:`M${d[y]} 148 V${175+_*5} H${d[v]} V148`,fill:"none",stroke:(t==null?void 0:t.index)===y||(t==null?void 0:t.index)===v?"var(--accent)":"#aaa",strokeWidth:"1.2",markerEnd:`url(#${o})`},_)),r.map((y,v)=>L.jsxs("g",{transform:`translate(${d[v]} 0)`,role:"button",tabIndex:"0","aria-label":`Select ${y.label}`,"aria-pressed":(t==null?void 0:t.index)===v,onClick:()=>i(v),onKeyDown:_=>{["Enter"," "].includes(_.key)&&(_.preventDefault(),i(v))},style:{cursor:"pointer"},children:[L.jsx("title",{children:y.label}),g(0,143,49,24.5,7),x(y.kind),L.jsx("path",{d:"M-32 143l19 9",stroke:(t==null?void 0:t.index)===v?"var(--accent)":"#777",strokeWidth:"3"}),L.jsx("text",{y:"210",textAnchor:"middle",fill:(t==null?void 0:t.index)===v?"var(--accent)":"#555",fontSize:"var(--mono-size)",fontFamily:"var(--mono)",fontWeight:"700",children:String(v+1).padStart(2,"0")})]},y.id||v))]})]})}function XN({nodes:r,selected:t,onSelect:i,connections:e,label:s="Interactive three-dimensional repository system"}){const o=xe.useRef(null),c=xe.useRef({selected:t,onSelect:i});c.current={selected:t,onSelect:i};const[h,d]=xe.useState(!1);return xe.useEffect(()=>{const f=o.current,g=getComputedStyle(f).getPropertyValue("--accent").trim();let x;try{x=new y_({antialias:!0,alpha:!0,preserveDrawingBuffer:!0})}catch{d(!0);return}x.setPixelRatio(Math.min(window.devicePixelRatio,2)),x.shadowMap.enabled=!0,x.shadowMap.type=PS,f.appendChild(x.domElement);const y=PM(r.length),v=new JS,_=new Gl(-9,9,7,-7,.1,100);_.position.set(5,13,20),_.lookAt(0,0,0),v.add(new E1(16777215,11908533,3));const A=new c_(16777215,4);A.position.set(-3,12,7),A.castShadow=!0,A.shadow.mapSize.set(2048,2048),Object.assign(A.shadow.camera,{left:-14,right:14,top:12,bottom:-12}),A.shadow.normalBias=.03,v.add(A);const b=[],S=[];function R(Et,Zt,me,Dt=0,fe=0,te=0){b.push(Et);const re=new o_({color:Zt,roughness:.75});S.push(re);const Pe=new Hn(Et,re);return Pe.position.set(Dt,fe,te),Pe.castShadow=!0,Pe.receiveShadow=!0,me.add(Pe),Pe}v.background=new Se(getComputedStyle(f).getPropertyValue("--paper").trim());const B=new g1({opacity:.12});S.push(B);const N=new Vl(200,200);b.push(N);const D=new Hn(N,B);D.position.y=-.005,D.rotation.x=-Math.PI/2,D.receiveShadow=!0,v.add(D);const I=new R1(y.gridSize,y.gridSize/Na,wM,CS);I.position.set(y.gridX,.002,y.gridZ),v.add(I);const O=[],M=[],w=[],z=[];r.forEach((Et,Zt)=>{const me=new co;me.position.set(y.centers[Zt],0,0),v.add(me),O.push(me);const Dt=new co;me.add(Dt),M.push(Dt),R(new yi(Jn,.18,Jn),"#d3d3d3",me,0,.09,0);const fe=R(new yi(.58,.025,.08),"#777777",me,-.65,.2,1);if(fe.material.dispose(),fe.material=new Zu({color:"#777777",toneMapped:!1}),S.push(fe.material),w.push(fe),Et.kind==="browser"||Et.kind==="input"||Et.kind==="cli")R(new yi(1.8,1.35,.15),"#555555",Dt,0,1.05,-.2),R(new yi(1.58,1.12,.025),"#252525",Dt,0,1.05,-.11),R(new yi(.1,.55,.12),"#818181",Dt,0,.45,-.2),R(new yi(1,.08,.55),"#adadad",Dt,0,.25,0);else if(Et.kind==="database")for(let te=0;te<3;te++)R(new Qu(.78,.78,.3,64),"#b9b9b9",Dt,0,.42+te*.36,0);else if(Et.kind==="output"){R(new yi(1.7,.14,1.5),"#eeeeee",Dt,0,.35,0);for(let te=0;te<3;te++)R(new yi(1.1,.03,.12),"#777777",Dt,0,.44,-.35+te*.3)}else if(Et.kind==="operation")R(new Qu(.7,.7,.65,8),"#bfbfbf",Dt,0,.6,0);else if(Et.kind==="transfer"){const te=R(new yi(1.25,.25,.9),"#bfbfbf",Dt,0,.7,0);te.rotation.y=Math.PI/4}else if(Et.kind==="react")for(let te=0;te<3;te++)R(new yi(1.8-te*.22,.22,1.5-te*.15),"#c1c1c1",Dt,0,.4+te*.35,0);else if(Et.kind==="step"||Et.kind==="file")R(new yi(1.65,.22,1.4),"#bfbfbf",Dt,0,.42,0);else if(Et.kind==="api")R(new yi(.35,1.3,1.25),"#b8b8b8",Dt,-.65,.85,0),R(new yi(.35,1.3,1.25),"#b8b8b8",Dt,.65,.85,0),R(new yi(1.65,.25,1.25),"#d8d8d8",Dt,0,1.5,0);else{R(new yi(1.65,1.3,1.4),"#bfbfbf",Dt,0,.85,0);for(let te=0;te<6;te++)R(new yi(.85,.035,.025),"#6b6b6b",Dt,0,.55+te*.13,.715)}me.traverse(te=>{te.isMesh&&(te.userData.index=Zt)}),!e&&Zt<r.length-1&&z.push(R(new yi(wS,.025,.045),"#999999",v,me.position.x+Xu/2,.03,0))}),e&&e.forEach((Et,Zt)=>{const me=r.findIndex(Le=>Le.id===Et.from),Dt=r.findIndex(Le=>Le.id===Et.to);if(me<0||Dt<0||me===Dt)return;const fe=O[me].position.x,te=O[Dt].position.x,re=-Jn/2-(Zt+1)*Na,Pe=[new J(fe,.03,-Jn/2),new J(fe,.03,re),new J(te,.03,re),new J(te,.03,-Jn/2)],ri=new m1;for(let Le=1;Le<Pe.length;Le++)ri.add(new s_(Pe[Le-1],Pe[Le]));const pi=R(new Lm(ri,24,.015,4,!1),"#999999",v);pi.userData.source=me,pi.userData.target=Dt,z.push(pi)}),z.forEach(Et=>{Et.material.dispose(),Et.material=new Zu({color:"#999999",toneMapped:!1}),S.push(Et.material)});const V=new N1,X=new le;function Q(Et){const Zt=f.getBoundingClientRect();return X.set((Et.clientX-Zt.left)/Zt.width*2-1,-(Et.clientY-Zt.top)/Zt.height*2+1),V.setFromCamera(X,_),V.intersectObjects(O,!0)[0]}function W(Et){const Zt=Q(Et);Zt&&c.current.onSelect(Zt.object.userData.index)}function tt(Et){f.style.cursor=Q(Et)?"pointer":"default"}f.addEventListener("click",W),f.addEventListener("pointermove",tt);let k=!0;const H=new ResizeObserver(()=>{const Et=f.clientWidth,Zt=f.clientHeight;x.setSize(Et,Zt);const me=Et/Zt,Dt=Math.max(4.5,(y.width/2+1.25)/me);_.left=-Dt*me,_.right=Dt*me,_.top=Dt,_.bottom=-Dt,_.updateProjectionMatrix(),k=!0});H.observe(f);const st=window.matchMedia("(prefers-reduced-motion: reduce)"),et=new Se(g),pt=new Se(g),U=new Se("#777777"),Y=new Se("#999999");let ft,At,Nt=0,zt=!1,ot=[],yt=[],wt=[];function ce(Et){var me;const Zt=(me=c.current.selected)==null?void 0:me.index;if((Zt!==At||At===void 0&&!ot.length)&&(ot=M.map(Dt=>Dt.position.y),yt=w.map(Dt=>Dt.material.color.clone()),wt=z.map(Dt=>Dt.material.color.clone()),At=Zt,Nt=Et,zt=!0),zt||k){const Dt=st.matches?1:Math.min((Et-Nt)/360,1),fe=1-Math.pow(1-Dt,3);O.forEach((te,re)=>{M[re].position.y=PA.lerp(ot[re],re===Zt?.22:0,fe),w[re].material.color.lerpColors(yt[re],re===Zt?pt:U,fe)}),z.forEach((te,re)=>{te.material.color.lerpColors(wt[re],(e?te.userData.target===Zt||te.userData.source===Zt:re===Zt-1)?et:Y,fe)}),x.render(v,_),zt=Dt<1,k=!1}ft=requestAnimationFrame(ce)}return ft=requestAnimationFrame(ce),()=>{cancelAnimationFrame(ft),H.disconnect(),f.removeEventListener("click",W),f.removeEventListener("pointermove",tt),b.forEach(Et=>Et.dispose()),S.forEach(Et=>Et.dispose()),I.geometry.dispose(),I.material.dispose(),x.dispose(),x.domElement.remove()}},[r,e]),L.jsx("div",{className:"instrument-scene",ref:o,"aria-label":s,children:h&&L.jsx(GN,{nodes:r,selected:t,onSelect:i,connections:e,label:s})})}function ap({path:r}){const t=r.split("/");return t.map((i,e)=>L.jsxs(xe.Fragment,{children:[i,e<t.length-1&&L.jsxs(L.Fragment,{children:["/",L.jsx("wbr",{})]})]},e))}function nS({report:r,curated:t,node:i,active:e,trace:s,step:o,mode:c,tab:h,setTab:d}){var g;const f=(s==null?void 0:s.evidence)||(i==null?void 0:i.evidence)||[];return L.jsxs("aside",{className:`instrument-inspector inspector-${c}`,"aria-label":c==="system"?"02 / Module details":"03 / Action details","data-tab":h,children:[L.jsx("div",{className:"inspector-tabs",children:["part","files","notes"].map(x=>L.jsx("button",{"aria-pressed":h===x,onClick:()=>d(x),children:x},x))}),L.jsxs(Om,{className:"inspector-content",children:[h==="part"?L.jsxs(L.Fragment,{children:[L.jsxs("span",{className:"eyebrow",children:[c==="trace"?s?`ACTION STEP / ${String(o+1).padStart(2,"0")}`:"ACTION OVERVIEW":`SELECTED MODULE / ${String(e+1).padStart(2,"0")}`," "]}),L.jsx("h2",{children:c==="trace"?(s==null?void 0:s.title)||r.traceTitle:(i==null?void 0:i.label)||"No source components"}),s&&i&&L.jsxs("p",{className:"inspection-context",children:["MODULE ",String(e+1).padStart(2,"0")," / ",i.label]}),L.jsx("p",{children:c==="trace"?(s==null?void 0:s.description)||r.traceSummary:(i==null?void 0:i.detail)||"No readable components were established."}),L.jsx("div",{className:"inspector-rule"}),L.jsx("span",{className:"eyebrow",children:f.length?"SUPPORTING FILES":"EVIDENCE STATUS"}),f.length?f.map(x=>{var y,v,_;return L.jsxs("div",{className:"source-file",children:[L.jsxs("span",{children:["↳ ",L.jsx(ap,{path:x})]}),L.jsx("p",{children:((y=r.evidence.find(A=>A.path===x))==null?void 0:y.claim)||"Referenced by this action step."}),((v=r.evidence.find(A=>A.path===x))==null?void 0:v.excerpt)&&L.jsxs("details",{children:[L.jsxs("summary",{children:["Read source excerpt",(_=r.evidence.find(A=>A.path===x))!=null&&_.startLine?` · lines ${r.evidence.find(A=>A.path===x).startLine}–${r.evidence.find(A=>A.path===x).endLine}`:""]}),L.jsx("pre",{children:r.evidence.find(A=>A.path===x).excerpt})]})]},x)}):L.jsx("p",{children:c==="trace"&&!s?"Select an action step to inspect its supporting files.":"No source references are attached to this selection."}),!t&&((g=r.connections)==null?void 0:g.filter(x=>x.from===(i==null?void 0:i.id)||x.to===(i==null?void 0:i.id)).map((x,y)=>L.jsxs("div",{className:"source-file",children:[L.jsxs("span",{children:[x.from," → ",x.to]}),L.jsx("p",{children:r.analysisKind==="agent"?x.label:`Import declared in ${x.from}:${x.line}.`})]},`edge-${y}`))),L.jsx("div",{className:"inspector-note",children:t?"Reference explanation. Playback illustrates the documented sequence; it is not a live execution.":r.analysisKind==="agent"?"Agent-authored source analysis. References are checked against local files; interpretations and runtime behavior are not independently verified.":"Source imports and direct calls only. This is a static reading, not a verified runtime or deployment graph."})]}):h==="files"?L.jsxs(L.Fragment,{children:[L.jsx("span",{className:"eyebrow",children:"REPOSITORY EVIDENCE"}),L.jsx("h2",{children:"Source index"}),r.evidence.map(x=>L.jsxs("div",{className:"source-file",children:[L.jsx("span",{children:L.jsx(ap,{path:x.path})}),L.jsx("p",{children:x.claim})]},x.path))]}):L.jsxs(L.Fragment,{children:[L.jsx("span",{className:"eyebrow",children:"OPERATOR NOTES"}),L.jsx("h2",{children:"What matters"}),L.jsx("p",{children:r.matters}),L.jsx("h3",{children:"Data & persistence"}),L.jsx("p",{children:r.dataSummary}),L.jsx("h3",{children:"Project map"}),r.projectMap.map(x=>L.jsxs("div",{className:"source-file",children:[L.jsx("span",{children:L.jsx(ap,{path:x.path})}),L.jsx("p",{children:x.description})]},x.path)),L.jsx("h3",{children:"Tech stack"}),L.jsx("p",{children:r.stack.join(" / ")}),r.decisions.map(x=>L.jsx("p",{children:x},x))]}),L.jsxs("div",{className:"inspector-footer",children:[r.fileCount," FILES / ",r.generatedAt,L.jsx("br",{}),"SOURCE: ",r.sourceLabel]})]})]})}function WN({initialReport:r=Da}){const[t,i]=xe.useState("light"),e=["light","dark","blue"],s=e[(e.indexOf(t)+1)%e.length];xe.useLayoutEffect(()=>(document.documentElement.dataset.theme=t,()=>{delete document.documentElement.dataset.theme}),[t]);const[o,c]=xe.useState(r),[h,d]=xe.useState(0),[f,g]=xe.useState(-1),[x,y]=xe.useState(!1),[v,_]=xe.useState("part"),[A,b]=xe.useState("part"),[S,R]=xe.useState(""),[B,N]=xe.useState(!1),[D,I]=xe.useState(""),[O,M]=xe.useState(!1),[w,z]=xe.useState("3d"),V=xe.useRef(null),X=xe.useRef(null),Q=xe.useRef(null);xe.useEffect(()=>{if(!O)return;function Y(At){var Nt,zt;!((Nt=X.current)!=null&&Nt.contains(At.target))&&!((zt=Q.current)!=null&&zt.contains(At.target))&&M(!1)}function ft(At){var Nt;At.key==="Escape"&&(M(!1),(Nt=Q.current)==null||Nt.focus())}return document.addEventListener("pointerdown",Y),document.addEventListener("keydown",ft),()=>{document.removeEventListener("pointerdown",Y),document.removeEventListener("keydown",ft)}},[O]);const W=o===Da,tt=f>=0?o.system.findIndex(Y=>{var ft;return Y.id===((ft=o.trace[f])==null?void 0:ft.nodeId)}):-1;function k(Y){g(Y),y(!1),b("part")}xe.useEffect(()=>{if(!x)return;const Y=setTimeout(()=>{if(f>=o.trace.length-1){y(!1);return}g(f+1)},1300);return()=>clearTimeout(Y)},[x,f,o]);function H(Y){d(Y),_("part")}async function st(Y){N(!0),I("");try{c(await Y()),d(0),g(-1),y(!1),_("part"),b("part"),M(!1)}catch(ft){I(ft.message)}finally{N(!1)}}const et=o.system[h],pt=o.system[tt],U=o.trace[f];return L.jsxs("main",{className:"instrument instrument-cards",children:[L.jsxs("header",{className:"instrument-header",children:[L.jsx("a",{className:"instrument-brand",href:"/","aria-label":"blnkfld home",children:L.jsx("span",{className:"wordmark blnkfld-lockup",children:L.jsx("span",{className:"blnkfld-mark","aria-hidden":"true"})})}),L.jsxs("button",{className:"app-theme-toggle","aria-label":`Theme: ${t}. Switch to ${s} theme`,onClick:()=>i(s),children:[L.jsx("span",{"aria-hidden":"true"}),"THEME"]})]}),L.jsxs("nav",{className:"instrument-header-right","aria-label":"Sections",children:[L.jsx("a",{href:"#repository",children:"01 / REPOSITORY"}),L.jsx("a",{href:"#system",children:"02 / SYSTEM"}),L.jsxs("a",{href:"#action",children:["03 / ",W||o.analysisKind==="agent"?"TRACE ONE ACTION":"SOURCE CALL PATH"]}),L.jsx("a",{href:"#how-to-run",children:"04 / GET STARTED"})]}),L.jsxs("div",{className:`instrument-body ${U?"inspecting-trace":"inspecting-system"}`,children:[L.jsxs("section",{className:"instrument-workspace",children:[L.jsxs("div",{id:"repository",className:"instrument-title",children:[L.jsxs("div",{children:[L.jsx("span",{className:"eyebrow",children:W?"01 / REFERENCE REPOSITORY":"01 / IMPORTED REPOSITORY"}),L.jsx("h1",{children:o.name}),L.jsx("p",{children:o.subtitle})]}),L.jsx(FN,{report:o})]}),L.jsxs("div",{className:"instrument-summary",children:[L.jsx("span",{className:"eyebrow",children:"IN ONE MINUTE"}),L.jsx("p",{children:o.summary}),Array.isArray(o.haiku)&&o.haiku.length===3&&L.jsxs(L.Fragment,{children:[L.jsx("span",{className:"eyebrow project-haiku-label",children:"A HAIKU"}),L.jsx("p",{className:"project-haiku","aria-label":"Project haiku",children:o.haiku.map((Y,ft)=>L.jsx("span",{children:Y},ft))})]})]}),L.jsx("hr",{className:"section-divider divider-system"}),L.jsxs("section",{id:"system",className:"scene-wrap","aria-labelledby":"system-heading",children:[L.jsxs("div",{className:"system-heading",children:[L.jsxs("div",{children:[L.jsxs("span",{className:"eyebrow",children:["02 / SYSTEM / ",String(o.system.length).padStart(2,"0")," COMPONENTS"]}),L.jsx("h2",{id:"system-heading",children:"How the parts work together"})]}),L.jsx("div",{className:"system-view","aria-label":"System view",children:["3d","connections"].map(Y=>L.jsx("button",{"aria-pressed":w===Y,onClick:()=>z(Y),children:Y==="3d"?"SYSTEM OVERVIEW":"SYSTEM ARCHITECTURE"},Y))})]}),L.jsx(Om,{children:L.jsxs("div",{className:"view-enter",children:[w==="3d"&&L.jsxs(L.Fragment,{children:[L.jsx(XN,{nodes:o.system,connections:W?void 0:o.connections,selected:{index:h},onSelect:H},t),L.jsx("div",{className:"module-controls",children:o.system.map((Y,ft)=>L.jsxs("button",{onClick:()=>H(ft),"aria-pressed":h===ft,children:[L.jsx("span",{children:String(ft+1).padStart(2,"0")}),L.jsx("strong",{children:Y.label})]},Y.id))})]}),w==="connections"&&L.jsx(VN,{report:o,selected:h,onSelect:H,curated:W},o.sourceLabel+o.generatedAt)]},w)})]}),o.analysisKind==="agent"&&L.jsxs("p",{className:"analysis-coverage",children:["Source references checked in ",o.evidence.length," files · ",o.fileCount," files inventoried · Static analysis by ",o.agent]}),o.analysisKind!=="agent"&&o.coverage&&L.jsxs("p",{className:"analysis-coverage",children:["Read ",o.coverage.readCount," of ",o.coverage.totalCount," files · Parsed ",o.coverage.parsedCount," JavaScript/TypeScript files",o.coverage.omittedCount>0?` · ${o.coverage.omittedCount} additional modules omitted from this view`:"",o.coverage.treeTruncated?" · GitHub tree is incomplete":"",". Other languages are not analyzed."]}),L.jsx("hr",{className:"section-divider divider-action"}),L.jsxs("section",{id:"action",className:"sequencer",children:[L.jsxs("div",{className:"sequence-heading",children:[L.jsxs("div",{children:[L.jsxs("span",{className:"eyebrow",children:["03 / ",W||o.analysisKind==="agent"?"TRACE ONE ACTION":"SOURCE CALL PATH"]}),L.jsx("h2",{children:o.traceTitle})]}),L.jsx("button",{className:"play-button","aria-label":x?"Pause action trace":"Play action trace",title:x?"Pause":"Play","aria-pressed":x,disabled:!o.trace.length,onClick:()=>{x?y(!1):((f<0||f===o.trace.length-1)&&g(0),y(!0),b("part"))},children:L.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:x?L.jsx("path",{d:"M9 6v12M15 6v12"}):L.jsx("path",{d:"m9 5 10 7-10 7Z"})})})]}),L.jsx("p",{className:"action-summary",children:o.traceSummary}),L.jsx(LN,{report:o,selected:f,onSelect:k})]}),L.jsx("hr",{className:"section-divider divider-run"}),L.jsxs("section",{id:"how-to-run",className:"instrument-run","aria-labelledby":"run-heading",children:[L.jsx("span",{className:"eyebrow",children:"04 / GET STARTED"}),L.jsx("h2",{id:"run-heading",children:"How to run"}),L.jsx("p",{children:o.howToRun}),L.jsxs("div",{className:"run-evidence",children:[L.jsx("span",{children:"EVIDENCE"}),(o.runEvidence||[]).map(Y=>L.jsx("span",{children:Y},Y))]})]})]}),L.jsx(nS,{report:o,curated:W,node:et,active:h,mode:"system",tab:v,setTab:_}),L.jsx(nS,{report:o,curated:W,node:pt,active:tt,trace:U,step:f,mode:"trace",tab:A,setTab:b}),["repository","system","action","run"].map(Y=>L.jsx("div",{className:`section-card-outline card-${Y}`,"aria-hidden":"true"},Y))]}),L.jsxs("footer",{className:"instrument-footer",children:[L.jsx("button",{ref:Q,"aria-expanded":O,"aria-controls":"repository-popover",onClick:()=>M(!O),children:"+ CHANGE REPOSITORY"}),L.jsx("span",{children:B?"ANALYZING…":o.sourceLabel}),L.jsxs("div",{className:"footer-links",children:[L.jsx(HN,{}),L.jsx("span",{"aria-hidden":"true",children:"/"}),L.jsx(IN,{})]})]}),O&&L.jsxs("form",{ref:X,id:"repository-popover",className:"repository-popover",onSubmit:Y=>{Y.preventDefault(),st(()=>CM(S))},children:[L.jsx("label",{htmlFor:"repo-url",children:"Public GitHub repository"}),L.jsx("input",{id:"repo-url",value:S,onChange:Y=>R(Y.target.value),placeholder:"https://github.com/owner/repository",required:!0}),L.jsx("button",{disabled:B,children:"Analyze repository ↗"}),L.jsx("button",{type:"button",disabled:B,onClick:()=>V.current.click(),children:"Choose local folder"}),D&&L.jsx("p",{role:"alert",children:D})]}),L.jsx("input",{ref:V,type:"file",webkitdirectory:"",multiple:!0,hidden:!0,onChange:Y=>{const ft=Array.from(Y.target.files);ft.length&&st(()=>AM(ft)),Y.target.value=""}})]})}const rp=Ob.createRoot(document.getElementById("root"));async function qN(){const r=new URLSearchParams(window.location.search);let t;if(r.get("local")==="1"||document.querySelector('meta[name="blnkfld-local"]')){rp.render(L.jsx("p",{style:{padding:36},children:"Opening your project brief…"}));try{const i=await fetch("/api/report");if(!i.ok)throw new Error("Could not load the local report. Open the link printed by blnkfld in your terminal.");if(t=await i.json(),!t.system||!t.evidence)throw new Error("The local report is invalid.");r.has("token")&&(r.delete("token"),window.history.replaceState(null,"","?"+r.toString()))}catch(i){rp.render(L.jsx("p",{role:"alert",style:{padding:36},children:i.message}));return}}rp.render(L.jsx(Pb.StrictMode,{children:L.jsx(WN,{initialReport:t})}))}qN();
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <link rel="icon" type="image/svg+xml" href="/assets/favicon-CuD_SWDf.svg?v=rounded-square" />
7
7
  <title>blnkfld : an agentic readme</title>
8
- <script type="module" crossorigin src="/assets/index-DKS6eYH1.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-Oy6E_vaZ.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-9KPr1HmV.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blnkfld",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {