tjs-lang 0.6.45 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CLAUDE.md +70 -444
  2. package/README.md +15 -82
  3. package/bin/benchmarks.ts +7 -7
  4. package/bin/dev.ts +2 -1
  5. package/demo/autocomplete.test.ts +1 -1
  6. package/demo/docs.json +743 -47
  7. package/demo/src/demo-nav.ts +5 -5
  8. package/demo/src/index.ts +28 -36
  9. package/demo/src/module-sw.ts +1 -1
  10. package/demo/src/playground-shared.ts +17 -17
  11. package/demo/src/playground.ts +13 -1
  12. package/demo/src/style.ts +4 -1
  13. package/demo/src/tjs-playground.ts +5 -5
  14. package/demo/src/user-store.ts +2 -1
  15. package/demo/static/favicon.svg +17 -24
  16. package/demo/static/tosi-platform.json +9304 -0
  17. package/dist/index.js +176 -175
  18. package/dist/index.js.map +5 -43
  19. package/dist/scripts/compat-effect.d.ts +16 -0
  20. package/dist/scripts/compat-kysely.d.ts +13 -0
  21. package/dist/scripts/compat-radash.d.ts +13 -0
  22. package/dist/scripts/compat-superstruct.d.ts +13 -0
  23. package/dist/scripts/compat-ts-pattern.d.ts +13 -0
  24. package/dist/scripts/compat-zod.d.ts +12 -0
  25. package/dist/src/lang/emitters/from-ts.d.ts +1 -1
  26. package/dist/src/lang/emitters/js-tests.d.ts +4 -0
  27. package/dist/src/lang/emitters/js.d.ts +2 -2
  28. package/dist/src/lang/index.d.ts +1 -0
  29. package/dist/src/lang/json-schema.d.ts +40 -0
  30. package/dist/src/lang/parser-transforms.d.ts +14 -0
  31. package/dist/src/lang/runtime.d.ts +39 -20
  32. package/dist/src/types/Type.d.ts +5 -0
  33. package/dist/tjs-batteries.js +3 -4
  34. package/dist/tjs-batteries.js.map +5 -13
  35. package/dist/tjs-eval.js +47 -0
  36. package/dist/tjs-eval.js.map +7 -0
  37. package/dist/tjs-from-ts.js +58 -0
  38. package/dist/tjs-from-ts.js.map +7 -0
  39. package/dist/tjs-lang.js +349 -0
  40. package/dist/tjs-lang.js.map +7 -0
  41. package/dist/tjs-vm.js +51 -51
  42. package/dist/tjs-vm.js.map +4 -19
  43. package/docs/README.md +21 -20
  44. package/docs/WASM-QUICKSTART.md +283 -0
  45. package/docs/diagrams/architecture-shift.svg +117 -0
  46. package/docs/diagrams/compile-runtime.svg +130 -0
  47. package/docs/diagrams/icon-riff-1.svg +55 -0
  48. package/docs/diagrams/icon-riff-2.svg +62 -0
  49. package/docs/diagrams/icon-riff-3.svg +61 -0
  50. package/docs/diagrams/platform-overview.svg +114 -0
  51. package/docs/diagrams/safe-eval.svg +147 -0
  52. package/docs/eval-v4/arch-comparison.svg +277 -0
  53. package/docs/eval-v4/bundler-tree.svg +250 -0
  54. package/docs/eval-v4/http-lifecycle.svg +148 -0
  55. package/docs/function-predicate-design.md +8 -8
  56. package/docs/native-engine-integration.md +2 -2
  57. package/editors/codemirror/autocomplete.test.ts +29 -29
  58. package/package.json +24 -12
  59. package/src/cli/commands/convert.test.ts +11 -8
  60. package/src/lang/codegen.test.ts +117 -112
  61. package/src/lang/docs.test.ts +22 -22
  62. package/src/lang/docs.ts +5 -8
  63. package/src/lang/emitters/dts.test.ts +13 -13
  64. package/src/lang/emitters/from-ts.ts +36 -9
  65. package/src/lang/emitters/js-tests.ts +143 -28
  66. package/src/lang/emitters/js.ts +44 -31
  67. package/src/lang/features.test.ts +259 -43
  68. package/src/lang/from-ts.test.ts +3 -3
  69. package/src/lang/function-predicate.test.ts +1 -1
  70. package/src/lang/index.ts +8 -47
  71. package/src/lang/json-schema.test.ts +261 -0
  72. package/src/lang/json-schema.ts +167 -0
  73. package/src/lang/parser-params.ts +28 -44
  74. package/src/lang/parser-transforms.ts +255 -0
  75. package/src/lang/parser.test.ts +32 -13
  76. package/src/lang/parser.ts +49 -11
  77. package/src/lang/perf.test.ts +11 -11
  78. package/src/lang/roundtrip.test.ts +3 -3
  79. package/src/lang/runtime.test.ts +167 -0
  80. package/src/lang/runtime.ts +213 -64
  81. package/src/lang/transpiler.test.ts +21 -21
  82. package/src/lang/typescript-syntax.test.ts +11 -9
  83. package/src/types/Type.ts +38 -1
  84. package/src/use-cases/bootstrap.test.ts +7 -7
  85. package/src/use-cases/client-server.test.ts +1 -1
  86. package/src/use-cases/malicious-actor.test.ts +1 -1
  87. package/src/use-cases/rag-processor.test.ts +1 -1
  88. package/src/use-cases/sophisticated-agents.test.ts +2 -2
  89. package/src/use-cases/transpiler-llm.test.ts +1 -1
  90. package/src/use-cases/unbundled-imports.test.ts +9 -9
  91. package/tjs-lang.svg +17 -25
  92. package/dist/tjs-full.js +0 -435
  93. package/dist/tjs-full.js.map +0 -45
  94. package/dist/tjs-transpiler.js +0 -3
  95. package/dist/tjs-transpiler.js.map +0 -11
@@ -0,0 +1,62 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Riff 2: "The Prism Owl" — the owl's screen/face has a prism effect
3
+ suggesting one input (TS) becomes multiple outputs. The three colored
4
+ beams represent the three pillars. Background shifts from the animation's
5
+ day palette to something more energetic. -->
6
+ <svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg">
7
+ <style>
8
+ .bg { fill: #181340; }
9
+ .screen { fill: #ffffff; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
10
+ .outline { fill: none; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
11
+ .wing { fill: #6e6e8e; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
12
+ .body { fill: #9e9ebe; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
13
+ .feet { fill: none; stroke: #fbed21; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
14
+ .beam-red { stroke: #ff1c24; stroke-width: 1.5; fill: none; stroke-linecap: round; }
15
+ .beam-green { stroke: #006736; stroke-width: 1.5; fill: none; stroke-linecap: round; }
16
+ .beam-blue { stroke: #3da8f4; stroke-width: 1.5; fill: none; stroke-linecap: round; }
17
+ .beam-in { stroke: #ffffff; stroke-width: 1.5; fill: none; stroke-linecap: round; opacity: 0.7; }
18
+ .star { fill: #fbed21; }
19
+ </style>
20
+
21
+ <!-- Background: dark navy (night/moon from animation) -->
22
+ <rect width="48" height="48" rx="8" class="bg"/>
23
+
24
+ <!-- Stars -->
25
+ <circle cx="5" cy="6" r="1" class="star"/>
26
+ <circle cx="42" cy="4" r="0.8" class="star"/>
27
+ <circle cx="38" cy="10" r="0.6" class="star"/>
28
+ <circle cx="3" cy="14" r="0.7" class="star"/>
29
+ <circle cx="44" cy="18" r="0.5" class="star"/>
30
+
31
+ <!-- Left wing -->
32
+ <path d="M7.5,16 C4.5,16,2,18.5,2,21.5 C2,24,4,26,6.5,26 L6.6,26 C7.4,26,8,26.6,8,27.4 C8,29.9,10.1,32,12.6,32 L16,32 C18.6,32,20.7,29.9,20.7,27.3 L20.7,21.4 C20.7,18.4,18.3,16,15.3,16 Z" class="wing"/>
33
+
34
+ <!-- Right wing -->
35
+ <path d="M40.5,16 C43.5,16,46,18.5,46,21.5 C46,24,44,26,41.5,26 L41.4,26 C40.6,26,40,26.6,40,27.4 C40,29.9,37.9,32,35.4,32 L32,32 C29.4,32,27.3,29.9,27.3,27.3 L27.3,21.4 C27.3,18.4,29.7,16,32.7,16 Z" class="wing"/>
36
+
37
+ <!-- Body -->
38
+ <path d="M17,29 L33,29 C33,34.5,28.5,39,23,39 C19.7,39,17,36.3,17,33 Z" class="body"/>
39
+
40
+ <!-- Feet (golden like sun) -->
41
+ <path d="M20,43 L18,41 L16,43" class="feet"/>
42
+ <path d="M32,43 L30,41 L28,43" class="feet"/>
43
+
44
+ <!-- Head/Screen -->
45
+ <rect x="6" y="6" width="30" height="23" rx="4" class="screen"/>
46
+
47
+ <!-- Input beam (white, entering left of screen) -->
48
+ <line x1="2" y1="17" x2="14" y2="17" class="beam-in"/>
49
+
50
+ <!-- Prism triangle on the screen face -->
51
+ <polygon points="14,11 14,23 25,17" fill="none" stroke="#000" stroke-width="1.5" stroke-linejoin="round"/>
52
+
53
+ <!-- Three output beams exiting right -->
54
+ <line x1="25" y1="14" x2="35" y2="10" class="beam-red"/>
55
+ <line x1="25" y1="17" x2="36" y2="17" class="beam-green"/>
56
+ <line x1="25" y1="20" x2="35" y2="24" class="beam-blue"/>
57
+
58
+ <!-- Tiny labels at beam ends -->
59
+ <text x="36" y="11" fill="#ff1c24" font-size="3.5" font-family="system-ui, sans-serif" font-weight="700">TS</text>
60
+ <text x="37" y="18" fill="#006736" font-size="3.5" font-family="system-ui, sans-serif" font-weight="700">TJS</text>
61
+ <text x="36" y="26" fill="#3da8f4" font-size="3.5" font-family="system-ui, sans-serif" font-weight="700">AJS</text>
62
+ </svg>
@@ -0,0 +1,61 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Riff 3: "Dawn Owl" — transitional sky (the animation goes day->storm->night)
3
+ This captures the sunrise moment. The owl's screen shows { } braces,
4
+ the most universal "code" symbol. Warm gradient background.
5
+ The owl is the same character but the palette says "new era." -->
6
+ <svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg">
7
+ <defs>
8
+ <linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
9
+ <stop offset="0%" stop-color="#3da8f4"/>
10
+ <stop offset="60%" stop-color="#fdbe52"/>
11
+ <stop offset="100%" stop-color="#fbed21"/>
12
+ </linearGradient>
13
+ </defs>
14
+ <style>
15
+ .screen { fill: #ffffff; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
16
+ .outline { fill: none; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
17
+ .wing { fill: #9e9e9e; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
18
+ .body { fill: #e4e4e4; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
19
+ .feet { fill: none; stroke: #000; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
20
+ .code { fill: none; stroke: #181340; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
21
+ .eye-line { fill: none; stroke: #000; stroke-width: 2; stroke-linecap: round; }
22
+ .sun-glow { fill: #fbed21; opacity: 0.3; }
23
+ </style>
24
+
25
+ <!-- Background: dawn gradient -->
26
+ <rect width="48" height="48" rx="8" fill="url(#sky)"/>
27
+
28
+ <!-- Sun peeking up from bottom -->
29
+ <circle cx="24" cy="48" r="12" class="sun-glow"/>
30
+ <circle cx="24" cy="48" r="8" fill="#fbed21" opacity="0.5"/>
31
+
32
+ <!-- Left wing -->
33
+ <path d="M7.5,16 C4.5,16,2,18.5,2,21.5 C2,24,4,26,6.5,26 L6.6,26 C7.4,26,8,26.6,8,27.4 C8,29.9,10.1,32,12.6,32 L16,32 C18.6,32,20.7,29.9,20.7,27.3 L20.7,21.4 C20.7,18.4,18.3,16,15.3,16 Z" class="wing"/>
34
+
35
+ <!-- Right wing -->
36
+ <path d="M40.5,16 C43.5,16,46,18.5,46,21.5 C46,24,44,26,41.5,26 L41.4,26 C40.6,26,40,26.6,40,27.4 C40,29.9,37.9,32,35.4,32 L32,32 C29.4,32,27.3,29.9,27.3,27.3 L27.3,21.4 C27.3,18.4,29.7,16,32.7,16 Z" class="wing"/>
37
+
38
+ <!-- Body -->
39
+ <path d="M17,29 L33,29 C33,34.5,28.5,39,23,39 C19.7,39,17,36.3,17,33 Z" class="body"/>
40
+
41
+ <!-- Feet -->
42
+ <path d="M20,43 L18,41 L16,43" class="feet"/>
43
+ <path d="M32,43 L30,41 L28,43" class="feet"/>
44
+
45
+ <!-- Rain lines (the storm is passing) -->
46
+ <path d="M35,35 L32.2,35 L32.2,37.8" class="feet"/>
47
+
48
+ <!-- Head/Screen -->
49
+ <rect x="6" y="6" width="30" height="23" rx="4" class="screen"/>
50
+
51
+ <!-- Nose line -->
52
+ <line x1="21" y1="11" x2="21" y2="23" class="outline"/>
53
+
54
+ <!-- Eyes — simple lines, owl is calm/confident -->
55
+ <line x1="11" y1="16" x2="17" y2="16" class="eye-line"/>
56
+ <line x1="25" y1="16" x2="31" y2="16" class="eye-line"/>
57
+
58
+ <!-- Code braces on forehead — { } -->
59
+ <path d="M13,8 C11.5,8 11,9 11,10 C11,11 10.5,11.5 10,11.5 C10.5,11.5 11,12 11,13 C11,14 11.5,15 13,15" class="code"/>
60
+ <path d="M29,8 C30.5,8 31,9 31,10 C31,11 31.5,11.5 32,11.5 C31.5,11.5 31,12 31,13 C31,14 30.5,15 29,15" class="code"/>
61
+ </svg>
@@ -0,0 +1,114 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 350" font-family="system-ui, -apple-system, sans-serif">
2
+ <style>
3
+ /* TJS Brand Palette (from icon + Lottie animation) */
4
+ :root {
5
+ --blue: #3da8f4;
6
+ --navy: #181340;
7
+ --yellow: #fbed21;
8
+ --amber: #fdbe52;
9
+ --red: #ff1c24;
10
+ --green: #006736;
11
+ --gray-light: #e4e4e4;
12
+ --gray-mid: #9e9e9e;
13
+ }
14
+
15
+ .bg { fill: #fafafa; stroke: #e4e4e4; }
16
+ .title-bar { fill: #181340; }
17
+ .title-text { fill: white; font-size: 20px; font-weight: 700; }
18
+
19
+ .col-bg { fill: white; stroke: #e4e4e4; }
20
+ .col-header { fill: #3da8f4; }
21
+ .col-header-text { fill: white; font-size: 14px; font-weight: 600; }
22
+
23
+ .box-ts { fill: #fff3f3; stroke: #ff1c24; }
24
+ .box-ts text { fill: #cc1118; }
25
+ .box-tjs { fill: #f0fff5; stroke: #006736; }
26
+ .box-tjs text { fill: #005028; }
27
+ .box-js { fill: #fffbe6; stroke: #fdbe52; }
28
+ .box-js text { fill: #8b6914; }
29
+ .box-neutral { fill: #f5f5f5; stroke: #9e9e9e; }
30
+ .box-neutral text { fill: #444; }
31
+ .box-safe { fill: #eef6ff; stroke: #3da8f4; }
32
+ .box-safe text { fill: #1a6ab5; }
33
+
34
+ .arrow-text { fill: #9e9e9e; font-size: 18px; }
35
+ .label { font-size: 13px; font-weight: 500; }
36
+ .label-bold { font-size: 13px; font-weight: 600; }
37
+ .label-sm { font-size: 10px; }
38
+ .label-lg { font-size: 12px; font-weight: 500; }
39
+
40
+ .shadow { filter: drop-shadow(0 2px 3px rgba(0,0,0,0.1)); }
41
+ </style>
42
+
43
+ <!-- Background -->
44
+ <rect width="720" height="340" rx="12" class="bg"/>
45
+
46
+ <!-- Title bar -->
47
+ <rect width="720" height="48" rx="12" class="title-bar"/>
48
+ <rect y="36" width="720" height="12" class="title-bar"/>
49
+ <text x="360" y="32" text-anchor="middle" class="title-text">TJS Platform</text>
50
+
51
+ <!-- Column: Language -->
52
+ <g class="shadow">
53
+ <rect x="20" y="68" width="220" height="262" rx="8" class="col-bg"/>
54
+ </g>
55
+ <rect x="20" y="68" width="220" height="36" rx="8" class="col-header"/>
56
+ <rect x="20" y="92" width="220" height="12" class="col-header"/>
57
+ <text x="130" y="92" text-anchor="middle" class="col-header-text">Language</text>
58
+
59
+ <g class="box-ts"><rect x="52" y="120" width="156" height="32" rx="6"/></g>
60
+ <text x="130" y="141" text-anchor="middle" class="label" fill="#cc1118">TypeScript</text>
61
+
62
+ <text x="130" y="166" text-anchor="middle" class="arrow-text">&#x2193;</text>
63
+
64
+ <g class="box-tjs"><rect x="52" y="178" width="156" height="32" rx="6"/></g>
65
+ <text x="130" y="199" text-anchor="middle" class="label-bold" fill="#005028">TJS</text>
66
+
67
+ <text x="130" y="228" text-anchor="middle" class="arrow-text">&#x2193;</text>
68
+
69
+ <g class="box-js"><rect x="52" y="240" width="156" height="32" rx="6"/></g>
70
+ <text x="130" y="261" text-anchor="middle" class="label" fill="#8b6914">JavaScript</text>
71
+
72
+ <!-- Column: Runtime -->
73
+ <g class="shadow">
74
+ <rect x="250" y="68" width="220" height="262" rx="8" class="col-bg"/>
75
+ </g>
76
+ <rect x="250" y="68" width="220" height="36" rx="8" class="col-header"/>
77
+ <rect x="250" y="92" width="220" height="12" class="col-header"/>
78
+ <text x="360" y="92" text-anchor="middle" class="col-header-text">Runtime</text>
79
+
80
+ <g class="box-neutral"><rect x="282" y="120" width="156" height="32" rx="6"/></g>
81
+ <text x="360" y="141" text-anchor="middle" class="label" fill="#444">__tjs metadata</text>
82
+
83
+ <text x="360" y="166" text-anchor="middle" class="arrow-text">&#x2193;</text>
84
+
85
+ <g class="box-neutral"><rect x="282" y="178" width="156" height="32" rx="6"/></g>
86
+ <text x="360" y="199" text-anchor="middle" class="label" fill="#444">Runtime Validation</text>
87
+
88
+ <text x="360" y="228" text-anchor="middle" class="arrow-text">&#x2193;</text>
89
+
90
+ <g class="box-neutral"><rect x="282" y="240" width="156" height="32" rx="6"/></g>
91
+ <text x="360" y="261" text-anchor="middle" class="label" fill="#444">Auto Documentation</text>
92
+
93
+ <!-- Column: Safe Execution -->
94
+ <g class="shadow">
95
+ <rect x="480" y="68" width="220" height="262" rx="8" class="col-bg"/>
96
+ </g>
97
+ <rect x="480" y="68" width="220" height="36" rx="8" class="col-header"/>
98
+ <rect x="480" y="92" width="220" height="12" class="col-header"/>
99
+ <text x="590" y="92" text-anchor="middle" class="col-header-text">Safe Execution</text>
100
+
101
+ <g class="box-safe"><rect x="512" y="120" width="156" height="32" rx="6"/></g>
102
+ <text x="590" y="141" text-anchor="middle" class="label" fill="#1a6ab5">AJS Agent</text>
103
+
104
+ <text x="590" y="166" text-anchor="middle" class="arrow-text">&#x2193;</text>
105
+
106
+ <g class="box-neutral"><rect x="512" y="178" width="156" height="32" rx="6"/></g>
107
+ <text x="590" y="199" text-anchor="middle" class="label" fill="#444">JSON AST</text>
108
+
109
+ <text x="590" y="228" text-anchor="middle" class="arrow-text">&#x2193;</text>
110
+
111
+ <g class="box-tjs"><rect x="512" y="236" width="156" height="44" rx="6"/></g>
112
+ <text x="590" y="255" text-anchor="middle" class="label-lg" fill="#005028">Gas-Limited VM</text>
113
+ <text x="590" y="270" text-anchor="middle" class="label-sm" fill="#005028">+ Injected Capabilities</text>
114
+ </svg>
@@ -0,0 +1,147 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 420" font-family="system-ui, -apple-system, sans-serif">
2
+ <style>
3
+ /* TJS Brand Palette */
4
+ .bg { fill: #fafafa; stroke: #e4e4e4; }
5
+
6
+ .box-untrusted { fill: #fff3f3; stroke: #ff1c24; stroke-width: 1.5; }
7
+ .box-cap { fill: #f5f5f5; stroke: #9e9e9e; }
8
+ .box-granted { fill: #f0fff5; stroke: #006736; stroke-width: 1.5; }
9
+ .box-blocked { fill: #fff3f3; stroke: #ff1c24; stroke-width: 1.5; }
10
+
11
+ .diamond { fill: #fffbe6; stroke: #fdbe52; stroke-width: 1.2; }
12
+ .diamond-text { fill: #8b6914; font-size: 10px; font-weight: 500; }
13
+
14
+ .arrow { stroke: #9e9e9e; stroke-width: 1.2; fill: none; }
15
+ .branch { stroke: #9e9e9e; stroke-width: 1.2; fill: none; }
16
+ .line-yes { stroke: #006736; stroke-width: 1.2; }
17
+ .line-no { stroke: #ff1c24; stroke-width: 1.2; }
18
+
19
+ .text-untrusted { fill: #cc1118; font-size: 14px; font-weight: 600; }
20
+ .text-cap { fill: #444; font-size: 12px; font-family: monospace; }
21
+ .text-granted { fill: #005028; font-size: 11px; font-weight: 500; }
22
+ .text-granted-mono { fill: #005028; font-size: 11px; font-family: monospace; font-weight: 500; }
23
+ .text-blocked { fill: #cc1118; font-size: 12px; font-weight: 600; }
24
+ .text-yes { fill: #006736; font-size: 9px; font-weight: 600; }
25
+ .text-no { fill: #ff1c24; font-size: 9px; font-weight: 600; }
26
+
27
+ .legend-bg { fill: white; stroke: #e4e4e4; }
28
+ .legend-title { fill: #181340; font-size: 11px; font-weight: 600; }
29
+ .legend-text { fill: #444; font-size: 11px; }
30
+ .legend-dot-yes { fill: #f0fff5; stroke: #006736; stroke-width: 1.2; }
31
+ .legend-dot-no { fill: #fff3f3; stroke: #ff1c24; stroke-width: 1.2; }
32
+
33
+ .shadow { filter: drop-shadow(0 2px 3px rgba(0,0,0,0.1)); }
34
+
35
+ .ah { fill: #9e9e9e; }
36
+ .ah-no { fill: #ff1c24; }
37
+ </style>
38
+
39
+ <defs>
40
+ <marker id="a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
41
+ <path d="M0 0 L10 5 L0 10z" class="ah"/>
42
+ </marker>
43
+ <marker id="an" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
44
+ <path d="M0 0 L10 5 L0 10z" class="ah-no"/>
45
+ </marker>
46
+ </defs>
47
+
48
+ <rect width="600" height="420" rx="12" class="bg"/>
49
+
50
+ <!-- Untrusted Code -->
51
+ <g id="node-untrusted" class="node shadow">
52
+ <rect x="210" y="16" width="180" height="40" rx="8" class="box-untrusted"/>
53
+ <text x="300" y="41" text-anchor="middle" class="text-untrusted">Untrusted Code</text>
54
+ </g>
55
+
56
+ <!-- Trunk -->
57
+ <line x1="300" y1="56" x2="300" y2="86" class="arrow"/>
58
+
59
+ <!-- Branches -->
60
+ <line x1="300" y1="86" x2="80" y2="120" class="branch"/>
61
+ <line x1="300" y1="86" x2="230" y2="120" class="branch"/>
62
+ <line x1="300" y1="86" x2="370" y2="120" class="branch"/>
63
+ <line x1="300" y1="86" x2="520" y2="120" class="branch"/>
64
+
65
+ <!-- Capability boxes -->
66
+ <rect x="30" y="120" width="100" height="32" rx="6" class="box-cap"/>
67
+ <text x="80" y="140" text-anchor="middle" class="text-cap">fetch()</text>
68
+
69
+ <rect x="180" y="120" width="100" height="32" rx="6" class="box-cap"/>
70
+ <text x="230" y="140" text-anchor="middle" class="text-cap">fs.read()</text>
71
+
72
+ <rect x="320" y="120" width="100" height="32" rx="6" class="box-cap"/>
73
+ <text x="370" y="140" text-anchor="middle" class="text-cap">loop</text>
74
+
75
+ <rect x="470" y="120" width="100" height="32" rx="6" class="box-cap"/>
76
+ <text x="520" y="140" text-anchor="middle" class="text-cap">console</text>
77
+
78
+ <!-- Arrows to diamonds -->
79
+ <line x1="80" y1="152" x2="80" y2="182" class="arrow" marker-end="url(#a)"/>
80
+ <line x1="230" y1="152" x2="230" y2="182" class="arrow" marker-end="url(#a)"/>
81
+ <line x1="370" y1="152" x2="370" y2="182" class="arrow" marker-end="url(#a)"/>
82
+ <line x1="520" y1="152" x2="520" y2="182" class="arrow" marker-end="url(#a)"/>
83
+
84
+ <!-- Diamonds -->
85
+ <polygon points="80,186 120,206 80,226 40,206" class="diamond"/>
86
+ <text x="80" y="210" text-anchor="middle" class="diamond-text">Granted?</text>
87
+
88
+ <polygon points="230,186 270,206 230,226 190,206" class="diamond"/>
89
+ <text x="230" y="210" text-anchor="middle" class="diamond-text">Granted?</text>
90
+
91
+ <polygon points="370,186 414,206 370,226 326,206" class="diamond"/>
92
+ <text x="370" y="210" text-anchor="middle" class="diamond-text">Fuel left?</text>
93
+
94
+ <polygon points="520,186 560,206 520,226 480,206" class="diamond"/>
95
+ <text x="520" y="210" text-anchor="middle" class="diamond-text">Granted?</text>
96
+
97
+ <!-- fetch: Y -> safeFetch -->
98
+ <line x1="55" y1="216" x2="20" y2="250" class="line-yes"/>
99
+ <text x="28" y="238" class="text-yes">Y</text>
100
+
101
+ <g class="shadow">
102
+ <rect x="0" y="254" width="110" height="44" rx="6" class="box-granted"/>
103
+ </g>
104
+ <text x="55" y="272" text-anchor="middle" class="text-granted">Your</text>
105
+ <text x="55" y="286" text-anchor="middle" class="text-granted-mono">safeFetch</text>
106
+
107
+ <!-- fetch: N -> Block -->
108
+ <line x1="105" y1="216" x2="135" y2="250" class="line-no"/>
109
+ <text x="127" y="238" class="text-no">N</text>
110
+
111
+ <rect x="115" y="254" width="70" height="28" rx="6" class="box-blocked"/>
112
+ <text x="150" y="273" text-anchor="middle" class="text-blocked">Block</text>
113
+
114
+ <!-- fs.read: N -> Block -->
115
+ <line x1="230" y1="226" x2="230" y2="250" class="line-no" marker-end="url(#an)"/>
116
+ <text x="240" y="242" class="text-no">N</text>
117
+ <rect x="195" y="254" width="70" height="28" rx="6" class="box-blocked"/>
118
+ <text x="230" y="273" text-anchor="middle" class="text-blocked">Block</text>
119
+
120
+ <!-- loop: Y -> Continue -->
121
+ <line x1="345" y1="216" x2="315" y2="250" class="line-yes"/>
122
+ <text x="322" y="238" class="text-yes">Y</text>
123
+ <rect x="285" y="254" width="80" height="28" rx="6" class="box-granted"/>
124
+ <text x="325" y="273" text-anchor="middle" class="text-granted">Continue</text>
125
+
126
+ <!-- loop: N -> Halt -->
127
+ <line x1="395" y1="216" x2="420" y2="250" class="line-no"/>
128
+ <text x="415" y="238" class="text-no">N</text>
129
+ <rect x="400" y="254" width="60" height="28" rx="6" class="box-blocked"/>
130
+ <text x="430" y="273" text-anchor="middle" class="text-blocked">Halt</text>
131
+
132
+ <!-- console: N -> Block -->
133
+ <line x1="520" y1="226" x2="520" y2="250" class="line-no" marker-end="url(#an)"/>
134
+ <text x="530" y="242" class="text-no">N</text>
135
+ <rect x="485" y="254" width="70" height="28" rx="6" class="box-blocked"/>
136
+ <text x="520" y="273" text-anchor="middle" class="text-blocked">Block</text>
137
+
138
+ <!-- Legend -->
139
+ <rect x="130" y="320" width="340" height="80" rx="8" class="legend-bg"/>
140
+ <text x="300" y="342" text-anchor="middle" class="legend-title">Capability-Based Security</text>
141
+
142
+ <circle cx="165" cy="362" r="6" class="legend-dot-yes"/>
143
+ <text x="180" y="366" class="legend-text">Granted = your wrapper runs</text>
144
+
145
+ <circle cx="165" cy="384" r="6" class="legend-dot-no"/>
146
+ <text x="180" y="388" class="legend-text">Not granted = silently blocked</text>
147
+ </svg>