diff --git a/src/components/blueprint/DetailPanel.tsx b/src/components/blueprint/DetailPanel.tsx
index aebc6e5..fbd7c91 100644
--- a/src/components/blueprint/DetailPanel.tsx
+++ b/src/components/blueprint/DetailPanel.tsx
@@ -69,7 +69,7 @@ export default function DetailPanel() {
{subsystem.depends_on.length > 0 && (
-
+
Depends On
{subsystem.depends_on.map((d, i) => (
@@ -78,6 +78,31 @@ export default function DetailPanel() {
)}
+
+ {subsystem.boundary && (
+
+ {subsystem.boundary.inputs.length > 0 && (
+
+
Inputs
+
+ {subsystem.boundary.inputs.map((input, i) => (
+ {input}
+ ))}
+
+
+ )}
+ {subsystem.boundary.outputs.length > 0 && (
+
+
Outputs
+
+ {subsystem.boundary.outputs.map((output, i) => (
+ {output}
+ ))}
+
+
+ )}
+
+ )}
>
)}
@@ -105,7 +130,7 @@ export default function DetailPanel() {
params: {api.params.map(p => p.name).join(', ') || 'none'}
- returns: {api.returns.type}
+ returns: {api.returns?.type || 'void'}
))}
diff --git a/src/data/blueprintParser.ts b/src/data/blueprintParser.ts
new file mode 100644
index 0000000..08f8feb
--- /dev/null
+++ b/src/data/blueprintParser.ts
@@ -0,0 +1,231 @@
+import blueprintMd from '../docs/blueprint.md?raw';
+
+export interface Boundary {
+ inputs: string[];
+ outputs: string[];
+}
+
+export interface Subsystem {
+ id: string;
+ name: string;
+ responsibilities: string[];
+ provides: string[];
+ depends_on: string[];
+ boundary?: Boundary;
+}
+
+export interface Module {
+ id: string;
+ name: string;
+ parent_subsystem: string;
+ responsibility: string;
+ public_api: {
+ fn: string;
+ params: { name: string; type: string }[];
+ returns?: { type: string };
+ }[];
+}
+
+export interface SystemMeta {
+ name: string;
+ version: string;
+ type: string;
+ description: string;
+ target_runtime: string;
+}
+
+export interface BlueprintData {
+ meta: SystemMeta;
+ subsystems: Subsystem[];
+ modules: Module[];
+}
+
+function extractYamlBlock(markdown: string, sectionName: string): string {
+ const pattern = new RegExp(`# ${sectionName}[\\s\\S]*?\`\`\`yaml\\n([\\s\\S]*?)\n\`\`\``, 'i');
+ const match = markdown.match(pattern);
+ return match ? match[1].trim() : '';
+}
+
+function parseSubsystemList(yaml: string): Subsystem[] {
+ const subsystems: Subsystem[] = [];
+ const lines = yaml.split('\n');
+ let currentSubsystem: Partial