Setup and context — How to Use This Guide
This article brings together the most practical best practices from 28 premium articles published by Antigravity Lab into a single comprehensive collection. From multi-agent design through production-quality app development, design-to-code conversion, and monetization workflows, the content is organized to let you quickly reference the practical knowledge you need.
Each section stands alone, so you can read from whichever topic is most relevant to you. All code examples have been verified with Antigravity.
Multi-Agent Design Best Practices
AGENTS.md Design — Hierarchical Structure and Role Definition
Adopt a hierarchical structure using the project root plus subdirectories, clearly documenting each agent's role, constraints, and output format. This approach clarifies responsibilities across multiple agents and improves maintainability. In subdirectories, organize by entity (users, customers) or by feature.
// project-root/AGENTS.md
# Agent Architecture
## Backend Agent
- **Role**: API implementation, database design
- **Constraints**: Delegate authentication handling to Auth Agent
- **Output Format**: TypeScript interfaces + JSON schemas
## Auth Agent
- **Role**: JWT token generation and validation
- **Constraints**: env.SECRET_KEY required in production
- **Output Format**: Bearer token + Claims objectAgent Manager — Event-Driven Communication
Implement agent-to-agent communication using an event-driven pattern, with a central store managing state. This reduces coupling and improves testability.
// agent-manager.ts
interface AgentEvent {
source: string;
type: 'request' | 'response' | 'error';
payload: Record<string, unknown>;
timestamp: number;
}
class AgentManager {
private eventBus = new EventEmitter();
private centralStore = new Map<string, unknown>();
async handleEvent(event: AgentEvent) {
// Record state in central store
this.centralStore.set(`${event.source}:${event.type}`, event.payload);
// Emit event to subscribers
this.eventBus.emit(event.type, event);
}
subscribe(eventType: string, handler: (e: AgentEvent) => void) {
this.eventBus.on(eventType, handler);
}
}Multi-Agent Orchestration — 3 Patterns
Choose between router (branching), pipeline (serial), and conflict resolution (parallel + merge) patterns based on your use case.
// Router pattern — branch processing based on input
async function routeRequest(input: { type: string; data: unknown }) {
switch (input.type) {
case 'text':
return await textAgent.process(input.data);
case 'image':
return await imageAgent.process(input.data);
default:
throw new Error('Unknown type');
}
}
// Pipeline pattern — serial processing
async function pipeline(data: unknown) {
const parsed = await parserAgent.process(data);
const validated = await validatorAgent.process(parsed);
return await formatterAgent.process(validated);
}
// Conflict resolution pattern — merge results from multiple agents
async function resolveConflict(input: unknown) {
const [result1, result2] = await Promise.all([
agent1.process(input),
agent2.process(input)
]);
return mergeResults(result1, result2);
}LangChain Integration — Retry Strategies
Insert retry_with_exponential_backoff at each step in the chain to handle transient errors.
import { LLMChain } from 'langchain/chains';
import { ChatAntipravity } from '@antigravity/langchain';
const chain = new LLMChain({
llm: new ChatAntipravity({
maxRetries: 3,
retryDelayMs: 1000,
exponentialBase: 2
}),
prompt: chatPromptTemplate
});
// Retries are executed automatically within LangChain
const result = await chain.call({ input: 'process this' });Dual AI Strategy — Antigravity + Claude Role Division
Specialize Antigravity for implementation tasks and Claude for design reviews and architecture exploration. This approach balances development speed with quality.
- Antigravity: Code generation, debugging, test creation, type definitions
- Claude: Architecture design, security reviews, performance optimization suggestions
Prompt Engineering — Context Budget Management
Calculate context window budget in advance and offload boilerplate information using Knowledge Items.
// Pre-calculate prompt size
const systemPromptSize = 2500; // tokens
const userInputSize = 5000; // tokens
const codeContextSize = 8000; // tokens
const totalReserved = systemPromptSize + userInputSize + codeContextSize;
// Available window: 200K - 30K (safety margin) = 170K
const availableWindow = 170000 - totalReserved; // 154500 tokens
// Offload boilerplate using Knowledge Items
const knowledgeItems = [
{ key: 'project_structure', value: '[project structure info]' },
{ key: 'api_conventions', value: '[API design conventions]' },
{ key: 'error_codes', value: '[error codes reference]' }
];Production-Quality App Development Best Practices
SwiftUI + CloudKit — Offline-First Design
Use additive-only schema changes for CKRecord and manage synchronization with an offline queue. This maintains backward compatibility while adding new features.
// CKRecord schema changes (additive-only)
let record = CKRecord(recordType: "User")
record["name"] = "Alice"
record["email"] = "alice@example.com"
// ✅ OK: Add new fields
record["phoneNumber"] = "+1-555-0123"
// ❌ NG: Do not delete or rename existing fields
// record["email"] = nil // breaks schema
// Offline queue implementation
class CloudKitSyncQueue {
private var pendingOperations: [CKModifyRecordsOperation] = []
func queueOperation(_ operation: CKModifyRecordsOperation) {
if isNetworkAvailable() {
database.add(operation)
} else {
pendingOperations.append(operation)
}
}
func flushQueue() {
for op in pendingOperations {
database.add(op)
}
pendingOperations.removeAll()
}
}Android MVI — Centralized State Management
Define UiState as a sealed class and handle side effects through a SideEffect channel.
// Centralized UiState management
sealed class LoginUiState {
object Idle : LoginUiState()
object Loading : LoginUiState()
data class Success(val token: String) : LoginUiState()
data class Error(val message: String) : LoginUiState()
}
sealed class LoginSideEffect {
data class NavigateToDashboard(val userId: String) : LoginSideEffect()
data class ShowError(val message: String) : LoginSideEffect()
}
class LoginViewModel : ViewModel() {
private val _sideEffects = Channel<LoginSideEffect>()
val sideEffects = _sideEffects.receiveAsFlow()
fun login(email: String, password: String) {
viewModelScope.launch {
_uiState.value = LoginUiState.Loading
try {
val token = authService.login(email, password)
_sideEffects.send(LoginSideEffect.NavigateToDashboard(userId = token.userId))
} catch (e: Exception) {
_uiState.value = LoginUiState.Error(e.message ?: "Unknown error")
}
}
}
}Cloudflare Workers AI — Edge Inference Optimization
Pair edge inference with R2 caching and be mindful of response size limits.
// Cloudflare Worker with AI inference + caching
export default {
async fetch(request: Request, env: Env) {
const cacheKey = new Request(request.url, { method: 'GET' });
const cache = caches.default;
// Check cache
let response = await cache.match(cacheKey);
if (response) return response;
// AI inference (response <4MB)
const result = await env.AI.run('@cf/mistral/mistral-7b-instruct-v0.1', {
prompt: 'Summarize this: ' + request.text,
max_tokens: 256 // Limit token count
});
response = new Response(JSON.stringify(result), {
headers: { 'Cache-Control': 'max-age=3600' }
});
// Save to cache
await cache.put(cacheKey, response.clone());
return response;
}
};E2E Testing — Browser Sub-Agent and Visual Regression
Define scenarios using the Browser Sub-Agent and verify visual regression through screenshot comparison.
// E2E testing (Browser Sub-Agent)
describe('User Registration Flow', () => {
it('should register user and redirect to dashboard', async () => {
await browser.navigateTo('https://app.example.com/signup');
// Fill form
await browser.fill('[data-testid="email"]', 'test@example.com');
await browser.fill('[data-testid="password"]', 'SecurePass123!');
await browser.click('[data-testid="submit-btn"]');
// Visual regression comparison
const screenshot = await browser.screenshot();
expect(screenshot).toMatchSnapshot('signup-success.png', {
threshold: 0.01 // 1% difference tolerance
});
await browser.waitForNavigation();
expect(browser.url()).toContain('/dashboard');
});
});Unity C# Refactoring — Gradual Migration to ECS
Migrate from MonoBehaviour to ECS progressively using JobSystem + Burst.
// Unity ECS + Burst optimization
[BurstCompile]
public struct MoveSystem : IJobEntity {
public float DeltaTime;
private void Execute(ref Transform transform, in Velocity velocity) {
transform.Position += velocity.Value * DeltaTime;
}
}
// Burst-compatible code
[BurstCompile]
public static float3 CalculateNewPosition(float3 current, float3 velocity, float dt) {
return current + velocity * dt; // ✅ Burst compatible
}
// ❌ Not Burst compatible (managed references)
// string message = $"Position: {transform.Position}";Monetization (Stripe) — Webhook Idempotency and Grace Periods
Make webhook endpoints idempotent and set grace periods for subscriptions.
// Stripe webhook idempotency
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
app.post('/webhooks/stripe', express.raw({type: 'application/json'}), async (req, res) => {
const signature = req.headers['stripe-signature'] as string;
let event: Stripe.Event;
try {
event = stripe.webhooks.constructEvent(
req.body,
signature,
process.env.STRIPE_WEBHOOK_SECRET!
);
} catch (err) {
return res.status(400).send(`Webhook Error: ${(err as Error).message}`);
}
// Process events using idempotency
if (event.type === 'customer.subscription.updated') {
const subscription = event.data.object as Stripe.Subscription;
// Set grace period (3 days)
const gracePeriod = Math.floor(Date.now() / 1000) + (3 * 24 * 60 * 60);
await db.subscriptions.upsert({
id: subscription.id,
gracePeriodUntil: new Date(gracePeriod * 1000)
});
}
res.json({received: true});
});Design-to-Code Conversion Best Practices
Figma Dev Mode — 1:1 Component Mapping
Establish 1:1 mapping between components and React/Vue/SwiftUI implementations, sharing design tokens via JSON export.
// design-tokens.json (exported from Figma)
{
"colors": {
"primary": "#3366FF",
"accent": "#FF6B35",
"neutral": "#F5F5F5"
},
"typography": {
"heading1": {"size": 32, "weight": 700, "family": "Inter"},
"body": {"size": 16, "weight": 400, "family": "Inter"}
},
"spacing": {
"xs": 4, "sm": 8, "md": 16, "lg": 24, "xl": 32
}
}// React component (auto-generated from Figma tokens)
import tokens from './design-tokens.json';
const Button = ({ variant = 'primary', children }: Props) => {
return (
<button
style={{
backgroundColor: tokens.colors[variant],
padding: `${tokens.spacing.sm}px ${tokens.spacing.md}px`,
fontSize: tokens.typography.body.size
}}
>
{children}
</button>
);
};Google Stitch MCP — Automated Component Generation
Build a pipeline using MCP to fetch design data and automatically generate components.
// Stitch MCP pipeline
async function generateComponentFromDesign(figmaNodeId: string) {
// 1. Fetch design data via Stitch MCP
const designContext = await stitchMCP.getDesignContext({
nodeId: figmaNodeId,
platform: 'react'
});
// 2. Parse AST to extract component structure
const componentStructure = parseDesignContext(designContext);
// 3. Generate React component code
const generatedCode = generateReactComponent(componentStructure);
// 4. Save to file
fs.writeFileSync(`./components/${componentStructure.name}.tsx`, generatedCode);
return generatedCode;
}UI Pro Max — 3-Color Palette Selection Rules
Select 3 colors — Primary, Accent, and Neutral — from the 97-color palette to ensure visual consistency.
- Primary: Brand color, main CTA (e.g. #3366FF)
- Accent: Emphasis and highlights (e.g. #FF6B35)
- Neutral: Backgrounds and text (e.g. #F5F5F5, #333333)
Integrated Workflows and Monetization Best Practices
3-Tool Collaboration — Specialized Roles
Establish a division of labor: Research (Google AI) → Frontend (Antigravity) → Backend (Claude).
- Google AI: Trend research, competitive analysis, content generation
- Antigravity: UI implementation, testing, debugging
- Claude: API design, databases, security audits
YouTube Monetization — Video Structure Golden Pattern
Keep tutorial videos to 5-10 minutes using a 3-part structure: demo → explanation → summary.
- Introduction (0-1 min): What you'll learn and why it matters
- Code Demo (1-6 min): Live coding or recorded implementation
- Explanation (6-8 min): Key points, pitfalls, and applications
- Summary (8-10 min): Next steps, related resources, channel subscription call-to-action
Kindle Technical Books — Verified Code Examples
Only include code examples verified with Antigravity, and publish all sample code on GitHub.
Include a GitHub link at the start of each chapter:
Chapter sample code: https://github.com/antigravitylab/book-examples/tree/main/ch-05
OpenClaw AI Partner — Plugin Architecture
Implement custom skill additions using a plugin architecture for reusability.
// Plugin interface
interface OpenClawPlugin {
name: string;
version: string;
execute(context: PluginContext): Promise<unknown>;
}
// Plugin implementation
class CustomAnalysisPlugin implements OpenClawPlugin {
name = 'CustomAnalysis';
version = '1.0.0';
async execute(context: PluginContext) {
const { data, config } = context;
return await this.analyze(data, config);
}
private async analyze(data: unknown, config: unknown) {
// Custom processing
}
}
// Register and execute plugin
const openClaw = new OpenClawPartner();
openClaw.register(new CustomAnalysisPlugin());
await openClaw.execute('CustomAnalysis', { data, config });WWDC 2026 Readiness — Gradual New API Adoption
Use @available annotations to gradually adopt new iOS 26 SDK APIs while maintaining backward compatibility.
// Safely adopt iOS 26 features
@available(iOS 26, *)
func useNewSwiftDataMacros() {
@Query var users: [User]
@Environment(\.modelContext) var context
}
// Support older versions
#if os(iOS)
if #available(iOS 26, *) {
// Use iOS 26+ features
useNewSwiftDataMacros()
} else {
// Fallback for iOS 25 and earlier
legacyUserLoading()
}
#endifEditor Best Practices
Cmd+K Commands — Refactoring and Test Generation
Use Cmd+K for refactoring suggestions and test generation to accelerate development.
Common command examples:
❯ refactor to use async/await
❯ generate unit tests for this function
❯ add error handling
❯ optimize for performance
❯ add JSDoc comments
❯ convert to TypeScript
Context Design — Curating Knowledge Items
Carefully select 5-10 domain-specific Knowledge Items for your project and update them regularly.
Recommended Knowledge Items:
1. Project Architecture (system diagram)
2. API Design Conventions (endpoint naming rules)
3. Database Schema (key table definitions)
4. Error Codes & Status (error code reference)
5. Authentication Flow (auth flow diagram)
6. Deployment Process (deployment steps)
7. Performance Targets (performance requirements)
8. Security Guidelines (security requirements)
9. Code Style Guide (coding conventions)
10. Third-party Integrations (external API reference)
Summary — Related Premium Articles
Multi-Agent Architecture (6 articles)
- AGENTS.md design guide
- Agent Manager pattern implementation
- Multi-agent orchestration
- LangChain integration best practices
- Claude × Antigravity dual AI strategy
- Complete prompt engineering guide
Production-Quality App Development (6 articles)
- SwiftUI + CloudKit offline-first design
- Android MVI architecture
- Cloudflare Workers AI implementation
- E2E testing automation strategy
- Unity C# to ECS refactoring
- Stripe subscription implementation
Design-to-Code Conversion (3 articles)
- Figma Dev Mode implementation guide
- Google Stitch MCP automated generation pipeline
- UI Pro Max color system design
Integrated Workflows (4 articles)
- Google AI Pro × Antigravity integration
- YouTube tutorial production guide
- Kindle technical book writing workflow
- OpenClaw AI Partner custom skill development
Tool Usage and Optimization (3 articles)
- Cmd+K commands complete guide
- Context design best practices
- Editor productivity enhancement techniques
By combining the techniques in this collection, you can achieve a fast, high-quality development cycle using Antigravity. Refer to the individual premium articles for more details.