Semantic AI compiler + completion engine that converts TypeScript/React web apps to native SwiftUI iOS apps. Auto-detects backend services (Supabase, Stripe, SSE streaming) and generates the right iOS SDK integrations.
morphkit/
├── src/
│ ├── index.ts # CLI entry point (10 commands: analyze, generate, plan, complete, verify, etc.)
│ ├── analyzer/ # Stage 1: Web app analysis (ts-morph AST parsing)
│ │ ├── repo-scanner.ts # File discovery, framework detection
│ │ ├── ast-parser.ts # TypeScript AST parsing, type/component extraction
│ │ ├── component-extractor.ts # React component analysis
│ │ ├── route-extractor.ts # Next.js App Router route tree
│ │ ├── state-extractor.ts # useState/Zustand/Redux/Context detection
│ │ ├── api-extractor.ts # fetch/axios/API route extraction
│ │ └── index.ts # Orchestrator: analyzeRepo()
│ ├── semantic/ # Stage 2: Semantic model building
│ │ ├── model.ts # Zod schemas — THE canonical type source
│ │ ├── builder.ts # Analyzer output → SemanticAppModel
│ │ ├── adapter.ts # Web patterns → iOS patterns mapping
│ │ └── index.ts
│ ├── generator/ # Stage 3: SwiftUI code generation
│ │ ├── swiftui-generator.ts # Views (List, Form, Detail, Dashboard)
│ │ ├── model-generator.ts # Swift Codable structs from entities
│ │ ├── navigation-generator.ts # TabView, NavigationStack, Router
│ │ ├── networking-generator.ts # URLSession API client
│ │ ├── project-generator.ts # Xcode project orchestrator
│ │ └── index.ts
│ ├── ai/ # AI integration (Claude, OpenAI, Grok)
│ │ ├── provider.ts # Provider-agnostic AIProvider interface
│ │ ├── providers/ # claude.ts, grok.ts, openai.ts implementations
│ │ ├── structured-output.ts # Zod schemas for AI responses
│ │ ├── prompts/ # Intent extraction, component mapping, code gen
│ │ └── index.ts
│ ├── mcp/ # Model Context Protocol server
│ │ └── server.ts # 9 MCP tools for Claude Code integration
│ └── verify.ts # Project verification & completion tracking
├── templates/ # Swift/SwiftUI code templates
├── test/
│ ├── analyzer/ # Unit tests for each extractor
│ ├── semantic/ # Builder tests
│ ├── generator/ # Generator output tests
│ ├── e2e/ # Full pipeline integration tests
│ └── __fixtures__/ # Sample Next.js app for testing
├── package.json
├── tsconfig.json
└── bunfig.toml
- Runtime: Bun 1.0+
- Language: TypeScript (strict mode)
- AST Parsing: ts-morph (TypeScript Compiler API)
- AI: Multi-provider (Claude, OpenAI, Grok) — auto-detected from env vars, or
--no-aifor heuristics only - Schemas: Zod for runtime validation + type inference
- Testing: bun:test with coverage
- CLI: Commander.js + chalk + ora
src/semantic/model.tsis the single source of truth for all types- All types are Zod schemas first, TypeScript types inferred via
z.infer<> - Generators must conform to the model types, not define their own
- The analyzer has its own types (ExtractedComponent, ExtractedRoute, etc.) that are mapped to semantic model types in the builder
CLI → Analyzer (ts-morph) → Builder (→ SemanticAppModel) → Adapter (→ iOS mapping) → Generator (→ SwiftUI files)
- Each stage is independent and testable
- AI is optional — builder falls back to heuristics when
XAI_API_KEYis not set - The SemanticAppModel is the boundary between analysis and generation
- Generated Swift targets iOS 17+ (use @Observable, not ObservableObject; #Preview, not PreviewProvider)
- All generated files start with
// Generated by Morphkit from: {relative_source_path} - Confidence scoring: high/medium/low per generated file
- Entity names are always PascalCase, variables camelCase in generated Swift
- Generated networking includes a
KeychainHelper.swiftfor secure iOS Keychain token storage - Generated
APIConfigurationenforces HTTPS in production with TLS 1.2+ minimum - Generated
APIClientusesAPIConfiguration.secureSessionwith proper timeout/TLS config - Swift validation runs both
swiftc -parse(per-file syntax) andswift build(cross-file types) after generation - Generated output compiles with zero errors across all 6 test fixtures (compilation guarantee)
ForEachclosures use explicit type annotations(item: Entity) into avoid Swift 6 type inference issues with complex view builders
- Run:
bun test - Typecheck:
bun run typecheck - E2E test uses
test/__fixtures__/sample-nextjs-app/— a real Next.js e-commerce app - Tests should verify generated output structure, not exact string matches
bun test # Run all tests
bun run typecheck # TypeScript strict checking
bun run src/index.ts analyze ./app # Analyze a Next.js app
bun run src/index.ts plan ./app # Generate iOS conversion plan (free)
bun run src/index.ts generate ./app -o ./ios # Generate SwiftUI project
bun run src/index.ts preview ./app # Preview without writing files
bun run src/index.ts verify ./ios # Check completion status of generated project
bun run src/index.ts complete ./ios # Auto-complete all TODOs using Claude API
bun run src/index.ts setup # Register MCP server in Claude Code
bun run src/index.ts sync ./app ./ios # Re-sync after web app changes
bun run src/index.ts watch ./app # Watch mode — re-generate on changes
bun run src/index.ts doctor # Diagnose configuration- CLI supports API key auth:
--api-keyflag,MORPHKIT_API_KEYenv var, or~/.morphkit/config - Backend: Supabase Auth (magic link) + Stripe (webhooks via Edge Functions)
- Tables:
users,api_keys,subscriptions,usage_logs(seesupabase/migrations/) - Edge Functions:
validate-key,log-usage,stripe-webhook(seesupabase/functions/) - Free tier: 20 conversions/month, Pro: unlimited
- Dashboard:
site/dashboard.html— usage tracking, API key management, Stripe checkout
- Provider-agnostic abstraction:
AIProviderinterface withanalyzeIntent,mapComponent,suggestStateArchitecture,generateCodemethods - Three implementations:
src/ai/providers/claude.ts,src/ai/providers/grok.ts,src/ai/providers/openai.ts - Factory function
createProvider(config)auto-detects the best available provider from environment variables - CLI flags:
--ai-provider <name>to force a provider,--no-aito disable entirely - All responses validated with Zod schemas (
AIIntentResultSchema,AIComponentMapResultSchema, etc.)
- Converts semantic
Entityobjects into Swift@Modelclasses for SwiftData persistence - Also generates
DataManagerwith cache-first loading patterns - Produces both
Codablestructs (for networking) and@Modelclasses (for persistence) - Field type mapping uses
mapTsTypeToSwift()andtypeDefToSwift()fromswiftui-generator.ts
- Handles Next.js App Router file-based routing (primary) and React Router detection (secondary)
- App Router: scans
app/directory forpage.tsx,layout.tsx,loading.tsxconventions - Dynamic routes (
[id],[...slug]) mapped to parameterizedNavigationStackdestinations - Route groups
(group)are recognized and flattened - React Router: detected via
react-router-domdependency inpackage.json
- File system watcher for iterative development workflow
- Monitors source TypeScript/React files for changes and re-runs generation
- Invoked via CLI with
--watchflag on thegeneratecommand
detectBackendServices()scans package.json for known services- Detected: Supabase (auth, database, storage, realtime), Stripe, Firebase, Clerk, OpenAI, Anthropic
- For Supabase: scans source files to detect which features are actually used
- Results populate
backendIntegrationson the SemanticAppModel - Generators use this to produce platform-specific code (SupabaseManager.swift, PaymentManager.swift, SSEClient.swift)
generatePlan(model)scores each screen as essential/recommended/optional/skip- Estimates complexity (low/medium/high) based on data requirements, SSE streaming, payments
- Produces a markdown plan document with detected stack, screen scoring, and next steps
- CLI:
morphkit plan <path>(always free — no API key required)
completeProject(path, options)iteratively resolves MORPHKIT-TODOs using Claude API- Builds structured context: view file + APIClient + models + reference implementation + CLAUDE.md
- Validates completed code with
swiftc --parsebefore writing - Early exits after 3 consecutive non-progress iterations
- CLI:
morphkit complete <path>(requires ANTHROPIC_API_KEY)
- ESLint with
@typescript-eslint/recommended— config in.eslintrc.json no-explicit-anyis set towarn(not error) due to existingas anycasts- Run:
bun run lint
9 tools exposed via the Model Context Protocol for Claude Code integration:
| Tool | Description |
|---|---|
morphkit_analyze |
Analyze a web app → return semantic model summary |
morphkit_generate |
Full pipeline: analyze → build → generate SwiftUI project |
morphkit_plan |
Generate prioritized implementation plan for iOS conversion |
morphkit_screen_context |
Return everything needed to complete a specific screen (view, models, API methods, reference patterns) |
morphkit_verify |
Check project completion: build status, TODO census, screen/API/model completion % |
morphkit_next_task |
Recommend the next screen to implement based on TODO count and dependency order |
morphkit_completion_status |
Machine-readable JSON with exact TODO locations, line numbers, hints for automated loops |
morphkit_complete_screen |
Full context for completing a single screen (view, APIClient, models, reference impl) |
morphkit_fix_build_error |
Parse Swift build errors and return structured context with surrounding code |
Register with morphkit setup — writes to .claude/settings.json.
verifyProject(path) returns a VerifyResult with:
buildStatus: pass/fail/skipped (runsswift buildif toolchain available)todosByCategory: counts ofMORPHKIT-TODO: <category>markerstodosByFile: per-file TODO countsscreenCompletion,apiCoverage,modelCompleteness: percentage metricsoverallPercentage: weighted composite scorenextStep: human-readable recommendation
Generated Swift files contain structured TODO markers: // MORPHKIT-TODO: <category>
Categories:
wire-api-fetch— Connect a view's data loading to APIClientwire-api-action— Connect a user action (submit, delete) to APIClientcomplete-model— Add real fields to a placeholder modelimplement-auth— Wire authentication flow
Each generated view also has // MORPHKIT-TODO-COUNT: N for quick completeness checks.
morphkit complete <project-path> iteratively resolves all MORPHKIT-TODOs using the Claude API:
- Calls
getDetailedTodos()to find remaining TODOs with exact file/line/context - Builds structured context: view file + APIClient + models + reference implementation + CLAUDE.md
- Calls Claude with a system prompt enforcing iOS 17+ patterns (@Observable, .task, NavigationStack)
- Validates completed code with
swiftc --parsebefore writing - Repeats until all TODOs are resolved or max iterations reached
Requires ANTHROPIC_API_KEY environment variable.
The generator creates slash commands for Claude Code in the output project:
/complete-screen— Complete a single screen by name/verify— Run verification and show completion status/next— Get the next recommended task/complete-all— Complete all remaining screens sequentially
- The
AnalysisResulttype inbuilder.tsmust match whatanalyzeRepo()returns fromanalyzer/index.ts - When adding new fields to the semantic model, update the Zod schema in
model.tsfirst, then update builder + generators - The
typeDefToSwift()function inswiftui-generator.tsis the canonical TypeDefinition → Swift type converter — reuse it, don't duplicate - Entity inference comes from 3 sources: TypeScript interfaces (highest priority), state patterns, API response types
- Tab inference uses route topology (top-level routes = tabs), not
screen.isEntryPoint ForEachwith complex view builders (AsyncImage, multiple modifiers) requires explicit closure type annotations in Swift 6 — the generators handle this automatically.onDeleteon ForEach requires Binding arrays in Swift 6 — cart views use.swipeActionsinstead- Generated endpoint methods use plural names for list fetches (
fetchProducts()) and singular for detail fetches (fetchProduct(id:))
Ashlr AI maintains a central documentation vault at ~/Desktop/documentation project/.
- This product's vault path:
01-products/morphkit/ - Agent briefing:
~/Desktop/documentation project/01-products/morphkit/agent-briefing.md - Sales context:
~/Desktop/documentation project/01-products/morphkit/sales-context.md - Full vault navigation:
~/Desktop/documentation project/CLAUDE.md
When working in this repo, update the vault when:
- Feature shipped → update
changelog.md+agent-briefing.md(Current Priorities, Current State) - Architecture change → update
architecture.md+agent-briefing.md(Architecture section) - Pricing change → update
sales-context.md+agent-briefing.md(Business Context) - Priority shift → update
roadmap.md+agent-briefing.md(Current Priorities)
Commit convention: vault: update morphkit/{file} — {reason}