@clawdreyhepburn/carapace 0.3.1 → 0.3.3
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/CHANGELOG.md +21 -0
- package/README.md +36 -1
- package/dist/cedar-engine-cedarling.d.ts +81 -0
- package/dist/cedar-engine-cedarling.js +651 -0
- package/dist/cedar-engine-cedarling.js.map +1 -0
- package/dist/cedar-engine.d.ts +77 -0
- package/dist/cedar-engine.js +374 -0
- package/dist/cedar-engine.js.map +1 -0
- package/dist/gui/html.d.ts +5 -0
- package/dist/gui/html.js +930 -0
- package/dist/gui/html.js.map +1 -0
- package/dist/gui/server.d.ts +28 -0
- package/dist/gui/server.js +159 -0
- package/dist/gui/server.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +584 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-proxy.d.ts +75 -0
- package/dist/llm-proxy.js +565 -0
- package/dist/llm-proxy.js.map +1 -0
- package/dist/mcp-aggregator.d.ts +29 -0
- package/dist/mcp-aggregator.js +144 -0
- package/dist/mcp-aggregator.js.map +1 -0
- package/dist/policy-source.d.ts +26 -0
- package/dist/policy-source.js +28 -0
- package/dist/policy-source.js.map +1 -0
- package/dist/types.d.ts +135 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/docs/carapace_proxy_tool_filter_flow_v3.svg +96 -0
- package/docs/ungated_ai_agent_capabilities.svg +143 -0
- package/package.json +1 -1
- package/src/cedar-engine-cedarling.ts +4 -0
- package/src/cedar-engine.ts +4 -0
- package/src/gui/html.ts +28 -3
- package/src/gui/server.ts +8 -1
- package/src/index.ts +12 -0
- package/src/policy-source.ts +44 -0
- package/src/types.ts +1 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<svg width="100%" viewBox="0 0 680 530" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
|
|
4
|
+
<path d="M2 1L8 5L2 9" fill="none" stroke="context-stroke" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</marker>
|
|
6
|
+
|
|
7
|
+
<mask id="imagine-text-gaps-jxkk9e" maskUnits="userSpaceOnUse"><rect x="0" y="0" width="680" height="530" fill="white"/><rect x="239.10523986816406" y="281.2499084472656" width="61.78950119018555" height="20.055686950683594" fill="black" rx="2"/><rect x="244" y="77.55548095703125" width="20.041765213012695" height="15.805651664733887" fill="black" rx="2"/><rect x="253.52288818359375" y="111.13880157470703" width="32.95419692993164" height="17.69455623626709" fill="black" rx="2"/><rect x="1.6765971183776855" y="8.388834953308105" width="20.646804809570312" height="12.027843475341797" fill="black" rx="2"/><rect x="425.48876953125" y="141.13880920410156" width="59.022552490234375" height="17.69455623626709" fill="black" rx="2"/><rect x="497.76171875" y="273.1387939453125" width="58.476539611816406" height="17.69455623626709" fill="black" rx="2"/><rect x="421.37786865234375" y="377.1387939453125" width="57.244327545166016" height="17.69455623626709" fill="black" rx="2"/><rect x="253.9434814453125" y="435.1387939453125" width="32.11304473876953" height="17.69455623626709" fill="black" rx="2"/><rect x="61.91438293457031" y="273.1387939453125" width="36.17123794555664" height="17.69455623626709" fill="black" rx="2"/><rect x="6" y="4.083252429962158" width="20.10817241668701" height="16.277877807617188" fill="black" rx="2"/><rect x="6" y="16.083251953125" width="41.69038009643555" height="16.277877807617188" fill="black" rx="2"/></mask></defs>
|
|
8
|
+
|
|
9
|
+
<!-- Dark background -->
|
|
10
|
+
<rect width="680" height="520" fill="#0a0a0a" style="fill:rgb(10, 10, 10);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
11
|
+
|
|
12
|
+
<!-- Subtle grid texture -->
|
|
13
|
+
<g opacity="0.04" stroke="#c4a87c" stroke-width="0.5" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.04;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
|
|
14
|
+
<line x1="0" y1="80" x2="680" y2="80" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
15
|
+
<line x1="0" y1="160" x2="680" y2="160" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
16
|
+
<line x1="0" y1="240" x2="680" y2="240" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
17
|
+
<line x1="0" y1="320" x2="680" y2="320" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
18
|
+
<line x1="0" y1="400" x2="680" y2="400" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
19
|
+
<line x1="0" y1="480" x2="680" y2="480" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
20
|
+
<line x1="80" y1="0" x2="80" y2="520" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
21
|
+
<line x1="160" y1="0" x2="160" y2="520" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
22
|
+
<line x1="240" y1="0" x2="240" y2="520" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
23
|
+
<line x1="320" y1="0" x2="320" y2="520" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
24
|
+
<line x1="400" y1="0" x2="400" y2="520" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
25
|
+
<line x1="480" y1="0" x2="480" y2="520" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
26
|
+
<line x1="560" y1="0" x2="560" y2="520" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
27
|
+
<line x1="640" y1="0" x2="640" y2="520" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
28
|
+
</g>
|
|
29
|
+
|
|
30
|
+
<!-- ====== AGENT CENTER ====== -->
|
|
31
|
+
<!-- Agent circle bg -->
|
|
32
|
+
<circle cx="270" cy="260" r="44" fill="#0f0d07" stroke="#c4a87c" stroke-width="1" opacity="0.9" style="fill:rgb(15, 13, 7);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
33
|
+
<!-- Robot head -->
|
|
34
|
+
<rect x="254" y="236" width="32" height="24" rx="4" style="fill:rgb(26, 21, 8);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.3px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
35
|
+
<!-- Robot eyes -->
|
|
36
|
+
<circle cx="263" cy="246" r="3" fill="#c4a87c" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
37
|
+
<circle cx="277" cy="246" r="3" fill="#c4a87c" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
38
|
+
<!-- Robot mouth -->
|
|
39
|
+
<rect x="261" y="253" width="14" height="3" rx="1" fill="#c4a87c" opacity="0.6" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.6;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
40
|
+
<!-- Antenna -->
|
|
41
|
+
<line x1="270" y1="236" x2="270" y2="228" stroke="#c4a87c" stroke-width="1.2" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
42
|
+
<circle cx="270" cy="225" r="3" fill="#c4a87c" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
43
|
+
<!-- Robot body -->
|
|
44
|
+
<rect x="256" y="262" width="28" height="18" rx="3" style="fill:rgb(26, 21, 8);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.3px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
45
|
+
<!-- Body slots -->
|
|
46
|
+
<rect x="260" y="266" width="7" height="3" rx="1" fill="#c4a87c" opacity="0.5" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.5;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
47
|
+
<rect x="270" y="266" width="7" height="3" rx="1" fill="#c4a87c" opacity="0.5" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.5;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
48
|
+
<!-- Agent label -->
|
|
49
|
+
<text x="270" y="296" text-anchor="middle" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:13px;font-weight:500;text-anchor:middle;dominant-baseline:auto">AI Agent</text>
|
|
50
|
+
|
|
51
|
+
<!-- ====== ARROWS (all same style, radiating out) ====== -->
|
|
52
|
+
<!-- Top -->
|
|
53
|
+
<line x1="270" y1="216" x2="270" y2="112" marker-end="url(#arrow)" stroke="#c4a87c" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:none;stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
54
|
+
<!-- Top-right (cloud API) -->
|
|
55
|
+
<line x1="301" y1="236" x2="450" y2="142" marker-end="url(#arrow)" stroke="#c4a87c" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:none;stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
56
|
+
<!-- Right (payments) -->
|
|
57
|
+
<line x1="314" y1="260" x2="498" y2="260" marker-end="url(#arrow)" stroke="#c4a87c" style="fill:none;stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
58
|
+
<!-- Bottom-right (database) -->
|
|
59
|
+
<line x1="301" y1="284" x2="450" y2="375" marker-end="url(#arrow)" stroke="#c4a87c" style="fill:none;stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
60
|
+
<!-- Bottom (files) -->
|
|
61
|
+
<line x1="270" y1="304" x2="270" y2="400" marker-end="url(#arrow)" stroke="#c4a87c" style="fill:none;stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
62
|
+
<!-- Left (email) -->
|
|
63
|
+
<line x1="226" y1="260" x2="100" y2="260" marker-end="url(#arrow)" stroke="#c4a87c" style="fill:none;stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
64
|
+
|
|
65
|
+
<!-- ====== CAPABILITY ICONS ====== -->
|
|
66
|
+
|
|
67
|
+
<!-- TOP: Terminal / Shell -->
|
|
68
|
+
<rect x="240" y="72" width="60" height="40" rx="5" fill="#0f0d07" stroke="#c4a87c" stroke-width="0.8" opacity="0.9" style="fill:rgb(15, 13, 7);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.8px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
69
|
+
<text x="248" y="89" font-family="monospace" font-size="10" fill="#c4a87c" opacity="0.7" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.7;font-family:monospace;font-size:10px;font-weight:400;text-anchor:start;dominant-baseline:auto">$_</text>
|
|
70
|
+
<line x1="247" y1="94" x2="291" y2="94" stroke="#c4a87c" stroke-width="0.6" opacity="0.3" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.6px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.3;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
71
|
+
<line x1="247" y1="99" x2="278" y2="99" stroke="#c4a87c" stroke-width="0.6" opacity="0.3" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.6px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.3;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
72
|
+
<text x="270" y="124" text-anchor="middle" style="fill:rgb(138, 130, 120);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:11px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Shell</text>
|
|
73
|
+
|
|
74
|
+
<!-- TOP-RIGHT: Cloud API -->
|
|
75
|
+
<!-- Cloud shape -->
|
|
76
|
+
<g transform="translate(430, 118)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
|
|
77
|
+
<path d="M8 22 Q3 22 2 17 Q-1 16 0 12 Q0 8 5 7 Q6 2 12 2 Q18 2 20 7 Q24 7 24 12 Q25 17 20 18 Q20 22 15 22 Z" fill="#0f0d07" stroke="#c4a87c" stroke-width="0.8" opacity="0.9" style="fill:rgb(15, 13, 7);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.8px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
78
|
+
<!-- API label inside cloud area -->
|
|
79
|
+
<text x="12" y="17" font-family="monospace" font-size="7" fill="#c4a87c" text-anchor="middle" opacity="0.8" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.8;font-family:monospace;font-size:7px;font-weight:400;text-anchor:middle;dominant-baseline:auto">API</text>
|
|
80
|
+
</g>
|
|
81
|
+
<text x="455" y="154" text-anchor="middle" style="fill:rgb(138, 130, 120);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:11px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Cloud API</text>
|
|
82
|
+
|
|
83
|
+
<!-- RIGHT: Credit card / Payments -->
|
|
84
|
+
<g transform="translate(504, 240)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
|
|
85
|
+
<rect x="0" y="-14" width="42" height="28" rx="4" fill="#0f0d07" stroke="#c4a87c" stroke-width="0.8" opacity="0.9" style="fill:rgb(15, 13, 7);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.8px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
86
|
+
<line x1="0" y1="-6" x2="42" y2="-6" stroke="#c4a87c" stroke-width="1.5" opacity="0.6" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:1.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.6;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
87
|
+
<rect x="4" y="2" width="8" height="5" rx="1" fill="#c4a87c" opacity="0.4" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.4;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
88
|
+
<rect x="15" y="3" width="16" height="2" rx="1" fill="#c4a87c" opacity="0.25" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.25;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
89
|
+
<rect x="15" y="7" width="10" height="2" rx="1" fill="#c4a87c" opacity="0.2" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.2;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
90
|
+
</g>
|
|
91
|
+
<text x="527" y="286" text-anchor="middle" style="fill:rgb(138, 130, 120);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:11px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Payments</text>
|
|
92
|
+
|
|
93
|
+
<!-- BOTTOM-RIGHT: Database -->
|
|
94
|
+
<g transform="translate(430, 360)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
|
|
95
|
+
<ellipse cx="14" cy="5" rx="14" ry="5" fill="#0f0d07" stroke="#c4a87c" stroke-width="0.8" opacity="0.9" style="fill:rgb(15, 13, 7);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.8px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
96
|
+
<path d="M0 5 Q0 14 14 14 Q28 14 28 5" fill="#0f0d07" stroke="#c4a87c" stroke-width="0.8" opacity="0.9" style="fill:rgb(15, 13, 7);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.8px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
97
|
+
<line x1="0" y1="9" x2="28" y2="9" stroke="#c4a87c" stroke-width="0.5" opacity="0.35" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.35;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
98
|
+
<ellipse cx="14" cy="9" rx="14" ry="3.5" fill="none" stroke="#c4a87c" stroke-width="0.5" opacity="0.25" style="fill:none;stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.25;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
99
|
+
</g>
|
|
100
|
+
<text x="450" y="390" text-anchor="middle" style="fill:rgb(138, 130, 120);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:11px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Database</text>
|
|
101
|
+
|
|
102
|
+
<!-- BOTTOM: File folder -->
|
|
103
|
+
<g transform="translate(247, 400)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
|
|
104
|
+
<path d="M0 8 Q0 0 8 0 L16 0 Q18 0 20 4 L42 4 Q46 4 46 8 L46 30 Q46 34 42 34 L4 34 Q0 34 0 30 Z" fill="#0f0d07" stroke="#c4a87c" stroke-width="0.8" opacity="0.9" style="fill:rgb(15, 13, 7);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.8px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
105
|
+
<line x1="4" y1="12" x2="42" y2="12" stroke="#c4a87c" stroke-width="0.5" opacity="0.3" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.3;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
106
|
+
<line x1="6" y1="18" x2="36" y2="18" stroke="#c4a87c" stroke-width="0.4" opacity="0.2" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.4px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.2;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
107
|
+
<line x1="6" y1="23" x2="30" y2="23" stroke="#c4a87c" stroke-width="0.4" opacity="0.2" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.4px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.2;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
108
|
+
</g>
|
|
109
|
+
<text x="270" y="448" text-anchor="middle" style="fill:rgb(138, 130, 120);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:11px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Files</text>
|
|
110
|
+
|
|
111
|
+
<!-- LEFT: Envelope / Email -->
|
|
112
|
+
<g transform="translate(58, 240)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
|
|
113
|
+
<rect x="0" y="-16" width="42" height="28" rx="3" fill="#0f0d07" stroke="#c4a87c" stroke-width="0.8" opacity="0.9" style="fill:rgb(15, 13, 7);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.8px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.9;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
114
|
+
<path d="M0 -16 L21 2 L42 -16" fill="none" stroke="#c4a87c" stroke-width="0.8" opacity="0.7" style="fill:none;stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.8px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.7;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
115
|
+
<line x1="0" y1="12" x2="14" y2="0" stroke="#c4a87c" stroke-width="0.6" opacity="0.3" mask="url(#imagine-text-gaps-jxkk9e)" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.6px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.3;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
116
|
+
<line x1="42" y1="12" x2="28" y2="0" stroke="#c4a87c" stroke-width="0.6" opacity="0.3" style="fill:rgb(0, 0, 0);stroke:rgb(196, 168, 124);color:rgb(0, 0, 0);stroke-width:0.6px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.3;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
117
|
+
</g>
|
|
118
|
+
<text x="80" y="286" text-anchor="middle" style="fill:rgb(138, 130, 120);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:11px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Email</text>
|
|
119
|
+
|
|
120
|
+
<!-- ====== POST-IT NOTE (slightly askew, near agent) ====== -->
|
|
121
|
+
<g transform="translate(164, 155) rotate(-6)" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
|
|
122
|
+
<!-- Drop shadow suggestion -->
|
|
123
|
+
<rect x="3" y="3" width="72" height="44" rx="2" fill="#000" opacity="0.35" style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.35;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
124
|
+
<!-- Post-it body -->
|
|
125
|
+
<rect x="0" y="0" width="72" height="44" rx="2" fill="#f5e642" style="fill:rgb(245, 230, 66);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
126
|
+
<!-- Tape strip at top -->
|
|
127
|
+
<rect x="22" y="-5" width="28" height="8" rx="2" fill="#d4c520" opacity="0.55" style="fill:rgb(212, 197, 32);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.55;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
128
|
+
<!-- Text lines -->
|
|
129
|
+
<text x="10" y="16" style="fill:rgb(42, 34, 24);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:10px;font-weight:500;text-anchor:start;dominant-baseline:auto">be</text>
|
|
130
|
+
<text x="10" y="28" style="fill:rgb(42, 34, 24);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", sans-serif;font-size:10px;font-weight:500;text-anchor:start;dominant-baseline:auto">careful</text>
|
|
131
|
+
<!-- Small doodle scribble -->
|
|
132
|
+
<path d="M10 36 Q30 34 50 37" fill="none" stroke="#2a2218" stroke-width="0.7" opacity="0.3" style="fill:none;stroke:rgb(42, 34, 24);color:rgb(0, 0, 0);stroke-width:0.7px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.3;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
133
|
+
</g>
|
|
134
|
+
|
|
135
|
+
<!-- Open "threat" glow dots on arrows to reinforce "everything is exposed" -->
|
|
136
|
+
<circle cx="270" cy="164" r="2.5" fill="#c4a87c" opacity="0.35" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.35;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
137
|
+
<circle cx="375" cy="189" r="2.5" fill="#c4a87c" opacity="0.35" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.35;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
138
|
+
<circle cx="406" cy="260" r="2.5" fill="#c4a87c" opacity="0.35" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.35;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
139
|
+
<circle cx="375" cy="329" r="2.5" fill="#c4a87c" opacity="0.35" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.35;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
140
|
+
<circle cx="270" cy="352" r="2.5" fill="#c4a87c" opacity="0.35" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.35;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
141
|
+
<circle cx="163" cy="260" r="2.5" fill="#c4a87c" opacity="0.35" style="fill:rgb(196, 168, 124);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:0.35;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
142
|
+
|
|
143
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -276,6 +276,10 @@ export class CedarlingEngine {
|
|
|
276
276
|
return true;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
getDefaultPolicy(): "deny-all" | "allow-all" {
|
|
280
|
+
return this.defaultPolicy;
|
|
281
|
+
}
|
|
282
|
+
|
|
279
283
|
getPolicies(): Array<{ id: string; effect: string; raw: string }> {
|
|
280
284
|
return [...this.policies.entries()].map(([id, p]) => ({ id, ...p }));
|
|
281
285
|
}
|
package/src/cedar-engine.ts
CHANGED
|
@@ -218,6 +218,10 @@ export class CedarEngine {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
/** Get all policies as raw text */
|
|
221
|
+
getDefaultPolicy(): "deny-all" | "allow-all" {
|
|
222
|
+
return this.defaultPolicy;
|
|
223
|
+
}
|
|
224
|
+
|
|
221
225
|
getPolicies(): Array<{ id: string; effect: string; raw: string }> {
|
|
222
226
|
return [...this.policies.values()].map((p) => ({
|
|
223
227
|
id: p.id,
|
package/src/gui/html.ts
CHANGED
|
@@ -339,9 +339,16 @@ export function guiHtml(): string {
|
|
|
339
339
|
</div>
|
|
340
340
|
</header>
|
|
341
341
|
|
|
342
|
+
<div id="not-enforcing-banner" style="display:none; background:#e8a735; color:#1a1a1a; padding:1rem 1.5rem; font-size:0.95rem; text-align:center; font-weight:500; line-height:1.6;">
|
|
343
|
+
⚠️ Carapace is loaded but <strong>not enforcing</strong>. No tools are gated and the LLM proxy is disabled.
|
|
344
|
+
Your agent is running without policy protection.<br>
|
|
345
|
+
To activate, run these two commands in your terminal:<br>
|
|
346
|
+
<code style="background:rgba(0,0,0,0.1); padding:0.3em 0.6em; border-radius:3px; display:inline-block; margin-top:0.3rem;">openclaw carapace setup && openclaw gateway restart</code>
|
|
347
|
+
</div>
|
|
348
|
+
|
|
342
349
|
<div class="container">
|
|
343
350
|
<div id="servers-section">
|
|
344
|
-
<h2>Servers</h2>
|
|
351
|
+
<h2>MCP Servers</h2>
|
|
345
352
|
<div class="servers" id="servers"></div>
|
|
346
353
|
</div>
|
|
347
354
|
|
|
@@ -533,6 +540,13 @@ export function guiHtml(): string {
|
|
|
533
540
|
function render() {
|
|
534
541
|
document.getElementById('total-count').textContent = state.toolCount ?? state.tools.length;
|
|
535
542
|
document.getElementById('enabled-count').textContent = state.enabledCount ?? state.tools.filter(t => t.enabled).length;
|
|
543
|
+
|
|
544
|
+
// Show/hide not-enforcing banner
|
|
545
|
+
const banner = document.getElementById('not-enforcing-banner');
|
|
546
|
+
if (banner) {
|
|
547
|
+
banner.style.display = state.notEnforcing ? 'block' : 'none';
|
|
548
|
+
}
|
|
549
|
+
|
|
536
550
|
renderServers();
|
|
537
551
|
renderTools();
|
|
538
552
|
renderPolicies();
|
|
@@ -540,8 +554,18 @@ export function guiHtml(): string {
|
|
|
540
554
|
}
|
|
541
555
|
|
|
542
556
|
function renderServers() {
|
|
557
|
+
const section = document.getElementById('servers-section');
|
|
543
558
|
const el = document.getElementById('servers');
|
|
544
559
|
const serverFilter = document.getElementById('server-filter');
|
|
560
|
+
const serverNames = Object.keys(state.servers);
|
|
561
|
+
|
|
562
|
+
// Hide entire section when no MCP servers are configured
|
|
563
|
+
if (serverNames.length === 0) {
|
|
564
|
+
section.style.display = 'none';
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
section.style.display = '';
|
|
568
|
+
|
|
545
569
|
el.innerHTML = Object.entries(state.servers).map(([name, s]) =>
|
|
546
570
|
'<div class="server-card"><div class="name">' +
|
|
547
571
|
'<span class="dot ' + (s.connected ? 'connected' : 'disconnected') + '"></span>' +
|
|
@@ -552,7 +576,7 @@ export function guiHtml(): string {
|
|
|
552
576
|
// Update server filter dropdown (preserve selection)
|
|
553
577
|
const prev = serverFilter.value;
|
|
554
578
|
serverFilter.innerHTML = '<option value="all">All servers</option>' +
|
|
555
|
-
|
|
579
|
+
serverNames.map(n => '<option value="' + esc(n) + '">' + esc(n) + '</option>').join('');
|
|
556
580
|
serverFilter.value = prev || 'all';
|
|
557
581
|
}
|
|
558
582
|
|
|
@@ -665,7 +689,8 @@ export function guiHtml(): string {
|
|
|
665
689
|
const el = document.getElementById('policies-list');
|
|
666
690
|
const policies = state.policies ?? [];
|
|
667
691
|
if (policies.length === 0) {
|
|
668
|
-
|
|
692
|
+
const mode = state.defaultPolicy === 'deny-all' ? 'Default deny is active — all tools are blocked.' : 'Default allow is active — all tools are permitted.';
|
|
693
|
+
el.innerHTML = '<div class="empty-state">No policies loaded. ' + mode + '<br><br>' +
|
|
669
694
|
'<button class="primary" onclick="openBuilder()">+ Create your first policy</button></div>';
|
|
670
695
|
return;
|
|
671
696
|
}
|
package/src/gui/server.ts
CHANGED
|
@@ -15,6 +15,7 @@ interface GuiOpts {
|
|
|
15
15
|
aggregator: McpAggregator;
|
|
16
16
|
cedar: CedarEngineInterface;
|
|
17
17
|
logger: Logger;
|
|
18
|
+
proxyEnabled?: boolean;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export class ControlGui {
|
|
@@ -23,12 +24,14 @@ export class ControlGui {
|
|
|
23
24
|
private cedar: CedarEngineInterface;
|
|
24
25
|
private logger: Logger;
|
|
25
26
|
private server: Server | null = null;
|
|
27
|
+
private proxyEnabled: boolean;
|
|
26
28
|
|
|
27
29
|
constructor(opts: GuiOpts) {
|
|
28
30
|
this.port = opts.port;
|
|
29
31
|
this.aggregator = opts.aggregator;
|
|
30
32
|
this.cedar = opts.cedar;
|
|
31
33
|
this.logger = opts.logger;
|
|
34
|
+
this.proxyEnabled = opts.proxyEnabled ?? false;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
async start(): Promise<void> {
|
|
@@ -60,12 +63,16 @@ export class ControlGui {
|
|
|
60
63
|
if (url.pathname === "/api/status" && req.method === "GET") {
|
|
61
64
|
const servers = this.aggregator.getServerStatus();
|
|
62
65
|
const tools = this.aggregator.listTools();
|
|
66
|
+
const enabledCount = tools.filter((t) => t.enabled).length;
|
|
63
67
|
this.json(res, {
|
|
64
68
|
servers,
|
|
65
69
|
tools,
|
|
66
70
|
policies: this.cedar.getPolicies(),
|
|
67
71
|
toolCount: tools.length,
|
|
68
|
-
enabledCount
|
|
72
|
+
enabledCount,
|
|
73
|
+
defaultPolicy: this.cedar.getDefaultPolicy?.() ?? "allow-all",
|
|
74
|
+
proxyEnabled: this.proxyEnabled,
|
|
75
|
+
notEnforcing: !this.proxyEnabled && enabledCount === 0,
|
|
69
76
|
});
|
|
70
77
|
return;
|
|
71
78
|
}
|
package/src/index.ts
CHANGED
|
@@ -63,6 +63,7 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
63
63
|
aggregator,
|
|
64
64
|
cedar,
|
|
65
65
|
logger,
|
|
66
|
+
proxyEnabled: !!proxyConfig?.enabled,
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
// --- LLM Proxy: intercept tool calls at the API level ---
|
|
@@ -197,6 +198,17 @@ export default function register(api: OpenClawPluginApi) {
|
|
|
197
198
|
);
|
|
198
199
|
}
|
|
199
200
|
}
|
|
201
|
+
|
|
202
|
+
// Warn if Carapace is loaded but not actually enforcing anything
|
|
203
|
+
const tools = aggregator.listTools();
|
|
204
|
+
const enabledCount = tools.filter((t: any) => t.enabled).length;
|
|
205
|
+
if (!proxy && enabledCount === 0) {
|
|
206
|
+
logger.warn(
|
|
207
|
+
`⚠️ Carapace is loaded but NOT ENFORCING. No tools are gated and the LLM proxy is disabled. ` +
|
|
208
|
+
`Your agent is running without policy protection. ` +
|
|
209
|
+
`Run "openclaw carapace setup" to activate enforcement, or configure policies at http://localhost:${config.guiPort ?? 19820}`
|
|
210
|
+
);
|
|
211
|
+
}
|
|
200
212
|
},
|
|
201
213
|
async stop() {
|
|
202
214
|
if (proxy) await proxy.stop();
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PolicySource — exposes Carapace's deployment-level Cedar policies
|
|
3
|
+
* so that OVID-ME can query the effective policy ceiling.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { readFileSync, readdirSync, existsSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Must match @clawdreyhepburn/ovid-me PolicySource interface.
|
|
12
|
+
*
|
|
13
|
+
* Kept as a local copy because ovid-me pulls in native dependencies
|
|
14
|
+
* (better-sqlite3) that would bloat Carapace's install. A type
|
|
15
|
+
* compatibility test in test/policy-source.test.ts guards against drift.
|
|
16
|
+
*
|
|
17
|
+
* Canonical definition: ovid-me/src/config.ts
|
|
18
|
+
*/
|
|
19
|
+
export interface PolicySource {
|
|
20
|
+
getEffectivePolicy(principal: string): Promise<string | null>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Reads all .cedar files from the policy directory and returns
|
|
25
|
+
* the concatenated policy text. Carapace policies are deployment-wide
|
|
26
|
+
* (not per-principal), so all policies apply to all principals.
|
|
27
|
+
*/
|
|
28
|
+
export class CarapacePolicySource implements PolicySource {
|
|
29
|
+
private policyDir: string;
|
|
30
|
+
|
|
31
|
+
constructor(policyDir?: string) {
|
|
32
|
+
this.policyDir = (policyDir ?? "~/.openclaw/mcp-policies/").replace("~", homedir());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async getEffectivePolicy(_principal: string): Promise<string | null> {
|
|
36
|
+
if (!existsSync(this.policyDir)) return null;
|
|
37
|
+
|
|
38
|
+
const files = readdirSync(this.policyDir).filter(f => f.endsWith(".cedar"));
|
|
39
|
+
if (files.length === 0) return null;
|
|
40
|
+
|
|
41
|
+
const policies = files.map(f => readFileSync(join(this.policyDir, f), "utf-8"));
|
|
42
|
+
return policies.join("\n\n");
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -105,6 +105,7 @@ export interface CedarEngineInterface {
|
|
|
105
105
|
isToolEnabled(qualifiedName: string): boolean;
|
|
106
106
|
savePolicy(id: string, raw: string): void;
|
|
107
107
|
deletePolicy(id: string): boolean;
|
|
108
|
+
getDefaultPolicy(): "deny-all" | "allow-all";
|
|
108
109
|
getPolicies(): Array<{ id: string; effect: string; raw: string }>;
|
|
109
110
|
getSchema(): CedarSchemaInfo;
|
|
110
111
|
saveSchema(raw: string): void;
|