Skip to content

Feature/partial mock faz0 - #87

Open
Enes-Kayiklik wants to merge 27 commits into
mainfrom
feature/partial-mock-faz0
Open

Enes-Kayiklik wants to merge 27 commits into
mainfrom
feature/partial-mock-faz0

Conversation

@Enes-Kayiklik

Copy link
Copy Markdown

Summary

Adds a first-class Modifiers pipeline so MockingStar can transform mock or live HTTP responses with JavaScript transformer(req, chain) functions, without changing /mock as the only ingress.

Definitions live on disk as {id}.js (id = filename). Enablement is not stored in the file: it is an ephemeral per-(domain, deviceId) activation set (mock or live source) that Maestro shards and the macOS UI can replace independently. Unmatched traffic keeps the existing mock-first / live-fallback path. Matched-but-broken transformers fail closed (HTTP 500), they do not silently skip the modifier.

The macOS app gains a Modifiers sidebar (list, detail, Claude-assisted authoring, Monaco draft-vs-original diff, Off / Mock / Live). The HTTP control plane adds CRUD, per-device PUT /modifiers, POST /modifiers/preview, CORS, and Swagger UI for the new OpenAPI spec.

Technical Details

  • /mock still resolves mocks; when the device has matching active modifiers, the chain terminal is live if any matched modifier requested live, otherwise the stored mock. disableLiveEnvironment=true (onlyMock) always forces the mock terminal.
  • Activation is process-local. Devices that never PUT /modifiers inherit the UI default ("") set. An explicit PUT (including []) isolates that deviceId. Only the exact header deviceId is used — Android advertising DeviceId is ignored so app traffic stays on the UI set.
  • Preview (POST /modifiers/preview) evaluates an unsaved draft and returns transformed + original bodies; it does not write .js or mock files. Mock source loads sampleMockRequestId; live source proxies once without creating a mock.
  • Rename (PUT with a new body id) rewrites the file, migrates every device activation set, and rolls back activation on 409/store failure.
  • Linux PluginCore ships no-op modifier store/chain (JS engine is macOS-only).
  • Breaking for clients that relied on case-insensitive deviceId for /mock flags: lookup is now exact so DeviceIddeviceId.
  • Activation is lost on MockingStar restart — Maestro/UI must re-PUT after process death.
  • Screenshots useful for: Modifiers list, detail split (response vs JS + Claude/Run), Off/Mock/Live, Mock List → Create Modifier.

Relevant domains

No Android channel paths (trendyol/search, common/, etc.). Whole diff is the MockingStar mock-server / macOS workspace.

MockingStar

  • Changes made: Modifier models, JS executor, per-device activation, /modifiers + preview APIs, OpenAPI/Swagger, Monaco diff editor, Modifiers feature module, sidebar/test-plan wiring, CI OpenAPI lint.
  • Reason: Partial-mock / response-transform without forking mock files per scenario; Maestro shards need isolated activation.
  • Impact: /mock behavior unchanged when no modifiers match. Exact deviceId matching can change which activation set a client hits. Live-only modifier terminals do not persist captured mocks (saveFileIfNeeded only on .default).

Structure

Architecture

  • Disk store (ModifierStore / filename persistence) vs ephemeral ModifierActivationStore (actor, (domain, deviceId){id: source}).
  • Onion chain: ModifierMatcherModifierChain / ModifierExecutor → JS transformer(req, chain) via ModifierBridge; terminal is stored-mock loader or live URLSession.
  • HTTP: HandleModifier + CORS; handler registered from HTTPServer / app on server start.
  • UI: new Features/Modifiers package (list/detail/create VMs, Claude client, draft editing); Editor isolates Monaco sessions and adds a diff WebView.
  • Linux: same API surface, no JS execution.

Dependencies

  • Added local package Features/Modifiers (CommonKit, CommonViewsKit, Editor).
  • Core/Server copies OpenAPI + Swagger UI resources.
  • Core/MockingStarCore tests now depend on Server.
  • CI: @redocly/cli lint on openapi.yaml.
  • No new third-party Swift packages in Package.swift; Claude uses existing HTTPS URLSession to GenAI Gateway. API key stored in UserDefaults (modifierGenAIGatewayAPIKey), not Keychain.

Unit tests

Test Coverage Analysis

  • Test Files Added/Modified:
    • FileUrlBuilderTests.swift, MockFileLocationTests.swift, ModifierMatcherTests.swift, ModifierPreviewModelsTests.swift
    • CommonViewsKitTests.swift
    • EditorSessionTests.swift
    • MockingStarDeviceIdTests.swift, ModifierActivationStoreTests.swift, ModifierIntegrationTests.swift, ModifierPreviewTests.swift
    • ModifierChainTests.swift, ModifierExecutorTests.swift, ModifierOnDemandStoreTests.swift, ModifierParserTests.swift, ModifierStoreTests.swift
    • CORSHandlerTests.swift, HandleDocsTests.swift, HandleModifierTests.swift, PublicEndpointContractTests.swift
    • MockDetailViewModelTests.swift
    • ClaudeMessagesClientTests.swift, ModifierClaudePromptBuilderTests.swift, ModifierCreateViewModelTests.swift, ModifierTransformerEditingTests.swift, ModifierViewModelTests.swift, UserDefaultsAPIKeyStoreTests.swift
  • Test Scenarios Covered:
    • Path/method/scenario matching; mock file location / URL builder; preview model coding
    • Device activation inherit vs explicit []; rename migrate/rollback; exact deviceId vs DeviceId
    • JS parse/execute, chain order, fail-closed errors, on-demand store load
    • HTTP CRUD, activation PUT, preview mock/live/error codes, CORS, OpenAPI docs route, public endpoint contract
    • List/detail/create VMs, transformer editing, Claude prompt/parse, API key store
    • Editor session isolation; MockDetail editor cache/session wiring
    • End-to-end modifier integration on /mock

Review order

  1. ModifierModel.swift — Disk definition + activation-aware API shape (enabled/source not in the .js file)
  2. ModifierPreviewModels.swift — Preview source enum, request/response, API error body
  3. ModifierCreationSeed.swift — Mock List → create prefill
  4. MockModel.swift — JS body type / mock identity used as sample mock
  5. PluginCore/Modifier/HTTPResult.swift — JS-facing HTTP result
  6. PluginCoreLinux/Modifier/HTTPResult.swift — Linux HTTP result stub
  7. ModifierDetailDraft.swift — Unsaved detail editor state
  8. MethodColor.swift — Removed; HTTP method color moved to shared badge
  9. ModifierMatcher.swift — Which active modifiers wrap a request
  10. MockFileLocation.swift — Shared mock file path extraction
  11. FileUrlBuilder.swift — Modifier + mock URL building
  12. FileManager.swift — File IO used by stores
  13. ModifierParser.swift.js metadata + transformer extraction
  14. PluginCore/Modifier/ModifierChain.swift — Onion proceed / order
  15. PluginCoreLinux/Modifier/ModifierChain.swift — Linux no-op chain
  16. ModifierExecutor.swift — Runs transformer, maps JS errors
  17. ModifierBridge.swift — QuickJS (macOS) host bindings
  18. ModifierTransformerEditing.swift — Draft JS edit helpers
  19. ModifierClaudePromptBuilder.swift — Schema-only Claude prompt
  20. ModifierClaudeResponseParser.swift — Extracts transformer from LLM output
  21. ModifierResponseSchemaSummarizer.swift — Token-safe JSON schema for Claude
  22. PluginCore/Modifier/ModifierStore.swift — Filename persist, rename, on-demand load
  23. PluginCoreLinux/Modifier/ModifierStore.swift — Linux store no-op
  24. ModifierActivationStore.swift — Ephemeral per-device sources, inherit, rename
  25. ModifierPreviewService.swift — Unsaved draft vs mock/live terminal
  26. StoredMockLoader.swift — Preview/mock terminal by sampleMockRequestId
  27. APIKeyStore.swift — GenAI key in UserDefaults
  28. ClaudeMessagesClient.swift — Gateway Chat Completions client
  29. ModifierAPIClient.swift — App HTTP client for /modifiers
  30. MockFileManager.swift — Test doubles for file IO
  31. MockFileUrlBuilder.swift — Test doubles for URLs
  32. MockURLSession.swift — Session fake for live terminal
  33. MockingStar.swift/mock routing, fail-closed chain, modifier handler, exact deviceId
  34. HandleModifier.swift — REST: list/create/update/delete/activate/preview
  35. HandleDocs.swift — Serves OpenAPI + Swagger UI
  36. Server.swift — Route + CORS registration
  37. CORSHandler.swift — Browser/control-plane CORS
  38. HTTPServer.swift — Registers modifier handler on start
  39. Editor.swift — Monaco editor API
  40. EditorSession.swift — Isolated editor sessions + JS language
  41. MonacoDiffSession.swift — Draft vs original line reveal
  42. WebView.swift — Hosts Monaco / diff HTML
  43. HTTPMethodBadge.swift — Shared method chip (replaces MockList MethodColor)
  44. NavigationStore.swift — Modifier routes
  45. ModifierListViewModel.swift — List + Off/Mock/Live activation
  46. ModifierDetailViewModel.swift — Save/rename, Run preview, source binding
  47. ModifierCreateViewModel.swift — Create flow + seed
  48. ModifierListView.swift — Sidebar list UI
  49. ModifierDetailView.swift — Split response / JS / Claude / Run
  50. ModifierCreateSheet.swift — Create sheet
  51. ModifierActivationPicker.swift — Off / Mock / Live control
  52. ModifierResponsePane.swift — Preview response pane
  53. MockDetailView.swift — Editor session wiring
  54. MockDetailViewModel.swift — Session-aware detail
  55. EditorCache.swift — Per-session Monaco cache
  56. MockListView.swift — Create Modifier from mock
  57. AppNavigationSplitView.swift — Modifiers destination
  58. SidebarView.swift — Modifiers entry
  59. SideBarServerViewModel.swift — Server start registers modifiers
  60. Features/Modifiers/Package.swift — New feature package
  61. Core/MockingStarCore/Package.swift — Server test dependency
  62. Core/Server/Package.swift — OpenAPI resource bundle
  63. openapi.yaml — Public modifier + docs contract
  64. index.html — Swagger UI shell
  65. index.css — Swagger UI layout
  66. swagger-initializer.js — Points UI at OpenAPI spec
  67. diff.html — Monaco diff page
  68. main.html — Monaco editor page (JS language)
  69. Modifiers.md — Device activation, preview, Maestro setup
  70. GettingStarted-CustomClient.md — Client deviceId notes
  71. contents.xcworkspacedata — Workspace includes Modifiers
  72. project.pbxproj — App target wiring
  73. Localizable.xcstrings — Mock List create-modifier copy
  74. unit-tests.yml — OpenAPI lint job
  75. TestPlan.xctestplan — Includes Modifiers tests
  76. FileUrlBuilderTests.swift — URL builder coverage
  77. MockFileLocationTests.swift — Mock path extraction
  78. ModifierMatcherTests.swift — Path/method/scenario match
  79. ModifierPreviewModelsTests.swift — Preview DTO coding
  80. CommonViewsKitTests.swift — Badge / navigation
  81. EditorSessionTests.swift — Isolated Monaco sessions
  82. MockingStarDeviceIdTests.swift — Exact deviceId vs DeviceId
  83. ModifierActivationStoreTests.swift — Inherit, explicit clear, rename
  84. ModifierIntegrationTests.swift/mock + chain terminal
  85. ModifierPreviewTests.swift — Preview mock/live/errors
  86. ModifierChainTests.swift — Order and short-circuit
  87. ModifierExecutorTests.swift — JS success/failure
  88. ModifierOnDemandStoreTests.swift — Lazy file load
  89. ModifierParserTests.swift.js parse
  90. ModifierStoreTests.swift — CRUD, rename, 409
  91. CORSHandlerTests.swift — CORS headers
  92. HandleDocsTests.swift — Docs routes
  93. HandleModifierTests.swift — HTTP control plane
  94. PublicEndpointContractTests.swift — Public API surface
  95. MockDetailViewModelTests.swift — Editor session
  96. ClaudeMessagesClientTests.swift — Gateway client
  97. ModifierClaudePromptBuilderTests.swift — Prompt contents
  98. ModifierCreateViewModelTests.swift — Create + seed
  99. ModifierTransformerEditingTests.swift — Draft JS edits
  100. ModifierViewModelTests.swift — List/detail activation + preview
  101. UserDefaultsAPIKeyStoreTests.swift — Key persistence

omersungur and others added 21 commits July 15, 2026 17:24
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Comment on lines +61 to +71
name: 'Lint OpenAPI Spec'
runs-on: ubuntu-latest

steps:
- name: Check out Repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Lint OpenAPI spec
run: npx --yes @redocly/cli lint Core/Server/Sources/Server/Resources/OpenAPI/openapi.yaml

steps:
- name: Check out Repository
uses: actions/checkout@v4
Enes-Kayiklik and others added 6 commits September 12, 2026 15:39
URLRequest lives outside Foundation on Linux; drop unused request shadow.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Redocly struct rule rejects OAS 3.0 nullable in 3.1 specs.

Co-authored-by: Cursor <cursoragent@cursor.com>
setUp yield raced the listener Task; CI saw empty lists and stale counts.

Co-authored-by: Cursor <cursoragent@cursor.com>
v2.3.1 pulls gcr.io; that registry now requires billing. v2.4.4 uses ghcr.io.

Co-authored-by: Cursor <cursoragent@cursor.com>
Xcode 26 treats SwiftyJS-expanded private(set) whitespace as an error.

Co-authored-by: Cursor <cursoragent@cursor.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants