+
+[optional body]
+
+[optional footer(s)]
+```
+
+### Types
+
+| Type | Description | Triggers Release? |
+|------|-------------|-------------------|
+| `feat` | New feature | Minor |
+| `fix` | Bug fix | Patch |
+| `docs` | Documentation | No |
+| `style` | Formatting | No |
+| `refactor` | Code refactoring | No |
+| `perf` | Performance | Patch |
+| `test` | Adding tests | No |
+| `chore` | Maintenance | No |
+| `ci` | CI/CD changes | No |
+
+### Scopes
+
+| Scope | Package |
+|-------|---------|
+| `web` | apps/web |
+| `api` | apps/api |
+| `cli` | apps/cli |
+| `config` | packages/config |
+| `deps` | Dependencies |
+| `ci` | GitHub Actions |
+
+### Examples
+
+```bash
+feat(cli): add terraform export command
+fix(api): resolve rate limiting issue
+docs(readme): update installation instructions
+chore(deps): update dependencies
+perf(cli): optimize resource scanning by 40%
+```
+
+## Pull Request Process
+
+### Before Submitting
+
+- [ ] Run `make pre-commit` and ensure all checks pass
+- [ ] Update documentation if needed
+- [ ] Add tests for new features
+- [ ] Update CHANGELOG.md for user-facing changes
+
+### PR Title Format
+
+Use Conventional Commits format:
+```
+feat(web): add dashboard analytics
+fix(cli): resolve timeout on large scans
+```
+
+### Review Process
+
+```mermaid
+graph LR
+ A[Create PR] --> B[Automated Checks]
+ B --> C{Checks Pass?}
+ C -->|No| D[Fix Issues]
+ D --> B
+ C -->|Yes| E[Code Review]
+ E --> F{Approved?}
+ F -->|No| G[Address Feedback]
+ G --> E
+ F -->|Yes| H[Squash & Merge]
+```
+
+### What Reviewers Look For
+
+- Code follows project style
+- Tests cover new functionality
+- Documentation is updated
+- No unnecessary dependencies added
+- Performance impact considered
+- Security implications reviewed
+
+## Questions?
+
+- Open a [Discussion](https://github.com/RepliMap/replimap-mono/discussions)
+- Email team@replimap.com
diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md
new file mode 100644
index 0000000..96e1d18
--- /dev/null
+++ b/DEPLOYMENT.md
@@ -0,0 +1,146 @@
+# Deployment Guide
+
+## Prerequisites
+
+### Required Secrets (GitHub Repository Settings -> Secrets)
+
+| Secret | Description | Where to get |
+|--------|-------------|--------------|
+| `VERCEL_TOKEN` | Vercel API token | Vercel Dashboard -> Settings -> Tokens |
+| `VERCEL_ORG_ID` | Vercel organization ID | Vercel Dashboard -> Settings -> General |
+| `VERCEL_PROJECT_ID_WEB` | Web project ID | Vercel Dashboard -> Project -> Settings |
+| `CLOUDFLARE_API_TOKEN` | CF API token | Cloudflare Dashboard -> API Tokens |
+| `PYPI_API_TOKEN` | PyPI upload token | PyPI -> Account Settings -> API tokens |
+
+## Platform Configuration
+
+### Vercel (apps/web)
+
+**CRITICAL:** In Vercel Dashboard:
+1. Go to Project Settings -> General
+2. Set **Root Directory** to: `apps/web`
+3. Framework Preset: Next.js (auto-detected)
+4. Node.js Version: 24.x
+
+Without this setting, the relative paths in vercel.json will fail
+and Vercel's build cache won't work correctly.
+
+### Cloudflare Workers (apps/api)
+
+**CRITICAL:** In Cloudflare Dashboard:
+1. Go to Workers -> Your Worker -> Settings
+2. Set **Root Directory** to: `apps/api`
+3. Compatibility flags: `nodejs_compat`
+
+Without this setting, wrangler deploy may fail to find dependencies.
+
+### PyPI (apps/cli)
+
+CLI releases are triggered by git tags:
+```bash
+# Create and push a release tag
+make tag-cli VERSION=0.5.0
+```
+
+## PyPI OIDC Trusted Publishing Setup
+
+OIDC (OpenID Connect) eliminates the need for long-lived API tokens. Configure once on PyPI:
+
+### Step 1: Create Publisher on PyPI
+
+1. Go to https://pypi.org/manage/account/publishing/
+2. Add a new "pending publisher" with:
+ - **PyPI Project Name**: `replimap`
+ - **Owner**: `RepliMap`
+ - **Repository**: `replimap-mono`
+ - **Workflow name**: `release-cli.yml`
+ - **Environment name**: `pypi`
+
+3. Repeat for TestPyPI at https://test.pypi.org/manage/account/publishing/
+ - **Environment name**: `testpypi`
+
+### Step 2: Create GitHub Environments
+
+1. Go to Repository Settings -> Environments
+2. Create environment `pypi`:
+ - Add protection rule: Required reviewers (optional)
+ - Add protection rule: Restrict to tags matching `cli-v*`
+3. Create environment `testpypi`:
+ - No special restrictions needed
+
+### Why OIDC?
+
+| Aspect | API Token | OIDC |
+|--------|-----------|------|
+| Secret Management | Manual rotation needed | No secrets to manage |
+| Scope | Can be overly broad | Scoped to specific workflow |
+| Audit | Limited | Full GitHub audit trail |
+| Revocation | Manual | Automatic |
+
+## Manual Deployment
+
+```bash
+# Deploy web to Vercel
+make deploy-web
+
+# Deploy api to Cloudflare
+make deploy-api
+
+# Release CLI to PyPI
+make release-cli
+```
+
+## Troubleshooting
+
+### "Cannot find module '@replimap/config'"
+Run: `make build-config`
+
+### Generated files out of sync
+Run: `make commit-config`
+
+### CLI config import fails
+Run: `make sync-cli-config`
+
+### Vercel build fails with "command not found: pnpm"
+Ensure the installCommand in vercel.json includes `corepack enable`:
+```json
+{
+ "installCommand": "cd ../.. && corepack enable && pnpm install"
+}
+```
+
+### Cloudflare Workers deployment fails
+1. Ensure you have the correct API token with Workers permissions
+2. Check that `wrangler.toml` has the correct `main` entry point
+3. Verify the worker name matches your Cloudflare configuration
+
+## CI/CD Workflows
+
+The monorepo includes the following GitHub Actions workflows:
+
+- **ci.yml**: Runs on all PRs and pushes to main
+ - Builds all packages
+ - Runs linting and type checking
+ - Verifies generated files are committed
+ - Tests CLI config loading
+
+- **deploy-web.yml**: Deploys to Vercel when apps/web or packages/config changes
+
+- **deploy-api.yml**: Deploys to Cloudflare when apps/api or packages/config changes
+
+- **release-cli.yml**: Publishes to PyPI when a `cli-v*` tag is pushed
+
+## Environment Variables
+
+### Web (apps/web)
+- `NEXT_PUBLIC_API_URL`: API endpoint URL
+- `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY`: Clerk authentication key
+- Other Next.js environment variables as needed
+
+### API (apps/api)
+- Configured in `wrangler.toml` `[vars]` section
+- Secrets set via `wrangler secret put`
+
+### CLI (apps/cli)
+- No build-time environment variables required
+- Runtime configuration via CLI flags or config files
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e0c3411
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,271 @@
+.PHONY: help install build dev clean lint typecheck test \
+ dev-web dev-api dev-cli build-config sync-cli-config \
+ deploy-web deploy-api release-cli deploy-all \
+ check-generated check-versions pre-commit setup info \
+ commit-config tag-cli update
+
+.DEFAULT_GOAL := help
+
+# Colors
+CYAN := \033[36m
+GREEN := \033[32m
+YELLOW := \033[33m
+RED := \033[31m
+RESET := \033[0m
+
+# Version detection
+NODE_VERSION := $(shell node --version 2>/dev/null || echo "not installed")
+PNPM_VERSION := $(shell pnpm --version 2>/dev/null || echo "not installed")
+PYTHON_VERSION := $(shell python3 --version 2>/dev/null || echo "not installed")
+NPM_VERSION := $(shell npm --version 2>/dev/null || echo "not installed")
+
+#==============================================================================
+# Help
+#==============================================================================
+help: ## Show this help message
+ @echo ""
+ @echo "$(CYAN)RepliMap Monorepo$(RESET)"
+ @echo "$(CYAN)=================$(RESET)"
+ @echo ""
+ @echo "$(GREEN)Environment:$(RESET)"
+ @echo " Node: $(NODE_VERSION) (required: 24.x)"
+ @echo " npm: $(NPM_VERSION)"
+ @echo " pnpm: $(PNPM_VERSION) (required: 9.x)"
+ @echo " Python: $(PYTHON_VERSION) (required: 3.11+)"
+ @echo ""
+ @echo "$(GREEN)Available commands:$(RESET)"
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \
+ awk 'BEGIN {FS = ":.*?## "}; {printf " $(CYAN)%-22s$(RESET) %s\n", $$1, $$2}'
+ @echo ""
+ @echo "$(GREEN)Quick start:$(RESET)"
+ @echo " make setup # First-time setup"
+ @echo " make dev-web # Start web dev server"
+ @echo " make dev-api # Start api dev server"
+ @echo ""
+
+#==============================================================================
+# Installation
+#==============================================================================
+install: ## Install all dependencies
+ @echo "$(CYAN)Enabling Corepack for consistent pnpm version...$(RESET)"
+ @corepack enable 2>/dev/null || echo "$(YELLOW)Corepack not available, using system pnpm$(RESET)"
+ pnpm install
+ @echo "$(GREEN)Dependencies installed$(RESET)"
+
+install-frozen: ## Install with frozen lockfile (CI)
+ @corepack enable 2>/dev/null || true
+ pnpm install --frozen-lockfile
+
+update: ## Update all dependencies
+ pnpm update --recursive
+ @echo "$(GREEN)Dependencies updated$(RESET)"
+
+#==============================================================================
+# Build
+#==============================================================================
+build: ## Build all packages
+ pnpm build
+
+build-config: ## Build shared config package
+ pnpm --filter @replimap/config build
+ @echo "$(GREEN)Config package built$(RESET)"
+
+build-web: build-config ## Build web app
+ pnpm --filter @replimap/web build
+
+build-api: build-config ## Build api app
+ pnpm --filter @replimap/api build
+
+build-cli: sync-cli-config ## Build CLI package
+ cd apps/cli && rm -rf dist/ build/ *.egg-info && python -m build
+ @echo "$(GREEN)CLI package built$(RESET)"
+
+#==============================================================================
+# Development
+#==============================================================================
+dev: ## Start all dev servers (parallel)
+ pnpm dev
+
+dev-web: ## Start web dev server
+ pnpm --filter @replimap/web dev
+
+dev-api: ## Start api dev server
+ pnpm --filter @replimap/api dev
+
+dev-cli: sync-cli-config ## Setup CLI for development
+ cd apps/cli && pip install -e ".[dev]" 2>/dev/null || pip install -e .
+ @echo "$(GREEN)CLI installed in dev mode$(RESET)"
+
+#==============================================================================
+# Config Sync
+#==============================================================================
+sync-cli-config: build-config ## Sync config to CLI (generates Python code)
+ @bash apps/cli/scripts/sync-config.sh
+
+check-generated: ## Verify generated files are committed
+ @pnpm --filter @replimap/config build
+ @if [ -n "$$(git status --porcelain packages/config/dist/)" ]; then \
+ echo "$(RED)Generated files out of sync!$(RESET)"; \
+ echo ""; \
+ echo "Run: make commit-config"; \
+ echo ""; \
+ git status --short packages/config/dist/; \
+ exit 1; \
+ fi
+ @echo "$(GREEN)Generated files in sync$(RESET)"
+
+#==============================================================================
+# Code Quality
+#==============================================================================
+lint: ## Run linters
+ pnpm lint
+
+typecheck: ## Run type checking
+ pnpm typecheck
+
+format: ## Format code
+ pnpm format 2>/dev/null || npx prettier --write "**/*.{ts,tsx,js,json,md}"
+ cd apps/cli && ruff format . 2>/dev/null || true
+
+test: ## Run all tests
+ pnpm test 2>/dev/null || true
+ cd apps/cli && pytest tests/ -v 2>/dev/null || echo "$(YELLOW)CLI tests skipped$(RESET)"
+
+pre-commit: lint typecheck check-generated ## Run pre-commit checks
+ @echo "$(GREEN)Pre-commit checks passed$(RESET)"
+
+#==============================================================================
+# Deployment
+#==============================================================================
+deploy-web: build-web ## Deploy web to Vercel
+ cd apps/web && vercel --prod
+
+deploy-api: build-api ## Deploy api to Cloudflare
+ cd apps/api && wrangler deploy --minify
+
+release-cli: build-cli ## Release CLI to PyPI
+ cd apps/cli && twine check dist/* && twine upload dist/*
+
+deploy-all: deploy-web deploy-api ## Deploy web and api
+ @echo "$(GREEN)All deployments complete$(RESET)"
+
+#==============================================================================
+# Cleanup
+#==============================================================================
+clean: ## Clean build artifacts
+ rm -rf node_modules .turbo
+ rm -rf apps/web/.next apps/web/out apps/web/node_modules
+ rm -rf apps/api/dist apps/api/node_modules .wrangler
+ rm -rf apps/cli/dist apps/cli/build apps/cli/*.egg-info
+ rm -rf packages/config/node_modules
+ find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
+ find . -type d -name ".turbo" -exec rm -rf {} + 2>/dev/null || true
+ find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true
+ @echo "$(GREEN)Cleaned$(RESET)"
+
+clean-all: clean ## Deep clean (includes generated files and caches)
+ rm -rf packages/config/dist
+ rm -rf apps/cli/replimap/_generated
+ pnpm store prune 2>/dev/null || true
+ @echo "$(GREEN)Deep cleaned$(RESET)"
+
+#==============================================================================
+# Setup & Info
+#==============================================================================
+setup: check-versions ## First-time development setup
+ @echo "$(CYAN)Setting up RepliMap development environment...$(RESET)"
+ @echo ""
+ $(MAKE) install
+ $(MAKE) build-config
+ $(MAKE) sync-cli-config
+ cd apps/cli && pip install -e ".[dev]" 2>/dev/null || pip install -e .
+ @echo ""
+ @echo "$(GREEN)Setup complete!$(RESET)"
+ @echo ""
+ @echo "$(CYAN)Next steps:$(RESET)"
+ @echo " make dev-web # Start web development"
+ @echo " make dev-api # Start api development"
+ @echo " make dev-cli # Setup CLI development"
+ @echo ""
+ @echo "$(CYAN)Deployment checklist:$(RESET)"
+ @echo " 1. Vercel: Set Root Directory to 'apps/web'"
+ @echo " 2. Cloudflare: Set Root Directory to 'apps/api'"
+ @echo " 3. Add secrets: VERCEL_TOKEN, CLOUDFLARE_API_TOKEN, PYPI_API_TOKEN"
+
+check-versions: ## Verify installed versions meet requirements
+ @echo "$(CYAN)Checking versions...$(RESET)"
+ @NODE_MAJOR=$$(node --version 2>/dev/null | cut -d. -f1 | tr -d 'v'); \
+ if [ -z "$$NODE_MAJOR" ]; then \
+ echo "$(RED)Node.js not installed$(RESET)"; \
+ exit 1; \
+ elif [ "$$NODE_MAJOR" -lt 20 ]; then \
+ echo "$(RED)Node.js v$$NODE_MAJOR found, need v20+ (v24 recommended)$(RESET)"; \
+ exit 1; \
+ elif [ "$$NODE_MAJOR" -lt 24 ]; then \
+ echo "$(YELLOW)Node.js $(NODE_VERSION) - works, but v24 recommended for Vercel parity$(RESET)"; \
+ else \
+ echo "$(GREEN)Node.js $(NODE_VERSION)$(RESET)"; \
+ fi
+ @if ! command -v pnpm >/dev/null 2>&1; then \
+ echo "$(RED)pnpm not installed. Run: corepack enable$(RESET)"; \
+ exit 1; \
+ fi
+ @PNPM_MAJOR=$$(pnpm --version | cut -d. -f1); \
+ if [ "$$PNPM_MAJOR" -lt 9 ]; then \
+ echo "$(YELLOW)pnpm v$$PNPM_MAJOR - upgrade to v9 recommended$(RESET)"; \
+ else \
+ echo "$(GREEN)pnpm $(PNPM_VERSION)$(RESET)"; \
+ fi
+ @echo "$(GREEN)npm $(NPM_VERSION)$(RESET)"
+ @if ! command -v python3 >/dev/null 2>&1; then \
+ echo "$(RED)Python 3 not installed$(RESET)"; \
+ exit 1; \
+ fi
+ @echo "$(GREEN)$(PYTHON_VERSION)$(RESET)"
+
+info: ## Show environment info
+ @echo ""
+ @echo "$(CYAN)RepliMap Monorepo$(RESET)"
+ @echo ""
+ @echo "$(GREEN)Environment:$(RESET)"
+ @echo " Node: $(NODE_VERSION)"
+ @echo " npm: $(NPM_VERSION)"
+ @echo " pnpm: $(PNPM_VERSION)"
+ @echo " Python: $(PYTHON_VERSION)"
+ @echo ""
+ @echo "$(GREEN)Required versions:$(RESET)"
+ @echo " Node: 24.x (Vercel production)"
+ @echo " pnpm: 9.x"
+ @echo " Python: 3.11+"
+ @echo ""
+ @echo "$(GREEN)Components:$(RESET)"
+ @echo " apps/web -> Next.js 16 (Vercel)"
+ @echo " apps/api -> Hono (Cloudflare Workers)"
+ @echo " apps/cli -> Python (PyPI)"
+ @echo " packages/config -> Shared configuration"
+ @echo ""
+ @if [ -f packages/config/dist/index.ts ]; then \
+ echo "$(GREEN)Config Version:$(RESET)"; \
+ grep "CONFIG_VERSION" packages/config/dist/index.ts 2>/dev/null | head -1 | sed 's/^/ /' || echo " (not found)"; \
+ else \
+ echo "$(YELLOW)Config not built. Run: make build-config$(RESET)"; \
+ fi
+ @echo ""
+
+#==============================================================================
+# Git Workflow
+#==============================================================================
+commit-config: build-config ## Build and commit config changes
+ git add packages/config/dist/
+ git commit -m "chore: regenerate config files [skip ci]" || echo "$(YELLOW)No changes to commit$(RESET)"
+
+tag-cli: ## Create CLI release tag (usage: make tag-cli VERSION=0.5.0)
+ @if [ -z "$(VERSION)" ]; then \
+ echo "$(RED)Usage: make tag-cli VERSION=0.5.0$(RESET)"; \
+ exit 1; \
+ fi
+ @echo "$(CYAN)Creating tag cli-v$(VERSION)...$(RESET)"
+ git tag -a "cli-v$(VERSION)" -m "CLI release v$(VERSION)"
+ git push origin "cli-v$(VERSION)"
+ @echo "$(GREEN)Tagged and pushed cli-v$(VERSION)$(RESET)"
+ @echo "$(CYAN)GitHub Actions will now build and publish to PyPI$(RESET)"
diff --git a/README.md b/README.md
index 2b88a88..cb123a1 100644
--- a/README.md
+++ b/README.md
@@ -1,132 +1,283 @@
-# RepliMap Monorepo
+
-Cloud Infrastructure Visualization & Compliance Platform
+# RepliMap
-## Structure
+**AWS Infrastructure Intelligence Platform**
+[](https://github.com/RepliMap/replimap-mono/actions/workflows/ci.yml)
+
+[](https://nodejs.org/)
+[](https://python.org/)
+[](https://pnpm.io/)
+[](https://www.typescriptlang.org/)
+
+[](https://pypi.org/project/replimap/)
+[](https://pypi.org/project/replimap/)
+[](LICENSE)
+
+[Website](https://replimap.com) | [Documentation](https://replimap.com/docs) | [CLI](https://pypi.org/project/replimap/) | [Changelog](CHANGELOG.md)
+
+
+
+---
+
+## What is RepliMap?
+
+RepliMap scans your AWS production environment and generates Terraform code to replicate it for staging, disaster recovery, or compliance testing.
+
+### Architecture Overview
+
+```mermaid
+graph TB
+ subgraph "User Environment"
+ AWS[("AWS Cloud
Production")]
+ TF["Terraform Code
Generated"]
+ end
+
+ subgraph "RepliMap Platform"
+ CLI["CLI
(Python)"]
+ API["API
(Cloudflare Workers)"]
+ WEB["Dashboard
(Next.js)"]
+ DB[("Database")]
+ end
+
+ AWS -->|"1. Scan"| CLI
+ CLI -->|"2. Analyze"| API
+ API --> DB
+ CLI -->|"3. Generate"| TF
+ WEB -->|"View Results"| API
+
+ style AWS fill:#FF9900,stroke:#232F3E,color:#232F3E
+ style CLI fill:#3776AB,stroke:#FFD43B,color:white
+ style API fill:#F38020,stroke:#F38020,color:white
+ style WEB fill:#000000,stroke:#000000,color:white
+ style TF fill:#7B42BC,stroke:#7B42BC,color:white
```
-replimap-mono/
-├── apps/
-│ ├── web/ # Next.js frontend (Vercel)
-│ ├── api/ # Hono API (Cloudflare Workers)
-│ └── cli/ # Python CLI (PyPI)
-├── packages/
-│ └── config/ # Shared configuration (JSON → TS/Python)
-└── .github/
- └── workflows/ # CI/CD pipelines
+
+### Data Flow
+
+```mermaid
+sequenceDiagram
+ participant U as User
+ participant C as CLI
+ participant A as API
+ participant W as AWS
+
+ U->>C: replimap scan
+ C->>W: Discover Resources
+ W-->>C: Resource Inventory
+ C->>C: Build Dependency Graph
+ C->>A: Upload Analysis
+ A-->>C: Scan ID
+ U->>C: replimap export
+ C->>C: Generate Terraform
+ C-->>U: ./terraform/*.tf
```
-## Prerequisites
+## Packages
-- Node.js 20+ (see `.nvmrc`)
-- pnpm 9+
-- Python 3.11+ (for CLI development)
+| Package | Description | Version | Status |
+|---------|-------------|---------|--------|
+| [`@replimap/web`](./apps/web) | Next.js Dashboard | Internal | [](https://replimap.com) |
+| [`@replimap/api`](./apps/api) | Hono API | Internal | [](https://api.replimap.com) |
+| [`replimap`](./apps/cli) | Python CLI | [](https://pypi.org/project/replimap/) | [](https://pypi.org/project/replimap/) |
+| [`@replimap/config`](./packages/config) | Shared Config | Internal | - |
-## Getting Started
+## Quick Start
+
+### Install CLI
```bash
-# Install dependencies
-pnpm install
+# Using pip
+pip install replimap
-# Build all packages
-pnpm build
+# Using pipx (recommended for CLI tools)
+pipx install replimap
-# Build config package only
-pnpm config:build
+# Using uv (fastest)
+uv tool install replimap
```
-## packages/config
+### Basic Usage
-Shared configuration that generates TypeScript and Python code from JSON source files.
+```bash
+# Authenticate with RepliMap
+replimap auth login
-### Source Files
+# Scan your AWS environment
+replimap scan --profile production --region ap-southeast-2
-- `src/plans.json` - Pricing plans configuration
-- `src/frameworks.json` - Compliance frameworks
-- `src/resources.json` - Supported AWS resources
-- `src/schema.json` - JSON Schema definitions
+# View dependency graph
+replimap graph --output graph.html
-### Generated Files
+# Generate Terraform code
+replimap export --format terraform --output ./staging-infra
+```
-The `dist/` directory contains auto-generated code (committed to git):
+## Development
-- `dist/index.ts` - TypeScript exports with full type safety
-- `dist/config.py` - Python dataclasses
+### Prerequisites
-### Usage
+| Tool | Version | Installation | Notes |
+|------|---------|--------------|-------|
+| Node.js | 24.x | [nodejs.org](https://nodejs.org/) | Required for web/api |
+| pnpm | 9.x | `corepack enable` | Package manager |
+| Python | 3.11+ | [python.org](https://python.org/) | Required for CLI |
+| Make | any | Pre-installed on Linux/macOS | See Windows section |
-**TypeScript:**
-```typescript
-import { PLANS, COMPLIANCE_FRAMEWORKS, isPlanName } from '@replimap/config';
+### Setup
-const proPlan = PLANS.pro;
-console.log(`Pro plan: $${proPlan.price_monthly / 100}/month`);
-```
+```bash
+# Clone the repository
+git clone https://github.com/RepliMap/replimap-mono.git
+cd replimap-mono
-**Python:**
-```python
-from packages.config.dist import config
+# First-time setup (installs all dependencies)
+make setup
-pro_plan = config.PLANS["pro"]
-print(f"Pro plan: ${pro_plan.price_monthly / 100}/month")
+# Start development servers
+make dev-web # Web on http://localhost:3000
+make dev-api # API on http://localhost:8787
+make dev-cli # Install CLI in editable mode
```
-### Updating Configuration
+### Available Commands
-1. Edit JSON files in `packages/config/src/`
-2. Run `pnpm config:build`
-3. Commit the changes (including generated `dist/` files)
+Run `make help` for full list. Key commands:
-The CI pipeline will verify generated files are up to date.
+```bash
+# Development
+make dev # Start all dev servers
+make build # Build all packages
+make test # Run all tests
+
+# Quality
+make lint # Run linters
+make typecheck # Type checking
+make pre-commit # All checks before committing
+
+# Deployment
+make deploy-web # Deploy to Vercel
+make deploy-api # Deploy to Cloudflare
+make release-cli # Publish to PyPI
+
+# Utilities
+make info # Show environment info
+make clean # Clean build artifacts
+```
-## Configuration Loading (CLI)
+### Windows Development
-The CLI uses a 4-layer configuration system:
+
+Click to expand Windows setup instructions
-| Priority | Source | Description |
-|----------|--------|-------------|
-| 1 | ENV | Environment variables (`REPLIMAP_*`) |
-| 2 | Drop-in | User config files (`~/.config/replimap/*.json`) |
-| 3 | Cache | Cached remote config (`~/.cache/replimap/`) |
-| 4 | Bundled | Default bundled config |
+#### Option 1: WSL2 (Recommended)
-See `apps/cli/replimap/config/loader.py.template` for implementation details.
+```powershell
+# Install WSL2 with Ubuntu
+wsl --install -d Ubuntu
-## CI/CD
+# Inside WSL, follow standard Linux setup
+cd /mnt/c/path/to/replimap-mono
+make setup
+```
-### CI Pipeline (`.github/workflows/ci.yml`)
+#### Option 2: PowerShell Commands
-- Config generation check (ensures dist files are committed)
-- TypeScript type checking
-- Python config validation
-- Linting
+If you cannot use WSL, here are PowerShell equivalents:
-### Deploy Pipeline (`.github/workflows/deploy.yml`)
+```powershell
+# Install dependencies
+corepack enable
+pnpm install
-Uses path-based filtering for conditional deployments:
+# Build
+pnpm build
-| Component | Trigger Paths | Deploy Target |
-|-----------|---------------|---------------|
-| Web | `apps/web/**`, `packages/config/dist/**` | Vercel |
-| API | `apps/api/**`, `packages/config/dist/**` | Cloudflare Workers |
-| CLI | `apps/cli/**`, `packages/config/dist/**` | PyPI |
+# Development
+pnpm --filter @replimap/web dev
+pnpm --filter @replimap/api dev
-## Development
+# CLI development
+cd apps/cli
+pip install -e ".[dev]"
+```
-```bash
-# Run development servers (when apps are migrated)
-pnpm dev
+#### Option 3: Git Bash
-# Type check all packages
-pnpm typecheck
+Install [Git for Windows](https://gitforwindows.org/) which includes Git Bash, then run `make` commands normally.
-# Lint all packages
-pnpm lint
+
-# Clean build artifacts
-pnpm clean
+## Project Structure
+
+```
+replimap-mono/
+├── apps/
+│ ├── web/ # Next.js 16 frontend
+│ │ ├── src/
+│ │ ├── package.json
+│ │ └── vercel.json
+│ ├── api/ # Hono + Cloudflare Workers
+│ │ ├── src/
+│ │ ├── package.json
+│ │ └── wrangler.toml
+│ └── cli/ # Python CLI
+│ ├── replimap/
+│ ├── pyproject.toml
+│ └── README.md
+├── packages/
+│ └── config/ # Shared configuration
+│ ├── src/ # JSON source files
+│ ├── dist/ # Generated TS + Python
+│ └── scripts/
+├── .github/
+│ ├── workflows/ # CI/CD pipelines
+│ ├── ISSUE_TEMPLATE/ # Bug/feature templates
+│ └── CODEOWNERS
+├── Makefile # Development commands
+├── turbo.json # Turborepo config
+├── CHANGELOG.md
+├── CONTRIBUTING.md
+├── SECURITY.md
+└── LICENSE
```
+## Security
+
+We take security seriously. Our security measures include:
+
+- **OIDC-based publishing** - No long-lived secrets for PyPI
+- **Dependabot** - Automated dependency updates
+- **SOC2 compliance** - Enterprise-grade infrastructure
+
+See [SECURITY.md](SECURITY.md) for vulnerability reporting.
+
## License
-Proprietary - All rights reserved
+This project is proprietary software. See [LICENSE](LICENSE) for details.
+
+## Contributing
+
+We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
+
+## Citation
+
+If you use RepliMap in academic work, please cite:
+
+```bibtex
+@software{replimap,
+ title = {RepliMap: AWS Infrastructure Intelligence Platform},
+ author = {RepliMap Team},
+ year = {2025},
+ url = {https://github.com/RepliMap/replimap-mono}
+}
+```
+
+---
+
+
+
+**Built with care in New Zealand**
+
+
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..68471c9
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,69 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported |
+| ------- | ------------------ |
+| 0.5.x | :white_check_mark: |
+| < 0.5 | :x: |
+
+## Reporting a Vulnerability
+
+We take security vulnerabilities seriously. If you discover a security issue, please report it responsibly.
+
+### How to Report
+
+1. **DO NOT** create a public GitHub issue for security vulnerabilities
+2. Email **security@replimap.com** with:
+ - Description of the vulnerability
+ - Steps to reproduce
+ - Potential impact assessment
+ - Any suggested fixes (optional)
+
+### What to Expect
+
+| Stage | Timeline |
+|-------|----------|
+| Acknowledgment | Within 48 hours |
+| Initial Assessment | Within 1 week |
+| Resolution (Critical) | 24-72 hours |
+| Resolution (High) | 1-2 weeks |
+| Resolution (Medium) | 2-4 weeks |
+| Resolution (Low) | Next release cycle |
+
+## Security Measures
+
+### Supply Chain Security
+
+| Measure | Implementation |
+|---------|---------------|
+| **Dependency Scanning** | Dependabot (weekly) |
+| **Static Analysis** | CodeQL on every PR |
+| **Secret Scanning** | GitHub Advanced Security |
+| **Package Publishing** | OIDC Trusted Publishing (no long-lived tokens) |
+
+### Infrastructure Security
+
+- All traffic encrypted (TLS 1.3)
+- AWS credentials never stored on our servers
+- SOC2 Type II compliant infrastructure
+- Regular penetration testing
+
+### Development Practices
+
+- Signed commits required for releases
+- Branch protection on `main`
+- Required reviews from CODEOWNERS
+- Automated security checks in CI
+
+## Security Contacts
+
+| Contact | Purpose |
+|---------|---------|
+| security@replimap.com | Vulnerability reports |
+
+## Security Hall of Fame
+
+We appreciate responsible disclosure. Researchers who report valid vulnerabilities will be acknowledged here (with permission).
+
+
diff --git a/apps/cli/MANIFEST.in b/apps/cli/MANIFEST.in
index 7fbb30e..795466a 100644
--- a/apps/cli/MANIFEST.in
+++ b/apps/cli/MANIFEST.in
@@ -3,6 +3,8 @@ include README.md
include CHANGELOG.md
recursive-include replimap/templates *.tf *.tf.j2 *.jinja2
recursive-include replimap *.py
+include replimap/_generated/*.py
+include replimap/_generated/**/*.py
global-exclude __pycache__
global-exclude *.pyc
global-exclude *.pyo
diff --git a/apps/cli/pyproject.toml b/apps/cli/pyproject.toml
index 39d33e5..6d862e4 100644
--- a/apps/cli/pyproject.toml
+++ b/apps/cli/pyproject.toml
@@ -87,6 +87,17 @@ Changelog = "https://github.com/RepliMap/replimap/blob/main/CHANGELOG.md"
[tool.hatch.build.targets.wheel]
packages = ["replimap"]
+[tool.hatch.build.targets.wheel.sources]
+"replimap" = "replimap"
+
+[tool.hatch.build]
+include = [
+ "replimap/**/*.py",
+ "replimap/_generated/*.py",
+ "replimap/py.typed",
+ "replimap/templates/**",
+]
+
[tool.hatch.build.targets.sdist]
exclude = [
"tests/",
diff --git a/apps/cli/replimap/_generated/__init__.py b/apps/cli/replimap/_generated/__init__.py
index 7186a36..13270ca 100644
--- a/apps/cli/replimap/_generated/__init__.py
+++ b/apps/cli/replimap/_generated/__init__.py
@@ -1 +1,3 @@
-"""Auto-generated configuration from packages/config."""
+# AUTO-GENERATED DIRECTORY
+# Contents generated from packages/config
+# Do not edit manually - changes will be overwritten
diff --git a/apps/cli/replimap/_generated/config.py b/apps/cli/replimap/_generated/config.py
new file mode 100644
index 0000000..65a5600
--- /dev/null
+++ b/apps/cli/replimap/_generated/config.py
@@ -0,0 +1,218 @@
+"""
+@replimap/config - Auto-generated configuration
+DO NOT EDIT - This file is generated from src/*.json
+
+Content Hash: 7abec13bd128
+"""
+
+from __future__ import annotations
+from dataclasses import dataclass
+from typing import Literal, Optional
+
+
+# ============================================================================
+# Version
+# ============================================================================
+
+CONFIG_VERSION: str = "7abec13bd128"
+
+
+# ============================================================================
+# Plans
+# ============================================================================
+
+PlanName = Literal["free", "pro", "team", "sovereign"]
+
+PLAN_NAMES: tuple[PlanName, ...] = ("free", "pro", "team", "sovereign",)
+
+
+@dataclass(frozen=True)
+class PlanConfig:
+ """Configuration for a pricing plan."""
+ price_monthly: int
+ scans_per_month: Optional[int]
+ max_accounts: Optional[int]
+ features: list[str]
+ addons: Optional[dict[str, int]] = None
+
+
+PLANS: dict[PlanName, PlanConfig] = {
+ "free": PlanConfig(
+ price_monthly=0,
+ scans_per_month=10,
+ max_accounts=None,
+ features=["basic_scan","graph_preview"],
+ addons=None,
+ ),
+ "pro": PlanConfig(
+ price_monthly=2900,
+ scans_per_month=None,
+ max_accounts=None,
+ features=["basic_scan","graph_preview","terraform_download","full_audit"],
+ addons=None,
+ ),
+ "team": PlanConfig(
+ price_monthly=9900,
+ scans_per_month=None,
+ max_accounts=10,
+ features=["*"],
+ addons=None,
+ ),
+ "sovereign": PlanConfig(
+ price_monthly=250000,
+ scans_per_month=None,
+ max_accounts=None,
+ features=["*"],
+ addons={"apra_cps234": 50000, "essential_eight": 30000, "rbnz_bs11": 40000, "dora": 50000},
+ ),
+}
+
+
+# ============================================================================
+# Compliance Frameworks
+# ============================================================================
+
+FrameworkId = Literal["apra_cps234", "essential_eight", "rbnz_bs11", "dora", "soc2", "iso27001"]
+
+FRAMEWORK_IDS: tuple[FrameworkId, ...] = ("apra_cps234", "essential_eight", "rbnz_bs11", "dora", "soc2", "iso27001",)
+
+
+@dataclass(frozen=True)
+class FrameworkConfig:
+ """Configuration for a compliance framework."""
+ name: str
+ region: str
+ description: str
+ controls_count: int
+
+
+COMPLIANCE_FRAMEWORKS: dict[FrameworkId, FrameworkConfig] = {
+ "apra_cps234": FrameworkConfig(
+ name="APRA CPS 234",
+ region="AU",
+ description="Information Security standard for APRA-regulated entities",
+ controls_count=36,
+ ),
+ "essential_eight": FrameworkConfig(
+ name="Essential Eight",
+ region="AU",
+ description="Australian Cyber Security Centre mitigation strategies",
+ controls_count=8,
+ ),
+ "rbnz_bs11": FrameworkConfig(
+ name="RBNZ BS11",
+ region="NZ",
+ description="Reserve Bank of New Zealand outsourcing policy",
+ controls_count=24,
+ ),
+ "dora": FrameworkConfig(
+ name="DORA",
+ region="EU",
+ description="Digital Operational Resilience Act",
+ controls_count=64,
+ ),
+ "soc2": FrameworkConfig(
+ name="SOC 2",
+ region="GLOBAL",
+ description="Service Organization Control 2",
+ controls_count=117,
+ ),
+ "iso27001": FrameworkConfig(
+ name="ISO 27001",
+ region="GLOBAL",
+ description="Information Security Management System",
+ controls_count=114,
+ ),
+}
+
+
+# ============================================================================
+# AWS Resources
+# ============================================================================
+
+ResourceCategory = Literal["compute", "storage", "database", "networking", "security", "messaging", "monitoring"]
+
+RESOURCE_CATEGORIES: tuple[ResourceCategory, ...] = ("compute", "storage", "database", "networking", "security", "messaging", "monitoring",)
+
+AWS_RESOURCES: dict[ResourceCategory, list[str]] = {
+ "compute": ["aws_instance","aws_lambda_function","aws_ecs_cluster","aws_ecs_service","aws_ecs_task_definition","aws_eks_cluster","aws_autoscaling_group"],
+ "storage": ["aws_s3_bucket","aws_ebs_volume","aws_efs_file_system","aws_fsx_lustre_file_system"],
+ "database": ["aws_db_instance","aws_rds_cluster","aws_dynamodb_table","aws_elasticache_cluster","aws_redshift_cluster"],
+ "networking": ["aws_vpc","aws_subnet","aws_security_group","aws_network_acl","aws_route_table","aws_internet_gateway","aws_nat_gateway","aws_lb","aws_lb_target_group","aws_cloudfront_distribution","aws_route53_zone"],
+ "security": ["aws_iam_role","aws_iam_policy","aws_iam_user","aws_iam_group","aws_kms_key","aws_secretsmanager_secret","aws_acm_certificate"],
+ "messaging": ["aws_sqs_queue","aws_sns_topic","aws_kinesis_stream","aws_eventbridge_rule"],
+ "monitoring": ["aws_cloudwatch_log_group","aws_cloudwatch_metric_alarm","aws_cloudtrail"],
+}
+
+ALL_AWS_RESOURCES: tuple[str, ...] = (
+ "aws_instance",
+ "aws_lambda_function",
+ "aws_ecs_cluster",
+ "aws_ecs_service",
+ "aws_ecs_task_definition",
+ "aws_eks_cluster",
+ "aws_autoscaling_group",
+ "aws_s3_bucket",
+ "aws_ebs_volume",
+ "aws_efs_file_system",
+ "aws_fsx_lustre_file_system",
+ "aws_db_instance",
+ "aws_rds_cluster",
+ "aws_dynamodb_table",
+ "aws_elasticache_cluster",
+ "aws_redshift_cluster",
+ "aws_vpc",
+ "aws_subnet",
+ "aws_security_group",
+ "aws_network_acl",
+ "aws_route_table",
+ "aws_internet_gateway",
+ "aws_nat_gateway",
+ "aws_lb",
+ "aws_lb_target_group",
+ "aws_cloudfront_distribution",
+ "aws_route53_zone",
+ "aws_iam_role",
+ "aws_iam_policy",
+ "aws_iam_user",
+ "aws_iam_group",
+ "aws_kms_key",
+ "aws_secretsmanager_secret",
+ "aws_acm_certificate",
+ "aws_sqs_queue",
+ "aws_sns_topic",
+ "aws_kinesis_stream",
+ "aws_eventbridge_rule",
+ "aws_cloudwatch_log_group",
+ "aws_cloudwatch_metric_alarm",
+ "aws_cloudtrail",
+)
+
+AwsResourceType = Literal["aws_instance", "aws_lambda_function", "aws_ecs_cluster", "aws_ecs_service", "aws_ecs_task_definition", "aws_eks_cluster", "aws_autoscaling_group", "aws_s3_bucket", "aws_ebs_volume", "aws_efs_file_system", "aws_fsx_lustre_file_system", "aws_db_instance", "aws_rds_cluster", "aws_dynamodb_table", "aws_elasticache_cluster", "aws_redshift_cluster", "aws_vpc", "aws_subnet", "aws_security_group", "aws_network_acl", "aws_route_table", "aws_internet_gateway", "aws_nat_gateway", "aws_lb", "aws_lb_target_group", "aws_cloudfront_distribution", "aws_route53_zone", "aws_iam_role", "aws_iam_policy", "aws_iam_user", "aws_iam_group", "aws_kms_key", "aws_secretsmanager_secret", "aws_acm_certificate", "aws_sqs_queue", "aws_sns_topic", "aws_kinesis_stream", "aws_eventbridge_rule", "aws_cloudwatch_log_group", "aws_cloudwatch_metric_alarm", "aws_cloudtrail"]
+
+
+# ============================================================================
+# Helper Functions
+# ============================================================================
+
+def is_plan_name(value: str) -> bool:
+ """Check if a string is a valid plan name."""
+ return value in PLAN_NAMES
+
+
+def is_framework_id(value: str) -> bool:
+ """Check if a string is a valid framework ID."""
+ return value in FRAMEWORK_IDS
+
+
+def is_aws_resource_type(value: str) -> bool:
+ """Check if a string is a valid AWS resource type."""
+ return value in ALL_AWS_RESOURCES
+
+
+def get_plan_features(plan: PlanName) -> list[str]:
+ """Get the list of features for a plan."""
+ config = PLANS[plan]
+ if "*" in config.features:
+ return ["basic_scan", "graph_preview", "terraform_download", "full_audit"]
+ return list(config.features)
diff --git a/apps/cli/replimap/py.typed b/apps/cli/replimap/py.typed
new file mode 100644
index 0000000..e69de29
diff --git a/apps/cli/scripts/sync-config.sh b/apps/cli/scripts/sync-config.sh
index c324024..8c24f69 100755
--- a/apps/cli/scripts/sync-config.sh
+++ b/apps/cli/scripts/sync-config.sh
@@ -6,32 +6,34 @@
set -e
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-CLI_ROOT="$(dirname "$SCRIPT_DIR")"
-MONO_ROOT="$(dirname "$(dirname "$CLI_ROOT")")"
-CONFIG_DIST="$MONO_ROOT/packages/config/dist"
-CLI_GENERATED="$CLI_ROOT/replimap/_generated"
+# Use git to find the monorepo root (robust against directory changes)
+REPO_ROOT="$(git rev-parse --show-toplevel)"
+CONFIG_PY="$REPO_ROOT/packages/config/dist/config.py"
+TARGET_DIR="$REPO_ROOT/apps/cli/replimap/_generated"
-echo "Syncing shared configuration to CLI..."
-echo " Source: $CONFIG_DIST"
-echo " Target: $CLI_GENERATED"
+echo "Syncing config..."
+echo " Monorepo Root: $REPO_ROOT"
# Create _generated directory if it doesn't exist
-mkdir -p "$CLI_GENERATED"
-
-# Create __init__.py if it doesn't exist
-if [ ! -f "$CLI_GENERATED/__init__.py" ]; then
- echo '"""Auto-generated configuration from packages/config."""' > "$CLI_GENERATED/__init__.py"
-fi
+mkdir -p "$TARGET_DIR"
# Check if config.py exists in the source
-if [ ! -f "$CONFIG_DIST/config.py" ]; then
- echo "Error: $CONFIG_DIST/config.py not found."
- echo "Please run 'pnpm build:config' first to generate the configuration."
+if [ -f "$CONFIG_PY" ]; then
+ cp "$CONFIG_PY" "$TARGET_DIR/config.py"
+ echo "Synced config.py to $TARGET_DIR"
+else
+ echo "Error: Source config not found at $CONFIG_PY"
+ echo " Action Required: Run 'pnpm --filter @replimap/config build' first"
exit 1
fi
-# Copy the Python config
-cp "$CONFIG_DIST/config.py" "$CLI_GENERATED/config.py"
+# Ensure __init__.py exists
+if [ ! -f "$TARGET_DIR/__init__.py" ]; then
+ cat > "$TARGET_DIR/__init__.py" << 'EOF'
+# AUTO-GENERATED - Do not edit manually
+# This file is generated by sync-config.sh
+EOF
+ echo "Created __init__.py"
+fi
-echo "Configuration synced successfully!"
+echo "Config sync complete"
diff --git a/apps/web/vercel.json b/apps/web/vercel.json
index 4a98ce0..259de34 100644
--- a/apps/web/vercel.json
+++ b/apps/web/vercel.json
@@ -1,8 +1,8 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"framework": "nextjs",
- "installCommand": "pnpm install",
- "buildCommand": "pnpm build",
+ "installCommand": "cd ../.. && corepack enable && pnpm install",
+ "buildCommand": "cd ../.. && pnpm --filter @replimap/config build && pnpm --filter @replimap/web build",
"outputDirectory": ".next",
"regions": ["iad1"],
"headers": [
diff --git a/package.json b/package.json
index ac70da4..180e937 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"lint": "turbo run lint",
"typecheck": "turbo run typecheck",
"clean": "turbo run clean && rm -rf node_modules",
+ "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
"dev:web": "turbo run dev --filter=@replimap/web",
"dev:api": "turbo run dev --filter=@replimap/api",
"build:web": "turbo run build --filter=@replimap/web",
@@ -17,12 +18,13 @@
"sync:cli-config": "bash apps/cli/scripts/sync-config.sh"
},
"devDependencies": {
+ "prettier": "^3.4.0",
"turbo": "^2.3.0",
"typescript": "^5.3.0"
},
- "packageManager": "pnpm@9.14.4",
+ "packageManager": "pnpm@9.15.0",
"engines": {
- "node": ">=24",
- "pnpm": ">=9"
+ "node": ">=20.0.0",
+ "npm": ">=10.0.0"
}
}
diff --git a/packages/config/package.json b/packages/config/package.json
index aded89b..3bbcd22 100644
--- a/packages/config/package.json
+++ b/packages/config/package.json
@@ -1,6 +1,7 @@
{
"name": "@replimap/config",
- "version": "0.0.1",
+ "version": "0.1.0",
+ "private": true,
"description": "Shared configuration for RepliMap - generates TypeScript and Python code from JSON",
"type": "module",
"main": "./dist/index.ts",
@@ -18,6 +19,7 @@
],
"scripts": {
"build": "tsx scripts/build.ts",
+ "dev": "tsx watch scripts/build.ts",
"check": "tsx scripts/build.ts --check",
"clean": "rm -rf dist && mkdir dist"
},
diff --git a/packages/config/tsconfig.json b/packages/config/tsconfig.json
index a52483e..9991cb7 100644
--- a/packages/config/tsconfig.json
+++ b/packages/config/tsconfig.json
@@ -11,6 +11,6 @@
"outDir": "./dist",
"rootDir": "./src"
},
- "include": ["src/**/*", "scripts/**/*"],
+ "include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c115007..32d069b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,6 +8,9 @@ importers:
.:
devDependencies:
+ prettier:
+ specifier: ^3.4.0
+ version: 3.7.4
turbo:
specifier: ^2.3.0
version: 2.7.4
@@ -4498,6 +4501,11 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
+ prettier@3.7.4:
+ resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==}
+ engines: {node: '>=14'}
+ hasBin: true
+
pretty-format@29.7.0:
resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -9664,6 +9672,8 @@ snapshots:
prelude-ls@1.2.1: {}
+ prettier@3.7.4: {}
+
pretty-format@29.7.0:
dependencies:
'@jest/schemas': 29.6.3
diff --git a/release-please-config.json b/release-please-config.json
new file mode 100644
index 0000000..d6bf9ae
--- /dev/null
+++ b/release-please-config.json
@@ -0,0 +1,40 @@
+{
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
+ "packages": {
+ ".": {
+ "release-type": "node",
+ "component": "replimap-mono",
+ "changelog-path": "CHANGELOG.md",
+ "bump-minor-pre-major": true,
+ "bump-patch-for-minor-pre-major": true
+ },
+ "apps/web": {
+ "release-type": "node",
+ "component": "replimap-web",
+ "changelog-path": "CHANGELOG.md"
+ },
+ "apps/api": {
+ "release-type": "node",
+ "component": "replimap-api",
+ "changelog-path": "CHANGELOG.md"
+ }
+ },
+ "plugins": [
+ {
+ "type": "node-workspace",
+ "updateAllPackages": true,
+ "merge": false
+ }
+ ],
+ "changelog-sections": [
+ {"type": "feat", "section": "Features"},
+ {"type": "fix", "section": "Bug Fixes"},
+ {"type": "perf", "section": "Performance"},
+ {"type": "docs", "section": "Documentation"},
+ {"type": "refactor", "section": "Refactoring"},
+ {"type": "chore", "section": "Maintenance", "hidden": true},
+ {"type": "test", "section": "Tests", "hidden": true},
+ {"type": "ci", "section": "CI/CD", "hidden": true}
+ ],
+ "separate-pull-requests": false
+}
diff --git a/turbo.json b/turbo.json
index d5362e5..9e90d39 100644
--- a/turbo.json
+++ b/turbo.json
@@ -1,10 +1,12 @@
{
"$schema": "https://turbo.build/schema.json",
+ "globalDependencies": [".env*"],
+ "globalEnv": ["NODE_ENV", "VERCEL_ENV", "NEXT_PUBLIC_*"],
"tasks": {
"build": {
"dependsOn": ["^build"],
- "inputs": ["$TURBO_DEFAULT$", ".env*"],
- "outputs": ["dist/**", ".next/**", "build/**"]
+ "outputs": ["dist/**", ".next/**", "build/**", "out/**"],
+ "env": ["NODE_ENV"]
},
"dev": {
"cache": false,
@@ -12,18 +14,18 @@
},
"lint": {
"dependsOn": ["^build"],
- "inputs": ["$TURBO_DEFAULT$"]
+ "outputs": []
},
"typecheck": {
"dependsOn": ["^build"],
- "inputs": ["$TURBO_DEFAULT$"]
+ "outputs": []
},
"clean": {
"cache": false
},
"check": {
"dependsOn": ["build"],
- "inputs": ["$TURBO_DEFAULT$"]
+ "outputs": []
}
}
}