@yiaany/ghostapi 0.1.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 (184) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/CONTRIBUTING.md +117 -0
  3. package/LICENSE +21 -0
  4. package/README.md +354 -0
  5. package/SECURITY.md +37 -0
  6. package/dist/agents/agentPrompt.d.ts +5 -0
  7. package/dist/agents/agentPrompt.js +30 -0
  8. package/dist/agents/agentPrompt.js.map +1 -0
  9. package/dist/ai/aiClient.d.ts +7 -0
  10. package/dist/ai/aiClient.js +30 -0
  11. package/dist/ai/aiClient.js.map +1 -0
  12. package/dist/ai/aiGenerator.d.ts +10 -0
  13. package/dist/ai/aiGenerator.js +101 -0
  14. package/dist/ai/aiGenerator.js.map +1 -0
  15. package/dist/ai/genericInference.d.ts +5 -0
  16. package/dist/ai/genericInference.js +80 -0
  17. package/dist/ai/genericInference.js.map +1 -0
  18. package/dist/ai/index.d.ts +3 -0
  19. package/dist/ai/index.js +2 -0
  20. package/dist/ai/index.js.map +1 -0
  21. package/dist/ai/jsonRepair.d.ts +2 -0
  22. package/dist/ai/jsonRepair.js +31 -0
  23. package/dist/ai/jsonRepair.js.map +1 -0
  24. package/dist/ai/prompts.d.ts +4 -0
  25. package/dist/ai/prompts.js +81 -0
  26. package/dist/ai/prompts.js.map +1 -0
  27. package/dist/behavior/behaviorStore.d.ts +12 -0
  28. package/dist/behavior/behaviorStore.js +72 -0
  29. package/dist/behavior/behaviorStore.js.map +1 -0
  30. package/dist/cache/index.d.ts +9 -0
  31. package/dist/cache/index.js +34 -0
  32. package/dist/cache/index.js.map +1 -0
  33. package/dist/cli/errors.d.ts +4 -0
  34. package/dist/cli/errors.js +9 -0
  35. package/dist/cli/errors.js.map +1 -0
  36. package/dist/cli/index.d.ts +2 -0
  37. package/dist/cli/index.js +277 -0
  38. package/dist/cli/index.js.map +1 -0
  39. package/dist/cli/parser.d.ts +56 -0
  40. package/dist/cli/parser.js +169 -0
  41. package/dist/cli/parser.js.map +1 -0
  42. package/dist/config/localConfig.d.ts +16 -0
  43. package/dist/config/localConfig.js +58 -0
  44. package/dist/config/localConfig.js.map +1 -0
  45. package/dist/config/serverConfig.d.ts +13 -0
  46. package/dist/config/serverConfig.js +44 -0
  47. package/dist/config/serverConfig.js.map +1 -0
  48. package/dist/dashboard/app.js +615 -0
  49. package/dist/dashboard/dashboard.d.ts +4 -0
  50. package/dist/dashboard/dashboard.js +20 -0
  51. package/dist/dashboard/dashboard.js.map +1 -0
  52. package/dist/dashboard/index.d.ts +1 -0
  53. package/dist/dashboard/index.html +298 -0
  54. package/dist/dashboard/index.js +2 -0
  55. package/dist/dashboard/index.js.map +1 -0
  56. package/dist/dashboard/styles.css +349 -0
  57. package/dist/errors/errorEngine.d.ts +3 -0
  58. package/dist/errors/errorEngine.js +65 -0
  59. package/dist/errors/errorEngine.js.map +1 -0
  60. package/dist/errors/index.d.ts +3 -0
  61. package/dist/errors/index.js +3 -0
  62. package/dist/errors/index.js.map +1 -0
  63. package/dist/errors/providerErrors.d.ts +3 -0
  64. package/dist/errors/providerErrors.js +6 -0
  65. package/dist/errors/providerErrors.js.map +1 -0
  66. package/dist/fault/faultLab.d.ts +27 -0
  67. package/dist/fault/faultLab.js +89 -0
  68. package/dist/fault/faultLab.js.map +1 -0
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.js +2 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/landing/assets/index-BXR41fAD.css +1 -0
  73. package/dist/landing/assets/index-D8_ggMRE.js +55 -0
  74. package/dist/landing/index.html +15 -0
  75. package/dist/landing/landing.d.ts +3 -0
  76. package/dist/landing/landing.js +12 -0
  77. package/dist/landing/landing.js.map +1 -0
  78. package/dist/mcp/server.d.ts +1 -0
  79. package/dist/mcp/server.js +52 -0
  80. package/dist/mcp/server.js.map +1 -0
  81. package/dist/providers/discord.d.ts +2 -0
  82. package/dist/providers/discord.js +11 -0
  83. package/dist/providers/discord.js.map +1 -0
  84. package/dist/providers/generic.d.ts +2 -0
  85. package/dist/providers/generic.js +13 -0
  86. package/dist/providers/generic.js.map +1 -0
  87. package/dist/providers/github.d.ts +2 -0
  88. package/dist/providers/github.js +11 -0
  89. package/dist/providers/github.js.map +1 -0
  90. package/dist/providers/index.d.ts +2 -0
  91. package/dist/providers/index.js +2 -0
  92. package/dist/providers/index.js.map +1 -0
  93. package/dist/providers/openai.d.ts +2 -0
  94. package/dist/providers/openai.js +15 -0
  95. package/dist/providers/openai.js.map +1 -0
  96. package/dist/providers/registry.d.ts +12 -0
  97. package/dist/providers/registry.js +23 -0
  98. package/dist/providers/registry.js.map +1 -0
  99. package/dist/providers/resend.d.ts +2 -0
  100. package/dist/providers/resend.js +12 -0
  101. package/dist/providers/resend.js.map +1 -0
  102. package/dist/providers/stripe.d.ts +2 -0
  103. package/dist/providers/stripe.js +15 -0
  104. package/dist/providers/stripe.js.map +1 -0
  105. package/dist/providers/twilio.d.ts +2 -0
  106. package/dist/providers/twilio.js +14 -0
  107. package/dist/providers/twilio.js.map +1 -0
  108. package/dist/providers/types.d.ts +13 -0
  109. package/dist/providers/types.js +2 -0
  110. package/dist/providers/types.js.map +1 -0
  111. package/dist/proxy/cacheKey.d.ts +2 -0
  112. package/dist/proxy/cacheKey.js +37 -0
  113. package/dist/proxy/cacheKey.js.map +1 -0
  114. package/dist/proxy/providerDetector.d.ts +11 -0
  115. package/dist/proxy/providerDetector.js +74 -0
  116. package/dist/proxy/providerDetector.js.map +1 -0
  117. package/dist/proxy/proxyHandler.d.ts +3 -0
  118. package/dist/proxy/proxyHandler.js +114 -0
  119. package/dist/proxy/proxyHandler.js.map +1 -0
  120. package/dist/proxy/requestNormalizer.d.ts +11 -0
  121. package/dist/proxy/requestNormalizer.js +30 -0
  122. package/dist/proxy/requestNormalizer.js.map +1 -0
  123. package/dist/report/safetyReport.d.ts +13 -0
  124. package/dist/report/safetyReport.js +65 -0
  125. package/dist/report/safetyReport.js.map +1 -0
  126. package/dist/rules/aiRules.d.ts +7 -0
  127. package/dist/rules/aiRules.js +31 -0
  128. package/dist/rules/aiRules.js.map +1 -0
  129. package/dist/scenarios/scenarioStore.d.ts +37 -0
  130. package/dist/scenarios/scenarioStore.js +201 -0
  131. package/dist/scenarios/scenarioStore.js.map +1 -0
  132. package/dist/security/headerSanitizer.d.ts +3 -0
  133. package/dist/security/headerSanitizer.js +12 -0
  134. package/dist/security/headerSanitizer.js.map +1 -0
  135. package/dist/security/maskSecrets.d.ts +1 -0
  136. package/dist/security/maskSecrets.js +2 -0
  137. package/dist/security/maskSecrets.js.map +1 -0
  138. package/dist/security/secrets.d.ts +4 -0
  139. package/dist/security/secrets.js +61 -0
  140. package/dist/security/secrets.js.map +1 -0
  141. package/dist/server/createServer.d.ts +8 -0
  142. package/dist/server/createServer.js +42 -0
  143. package/dist/server/createServer.js.map +1 -0
  144. package/dist/server/eventsStore.d.ts +17 -0
  145. package/dist/server/eventsStore.js +31 -0
  146. package/dist/server/eventsStore.js.map +1 -0
  147. package/dist/server/routes.d.ts +3 -0
  148. package/dist/server/routes.js +189 -0
  149. package/dist/server/routes.js.map +1 -0
  150. package/dist/server/sse.d.ts +5 -0
  151. package/dist/server/sse.js +32 -0
  152. package/dist/server/sse.js.map +1 -0
  153. package/dist/setup/sdkDetector.d.ts +9 -0
  154. package/dist/setup/sdkDetector.js +31 -0
  155. package/dist/setup/sdkDetector.js.map +1 -0
  156. package/dist/setup/setupGenerator.d.ts +28 -0
  157. package/dist/setup/setupGenerator.js +146 -0
  158. package/dist/setup/setupGenerator.js.map +1 -0
  159. package/dist/state/index.d.ts +1 -0
  160. package/dist/state/index.js +2 -0
  161. package/dist/state/index.js.map +1 -0
  162. package/dist/state/stateExtractor.d.ts +3 -0
  163. package/dist/state/stateExtractor.js +36 -0
  164. package/dist/state/stateExtractor.js.map +1 -0
  165. package/dist/state/stateResolver.d.ts +8 -0
  166. package/dist/state/stateResolver.js +95 -0
  167. package/dist/state/stateResolver.js.map +1 -0
  168. package/dist/state/stateStore.d.ts +4 -0
  169. package/dist/state/stateStore.js +72 -0
  170. package/dist/state/stateStore.js.map +1 -0
  171. package/dist/tests/testGenerator.d.ts +6 -0
  172. package/dist/tests/testGenerator.js +33 -0
  173. package/dist/tests/testGenerator.js.map +1 -0
  174. package/dist/utils/json.d.ts +2 -0
  175. package/dist/utils/json.js +10 -0
  176. package/dist/utils/json.js.map +1 -0
  177. package/docs/release-checklist.md +71 -0
  178. package/examples/agent-instructions/README.md +39 -0
  179. package/examples/generic-rest/README.md +27 -0
  180. package/examples/github-fetch/README.md +35 -0
  181. package/examples/resend-node/README.md +22 -0
  182. package/examples/stripe-node/README.md +29 -0
  183. package/examples/twilio-node/README.md +21 -0
  184. package/package.json +67 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to GhostAPI will be documented in this file.
4
+
5
+ The format follows the spirit of [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project uses semantic versioning once public releases begin.
6
+
7
+ ## 0.1.0 - 2026-07-14
8
+
9
+ ### Added
10
+
11
+ - Local Express proxy server on `127.0.0.1:8080` by default.
12
+ - CLI commands for `start`, `clear`, `model`, `providers`, `doctor`, and `init`.
13
+ - Native MVP provider adapters for Stripe, Twilio, Resend, GitHub, and Discord.
14
+ - Generic fallback coverage for other REST APIs with lightweight service inference.
15
+ - Request normalization and secret masking for headers, query, and JSON bodies.
16
+ - File-per-entry response cache under `.ghostapi/cache/{provider}/{hash}.json`.
17
+ - Local state store under `.ghostapi/state.json` with save/read/list/delete behavior.
18
+ - Provider-specific validation and error formatting for key MVP flows.
19
+ - LLM-backed JSON mock generation with offline fallback.
20
+ - Realtime dashboard at `/dashboard` with SSE events from `/events`.
21
+ - Persistent telemetry history at `.ghostapi/events.jsonl`.
22
+ - Examples for Stripe, Resend, Twilio, GitHub, generic REST, and AI agent instructions.
23
+ - Open-source project docs, security policy, issue templates, and PR template.
24
+
25
+ ### Security
26
+
27
+ - No real external provider API calls by default.
28
+ - Secrets are masked before prompt construction, cache key generation, event logging, and dashboard rendering.
29
+ - `ghostapi doctor` warns about unsafe TLS bypass settings.
@@ -0,0 +1,117 @@
1
+ # Contributing to GhostAPI
2
+
3
+ Thanks for helping improve GhostAPI. This project aims to be small, safe, local-first, and useful for developers and AI coding agents.
4
+
5
+ ## Setup
6
+
7
+ Requirements:
8
+
9
+ - Node.js 20 or newer
10
+ - npm
11
+
12
+ Install dependencies:
13
+
14
+ ```bash
15
+ npm install
16
+ ```
17
+
18
+ Run the local development server:
19
+
20
+ ```bash
21
+ npm run dev
22
+ ```
23
+
24
+ Open:
25
+
26
+ ```text
27
+ http://localhost:8080/dashboard
28
+ ```
29
+
30
+ ## Scripts
31
+
32
+ ```bash
33
+ npm run typecheck
34
+ npm test
35
+ npm run build
36
+ npm run dev
37
+ ```
38
+
39
+ Use these before opening a pull request:
40
+
41
+ ```bash
42
+ npm run typecheck
43
+ npm test
44
+ npm run build
45
+ ```
46
+
47
+ ## Tests
48
+
49
+ Tests are written with Vitest and must stay local-only. Do not add tests that call real Stripe, Twilio, Resend, GitHub, OpenAI, or any other external API.
50
+
51
+ Current test areas include:
52
+
53
+ - Secret masking
54
+ - Provider detection
55
+ - Cache key stability
56
+ - State save/read/list/delete
57
+ - Provider error formatting
58
+ - Prompt construction and JSON repair
59
+ - Proxy flow integration
60
+ - Dashboard/SSE event formatting
61
+
62
+ Shared fixtures live in `test/fixtures/`.
63
+
64
+ ## Coding Style
65
+
66
+ - TypeScript strict mode.
67
+ - ESM modules.
68
+ - Prefer functions and simple objects over classes.
69
+ - Keep modules small and direct.
70
+ - Avoid `any`; use `unknown` and narrow values where possible.
71
+ - Add comments only where behavior is not obvious.
72
+ - Keep user-facing errors actionable.
73
+ - Do not introduce network calls to real provider APIs by default.
74
+
75
+ ## Adding A Provider
76
+
77
+ GhostAPI intentionally keeps native adapters limited. For the MVP, native adapters are:
78
+
79
+ - Stripe
80
+ - Twilio
81
+ - Resend
82
+ - GitHub
83
+ - Discord
84
+ - OpenAI
85
+ - Generic fallback
86
+
87
+ Before adding a new native adapter, ask whether generic fallback plus prompt hints is enough. Native adapters should be reserved for providers where contract-specific behavior, validation, or error formatting is clearly worth maintaining.
88
+
89
+ If a native adapter is justified:
90
+
91
+ 1. Add the adapter under `src/providers/`.
92
+ 2. Register it in `src/providers/registry.ts`.
93
+ 3. Add detection rules in `src/proxy/providerDetector.ts`.
94
+ 4. Add provider-specific prompt guidance in `src/ai/prompts.ts` only if useful.
95
+ 5. Add tests for detection, formatting, validation, and proxy behavior.
96
+ 6. Update README provider matrix.
97
+
98
+ ## Adding Prompt Hints
99
+
100
+ Most services should use generic fallback. To improve generic behavior:
101
+
102
+ 1. Add or refine lightweight inference in `src/ai/genericInference.ts`.
103
+ 2. Keep labels best-effort, such as `generic:shopify-like`.
104
+ 3. Do not add provider-specific validation or error formats for generic services.
105
+ 4. Add tests in `test/genericInference.test.ts`.
106
+ 5. Update README coverage if the change affects documented behavior.
107
+
108
+ ## Pull Request Checklist
109
+
110
+ - The change is scoped and explained clearly.
111
+ - `npm run typecheck` passes.
112
+ - `npm test` passes.
113
+ - `npm run build` passes.
114
+ - New behavior has tests when practical.
115
+ - No real external API calls were added by default.
116
+ - Secrets are not logged, cached, sent to LLM prompts, or exposed in dashboard payloads.
117
+ - README or examples are updated when user-facing behavior changes.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GhostAPI contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,354 @@
1
+ # GhostAPI
2
+
3
+ **The local internet for AI coding agents.**
4
+
5
+ GhostAPI runs on your machine and simulates third-party APIs like Stripe, Twilio, Resend, GitHub, Discord, OpenAI, and generic REST services. Point your app or coding agent at `localhost`, get realistic provider-shaped responses, inspect everything in a dashboard, replay scenarios, and never hit production by accident.
6
+
7
+ ```bash
8
+ npx ghostapi start --open
9
+ ```
10
+
11
+ ```text
12
+ Your app or agent -> http://127.0.0.1:8080 -> GhostAPI -> local state, cache, scenarios, chaos, dashboard
13
+ ```
14
+
15
+ ## Why GhostAPI Exists
16
+
17
+ AI agents are becoming excellent at writing integration code. They also run that code.
18
+
19
+ That is dangerous when the code touches real providers:
20
+
21
+ - Stripe charges can become real money movement.
22
+ - Twilio calls can send real SMS messages.
23
+ - Resend calls can send real email.
24
+ - GitHub calls can mutate real repositories.
25
+ - OpenAI calls can spend real tokens and leak test data.
26
+ - Production API keys can end up in logs, prompts, screenshots, or cache files.
27
+
28
+ GhostAPI gives agents a safe world to develop in: local, observable, stateful, replayable, and controlled by MCP.
29
+
30
+ ## What You Get
31
+
32
+ - **Local API proxy** on `127.0.0.1:8080`.
33
+ - **Provider-shaped mocks** for Stripe, Twilio, Resend, GitHub, Discord, OpenAI, and generic REST.
34
+ - **Live dashboard** at `/dashboard` with traffic, request/response inspection, setup generation, scenarios, and Chaos Mode.
35
+ - **MCP server** so Claude CLI, Claude Desktop, Cline, Aider, Codex, OpenCode CLI/Desktop, Gemini CLI, Goose, OpenClaw, Hermes Desktop, and other agents can inspect state and control API behavior.
36
+ - **Scenario presets** for repeatable flows like payment failures and issue creation.
37
+ - **Custom scenarios** saved from traffic or imported as JSON.
38
+ - **Generated tests** from captured request/response events.
39
+ - **Safety reports** that flag live provider hosts and live-looking keys.
40
+ - **Copy-ready agent prompts** for Cursor, Claude, Cline, Aider, Codex, OpenCode, Gemini CLI, Goose, OpenClaw, Hermes, and any MCP client.
41
+ - **Chaos Mode** for realistic `429`, `503`, and latency testing.
42
+ - **Secret masking** before logs, cache, dashboard, events, or prompts.
43
+ - **One-click repo setup** for agent rules and MCP config.
44
+
45
+ ## Quick Start
46
+
47
+ Install globally:
48
+
49
+ ```bash
50
+ npm install -g ghostapi
51
+ ghostapi start --open
52
+ ```
53
+
54
+ Or run without installing:
55
+
56
+ ```bash
57
+ npx ghostapi start --open
58
+ ```
59
+
60
+ Open the dashboard manually:
61
+
62
+ ```bash
63
+ ghostapi open
64
+ ```
65
+
66
+ Health check:
67
+
68
+ ```bash
69
+ curl http://127.0.0.1:8080/health
70
+ ```
71
+
72
+ Send a local API request:
73
+
74
+ ```bash
75
+ curl -X POST http://127.0.0.1:8080/tasks \
76
+ -H "content-type: application/json" \
77
+ -d '{"title":"Write integration tests","status":"open"}'
78
+ ```
79
+
80
+ Dashboard:
81
+
82
+ ```text
83
+ http://127.0.0.1:8080/dashboard
84
+ ```
85
+
86
+ ## Agent Setup In One Command
87
+
88
+ Generate copy-ready setup for the current repo:
89
+
90
+ ```bash
91
+ ghostapi setup
92
+ ```
93
+
94
+ Write setup files safely without overwriting existing files:
95
+
96
+ ```bash
97
+ ghostapi setup --write
98
+ ```
99
+
100
+ This detects SDKs in `package.json` and generates:
101
+
102
+ - `.cursorrules`
103
+ - `AGENTS.md`
104
+ - `.cursor/mcp.json`
105
+ - `cline_mcp_settings.json`
106
+ - `claude_desktop_config.json`
107
+ - `.ghostapi/agent-configs/*` snippets for Claude CLI, Claude Desktop, Cline, Aider, Codex, OpenCode CLI, OpenCode Desktop, Gemini CLI, Goose, OpenClaw, Hermes Desktop, and universal MCP clients
108
+ - local env snippets
109
+ - SDK client patches for detected providers
110
+
111
+ The dashboard also includes **Agent Setup**, a copy-first onboarding modal for your agent stack.
112
+
113
+ ## MCP Server
114
+
115
+ Start the MCP server:
116
+
117
+ ```bash
118
+ ghostapi mcp
119
+ ```
120
+
121
+ Use this universal stdio MCP block in any client that supports MCP:
122
+
123
+ ```json
124
+ {
125
+ "mcpServers": {
126
+ "ghostapi": {
127
+ "command": "ghostapi",
128
+ "args": ["mcp"]
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ GhostAPI generates ready-to-copy snippets for:
135
+
136
+ - Claude CLI
137
+ - Claude Desktop
138
+ - Cline
139
+ - Aider
140
+ - Codex
141
+ - OpenCode CLI
142
+ - OpenCode Desktop
143
+ - Gemini CLI
144
+ - Goose
145
+ - OpenClaw
146
+ - Hermes Desktop
147
+ - any generic stdio MCP client
148
+
149
+ Some clients use different config file locations or command names across versions. GhostAPI writes the canonical server block under `.ghostapi/agent-configs/` so you can paste the same `ghostapi mcp` server into the right place for your client.
150
+
151
+ If you are developing from source, use:
152
+
153
+ ```json
154
+ {
155
+ "mcpServers": {
156
+ "ghostapi": {
157
+ "command": "node",
158
+ "args": ["dist/cli/index.js", "mcp"]
159
+ }
160
+ }
161
+ }
162
+ ```
163
+
164
+ Available tools:
165
+
166
+ | Tool | Purpose |
167
+ | --- | --- |
168
+ | `inspect_state` | Read local API objects from `.ghostapi/state.json`. |
169
+ | `set_api_behavior` | Force a deterministic response for `method + path`. |
170
+ | `get_traffic_logs` | Read recent local traffic events. |
171
+ | `toggle_chaos_mode` | Enable or disable local failure injection. |
172
+
173
+ This is the core product loop: the agent writes code, GhostAPI simulates the outside world, and MCP lets the agent inspect and control that world.
174
+
175
+ ## Scenario Presets
176
+
177
+ GhostAPI ships with replayable API flows:
178
+
179
+ - Stripe customer create
180
+ - Stripe payment intent failure
181
+ - Resend email send
182
+ - GitHub issue create
183
+
184
+ From the dashboard, open **Scenarios** and choose:
185
+
186
+ - **Replay** to apply deterministic behavior overrides.
187
+ - **Export** to copy portable scenario JSON.
188
+ - **Share** to copy a compact `ghostapi://scenario/...` payload.
189
+
190
+ Scenario APIs:
191
+
192
+ ```http
193
+ GET /api/scenarios
194
+ POST /api/scenarios
195
+ POST /api/scenarios/save-from-traffic
196
+ POST /api/scenarios/:id/replay
197
+ GET /api/scenarios/:id/export
198
+ POST /api/scenarios/:id/share
199
+ ```
200
+
201
+ ## Agent Prompts, Tests, And Safety Reports
202
+
203
+ The dashboard includes copy-first actions for agent workflows:
204
+
205
+ - **Copy Agent Prompt** gives any coding agent a clean GhostAPI operating prompt.
206
+ - **Generate Test** turns a selected traffic event into a Vitest API test.
207
+ - **Safety Report** scans the repo for live provider hosts and live-looking keys.
208
+ - **Save current traffic** turns recent events into a replayable custom scenario.
209
+
210
+ API endpoints:
211
+
212
+ ```http
213
+ GET /api/agent-prompt
214
+ GET /api/events/:id/test
215
+ GET /api/safety-report
216
+ ```
217
+
218
+ CLI safety report:
219
+
220
+ ```bash
221
+ ghostapi report
222
+ ```
223
+
224
+ ## Chaos Mode
225
+
226
+ Chaos Mode helps test retry logic and failure handling.
227
+
228
+ When enabled:
229
+
230
+ - 85% of requests pass through normally.
231
+ - 15% get a simulated failure or delay.
232
+ - Failures are provider-shaped `429` or upstream errors like `503`.
233
+ - Latency is randomized between 2 and 5 seconds.
234
+
235
+ Enable it from the dashboard or via MCP.
236
+
237
+ ## Provider Support
238
+
239
+ | Provider | Support |
240
+ | --- | --- |
241
+ | Stripe | Detection, validation, provider-shaped responses/errors, stateful objects. |
242
+ | Twilio | Detection, validation, Twilio-shaped errors. |
243
+ | Resend | Detection, validation, email-shaped mocks. |
244
+ | GitHub | Detection and realistic REST-style mocks. |
245
+ | Discord | Detection and local responses. |
246
+ | OpenAI | Detection for chat, responses, embeddings, models, images, audio, files, assistants, threads, vector stores. |
247
+ | Generic REST | Best-effort resource inference for unknown APIs. |
248
+
249
+ ## Using SDKs Locally
250
+
251
+ Stripe example:
252
+
253
+ ```ts
254
+ import Stripe from "stripe";
255
+
256
+ export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY ?? "sk_test_ghostapi", {
257
+ apiBase: process.env.GHOSTAPI_STRIPE_BASE_URL ?? "http://127.0.0.1:8080"
258
+ });
259
+ ```
260
+
261
+ OpenAI example:
262
+
263
+ ```ts
264
+ import OpenAI from "openai";
265
+
266
+ export const openai = new OpenAI({
267
+ apiKey: process.env.OPENAI_API_KEY ?? "sk-ghostapi",
268
+ baseURL: process.env.GHOSTAPI_OPENAI_BASE_URL ?? "http://127.0.0.1:8080/v1"
269
+ });
270
+ ```
271
+
272
+ ## CLI
273
+
274
+ ```bash
275
+ ghostapi start [--host 127.0.0.1] [--port 8080] [--model gpt-4o-mini] [--offline] [--https] [--open]
276
+ ghostapi open [--host 127.0.0.1] [--port 8080] [--https]
277
+ ghostapi setup [--write]
278
+ ghostapi report
279
+ ghostapi mcp
280
+ ghostapi doctor [--port 8080]
281
+ ghostapi init
282
+ ghostapi clear cache|state|events|all
283
+ ghostapi model get
284
+ ghostapi model set <model>
285
+ ghostapi providers list
286
+ ghostapi providers inspect <provider>
287
+ ```
288
+
289
+ ## Local Files
290
+
291
+ GhostAPI writes local development data under `.ghostapi/`:
292
+
293
+ | Path | Purpose |
294
+ | --- | --- |
295
+ | `.ghostapi/config.json` | Project config. |
296
+ | `.ghostapi/state.json` | Local API object state. |
297
+ | `.ghostapi/events.jsonl` | Persisted request events. |
298
+ | `.ghostapi/behaviors.json` | Deterministic behavior overrides from MCP/scenarios. |
299
+ | `.ghostapi/cache/*` | Cached mock responses. |
300
+
301
+ These files are local development artifacts and should not contain production secrets.
302
+
303
+ ## Safety Model
304
+
305
+ - No real provider calls by default.
306
+ - Offline fallback works without an LLM key.
307
+ - Secrets are masked from logs, dashboard, cache keys, event history, and AI prompts.
308
+ - Dashboard mutation APIs reject hostile cross-origin requests.
309
+ - Setup writing never overwrites existing files.
310
+ - Chaos Mode is opt-in.
311
+
312
+ ## Development
313
+
314
+ Install dependencies:
315
+
316
+ ```bash
317
+ npm install
318
+ ```
319
+
320
+ Run from source:
321
+
322
+ ```bash
323
+ npm run dev
324
+ ```
325
+
326
+ Verify:
327
+
328
+ ```bash
329
+ npm run typecheck
330
+ npm test
331
+ npm run build
332
+ npm pack --dry-run
333
+ ```
334
+
335
+ Current hardening status:
336
+
337
+ - Typecheck passing.
338
+ - Test suite passing: 21 files, 97 tests.
339
+ - Build passing.
340
+ - Package dry-run passing.
341
+ - Real dashboard and HTTP smoke checks passing.
342
+
343
+ ## Roadmap
344
+
345
+ - Scenario import and custom scenario builder.
346
+ - Record/replay from real traffic.
347
+ - More provider packs.
348
+ - CI mode for agent-generated integration tests.
349
+ - Shared team workspaces.
350
+ - Hosted docs and landing site.
351
+
352
+ ## License
353
+
354
+ MIT. See [LICENSE](./LICENSE).
package/SECURITY.md ADDED
@@ -0,0 +1,37 @@
1
+ # Security Policy
2
+
3
+ GhostAPI exists to make local integration development safer. Security-sensitive behavior should be treated as core product behavior, not an afterthought.
4
+
5
+ ## Supported Versions
6
+
7
+ GhostAPI is pre-1.0. Security fixes target the current `main` branch and the latest published package once releases begin.
8
+
9
+ ## Safety Model
10
+
11
+ - GhostAPI does not make real external provider API calls by default.
12
+ - Incoming requests are normalized and sanitized before use in prompts, cache keys, logs, or dashboard events.
13
+ - Secret-looking fields are masked, including `authorization`, `api_key`, `apikey`, `x-api-key`, `access_token`, `refresh_token`, `client_secret`, `password`, `secret`, `token`, and `key`.
14
+ - Known token patterns are masked, including Stripe keys, GitHub tokens, Slack bot tokens, SendGrid keys, and bearer tokens.
15
+ - Local cache entries are stored under `.ghostapi/cache/{provider}/{hash}.json`.
16
+ - Local state is stored under `.ghostapi/state.json`.
17
+ - `ghostapi doctor` warns when `NODE_TLS_REJECT_UNAUTHORIZED=0` is set.
18
+
19
+ ## Reporting A Vulnerability
20
+
21
+ Please do not open a public issue for a vulnerability.
22
+
23
+ Until a dedicated security email is published, report privately to the project maintainer or repository owner and include:
24
+
25
+ - A clear description of the issue.
26
+ - Steps to reproduce.
27
+ - Expected impact.
28
+ - Whether secrets, prompts, cache, state, dashboard events, or network behavior are involved.
29
+ - Suggested fix, if you have one.
30
+
31
+ We will acknowledge valid reports as quickly as possible and prioritize fixes that could leak secrets, trigger real external calls unexpectedly, or expose local data.
32
+
33
+ ## Out Of Scope
34
+
35
+ - Issues requiring malicious local filesystem access outside GhostAPI's process permissions.
36
+ - Vulnerabilities in unsupported Node.js versions.
37
+ - Reports without reproduction details.
@@ -0,0 +1,5 @@
1
+ export type AgentPrompt = {
2
+ title: string;
3
+ content: string;
4
+ };
5
+ export declare function generateAgentPrompt(projectRoot?: string): Promise<AgentPrompt>;
@@ -0,0 +1,30 @@
1
+ import { generateRepoSetup } from "../setup/setupGenerator.js";
2
+ export async function generateAgentPrompt(projectRoot = process.cwd()) {
3
+ const setup = await generateRepoSetup(projectRoot);
4
+ const detected = setup.detected.length > 0 ? setup.detected.join(", ") : "no known SDKs detected";
5
+ return {
6
+ title: "GhostAPI Agent Prompt",
7
+ content: [
8
+ "Use GhostAPI as the local API layer for this repository.",
9
+ "",
10
+ "Rules:",
11
+ "- Do not call production third-party APIs unless the user explicitly asks.",
12
+ "- Route local SDKs and HTTP clients to http://127.0.0.1:8080.",
13
+ "- Use GhostAPI MCP tools when available: inspect_state, set_api_behavior, get_traffic_logs, toggle_chaos_mode.",
14
+ "- Before assuming remote state, inspect GhostAPI state and traffic logs.",
15
+ "- Use scenario replay for payment, email, GitHub, and failure-path tests.",
16
+ "- Use Chaos Mode to verify retry, timeout, and degraded-provider handling.",
17
+ "- Never expose real API keys in logs, screenshots, generated tests, or committed files.",
18
+ "",
19
+ `Detected SDKs: ${detected}.`,
20
+ "",
21
+ "Useful commands:",
22
+ "```bash",
23
+ "ghostapi start --open",
24
+ "ghostapi mcp",
25
+ "ghostapi setup --write",
26
+ "```"
27
+ ].join("\n")
28
+ };
29
+ }
30
+ //# sourceMappingURL=agentPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentPrompt.js","sourceRoot":"","sources":["../../src/agents/agentPrompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAO/D,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE;IACnE,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC;IAClG,OAAO;QACL,KAAK,EAAE,uBAAuB;QAC9B,OAAO,EAAE;YACP,0DAA0D;YAC1D,EAAE;YACF,QAAQ;YACR,4EAA4E;YAC5E,+DAA+D;YAC/D,gHAAgH;YAChH,0EAA0E;YAC1E,2EAA2E;YAC3E,4EAA4E;YAC5E,yFAAyF;YACzF,EAAE;YACF,kBAAkB,QAAQ,GAAG;YAC7B,EAAE;YACF,kBAAkB;YAClB,SAAS;YACT,uBAAuB;YACvB,cAAc;YACd,wBAAwB;YACxB,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ServerConfig } from "../config/serverConfig.js";
2
+ type AiMessage = {
3
+ role: "system" | "user";
4
+ content: string;
5
+ };
6
+ export declare function askLLM(messages: AiMessage[], config: ServerConfig): Promise<string>;
7
+ export {};
@@ -0,0 +1,30 @@
1
+ export async function askLLM(messages, config) {
2
+ if (!config.apiKey) {
3
+ throw new Error("No LLM API key configured");
4
+ }
5
+ // A basic OpenAI-compatible implementation. Since GPT-4o-mini / GPT-4o are standard defaults,
6
+ // OpenAI chat completions endpoint is assumed for MVP.
7
+ const response = await fetch("https://api.openai.com/v1/chat/completions", {
8
+ method: "POST",
9
+ headers: {
10
+ "Content-Type": "application/json",
11
+ Authorization: `Bearer ${config.apiKey}`
12
+ },
13
+ body: JSON.stringify({
14
+ model: config.model,
15
+ messages,
16
+ temperature: 0.1
17
+ })
18
+ });
19
+ if (!response.ok) {
20
+ const text = await response.text();
21
+ throw new Error(`LLM Error: ${response.status} ${text}`);
22
+ }
23
+ const json = await response.json();
24
+ const content = json.choices?.[0]?.message?.content;
25
+ if (typeof content !== "string" || content.trim() === "") {
26
+ throw new Error("Invalid LLM response shape");
27
+ }
28
+ return content;
29
+ }
30
+ //# sourceMappingURL=aiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aiClient.js","sourceRoot":"","sources":["../../src/ai/aiClient.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,QAAqB,EAAE,MAAoB;IACtE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,+FAA+F;IAC/F,uDAAuD;IACvD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,4CAA4C,EAAE;QACzE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;SACzC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ;YACR,WAAW,EAAE,GAAG;SACjB,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,cAAc,QAAQ,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA4B,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;IACpD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Response } from "express";
2
+ import type { NormalizedRequest } from "../proxy/requestNormalizer.js";
3
+ import type { ServerConfig } from "../config/serverConfig.js";
4
+ import type { ProviderName } from "../providers/types.js";
5
+ export type AiMockResponse = {
6
+ status: number;
7
+ headers: Record<string, string>;
8
+ body: unknown;
9
+ };
10
+ export declare function generateAiMock(request: NormalizedRequest, provider: ProviderName, response: Response, config: ServerConfig): Promise<AiMockResponse | "streamed">;