@yiaany/ghostapi 0.1.9 → 0.2.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.
Files changed (292) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/CONTRIBUTING.md +132 -119
  3. package/LICENSE +21 -21
  4. package/PROVENANCE.md +13 -0
  5. package/README.md +78 -84
  6. package/SECURITY.md +56 -53
  7. package/dist/actions/gateway.js +320 -72
  8. package/dist/actions/gateway.js.map +1 -1
  9. package/dist/actions/index.d.ts +2 -2
  10. package/dist/actions/index.js +1 -1
  11. package/dist/actions/index.js.map +1 -1
  12. package/dist/agents/agentPrompt.js +7 -5
  13. package/dist/agents/agentPrompt.js.map +1 -1
  14. package/dist/ai/aiClient.js +5 -5
  15. package/dist/ai/aiClient.js.map +1 -1
  16. package/dist/ai/aiGenerator.js +66 -26
  17. package/dist/ai/aiGenerator.js.map +1 -1
  18. package/dist/ai/genericInference.js +151 -36
  19. package/dist/ai/genericInference.js.map +1 -1
  20. package/dist/ai/prompts.js +55 -49
  21. package/dist/ai/prompts.js.map +1 -1
  22. package/dist/approvals/approvalInbox.js +649 -133
  23. package/dist/approvals/approvalInbox.js.map +1 -1
  24. package/dist/approvals/index.d.ts +2 -2
  25. package/dist/approvals/index.js +1 -1
  26. package/dist/approvals/index.js.map +1 -1
  27. package/dist/behavior/behaviorStore.js +34 -14
  28. package/dist/behavior/behaviorStore.js.map +1 -1
  29. package/dist/cache/index.js +14 -5
  30. package/dist/cache/index.js.map +1 -1
  31. package/dist/cli/index.js +226 -93
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/openUrl.js +17 -3
  34. package/dist/cli/openUrl.js.map +1 -1
  35. package/dist/cli/parser.js +79 -18
  36. package/dist/cli/parser.js.map +1 -1
  37. package/dist/config/dataPaths.js +4 -2
  38. package/dist/config/dataPaths.js.map +1 -1
  39. package/dist/config/localConfig.js +5 -2
  40. package/dist/config/localConfig.js.map +1 -1
  41. package/dist/config/serverConfig.js +11 -5
  42. package/dist/config/serverConfig.js.map +1 -1
  43. package/dist/contracts/contract.js +311 -83
  44. package/dist/contracts/contract.js.map +1 -1
  45. package/dist/contracts/index.d.ts +2 -2
  46. package/dist/contracts/index.js +1 -1
  47. package/dist/contracts/index.js.map +1 -1
  48. package/dist/credentials/credentialBroker.js +391 -79
  49. package/dist/credentials/credentialBroker.js.map +1 -1
  50. package/dist/credentials/index.d.ts +2 -2
  51. package/dist/credentials/index.js +1 -1
  52. package/dist/credentials/index.js.map +1 -1
  53. package/dist/dashboard/app.js +823 -685
  54. package/dist/dashboard/dashboard.js.map +1 -1
  55. package/dist/dashboard/index.html +704 -267
  56. package/dist/dashboard/styles.css +1040 -349
  57. package/dist/egress/capabilities.js +55 -25
  58. package/dist/egress/capabilities.js.map +1 -1
  59. package/dist/egress/linuxBootstrap.js +47 -11
  60. package/dist/egress/linuxBootstrap.js.map +1 -1
  61. package/dist/egress/run.js +170 -31
  62. package/dist/egress/run.js.map +1 -1
  63. package/dist/errors/errorEngine.js +15 -3
  64. package/dist/errors/errorEngine.js.map +1 -1
  65. package/dist/errors/providerErrors.js.map +1 -1
  66. package/dist/evals/evals.js +304 -78
  67. package/dist/evals/evals.js.map +1 -1
  68. package/dist/evals/index.d.ts +2 -2
  69. package/dist/evals/index.js +1 -1
  70. package/dist/evals/index.js.map +1 -1
  71. package/dist/evidence/index.d.ts +2 -2
  72. package/dist/evidence/index.js +1 -1
  73. package/dist/evidence/index.js.map +1 -1
  74. package/dist/evidence/report.d.ts +1 -1
  75. package/dist/evidence/report.js +263 -79
  76. package/dist/evidence/report.js.map +1 -1
  77. package/dist/fault/faultLab.js +24 -9
  78. package/dist/fault/faultLab.js.map +1 -1
  79. package/dist/index.d.ts +42 -42
  80. package/dist/index.js +21 -21
  81. package/dist/index.js.map +1 -1
  82. package/dist/inventory/analysis.d.ts +1 -1
  83. package/dist/inventory/analysis.js +174 -50
  84. package/dist/inventory/analysis.js.map +1 -1
  85. package/dist/inventory/index.d.ts +4 -4
  86. package/dist/inventory/index.js +3 -3
  87. package/dist/inventory/index.js.map +1 -1
  88. package/dist/inventory/inventoryController.js +362 -115
  89. package/dist/inventory/inventoryController.js.map +1 -1
  90. package/dist/inventory/types.js +680 -140
  91. package/dist/inventory/types.js.map +1 -1
  92. package/dist/ledger/actionLedger.js +355 -78
  93. package/dist/ledger/actionLedger.js.map +1 -1
  94. package/dist/ledger/index.d.ts +2 -2
  95. package/dist/ledger/index.js +1 -1
  96. package/dist/ledger/index.js.map +1 -1
  97. package/dist/mcp/server.js +26 -11
  98. package/dist/mcp/server.js.map +1 -1
  99. package/dist/policy/index.d.ts +2 -2
  100. package/dist/policy/index.js +1 -1
  101. package/dist/policy/index.js.map +1 -1
  102. package/dist/policy/policy.js +112 -32
  103. package/dist/policy/policy.js.map +1 -1
  104. package/dist/productTelemetry/index.js +71 -20
  105. package/dist/productTelemetry/index.js.map +1 -1
  106. package/dist/providers/conformance.js +10 -5
  107. package/dist/providers/conformance.js.map +1 -1
  108. package/dist/providers/discord.js +2 -2
  109. package/dist/providers/generic.js +3 -3
  110. package/dist/providers/github.js +2 -2
  111. package/dist/providers/index.d.ts +3 -3
  112. package/dist/providers/index.js +2 -2
  113. package/dist/providers/index.js.map +1 -1
  114. package/dist/providers/openai.js +3 -3
  115. package/dist/providers/packs/resendPack.js +51 -25
  116. package/dist/providers/packs/resendPack.js.map +1 -1
  117. package/dist/providers/packs/stripePack.js +590 -121
  118. package/dist/providers/packs/stripePack.js.map +1 -1
  119. package/dist/providers/registry.js +4 -4
  120. package/dist/providers/registry.js.map +1 -1
  121. package/dist/providers/runtime.js +7 -6
  122. package/dist/providers/runtime.js.map +1 -1
  123. package/dist/providers/stripeWebhook.js +39 -10
  124. package/dist/providers/stripeWebhook.js.map +1 -1
  125. package/dist/providers/twilio.js +2 -2
  126. package/dist/proxy/cacheKey.js +9 -2
  127. package/dist/proxy/cacheKey.js.map +1 -1
  128. package/dist/proxy/providerDetector.js +22 -9
  129. package/dist/proxy/providerDetector.js.map +1 -1
  130. package/dist/proxy/proxyHandler.js +57 -22
  131. package/dist/proxy/proxyHandler.js.map +1 -1
  132. package/dist/proxy/requestNormalizer.js +4 -2
  133. package/dist/proxy/requestNormalizer.js.map +1 -1
  134. package/dist/reliability/costGovernance.js +211 -49
  135. package/dist/reliability/costGovernance.js.map +1 -1
  136. package/dist/reliability/index.d.ts +8 -8
  137. package/dist/reliability/index.js +4 -4
  138. package/dist/reliability/index.js.map +1 -1
  139. package/dist/reliability/reconciliation.js +274 -65
  140. package/dist/reliability/reconciliation.js.map +1 -1
  141. package/dist/reliability/runtimeHealth.js +127 -35
  142. package/dist/reliability/runtimeHealth.js.map +1 -1
  143. package/dist/reliability/slo.js +257 -50
  144. package/dist/reliability/slo.js.map +1 -1
  145. package/dist/report/safetyReport.d.ts +6 -0
  146. package/dist/report/safetyReport.js +56 -12
  147. package/dist/report/safetyReport.js.map +1 -1
  148. package/dist/rules/aiRules.js +5 -5
  149. package/dist/rules/aiRules.js.map +1 -1
  150. package/dist/safety/index.d.ts +2 -2
  151. package/dist/safety/index.js +1 -1
  152. package/dist/safety/index.js.map +1 -1
  153. package/dist/safety/safetyController.js +675 -165
  154. package/dist/safety/safetyController.js.map +1 -1
  155. package/dist/scenarios/scenarioBundle.js +204 -71
  156. package/dist/scenarios/scenarioBundle.js.map +1 -1
  157. package/dist/scenarios/scenarioStore.js +88 -29
  158. package/dist/scenarios/scenarioStore.js.map +1 -1
  159. package/dist/security/headerSanitizer.js +52 -10
  160. package/dist/security/headerSanitizer.js.map +1 -1
  161. package/dist/security/secrets.js +10 -5
  162. package/dist/security/secrets.js.map +1 -1
  163. package/dist/server/accessControl.js +37 -10
  164. package/dist/server/accessControl.js.map +1 -1
  165. package/dist/server/createServer.js +1 -1
  166. package/dist/server/createServer.js.map +1 -1
  167. package/dist/server/eventsStore.js +15 -5
  168. package/dist/server/eventsStore.js.map +1 -1
  169. package/dist/server/routes.js +61 -19
  170. package/dist/server/routes.js.map +1 -1
  171. package/dist/server/sse.js +1 -1
  172. package/dist/server/sse.js.map +1 -1
  173. package/dist/setup/sdkDetector.js +7 -2
  174. package/dist/setup/sdkDetector.js.map +1 -1
  175. package/dist/setup/setupGenerator.js +136 -48
  176. package/dist/setup/setupGenerator.js.map +1 -1
  177. package/dist/state/stateExtractor.js +3 -1
  178. package/dist/state/stateExtractor.js.map +1 -1
  179. package/dist/state/stateResolver.js +10 -7
  180. package/dist/state/stateResolver.js.map +1 -1
  181. package/dist/state/stateStore.js +13 -4
  182. package/dist/state/stateStore.js.map +1 -1
  183. package/dist/storage/fileStore.js +12 -4
  184. package/dist/storage/fileStore.js.map +1 -1
  185. package/dist/teamControl/controlPlane.js +846 -174
  186. package/dist/teamControl/controlPlane.js.map +1 -1
  187. package/dist/teamControl/deployment.js +19 -5
  188. package/dist/teamControl/deployment.js.map +1 -1
  189. package/dist/teamControl/index.d.ts +4 -4
  190. package/dist/teamControl/index.js +2 -2
  191. package/dist/teamControl/index.js.map +1 -1
  192. package/dist/tests/testGenerator.js +15 -7
  193. package/dist/tests/testGenerator.js.map +1 -1
  194. package/dist/trust/index.d.ts +2 -2
  195. package/dist/trust/index.js +1 -1
  196. package/dist/trust/index.js.map +1 -1
  197. package/dist/trust/trustLadder.js +309 -63
  198. package/dist/trust/trustLadder.js.map +1 -1
  199. package/dist/worlds/index.d.ts +2 -2
  200. package/dist/worlds/index.js +1 -1
  201. package/dist/worlds/index.js.map +1 -1
  202. package/dist/worlds/worlds.js +364 -65
  203. package/dist/worlds/worlds.js.map +1 -1
  204. package/docs/assets/dashboard.png +0 -0
  205. package/docs/ci.md +49 -49
  206. package/docs/github-actions.md +84 -84
  207. package/docs/mcp.md +58 -52
  208. package/docs/policy.md +63 -61
  209. package/docs/providers/authoring-packs.md +180 -175
  210. package/docs/providers/stripe-core-pack.md +84 -82
  211. package/docs/releases/README.md +13 -0
  212. package/docs/security/action-gateway-threat-model.md +34 -34
  213. package/docs/security/action-ledger-incident-replay-threat-model.md +42 -42
  214. package/docs/security/approval-inbox-threat-model.md +35 -35
  215. package/docs/security/credential-broker-threat-model.md +52 -52
  216. package/docs/security/egress-threat-model.md +126 -126
  217. package/docs/security/inventory-threat-model.md +104 -104
  218. package/docs/security/kill-switch-budgets-threat-model.md +37 -37
  219. package/docs/security/reliability-threat-model.md +111 -111
  220. package/docs/security/trust-ladder-threat-model.md +33 -33
  221. package/docs/telemetry.md +14 -0
  222. package/docs/usage.md +680 -571
  223. package/examples/README.md +10 -10
  224. package/examples/agent-instructions/README.md +39 -39
  225. package/examples/ci-smoke/README.md +21 -21
  226. package/examples/ci-smoke/ghostapi.policy.yaml +22 -22
  227. package/examples/ci-smoke/package.json +9 -9
  228. package/examples/ci-smoke/production-egress.mjs +4 -2
  229. package/examples/ci-smoke/safe.mjs +21 -17
  230. package/examples/evals/README.md +24 -24
  231. package/examples/evals/retry-after.eval.json +71 -52
  232. package/examples/generic-rest/README.md +27 -27
  233. package/examples/github-fetch/README.md +38 -35
  234. package/examples/openai-streaming/README.md +16 -16
  235. package/examples/openai-streaming/streaming-tool-call.mjs +44 -31
  236. package/examples/policy/ghostapi.policy.yaml +27 -27
  237. package/examples/record-replay/README.md +19 -19
  238. package/examples/record-replay/replay-requests.json +22 -22
  239. package/examples/record-replay/stripe-checkout.har.json +30 -30
  240. package/examples/resend-node/README.md +22 -22
  241. package/examples/stripe-node/README.md +35 -35
  242. package/examples/stripe-node/checkout-flow.mjs +87 -61
  243. package/examples/twilio-node/README.md +21 -21
  244. package/examples/worlds/README.md +19 -19
  245. package/examples/worlds/subscription-recovery.mjs +21 -12
  246. package/package.json +28 -6
  247. package/dist/landing/assets/index-BXR41fAD.css +0 -1
  248. package/dist/landing/assets/index-CxWsopzP.css +0 -1
  249. package/dist/landing/assets/index-D8_ggMRE.js +0 -55
  250. package/dist/landing/assets/index-DZlpyhqd.js +0 -55
  251. package/dist/landing/assets/index-Dk-Xezs3.js +0 -55
  252. package/dist/landing/index.html +0 -15
  253. package/dist/landing/landing.d.ts +0 -3
  254. package/dist/landing/landing.js +0 -12
  255. package/dist/landing/landing.js.map +0 -1
  256. package/docs/commercial/README.md +0 -29
  257. package/docs/commercial/data-inventory.md +0 -36
  258. package/docs/commercial/manual-invoicing.md +0 -44
  259. package/docs/commercial/metrics.md +0 -51
  260. package/docs/commercial/pricing.md +0 -103
  261. package/docs/commercial/privacy-policy-draft.md +0 -41
  262. package/docs/commercial/terms-topics-for-counsel.md +0 -51
  263. package/docs/design-partners/README.md +0 -52
  264. package/docs/design-partners/demo-narratives.md +0 -33
  265. package/docs/design-partners/design-partner-offer.md +0 -39
  266. package/docs/design-partners/discovery-questions.md +0 -28
  267. package/docs/design-partners/feedback-capture-template.md +0 -48
  268. package/docs/design-partners/icp-one-pager.md +0 -43
  269. package/docs/design-partners/onboarding-checklist.md +0 -33
  270. package/docs/design-partners/pilot-success-criteria.md +0 -27
  271. package/docs/design-partners/pricing-interview-script.md +0 -18
  272. package/docs/design-partners/telemetry-plan.md +0 -48
  273. package/docs/development/baseline.md +0 -114
  274. package/docs/development/onboarding-smoke.md +0 -37
  275. package/docs/development/verification-0.1.8.md +0 -25
  276. package/docs/enterprise-product-roadmap-ru.md +0 -1879
  277. package/docs/fundraising/README.md +0 -87
  278. package/docs/fundraising/data-room-checklist.md +0 -72
  279. package/docs/fundraising/demo-script.md +0 -52
  280. package/docs/fundraising/design-partners-50.md +0 -74
  281. package/docs/fundraising/launch-posts.md +0 -37
  282. package/docs/fundraising/metrics-and-evidence.md +0 -30
  283. package/docs/fundraising/roadmap-12-month.md +0 -25
  284. package/docs/fundraising/technical-due-diligence-index.md +0 -37
  285. package/docs/fundraising/yc-application.md +0 -25
  286. package/docs/hosted-pilot.md +0 -111
  287. package/docs/operations/disaster-recovery-runbook.md +0 -81
  288. package/docs/operations/kill-switch-runbook.md +0 -32
  289. package/docs/release-checklist.md +0 -83
  290. package/docs/release-migration-and-rollback.md +0 -63
  291. package/docs/release-readiness.md +0 -39
  292. package/docs/team-control-plane.md +0 -72
@@ -1,304 +1,741 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>GhostAPI Dashboard</title>
7
- <link rel="stylesheet" href="/dashboard/styles.css">
8
- <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>👻</text></svg>">
9
- </head>
10
- <body>
11
-
12
- <div class="app-wrapper">
13
-
14
- <!-- Left Nav Sidebar (Exact React replica) -->
15
- <aside class="sidebar" id="sidebar">
16
- <!-- Workspace Switcher -->
17
- <div class="ws-switcher">
18
- <div class="ws-btn" style="cursor: default">
19
- <div class="ws-btn-content">
20
- <div class="ws-avatar"><img src="/docs/assets/ghostapi-avatar.png" alt="GhostAPI Logo" style="width: 100%; height: 100%; object-fit: cover; border-radius: 4px;" /></div>
21
- <div class="ws-info">
22
- <span class="ws-title">GhostAPI.local</span>
23
- <span class="ws-subtitle">Proxy Engine</span>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>GhostAPI Dashboard</title>
7
+ <link rel="stylesheet" href="/dashboard/styles.css" />
8
+ <link
9
+ rel="icon"
10
+ href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>👻</text></svg>"
11
+ />
12
+ </head>
13
+ <body>
14
+ <div class="app-wrapper">
15
+ <!-- Left Nav Sidebar (Exact React replica) -->
16
+ <aside class="sidebar" id="sidebar">
17
+ <!-- Workspace Switcher -->
18
+ <div class="ws-switcher">
19
+ <div class="ws-btn" style="cursor: default">
20
+ <div class="ws-btn-content">
21
+ <div class="ws-avatar">
22
+ <img
23
+ src="/docs/assets/ghostapi-avatar.png"
24
+ alt="GhostAPI Logo"
25
+ style="
26
+ width: 100%;
27
+ height: 100%;
28
+ object-fit: cover;
29
+ border-radius: 4px;
30
+ "
31
+ />
32
+ </div>
33
+ <div class="ws-info">
34
+ <span class="ws-title">GhostAPI.local</span>
35
+ <span class="ws-subtitle">Proxy Engine</span>
36
+ </div>
37
+ </div>
24
38
  </div>
25
39
  </div>
26
- </div>
27
- </div>
28
40
 
29
- <!-- Navigation Scroll -->
30
- <div class="nav-scroll-area">
31
- <!-- Group 1 -->
32
- <div class="nav-group">
33
- <div class="nav-item" onclick="openSearch()">
34
- <div class="nav-item-left">
35
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
36
- <span class="nav-item-title">Search</span>
37
- </div>
38
- <div class="nav-item-right"><div class="sc-badge">⌘K</div></div>
39
- </div>
40
- <div class="nav-item active" id="nav-all" onclick="setFilter('all')">
41
- <div class="nav-item-left">
42
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="3" y1="9" x2="21" y2="9"></line><line x1="9" y1="21" x2="9" y2="9"></line></svg>
43
- <span class="nav-item-title">Live Traffic</span>
44
- </div>
45
- </div>
46
- <div class="nav-item" onclick="generateRepoSetup(event)">
47
- <div class="nav-item-left">
48
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v6"></path><path d="m16 6-4 4-4-4"></path><rect x="4" y="12" width="16" height="8" rx="2"></rect><path d="M8 16h.01"></path><path d="M12 16h.01"></path></svg>
49
- <span class="nav-item-title">Agent Setup</span>
50
- </div>
51
- <div class="nav-item-right"><div class="sc-badge">generate</div></div>
52
- </div>
53
- <div class="nav-item" onclick="openScenarios(event)">
54
- <div class="nav-item-left">
55
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h16"></path><path d="M4 12h10"></path><path d="M4 18h7"></path><path d="m15 16 2 2 4-4"></path></svg>
56
- <span class="nav-item-title">Scenarios</span>
57
- </div>
58
- </div>
59
- <div class="nav-item" onclick="copyAgentPrompt(event)">
60
- <div class="nav-item-left">
61
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a4 4 0 0 1-4 4H7l-4 4V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z"></path></svg>
62
- <span class="nav-item-title">Copy Agent Prompt</span>
41
+ <!-- Navigation Scroll -->
42
+ <div class="nav-scroll-area">
43
+ <!-- Group 1 -->
44
+ <div class="nav-group">
45
+ <div class="nav-item" onclick="openSearch()">
46
+ <div class="nav-item-left">
47
+ <svg
48
+ class="nav-item-icon"
49
+ viewBox="0 0 24 24"
50
+ fill="none"
51
+ stroke="currentColor"
52
+ stroke-width="1.5"
53
+ stroke-linecap="round"
54
+ stroke-linejoin="round"
55
+ >
56
+ <circle cx="11" cy="11" r="8"></circle>
57
+ <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
58
+ </svg>
59
+ <span class="nav-item-title">Search</span>
60
+ </div>
61
+ <div class="nav-item-right"><div class="sc-badge">⌘K</div></div>
62
+ </div>
63
+ <div
64
+ class="nav-item active"
65
+ id="nav-all"
66
+ onclick="setFilter('all')"
67
+ >
68
+ <div class="nav-item-left">
69
+ <svg
70
+ class="nav-item-icon"
71
+ viewBox="0 0 24 24"
72
+ fill="none"
73
+ stroke="currentColor"
74
+ stroke-width="1.5"
75
+ stroke-linecap="round"
76
+ stroke-linejoin="round"
77
+ >
78
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
79
+ <line x1="3" y1="9" x2="21" y2="9"></line>
80
+ <line x1="9" y1="21" x2="9" y2="9"></line>
81
+ </svg>
82
+ <span class="nav-item-title">Live Traffic</span>
83
+ </div>
84
+ </div>
85
+ <div class="nav-item" onclick="generateRepoSetup(event)">
86
+ <div class="nav-item-left">
87
+ <svg
88
+ class="nav-item-icon"
89
+ viewBox="0 0 24 24"
90
+ fill="none"
91
+ stroke="currentColor"
92
+ stroke-width="1.5"
93
+ stroke-linecap="round"
94
+ stroke-linejoin="round"
95
+ >
96
+ <path d="M12 2v6"></path>
97
+ <path d="m16 6-4 4-4-4"></path>
98
+ <rect x="4" y="12" width="16" height="8" rx="2"></rect>
99
+ <path d="M8 16h.01"></path>
100
+ <path d="M12 16h.01"></path>
101
+ </svg>
102
+ <span class="nav-item-title">Agent Setup</span>
103
+ </div>
104
+ <div class="nav-item-right">
105
+ <div class="sc-badge">generate</div>
106
+ </div>
107
+ </div>
108
+ <div class="nav-item" onclick="openScenarios(event)">
109
+ <div class="nav-item-left">
110
+ <svg
111
+ class="nav-item-icon"
112
+ viewBox="0 0 24 24"
113
+ fill="none"
114
+ stroke="currentColor"
115
+ stroke-width="1.5"
116
+ stroke-linecap="round"
117
+ stroke-linejoin="round"
118
+ >
119
+ <path d="M4 6h16"></path>
120
+ <path d="M4 12h10"></path>
121
+ <path d="M4 18h7"></path>
122
+ <path d="m15 16 2 2 4-4"></path>
123
+ </svg>
124
+ <span class="nav-item-title">Scenarios</span>
125
+ </div>
126
+ </div>
127
+ <div class="nav-item" onclick="copyAgentPrompt(event)">
128
+ <div class="nav-item-left">
129
+ <svg
130
+ class="nav-item-icon"
131
+ viewBox="0 0 24 24"
132
+ fill="none"
133
+ stroke="currentColor"
134
+ stroke-width="1.5"
135
+ stroke-linecap="round"
136
+ stroke-linejoin="round"
137
+ >
138
+ <path
139
+ d="M21 15a4 4 0 0 1-4 4H7l-4 4V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z"
140
+ ></path>
141
+ </svg>
142
+ <span class="nav-item-title">Copy Agent Prompt</span>
143
+ </div>
144
+ </div>
145
+ <div class="nav-item" onclick="openSafetyReport(event)">
146
+ <div class="nav-item-left">
147
+ <svg
148
+ class="nav-item-icon"
149
+ viewBox="0 0 24 24"
150
+ fill="none"
151
+ stroke="currentColor"
152
+ stroke-width="1.5"
153
+ stroke-linecap="round"
154
+ stroke-linejoin="round"
155
+ >
156
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
157
+ <path d="m9 12 2 2 4-4"></path>
158
+ </svg>
159
+ <span class="nav-item-title">Provider-Risk Scan</span>
160
+ </div>
161
+ </div>
63
162
  </div>
64
- </div>
65
- <div class="nav-item" onclick="openSafetyReport(event)">
66
- <div class="nav-item-left">
67
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path><path d="m9 12 2 2 4-4"></path></svg>
68
- <span class="nav-item-title">Safety Report</span>
163
+
164
+ <!-- Group 2 Filters -->
165
+ <div class="nav-group">
166
+ <span class="nav-heading">Filter Providers</span>
167
+ <div class="nav-item" id="nav-stripe" onclick="setFilter('stripe')">
168
+ <div class="nav-item-left">
169
+ <svg
170
+ class="nav-item-icon"
171
+ viewBox="0 0 24 24"
172
+ fill="none"
173
+ stroke="currentColor"
174
+ stroke-width="1.5"
175
+ stroke-linecap="round"
176
+ stroke-linejoin="round"
177
+ >
178
+ <path
179
+ d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"
180
+ ></path>
181
+ </svg>
182
+ <span class="nav-item-title">Stripe</span>
183
+ </div>
184
+ </div>
185
+ <div class="nav-item" id="nav-twilio" onclick="setFilter('twilio')">
186
+ <div class="nav-item-left">
187
+ <svg
188
+ class="nav-item-icon"
189
+ viewBox="0 0 24 24"
190
+ fill="none"
191
+ stroke="currentColor"
192
+ stroke-width="1.5"
193
+ stroke-linecap="round"
194
+ stroke-linejoin="round"
195
+ >
196
+ <path d="M21 21v-4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v4"></path>
197
+ <path d="M3 21v-4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4"></path>
198
+ <path d="M9 15V9a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v6"></path>
199
+ </svg>
200
+ <span class="nav-item-title">Twilio</span>
201
+ </div>
202
+ </div>
203
+ <div class="nav-item" id="nav-resend" onclick="setFilter('resend')">
204
+ <div class="nav-item-left">
205
+ <svg
206
+ class="nav-item-icon"
207
+ viewBox="0 0 24 24"
208
+ fill="none"
209
+ stroke="currentColor"
210
+ stroke-width="1.5"
211
+ stroke-linecap="round"
212
+ stroke-linejoin="round"
213
+ >
214
+ <path
215
+ d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"
216
+ ></path>
217
+ <polyline points="22,6 12,13 2,6"></polyline>
218
+ </svg>
219
+ <span class="nav-item-title">Resend</span>
220
+ </div>
221
+ </div>
222
+ <div class="nav-item" id="nav-github" onclick="setFilter('github')">
223
+ <div class="nav-item-left">
224
+ <svg
225
+ class="nav-item-icon"
226
+ viewBox="0 0 24 24"
227
+ fill="none"
228
+ stroke="currentColor"
229
+ stroke-width="1.5"
230
+ stroke-linecap="round"
231
+ stroke-linejoin="round"
232
+ >
233
+ <path
234
+ d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"
235
+ ></path>
236
+ <path d="M9 18c-4.51 2-5-2-7-2"></path>
237
+ </svg>
238
+ <span class="nav-item-title">GitHub</span>
239
+ </div>
240
+ </div>
241
+ <div
242
+ class="nav-item"
243
+ id="nav-discord"
244
+ onclick="setFilter('discord')"
245
+ >
246
+ <div class="nav-item-left">
247
+ <svg
248
+ class="nav-item-icon"
249
+ viewBox="0 0 24 24"
250
+ fill="none"
251
+ stroke="currentColor"
252
+ stroke-width="1.5"
253
+ stroke-linecap="round"
254
+ stroke-linejoin="round"
255
+ >
256
+ <path
257
+ d="M18 10a4 4 0 0 0-4-4h-4a4 4 0 0 0-4 4v4a4 4 0 0 0 4 4h4a4 4 0 0 0 4-4v-4z"
258
+ ></path>
259
+ <line x1="8" y1="10" x2="8" y2="10.01"></line>
260
+ <line x1="16" y1="10" x2="16" y2="10.01"></line>
261
+ </svg>
262
+ <span class="nav-item-title">Discord</span>
263
+ </div>
264
+ </div>
265
+ <div class="nav-item" id="nav-openai" onclick="setFilter('openai')">
266
+ <div class="nav-item-left">
267
+ <svg
268
+ class="nav-item-icon"
269
+ viewBox="0 0 24 24"
270
+ fill="none"
271
+ stroke="currentColor"
272
+ stroke-width="1.5"
273
+ stroke-linecap="round"
274
+ stroke-linejoin="round"
275
+ >
276
+ <circle cx="12" cy="12" r="3"></circle>
277
+ <path
278
+ d="M12 2a5 5 0 0 1 4.3 2.5A5 5 0 0 1 22 9a5 5 0 0 1-1.4 3.5A5 5 0 0 1 16 20a5 5 0 0 1-8.3-.5A5 5 0 0 1 2 15a5 5 0 0 1 1.4-3.5A5 5 0 0 1 8 4a5 5 0 0 1 4-2z"
279
+ ></path>
280
+ </svg>
281
+ <span class="nav-item-title">OpenAI</span>
282
+ </div>
283
+ </div>
284
+ <div
285
+ class="nav-item"
286
+ id="nav-generic"
287
+ onclick="setFilter('generic')"
288
+ >
289
+ <div class="nav-item-left">
290
+ <svg
291
+ class="nav-item-icon"
292
+ viewBox="0 0 24 24"
293
+ fill="none"
294
+ stroke="currentColor"
295
+ stroke-width="1.5"
296
+ stroke-linecap="round"
297
+ stroke-linejoin="round"
298
+ >
299
+ <polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
300
+ <polyline points="2 17 12 22 22 17"></polyline>
301
+ <polyline points="2 12 12 17 22 12"></polyline>
302
+ </svg>
303
+ <span class="nav-item-title">Generic REST</span>
304
+ </div>
305
+ </div>
69
306
  </div>
70
307
  </div>
71
- </div>
72
308
 
73
- <!-- Group 2 Filters -->
74
- <div class="nav-group">
75
- <span class="nav-heading">Filter Providers</span>
76
- <div class="nav-item" id="nav-stripe" onclick="setFilter('stripe')">
77
- <div class="nav-item-left">
78
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg>
79
- <span class="nav-item-title">Stripe</span>
309
+ <!-- Nav Bottom -->
310
+ <div class="nav-bottom">
311
+ <div class="nav-item" onclick="clearStorage('cache', event)">
312
+ <div class="nav-item-left">
313
+ <svg
314
+ class="nav-item-icon"
315
+ viewBox="0 0 24 24"
316
+ fill="none"
317
+ stroke="currentColor"
318
+ stroke-width="1.5"
319
+ stroke-linecap="round"
320
+ stroke-linejoin="round"
321
+ >
322
+ <rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect>
323
+ <rect x="9" y="9" width="6" height="6"></rect>
324
+ <line x1="9" y1="1" x2="9" y2="4"></line>
325
+ <line x1="15" y1="1" x2="15" y2="4"></line>
326
+ <line x1="9" y1="20" x2="9" y2="23"></line>
327
+ <line x1="15" y1="20" x2="15" y2="23"></line>
328
+ <line x1="20" y1="9" x2="23" y2="9"></line>
329
+ <line x1="20" y1="14" x2="23" y2="14"></line>
330
+ <line x1="1" y1="9" x2="4" y2="9"></line>
331
+ <line x1="1" y1="14" x2="4" y2="14"></line>
332
+ </svg>
333
+ <span class="nav-item-title">Clear Cache</span>
334
+ </div>
80
335
  </div>
81
- </div>
82
- <div class="nav-item" id="nav-twilio" onclick="setFilter('twilio')">
83
- <div class="nav-item-left">
84
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 21v-4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v4"></path><path d="M3 21v-4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4"></path><path d="M9 15V9a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v6"></path></svg>
85
- <span class="nav-item-title">Twilio</span>
336
+ <div class="nav-item" onclick="clearStorage('state', event)">
337
+ <div class="nav-item-left">
338
+ <svg
339
+ class="nav-item-icon"
340
+ viewBox="0 0 24 24"
341
+ fill="none"
342
+ stroke="currentColor"
343
+ stroke-width="1.5"
344
+ stroke-linecap="round"
345
+ stroke-linejoin="round"
346
+ >
347
+ <circle cx="12" cy="12" r="3"></circle>
348
+ <path
349
+ d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
350
+ ></path>
351
+ </svg>
352
+ <span class="nav-item-title">Clear State</span>
353
+ </div>
86
354
  </div>
87
- </div>
88
- <div class="nav-item" id="nav-resend" onclick="setFilter('resend')">
89
- <div class="nav-item-left">
90
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
91
- <span class="nav-item-title">Resend</span>
355
+ <div
356
+ class="nav-item fault-toggle"
357
+ id="fault-toggle"
358
+ onclick="toggleFaultLab(event)"
359
+ >
360
+ <div class="nav-item-left">
361
+ <svg
362
+ class="nav-item-icon"
363
+ viewBox="0 0 24 24"
364
+ fill="none"
365
+ stroke="currentColor"
366
+ stroke-width="1.5"
367
+ stroke-linecap="round"
368
+ stroke-linejoin="round"
369
+ >
370
+ <path d="M13 2 3 14h8l-1 8 11-14h-8l0-6z"></path>
371
+ </svg>
372
+ <span class="nav-item-title">Chaos Mode</span>
373
+ </div>
374
+ <span class="fault-state" id="fault-state">Off</span>
92
375
  </div>
93
- </div>
94
- <div class="nav-item" id="nav-github" onclick="setFilter('github')">
95
- <div class="nav-item-left">
96
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"></path><path d="M9 18c-4.51 2-5-2-7-2"></path></svg>
97
- <span class="nav-item-title">GitHub</span>
376
+ <div class="nav-item" onclick="generateAiRules(event)">
377
+ <div class="nav-item-left">
378
+ <svg
379
+ class="nav-item-icon"
380
+ viewBox="0 0 24 24"
381
+ fill="none"
382
+ stroke="currentColor"
383
+ stroke-width="1.5"
384
+ stroke-linecap="round"
385
+ stroke-linejoin="round"
386
+ >
387
+ <path d="M12 3v3"></path>
388
+ <path d="M18.36 5.64 16.24 7.76"></path>
389
+ <path d="M21 12h-3"></path>
390
+ <path d="M18.36 18.36 16.24 16.24"></path>
391
+ <path d="M12 18v3"></path>
392
+ <path d="M7.76 16.24 5.64 18.36"></path>
393
+ <path d="M6 12H3"></path>
394
+ <path d="M7.76 7.76 5.64 5.64"></path>
395
+ <circle cx="12" cy="12" r="3"></circle>
396
+ </svg>
397
+ <span class="nav-item-title">Generate AI Rules</span>
398
+ </div>
98
399
  </div>
99
400
  </div>
100
- <div class="nav-item" id="nav-discord" onclick="setFilter('discord')">
101
- <div class="nav-item-left">
102
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 10a4 4 0 0 0-4-4h-4a4 4 0 0 0-4 4v4a4 4 0 0 0 4 4h4a4 4 0 0 0 4-4v-4z"></path><line x1="8" y1="10" x2="8" y2="10.01"></line><line x1="16" y1="10" x2="16" y2="10.01"></line></svg>
103
- <span class="nav-item-title">Discord</span>
401
+ </aside>
402
+
403
+ <button
404
+ class="sidebar-backdrop"
405
+ id="sidebar-backdrop"
406
+ type="button"
407
+ aria-label="Close navigation"
408
+ ></button>
409
+
410
+ <!-- Main Content Structure -->
411
+ <main class="main">
412
+ <!-- Topbar -->
413
+ <header class="topbar">
414
+ <div class="topbar-left">
415
+ <button
416
+ class="toggle-btn"
417
+ id="sidebar-toggle"
418
+ type="button"
419
+ aria-label="Toggle navigation"
420
+ title="Toggle navigation"
421
+ >
422
+ <svg
423
+ viewBox="0 0 24 24"
424
+ width="18"
425
+ height="18"
426
+ fill="none"
427
+ stroke="currentColor"
428
+ stroke-width="1.5"
429
+ stroke-linecap="round"
430
+ stroke-linejoin="round"
431
+ >
432
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
433
+ <line x1="9" y1="3" x2="9" y2="21"></line>
434
+ </svg>
435
+ </button>
104
436
  </div>
105
- </div>
106
- <div class="nav-item" id="nav-openai" onclick="setFilter('openai')">
107
- <div class="nav-item-left">
108
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M12 2a5 5 0 0 1 4.3 2.5A5 5 0 0 1 22 9a5 5 0 0 1-1.4 3.5A5 5 0 0 1 16 20a5 5 0 0 1-8.3-.5A5 5 0 0 1 2 15a5 5 0 0 1 1.4-3.5A5 5 0 0 1 8 4a5 5 0 0 1 4-2z"></path></svg>
109
- <span class="nav-item-title">OpenAI</span>
437
+ <div class="breadcrumb topbar-center" aria-label="Current view">
438
+ <span class="brand-lockup">
439
+ <img
440
+ class="topbar-brand-icon"
441
+ src="/docs/assets/ghostapi-avatar.png"
442
+ alt=""
443
+ />
444
+ <strong>GhostAPI</strong>
445
+ </span>
446
+ <span class="breadcrumb-divider">/</span>
447
+ <span class="breadcrumb-active">Live Traffic</span>
110
448
  </div>
111
- </div>
112
- <div class="nav-item" id="nav-generic" onclick="setFilter('generic')">
113
- <div class="nav-item-left">
114
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
115
- <span class="nav-item-title">Generic REST</span>
449
+ <div class="topbar-right">
450
+ <div class="status-indicator connected" id="status-indicator">
451
+ <div class="status-dot"></div>
452
+ <span id="status-text">Connected</span>
453
+ </div>
116
454
  </div>
117
- </div>
118
- </div>
119
- </div>
455
+ </header>
120
456
 
121
- <!-- Nav Bottom -->
122
- <div class="nav-bottom">
123
- <div class="nav-item" onclick="clearStorage('cache', event)">
124
- <div class="nav-item-left">
125
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect><rect x="9" y="9" width="6" height="6"></rect><line x1="9" y1="1" x2="9" y2="4"></line><line x1="15" y1="1" x2="15" y2="4"></line><line x1="9" y1="20" x2="9" y2="23"></line><line x1="15" y1="20" x2="15" y2="23"></line><line x1="20" y1="9" x2="23" y2="9"></line><line x1="20" y1="14" x2="23" y2="14"></line><line x1="1" y1="9" x2="4" y2="9"></line><line x1="1" y1="14" x2="4" y2="14"></line></svg>
126
- <span class="nav-item-title">Clear Cache</span>
127
- </div>
128
- </div>
129
- <div class="nav-item" onclick="clearStorage('state', event)">
130
- <div class="nav-item-left">
131
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
132
- <span class="nav-item-title">Clear State</span>
133
- </div>
134
- </div>
135
- <div class="nav-item fault-toggle" id="fault-toggle" onclick="toggleFaultLab(event)">
136
- <div class="nav-item-left">
137
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 3 14h8l-1 8 11-14h-8l0-6z"></path></svg>
138
- <span class="nav-item-title">Chaos Mode</span>
139
- </div>
140
- <span class="fault-state" id="fault-state">Off</span>
141
- </div>
142
- <div class="nav-item" onclick="generateAiRules(event)">
143
- <div class="nav-item-left">
144
- <svg class="nav-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v3"></path><path d="M18.36 5.64 16.24 7.76"></path><path d="M21 12h-3"></path><path d="M18.36 18.36 16.24 16.24"></path><path d="M12 18v3"></path><path d="M7.76 16.24 5.64 18.36"></path><path d="M6 12H3"></path><path d="M7.76 7.76 5.64 5.64"></path><circle cx="12" cy="12" r="3"></circle></svg>
145
- <span class="nav-item-title">Generate AI Rules</span>
146
- </div>
147
- </div>
148
- </div>
149
- </aside>
457
+ <!-- Content Engine -->
458
+ <div class="content-wrapper">
459
+ <!-- Event List Pane -->
460
+ <div class="event-list-pane">
461
+ <div class="event-list-header">
462
+ <h2>Requests</h2>
463
+ <div class="event-count" id="event-count">0</div>
464
+ </div>
465
+ <div class="events-scroll" id="event-list">
466
+ <!-- JS mounts events here -->
467
+ </div>
468
+ </div>
150
469
 
151
- <!-- Main Content Structure -->
152
- <main class="main">
153
-
154
- <!-- Topbar -->
155
- <header class="topbar">
156
- <div class="topbar-left">
157
- <button class="toggle-btn" id="sidebar-toggle">
158
- <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="9" y1="3" x2="9" y2="21"></line></svg>
159
- </button>
160
- <div class="breadcrumb">
161
- <span>GhostAPI</span>
162
- <span>/</span>
163
- <span class="breadcrumb-active">Live Traffic</span>
164
- </div>
165
- </div>
166
- <div class="topbar-right">
167
- <div class="status-indicator connected" id="status-indicator">
168
- <div class="status-dot"></div>
169
- <span id="status-text">Connected</span>
170
- </div>
171
- </div>
172
- </header>
470
+ <!-- Details Split Pane -->
471
+ <div class="details-pane">
472
+ <!-- Empty State -->
473
+ <div class="empty-view" id="empty-details">
474
+ <svg
475
+ viewBox="0 0 24 24"
476
+ width="48"
477
+ height="48"
478
+ fill="none"
479
+ stroke="currentColor"
480
+ stroke-width="1.5"
481
+ stroke-linecap="round"
482
+ stroke-linejoin="round"
483
+ >
484
+ <circle cx="12" cy="12" r="10"></circle>
485
+ <line x1="12" y1="16" x2="12" y2="12"></line>
486
+ <line x1="12" y1="8" x2="12.01" y2="8"></line>
487
+ </svg>
488
+ <p>Select a request to view details</p>
489
+ </div>
173
490
 
174
- <!-- Content Engine -->
175
- <div class="content-wrapper">
176
-
177
- <!-- Event List Pane -->
178
- <div class="event-list-pane">
179
- <div class="event-list-header">
180
- <h2>Requests</h2>
181
- <div class="event-count" id="event-count">0</div>
182
- </div>
183
- <div class="events-scroll" id="event-list">
184
- <!-- JS mounts events here -->
185
- </div>
186
- </div>
491
+ <!-- Populated Details -->
492
+ <div class="details-content" id="details-content">
493
+ <div class="dep-header">
494
+ <div class="dep-title">
495
+ <span class="ec-method" id="d-method"></span>
496
+ <span id="d-path"></span>
497
+ </div>
498
+ <div class="dep-badges">
499
+ <button class="mini-action" onclick="generateSelectedTest()">
500
+ Generate Test
501
+ </button>
502
+ <span class="pill" id="d-status"></span>
503
+ <span class="pill" id="d-time"></span>
504
+ <span class="pill" id="d-provider"></span>
505
+ <span class="pill" id="d-source"></span>
506
+ </div>
507
+ </div>
187
508
 
188
- <!-- Details Split Pane -->
189
- <div class="details-pane">
190
- <!-- Empty State -->
191
- <div class="empty-view" id="empty-details">
192
- <svg viewBox="0 0 24 24" width="48" height="48" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
193
- <p>Select a request to view details</p>
509
+ <div class="json-split">
510
+ <div class="json-pane">
511
+ <div class="json-header">
512
+ <span>Request</span>
513
+ <svg
514
+ class="ws-icon"
515
+ style="cursor: pointer"
516
+ viewBox="0 0 24 24"
517
+ fill="none"
518
+ stroke="currentColor"
519
+ stroke-width="1.5"
520
+ stroke-linecap="round"
521
+ stroke-linejoin="round"
522
+ onclick="copy('req')"
523
+ >
524
+ <rect
525
+ x="9"
526
+ y="9"
527
+ width="13"
528
+ height="13"
529
+ rx="2"
530
+ ry="2"
531
+ ></rect>
532
+ <path
533
+ d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
534
+ ></path>
535
+ </svg>
536
+ </div>
537
+ <div class="json-body"><pre id="d-req-body"></pre></div>
538
+ </div>
539
+ <div class="json-pane">
540
+ <div class="json-header">
541
+ <span>Response</span>
542
+ <svg
543
+ class="ws-icon"
544
+ style="cursor: pointer"
545
+ viewBox="0 0 24 24"
546
+ fill="none"
547
+ stroke="currentColor"
548
+ stroke-width="1.5"
549
+ stroke-linecap="round"
550
+ stroke-linejoin="round"
551
+ onclick="copy('res')"
552
+ >
553
+ <rect
554
+ x="9"
555
+ y="9"
556
+ width="13"
557
+ height="13"
558
+ rx="2"
559
+ ry="2"
560
+ ></rect>
561
+ <path
562
+ d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
563
+ ></path>
564
+ </svg>
565
+ </div>
566
+ <div class="json-body"><pre id="d-res-body"></pre></div>
567
+ </div>
568
+ </div>
569
+ </div>
570
+ </div>
194
571
  </div>
572
+ </main>
195
573
 
196
- <!-- Populated Details -->
197
- <div class="details-content" id="details-content">
198
- <div class="dep-header">
199
- <div class="dep-title">
200
- <span class="ec-method" id="d-method"></span>
201
- <span id="d-path"></span>
202
- </div>
203
- <div class="dep-badges">
204
- <button class="mini-action" onclick="generateSelectedTest()">Generate Test</button>
205
- <span class="pill" id="d-status"></span>
206
- <span class="pill" id="d-time"></span>
207
- <span class="pill" id="d-provider"></span>
208
- <span class="pill" id="d-source"></span>
209
- </div>
574
+ <!-- Modal Search -->
575
+ <div class="modal-overlay" id="search-modal">
576
+ <div class="modal-content">
577
+ <div class="modal-header">
578
+ <svg
579
+ viewBox="0 0 24 24"
580
+ width="18"
581
+ height="18"
582
+ fill="none"
583
+ stroke="currentColor"
584
+ stroke-width="1.5"
585
+ stroke-linecap="round"
586
+ stroke-linejoin="round"
587
+ >
588
+ <circle cx="11" cy="11" r="8"></circle>
589
+ <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
590
+ </svg>
591
+ <input
592
+ type="text"
593
+ class="modal-input"
594
+ id="search-input"
595
+ placeholder="Search paths, providers, payloads..."
596
+ />
597
+ <div class="sc-badge" style="display: flex">ESC</div>
210
598
  </div>
211
-
212
- <div class="json-split">
213
- <div class="json-pane">
214
- <div class="json-header">
215
- <span>Request</span>
216
- <svg class="ws-icon" style="cursor:pointer" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" onclick="copy('req')"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
217
- </div>
218
- <div class="json-body"><pre id="d-req-body"></pre></div>
219
- </div>
220
- <div class="json-pane">
221
- <div class="json-header">
222
- <span>Response</span>
223
- <svg class="ws-icon" style="cursor:pointer" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" onclick="copy('res')"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
224
- </div>
225
- <div class="json-body"><pre id="d-res-body"></pre></div>
226
- </div>
599
+ <div class="modal-body">
600
+ <svg
601
+ viewBox="0 0 24 24"
602
+ width="24"
603
+ height="24"
604
+ fill="none"
605
+ stroke="currentColor"
606
+ stroke-width="1.5"
607
+ stroke-linecap="round"
608
+ stroke-linejoin="round"
609
+ style="opacity: 0.3"
610
+ >
611
+ <polyline points="4 7 4 4 20 4 20 7"></polyline>
612
+ <line x1="9" y1="20" x2="15" y2="20"></line>
613
+ <line x1="12" y1="4" x2="12" y2="20"></line>
614
+ </svg>
615
+ <p>Type to filter live traffic...</p>
227
616
  </div>
228
617
  </div>
229
-
230
618
  </div>
231
- </div>
232
- </main>
233
-
234
- <!-- Modal Search -->
235
- <div class="modal-overlay" id="search-modal">
236
- <div class="modal-content">
237
- <div class="modal-header">
238
- <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
239
- <input type="text" class="modal-input" id="search-input" placeholder="Search paths, providers, payloads...">
240
- <div class="sc-badge" style="display:flex">ESC</div>
241
- </div>
242
- <div class="modal-body">
243
- <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="opacity: 0.3"><polyline points="4 7 4 4 20 4 20 7"></polyline><line x1="9" y1="20" x2="15" y2="20"></line><line x1="12" y1="4" x2="12" y2="20"></line></svg>
244
- <p>Type to filter live traffic...</p>
245
- </div>
246
- </div>
247
- </div>
248
619
 
249
- <div class="modal-overlay" id="rules-modal">
250
- <div class="modal-content rules-modal-content">
251
- <div class="modal-header rules-modal-header">
252
- <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5V4a2 2 0 0 1 2-2h9l5 5v12.5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2z"></path><path d="M14 2v6h6"></path></svg>
253
- <div class="rules-title-block">
254
- <strong id="rules-title">.cursorrules</strong>
255
- <span id="rules-subtitle">Generated from package.json</span>
620
+ <div class="modal-overlay" id="rules-modal">
621
+ <div class="modal-content rules-modal-content">
622
+ <div class="modal-header rules-modal-header">
623
+ <svg
624
+ viewBox="0 0 24 24"
625
+ width="18"
626
+ height="18"
627
+ fill="none"
628
+ stroke="currentColor"
629
+ stroke-width="1.5"
630
+ stroke-linecap="round"
631
+ stroke-linejoin="round"
632
+ >
633
+ <path
634
+ d="M4 19.5V4a2 2 0 0 1 2-2h9l5 5v12.5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2z"
635
+ ></path>
636
+ <path d="M14 2v6h6"></path>
637
+ </svg>
638
+ <div class="rules-title-block">
639
+ <strong id="rules-title">.cursorrules</strong>
640
+ <span id="rules-subtitle">Generated from package.json</span>
641
+ </div>
642
+ <button
643
+ class="modal-action"
644
+ id="rules-copy-button"
645
+ onclick="copyRules()"
646
+ >
647
+ Copy
648
+ </button>
649
+ <button class="modal-action ghost" onclick="closeRulesModal()">
650
+ Close
651
+ </button>
652
+ </div>
653
+ <div class="rules-body">
654
+ <pre id="rules-output">Generating...</pre>
655
+ </div>
256
656
  </div>
257
- <button class="modal-action" id="rules-copy-button" onclick="copyRules()">Copy</button>
258
- <button class="modal-action ghost" onclick="closeRulesModal()">Close</button>
259
- </div>
260
- <div class="rules-body">
261
- <pre id="rules-output">Generating...</pre>
262
657
  </div>
263
- </div>
264
- </div>
265
658
 
266
- <div class="modal-overlay" id="setup-modal">
267
- <div class="modal-content setup-modal-content">
268
- <div class="modal-header rules-modal-header">
269
- <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v6"></path><path d="m16 6-4 4-4-4"></path><rect x="4" y="12" width="16" height="8" rx="2"></rect></svg>
270
- <div class="rules-title-block">
271
- <strong>Agent Setup</strong>
272
- <span id="setup-subtitle">Generate and copy setup for this repo</span>
659
+ <div class="modal-overlay" id="setup-modal">
660
+ <div class="modal-content setup-modal-content">
661
+ <div class="modal-header rules-modal-header">
662
+ <svg
663
+ viewBox="0 0 24 24"
664
+ width="18"
665
+ height="18"
666
+ fill="none"
667
+ stroke="currentColor"
668
+ stroke-width="1.5"
669
+ stroke-linecap="round"
670
+ stroke-linejoin="round"
671
+ >
672
+ <path d="M12 2v6"></path>
673
+ <path d="m16 6-4 4-4-4"></path>
674
+ <rect x="4" y="12" width="16" height="8" rx="2"></rect>
675
+ </svg>
676
+ <div class="rules-title-block">
677
+ <strong>Agent Setup</strong>
678
+ <span id="setup-subtitle"
679
+ >Generate and copy setup for this repo</span
680
+ >
681
+ </div>
682
+ <button
683
+ class="modal-action"
684
+ id="setup-copy-button"
685
+ onclick="copySetupOutput()"
686
+ >
687
+ Copy Selected
688
+ </button>
689
+ <button class="modal-action ghost" onclick="closeSetupModal()">
690
+ Close
691
+ </button>
692
+ </div>
693
+ <div class="setup-grid">
694
+ <div class="setup-list" id="setup-list"></div>
695
+ <div class="rules-body setup-output">
696
+ <pre id="setup-output">Generating setup...</pre>
697
+ </div>
698
+ </div>
273
699
  </div>
274
- <button class="modal-action" id="setup-copy-button" onclick="copySetupOutput()">Copy Selected</button>
275
- <button class="modal-action ghost" onclick="closeSetupModal()">Close</button>
276
700
  </div>
277
- <div class="setup-grid">
278
- <div class="setup-list" id="setup-list"></div>
279
- <div class="rules-body setup-output"><pre id="setup-output">Generating setup...</pre></div>
280
- </div>
281
- </div>
282
- </div>
283
701
 
284
- <div class="modal-overlay" id="scenarios-modal">
285
- <div class="modal-content setup-modal-content">
286
- <div class="modal-header rules-modal-header">
287
- <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h16"></path><path d="M4 12h10"></path><path d="M4 18h7"></path><path d="m15 16 2 2 4-4"></path></svg>
288
- <div class="rules-title-block">
289
- <strong>Scenario Presets</strong>
290
- <span id="scenarios-subtitle">Arm, export, or share agent-ready API behavior</span>
702
+ <div class="modal-overlay" id="scenarios-modal">
703
+ <div class="modal-content setup-modal-content">
704
+ <div class="modal-header rules-modal-header">
705
+ <svg
706
+ viewBox="0 0 24 24"
707
+ width="18"
708
+ height="18"
709
+ fill="none"
710
+ stroke="currentColor"
711
+ stroke-width="1.5"
712
+ stroke-linecap="round"
713
+ stroke-linejoin="round"
714
+ >
715
+ <path d="M4 6h16"></path>
716
+ <path d="M4 12h10"></path>
717
+ <path d="M4 18h7"></path>
718
+ <path d="m15 16 2 2 4-4"></path>
719
+ </svg>
720
+ <div class="rules-title-block">
721
+ <strong>Scenario Presets</strong>
722
+ <span id="scenarios-subtitle"
723
+ >Arm, export, or share agent-ready API behavior</span
724
+ >
725
+ </div>
726
+ <button class="modal-action ghost" onclick="closeScenariosModal()">
727
+ Close
728
+ </button>
729
+ </div>
730
+ <div class="scenario-shell">
731
+ <div class="scenario-list" id="scenario-list"></div>
732
+ <div class="rules-body scenario-output">
733
+ <pre id="scenario-output">Select a scenario.</pre>
734
+ </div>
735
+ </div>
291
736
  </div>
292
- <button class="modal-action ghost" onclick="closeScenariosModal()">Close</button>
293
- </div>
294
- <div class="scenario-shell">
295
- <div class="scenario-list" id="scenario-list"></div>
296
- <div class="rules-body scenario-output"><pre id="scenario-output">Select a scenario.</pre></div>
297
737
  </div>
298
738
  </div>
299
- </div>
300
-
301
- </div>
302
- <script src="/dashboard/app.js"></script>
303
- </body>
739
+ <script src="/dashboard/app.js"></script>
740
+ </body>
304
741
  </html>