@tinkerlandai/indiana-iam 0.4.0 → 0.5.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/README.md CHANGED
@@ -119,7 +119,26 @@ and statically generated TanStack file-route trees registered with `createRouter
119
119
  React Router supports imported static path constants, inline `Component` functions and source-proven lazy import forwarding.
120
120
  Data-router `route.lazy` objects support a static module's named `Component`, or a source-proven mapper that captures
121
121
  the component export. Mapper factories, imports and business loaders are never executed. Unknown overrides remain gaps.
122
- MDX pages/layouts need a separate adapter and explicitly report incomplete route coverage.
122
+ Markdown/MDX pages, layouts and local imports retain original routes and source coordinates.
123
+ The pinned Markdown/MDX parsers project headings, lists, GFM tables/tasks, code, links, images and bounded source JSX.
124
+ Merchant MDX compilers/plugins, ESM side effects, arbitrary expressions and active HTML are never executed.
125
+ Generated Markdown markup stays preview-only; custom MDX component mappings and plugin transforms remain gaps.
126
+ CSS Modules retain source-literal default imports, deterministic local preview class names,
127
+ scoped selectors and static declarations, including standard media/supports/container rules.
128
+ Global selectors, resource loads, composition, nested preprocessing and animation definitions stay explicit gaps;
129
+ merchant PostCSS plugins and configuration are never executed. Compiled CSS remains a separate build input.
130
+ Mantine core forms, headings, containers, tables, images and controlled Modal/Drawer visibility have an inert
131
+ semantic HTML profile. Source labels, ordinary form constraints and safe default values are retained;
132
+ password values stay redacted. Theme resolution, responsive object props, portal positioning, focus handling
133
+ and library callbacks remain unobserved. Boolean `useDisclosure` without lifecycle callbacks, controlled Tabs,
134
+ Drawer/Modal close controls and native Accordion folding have bounded local previews. This profile does not
135
+ import Mantine or run its hooks.
136
+ Async source helpers and TanStack queries can expose source-declared literal fixtures, including a source-proven
137
+ timer-only delay. IAM interprets their AST without executing functions, awaiting timers or invoking query callbacks.
138
+ Safe-integer locale formatting uses deterministic English grouping in the source preview.
139
+ Declared `initialData` retains its source initial state; loading/error/network outcomes otherwise stay unknown.
140
+ Only the known frontend `services/api` source path is included; framework API routes, server trees and credentials
141
+ stay outside the scan. Remote data, mutations, impure helpers and ambiguous bindings remain unobserved.
123
142
  TanStack reads the registered generated tree, including pathless layouts, index routes and simple `$param` paths;
124
143
  custom history/basepath and complex parameter patterns require separate adapters. Loaders, guards, retry/reload behavior
125
144
  and runtime data remain unobserved. Unsupported optional React paths are isolated as gaps.
@@ -138,11 +157,15 @@ Source-proven `useSyncExternalStore` matchMedia getters retain both typed viewpo
138
157
  viewport. Subscriptions are not run. UI preference cookies with an explicit source SSR guard use an empty-cookie
139
158
  preview; auth/session cookies and arbitrary stores stay unobserved. Pure lazy local-state initializers are interpreted
140
159
  under the same bounded rules; merchant callbacks and browser storage are never executed or read.
141
- The complete validated IAM must fit within 8 MiB; oversized projections fail without emitting a truncated artifact.
160
+ IAM has no configured page, node or total artifact byte limit. The exporter retains every supported route.
142
161
  Large artifacts store sizeable HTML/preorder-map pairs as `domPayload` (`gzip-json-v1`), while keeping `html: ""`
143
162
  and `nodes: []` in that document's wire record. This lossless storage encoding preserves all source IDs, DOM values,
144
- HTML/DOM hashes and targets. Route navigation stores the exact interaction-array index instead of repeating its ID; validation checks node, route, destination and parameters. Source files retain their full hashes; component/element records cover reachable route compositions and shared fragments. Text node IDs that follow the original parent/index identity formula are derived locally instead of repeated; explicit exceptions remain stored, and every resolved source-map hash is checked. The document hash pins its encoded storage body; decoding is local and bounded to
145
- 8 MiB per payload and 32 MiB in aggregate. The final IAM file limit stays 8 MiB. Exported page HTML is expanded.
163
+ HTML/DOM hashes and targets. Route navigation stores the exact interaction-array index instead of repeating its ID; validation checks node, route, destination and parameters. Source files retain their full hashes; component/element records cover reachable route compositions and shared fragments. Text node IDs that follow the original parent/index identity formula are derived locally instead of repeated; explicit exceptions remain stored, and every resolved source-map hash is checked. The document hash pins its encoded storage body; decoding is local and checks the exact declared size and hashes. Exported page HTML is expanded.
164
+ The standalone viewer embeds only its route directory and hash-pinned document references. It reads and expands
165
+ the selected document on demand, cancels superseded reads and retains one expanded page. Derived page files
166
+ come from the complete validated IAM; the complete JSON remains the source of release identity.
167
+ Serve the output directory over loopback HTTP to open `index.html`; browser `file://` restrictions prevent
168
+ on-demand reads of its document files. Serving the exported files does not run the App or its backend.
146
169
  Use the matching 0.4 generator, validator and viewer together. Indiana ingestion/viewer sources must be updated
147
170
  before uploading compressed artifacts; publishing this npm package alone does not deploy Indiana. The offline
148
171
  viewer uses the browser's built-in `DecompressionStream` and never fetches a decoder or merchant content.
package/assets/viewer.js CHANGED
@@ -119,6 +119,11 @@ async function mountIamViewer(m, consoleContext) {
119
119
  }
120
120
  document.body.dataset.panel = "canvas";
121
121
  $("viewport").value = String(viewport);
122
+ const inlineDocuments=new Map(m.documents.map(document=>[document.documentKey,document]));
123
+ const localDocumentFiles=new Map((m.documentFiles??[]).map(file=>[file.documentKey,file]));
124
+ const directoryInteractions=m.interactions;
125
+ const expandedDocuments=new WeakSet();
126
+ let localRead=null;
122
127
  const changes = new Map(), baseline = new Map(), originalValues = new Map(), localValues = new Map(), savedViews = new Map(), seededViews = new Set();
123
128
  let baselineLoaded = false;
124
129
  let pendingDocument=null,projectionReadOnly=false,retryOpen=null;
@@ -208,7 +213,7 @@ async function mountIamViewer(m, consoleContext) {
208
213
  $("commit").textContent = "";
209
214
  $("page-count").textContent = m.pages.length;
210
215
  $("summary").textContent =
211
- `${m.pages.length} ${tr("页面")} · ${m.components.length} ${tr("组件")} · ${consoleContext?.catalog?.nodeCount??m.documents.reduce((n, d) => n + d.nodes.length, 0)} ${tr("DOM 节点")}`;
216
+ `${m.pages.length} ${tr("页面")} · ${m.summary?.components??m.components.length} ${tr("组件")} · ${consoleContext?.catalog?.nodeCount??m.summary?.nodes??m.documents.reduce((n, d) => n + d.nodes.length, 0)} ${tr("DOM 节点")}`;
212
217
  $("gap-count").textContent = `${consoleContext?.catalog?.gapCount??m.coverage.gaps.length} ${iamEnglish ? "coverage gaps" : "项缺口已记录"}`;
213
218
  $("coverage-description").textContent =
214
219
  tr("这是从 App 源码生成的 HTML/CSS/JS 投影。未运行原应用;动态数据、鉴权状态、字体与第三方组件可能不完整。只有明确提取的界面状态可模拟。");
@@ -299,13 +304,49 @@ async function mountIamViewer(m, consoleContext) {
299
304
  "<\/script>" + (keyboard ? "<script>" + keyboard.js.replaceAll("</script", "<\\/script") + "<\/script>" : "") + "</body></html>"
300
305
  );
301
306
  }
302
- function openPage(next, targetUrl = next.route, renderKey, historyMove=null) {
307
+ async function openPage(next, targetUrl = next.route, renderKey, historyMove=null) {
303
308
  if (consoleContext) targetUrl = viewUrl(targetUrl);
304
309
  retryOpen={pageKey:next.pageKey,targetUrl,renderKey,historyMove};
305
310
  if(consoleContext)consoleContext.documentReady=false;
306
311
  const nextRender=m.routeTree.renders.find(render=>render.routeKey===next.pageKey&&render.renderKey===(renderKey??m.routeTree.routes.find(route=>route.routeKey===next.pageKey).initialRenderKey));
307
312
  if (!nextRender) throw Error("Unknown preview render");
308
- const nextDocument=byId(m.documents,"documentKey",nextRender.documentKey);
313
+ let nextDocument=byId(m.documents,"documentKey",nextRender.documentKey);
314
+ if(!consoleContext || consoleContext.mode!=="documents"){
315
+ localRead?.abort();localRead=null;pendingDocument=null;
316
+ if(!nextDocument||!expandedDocuments.has(nextDocument)){
317
+ const request={pageKey:next.pageKey,renderKey:nextRender.renderKey};
318
+ const controller=new AbortController();localRead=controller;pendingDocument=request;
319
+ $("document-status").textContent=tr("正在打开页面资料…");$("export").disabled=true;
320
+ try{
321
+ const file=localDocumentFiles.get(nextRender.documentKey);
322
+ if(file){
323
+ if(!/^document_[a-f0-9]{64}$/.test(file.documentKey)||!/^[a-f0-9]{64}$/.test(file.sha256)||!Number.isSafeInteger(file.bytes)||file.bytes<1)throw Error("Invalid local document reference");
324
+ const response=await fetch(new URL('documents/'+file.documentKey+'/material.json',location.href),{signal:controller.signal});
325
+ if(!response.ok)throw Error("Local document unavailable");
326
+ const bytes=await response.arrayBuffer();
327
+ if(bytes.byteLength!==file.bytes)throw Error("Local document size mismatch");
328
+ const actual=[...new Uint8Array(await crypto.subtle.digest('SHA-256',bytes))].map(b=>b.toString(16).padStart(2,'0')).join('');
329
+ if(actual!==file.sha256)throw Error("Local document digest mismatch");
330
+ const material=JSON.parse(new TextDecoder('utf-8',{fatal:true}).decode(bytes));
331
+ const stored=material.document;
332
+ if(stored.documentKey!==nextRender.documentKey||stored.pageKey!==next.pageKey||stored.hashes.document!==nextRender.documentHash)throw Error("Local document scope mismatch");
333
+ const expanded=await expandNodeHashes(stored,request);
334
+ if(pendingDocument!==request)return;
335
+ for(const key of ['elements','styles','assets','scripts','components','interactions'])m[key]=material[key];
336
+ activeGraph=material.routeTree;m.routeTree={...activeGraph,routes:m.routeTree.routes,renders:m.routeTree.renders};expandedDocuments.add(expanded);m.documents=[expanded];
337
+ }else{
338
+ const stored=inlineDocuments.get(nextRender.documentKey);if(!stored)throw Error("Missing local document");
339
+ const expanded=await expandNodeHashes(stored,request);
340
+ if(pendingDocument!==request)return;
341
+ expandedDocuments.add(expanded);m.documents=[expanded];
342
+ }
343
+ pendingDocument=null;localRead=null;nextDocument=m.documents[0];
344
+ }catch(error){
345
+ if(pendingDocument===request){pendingDocument=null;localRead=null;$("document-status").textContent=tr("页面资料校验失败,请重新打开此版本。");toast(tr("页面资料校验失败,请重新打开此版本。"));}
346
+ return;
347
+ }
348
+ }
349
+ }
309
350
  if(!nextDocument&&consoleContext?.mode==="documents"){
310
351
  pendingDocument={requestId:crypto.randomUUID(),pageKey:next.pageKey,renderKey:nextRender.renderKey,targetUrl,historyMove,documentKey:nextRender.documentKey,documentHash:nextRender.documentHash};
311
352
  $("document-status").textContent=tr("正在打开页面资料…");$("export").disabled=true;
@@ -493,12 +534,12 @@ async function mountIamViewer(m, consoleContext) {
493
534
  function checkedDomPayload(document) {
494
535
  const payload = document.domPayload;
495
536
  if (!payload) return null;
496
- if (document.html !== "" || !Array.isArray(document.nodes) || document.nodes.length || Object.keys(payload).sort().join(",") !== "bytes,data,encoding" || payload.encoding !== "gzip-json-v1" || !Number.isSafeInteger(payload.bytes) || payload.bytes < 1 || payload.bytes > 8_388_608 || typeof payload.data !== "string" || !payload.data.length || payload.data.length > 11_184_812 || payload.data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(payload.data)) throw Error("Invalid compressed DOM payload");
537
+ if (document.html !== "" || !Array.isArray(document.nodes) || document.nodes.length || Object.keys(payload).sort().join(",") !== "bytes,data,encoding" || payload.encoding !== "gzip-json-v1" || !Number.isSafeInteger(payload.bytes) || payload.bytes < 1 || typeof payload.data !== "string" || !payload.data.length || payload.data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(payload.data)) throw Error("Invalid compressed DOM payload");
497
538
  return payload;
498
539
  }
499
540
  function parsedDomPayload(text) {
500
541
  const value = JSON.parse(text);
501
- if (!value || Object.keys(value).sort().join(",") !== "html,nodes" || typeof value.html !== "string" || value.html.length > 2_000_000 || !value.html.isWellFormed() || !Array.isArray(value.nodes) || value.nodes.length > 12000 || JSON.stringify(value) !== text) throw Error("Invalid expanded DOM payload");
542
+ if (!value || Object.keys(value).sort().join(",") !== "html,nodes" || typeof value.html !== "string" || !value.html.isWellFormed() || !Array.isArray(value.nodes) || JSON.stringify(value) !== text) throw Error("Invalid expanded DOM payload");
502
543
  return value;
503
544
  }
504
545
  async function documentDomBrowser(document) {
@@ -529,7 +570,7 @@ async function documentDomBrowser(document) {
529
570
  /* END COMPRESSED DOM */
530
571
  /* BEGIN HTML DOM DERIVATION */
531
572
  function expandDomNodes(document, body, deriveTextId) {
532
- if(document.nodeEncoding!=='html-preorder-v1'||document.nodeHashMode!=='derived-v1'||!document.sourceMappingsHash||document.nodes.length>12000)throw Error('Invalid HTML-derived DOM mode');
573
+ if(document.nodeEncoding!=='html-preorder-v1'||document.nodeHashMode!=='derived-v1'||!document.sourceMappingsHash)throw Error('Invalid HTML-derived DOM mode');
533
574
  let index=0;const result=[];
534
575
  function visit(node,parentId,depth,childIndex=0){
535
576
  if(depth>128||![1,3].includes(node.nodeType))throw Error('Invalid HTML-derived DOM structure');
@@ -553,11 +594,11 @@ function expandDomNodes(document, body, deriveTextId) {
553
594
  const {domPayload, ...plain} = document;
554
595
  document = {...plain, ...decoded};
555
596
  }
556
- if(!Array.isArray(document.nodes)||document.nodes.length>12000)throw Error('Node hash budget');
597
+ if(!Array.isArray(document.nodes))throw Error('Node hash budget');
557
598
  const body=new DOMParser().parseFromString('<!doctype html><html><body>'+document.html+'</body></html>','text/html').body,textIds=new Map(),pendingText=[];
558
599
  let preorder=0;
559
600
  const collectText=(node,parentId,childIndex=0,depth=0)=>{
560
- if(!node||depth>128||preorder>=12000)throw Error('DOM derivation budget');
601
+ if(!node||depth>128)throw Error('DOM derivation budget');
561
602
  const ref=document.nodes[preorder++];if(!ref)throw Error('Missing source node');
562
603
  const id=node.nodeType===1?node.getAttribute('data-iam-node'):ref.nodeId;
563
604
  if(node.nodeType===3&&!id)pendingText.push({parentId,index:childIndex,key:parentId+':'+childIndex});
@@ -595,12 +636,12 @@ function expandDomNodes(document, body, deriveTextId) {
595
636
  const request=pendingDocument;
596
637
  try{
597
638
  const projection=data.projection;
598
- if(projection?.format!=="indiana-document-projection"||projection.schemaVersion!==2||projection.versionId!==consoleContext.versionId||projection.manifestDigest!==consoleContext.manifestDigest||projection.pageKey!==request.pageKey||projection.renderKey!==(request.renderKey??null)||projection.documentKey!==request.documentKey||projection.documentHash!==request.documentHash||typeof projection.payload!=="string"||projection.payload.length>8388608)throw Error("Projection scope mismatch");
639
+ if(projection?.format!=="indiana-document-projection"||projection.schemaVersion!==2||projection.versionId!==consoleContext.versionId||projection.manifestDigest!==consoleContext.manifestDigest||projection.pageKey!==request.pageKey||projection.renderKey!==(request.renderKey??null)||projection.documentKey!==request.documentKey||projection.documentHash!==request.documentHash||typeof projection.payload!=="string")throw Error("Projection scope mismatch");
599
640
  const material=JSON.parse(projection.payload),document=material.document;
600
641
  const {hashes,...body}=document;
601
642
  if(document.documentKey!==request.documentKey||document.pageKey!==request.pageKey||hashes.document!==request.documentHash||await hash("iam/document/v1\0"+canonical(body))!==request.documentHash)throw Error("Projection document hash mismatch");
602
643
  const provided = new Map();
603
- if (!Array.isArray(material.resourceRefs) || material.resourceRefs.length > 2048) throw Error("Invalid preview resources");
644
+ if (!Array.isArray(material.resourceRefs)) throw Error("Invalid preview resources");
604
645
  for (const kind of ["styles","assets","scripts"]) {
605
646
  if (!Array.isArray(material[kind])) throw Error("Invalid preview resource kind");
606
647
  for (const value of material[kind]) {
@@ -616,7 +657,6 @@ function expandDomNodes(document, body, deriveTextId) {
616
657
  if(!entry||entry.kind!==ref.kind)throw Error("Missing preview resource");
617
658
  resolved.set(ref.hash,entry);
618
659
  }
619
- if([...resolved.values()].reduce((bytes,entry)=>bytes+entry.bytes,0)>8_388_608)throw Error("Preview resource byte budget");
620
660
  for (const kind of ["styles","assets","scripts"]) material[kind]=[...resolved.values()].filter(entry=>entry.kind===kind).map(entry=>entry.value);
621
661
  const script=document.scriptKey?material.scripts.find(script=>script.scriptKey===document.scriptKey):{js:document.js,sha256:hashes.js};
622
662
  if(!script||!consoleContext.reviewedRuntimeHashes.includes(script.sha256)||await hash(script.js)!==script.sha256||document.scriptKey&&document.scriptKey!=="script_"+script.sha256)throw Error("Unreviewed preview runtime");
@@ -629,7 +669,7 @@ function expandDomNodes(document, body, deriveTextId) {
629
669
  if(consoleContext.catalog)m.routeTree={...material.routeTree,routes:consoleContext.catalog.routes,renders:consoleContext.catalog.renders};
630
670
  const expanded=await expandNodeHashes(document,request);
631
671
  if(pendingDocument!==request)return;
632
- m.documents=[expanded];projectionReadOnly=projection.readOnly;pendingDocument=null;
672
+ expandedDocuments.add(expanded);m.documents=[expanded];projectionReadOnly=projection.readOnly;pendingDocument=null;
633
673
  openPage(m.pages.find(page=>page.pageKey===request.pageKey),request.targetUrl,request.renderKey,request.historyMove);
634
674
  }catch{if(pendingDocument===request){pendingDocument=null;projectionReadOnly=true;renderSaveCount();parent.postMessage({channel:"indiana-iam-console-v1",nonce:consoleContext.nonce,versionId:consoleContext.versionId,type:"error"},"*");}}
635
675
  return;
@@ -804,9 +844,9 @@ function expandDomNodes(document, body, deriveTextId) {
804
844
  text("strong", p.route),
805
845
  text(
806
846
  "small",
807
- p.componentKeys.length +
847
+ (p.componentCount??p.componentKeys.length) +
808
848
  tr(" 组件 · ") +
809
- p.stateKeys.length +
849
+ (p.stateCount??p.stateKeys.length) +
810
850
  tr(" 状态候选"),
811
851
  ),
812
852
  );
@@ -814,7 +854,7 @@ function expandDomNodes(document, body, deriveTextId) {
814
854
  const links = text("div", "", "map-targets"),
815
855
  ids = [
816
856
  ...new Set(
817
- m.interactions
857
+ directoryInteractions
818
858
  .filter((i) => i.pageKey === p.pageKey && i.targetPageKey)
819
859
  .map((i) => i.targetPageKey),
820
860
  ),
@@ -839,9 +879,9 @@ function expandDomNodes(document, body, deriveTextId) {
839
879
  format: "indiana-local-preview-changes",
840
880
  schemaVersion: 1,
841
881
  sourceGraphDigest: m.release.sourceGraphDigest,
842
- manifestDocumentHashes: m.documents.map((d) => ({
843
- documentKey: d.documentKey,
844
- hash: d.hashes.document,
882
+ manifestDocumentHashes: m.routeTree.renders.map((row) => ({
883
+ documentKey: row.documentKey,
884
+ hash: row.documentHash,
845
885
  })),
846
886
  changes: [...changes.values()],
847
887
  scope: "local_preview_only",
@@ -859,19 +899,7 @@ function expandDomNodes(document, body, deriveTextId) {
859
899
  toast(tr("导出本地 JSON;未保存到服务器或应用到商户。"));
860
900
  });
861
901
  renderNav();
862
- if (m.documents.length) {
863
- const initialRequest = {};
864
- pendingDocument = initialRequest;
865
- const expandedBytes = m.documents.reduce((total, document) => total + (document.domPayload?.bytes ?? new TextEncoder().encode(JSON.stringify({html:document.html,nodes:document.nodes})).byteLength), 0);
866
- if (!Number.isSafeInteger(expandedBytes) || expandedBytes > 33_554_432) throw Error("Expanded DOM aggregate byte budget exceeded");
867
- // Sequential decoding bounds peak memory for a multi-route artifact.
868
- const expandedDocuments = [];
869
- for (const document of m.documents) expandedDocuments.push(await expandNodeHashes(document, initialRequest));
870
- m.documents = expandedDocuments;
871
- pendingDocument = null;
872
- renderNav();
873
- }
874
- openPage(page,consoleContext?.initialPage?.url??page.route,consoleContext?.initialPage?.renderKey??consoleContext?.catalog?.graph.variables.find(variable=>variable.id===consoleContext.initialPage?.variableKey)?.renderKey);
902
+ await openPage(page,consoleContext?.initialPage?.url??page.route,consoleContext?.initialPage?.renderKey??consoleContext?.catalog?.graph.variables.find(variable=>variable.id===consoleContext.initialPage?.variableKey)?.renderKey);
875
903
  }
876
904
  (async () => {
877
905
  const data = JSON.parse(document.getElementById("iam-data").textContent);
@@ -908,7 +936,7 @@ function expandDomNodes(document, body, deriveTextId) {
908
936
  const model={format:"indiana-preview-material",schemaVersion:1,app:{name:catalog.appName},release:{sourceGraphDigest:catalog.sourceGraphDigest},pages:catalog.routes.map(route=>({pageKey:route.routeKey,route:route.path,title:route.path,documentKeys:[route.documentKey],stateKeys:[],componentKeys:[]})),documents:[],elements:[],components:[],interactions:[],styles:[],scripts:[],assets:[],coverage:{gaps:[]},routeTree:{schemaVersion:catalog.renderIndexVersion,routes:catalog.routes,renders:catalog.renders,variables:catalog.graph.variables.map(variable=>({variableKey:variable.id,routeKey:variable.routeId,renderKey:variable.renderKey})),states:[],transitions:[],bindings:[],targets:[],navigation:[]}};
909
937
  await mountIamViewer(model,context);loading.hidden=true;document.querySelector(".workspace").hidden=false;return;
910
938
  }
911
- if (!(message.bytes instanceof Uint8Array) || message.bytes.byteLength !== context.bytes || message.bytes.byteLength > 8388608) throw new Error("Invalid IAM bytes");
939
+ if (!(message.bytes instanceof Uint8Array) || message.bytes.byteLength !== context.bytes) throw new Error("Invalid IAM bytes");
912
940
  const digest = [...new Uint8Array(await crypto.subtle.digest("SHA-256", message.bytes))].map(b => b.toString(16).padStart(2,"0")).join("");
913
941
  if (digest !== context.manifestDigest) throw new Error("IAM digest mismatch");
914
942
  const manifest = JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(message.bytes));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinkerlandai/indiana-iam",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Build-time Indiana App Manifest (IAM) generator for Next.js and Vite apps: scans source after the production build and writes the IAM and its release descriptor.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -49,10 +49,16 @@
49
49
  "jsdom": "26.1.0",
50
50
  "lucide-static": "1.34.0",
51
51
  "magic-string": "0.30.21",
52
+ "mdast-util-from-markdown": "2.1.0",
53
+ "mdast-util-gfm": "3.1.0",
54
+ "mdast-util-mdx": "3.0.0",
55
+ "micromark-extension-gfm": "3.0.0",
56
+ "micromark-extension-mdxjs": "3.0.0",
52
57
  "pako": "3.0.2",
53
58
  "sharp": "0.35.5",
54
59
  "tailwind-merge": "3.7.0",
55
60
  "tailwindcss": "4.3.3",
56
- "typescript": "5.9.3"
61
+ "typescript": "5.9.3",
62
+ "yaml": "2.9.1"
57
63
  }
58
64
  }