Welcome to this hands-on tutorial for beginners! You will learn how to use Antigravity, Google's agent-first development platform, together with OpenSpec, a specification framework for spec-driven development (SDD). By the end of this codelab, you will understand how to write clear specifications and let autonomous agents implement them for you.
Before we start with OpenSpec, let's get acquainted with Antigravity — the platform we will use throughout this codelab.
Antigravity is Google's agentic development platform that evolves the IDE into the agent-first era. Unlike a traditional code editor or a simple chat assistant, Antigravity is an autonomous system capable of planning, coding, and web browsing on your behalf.
Think of Antigravity as Mission Control for autonomous agents. Instead of working with one linear chat session, you can dispatch multiple agents simultaneously to handle different tasks, dramatically multiplying your productivity.
Antigravity's two-window architecture makes this possible:
Some things Antigravity can do for you:
Before installing Antigravity, ensure your system meets the following requirements:
After launching the application, you will see three options on the welcome screen:
Sign in with your personal Gmail account to activate your free preview quota.
The Agent Manager is where you talk to your agents. You can use natural language to give instructions, for example:
For inline suggestions directly inside the editor, press Cmd + I (Mac) or Ctrl + I (Windows/Linux). This opens a quick prompt for code suggestions or terminal command generation without leaving the editor.
Stitch is Google's design tool for building UIs. Its MCP server lets Antigravity interact with Stitch directly — generating components, editing designs, and syncing UI work without leaving your agent session.
After saving, Antigravity registers the server with the following configuration:
{
"mcpServers": {
"stitch": {
"serverUrl": "https://stitch.googleapis.com/mcp",
"headers": {
"X-Goog-Api-Key": "YOUR_STITCH_API_KEY"
}
}
}
}
You can review or update this at any time via Antigravity: Manage MCP Servers → Manage MCP Servers tab.
Once connected, you can ask Antigravity to interact with your Stitch designs directly from the Agent Manager.
Now that you are comfortable with Antigravity, it's time to structure your work with OpenSpec and Spec-Driven Development (SDD).
OpenSpec is a specification framework that bridges communication between you and your AI coding agents. Its core philosophy is simple: agree before you build — humans and AI align on specifications before any code is written.
OpenSpec supports 30+ AI coding assistants including Antigravity, Claude Code, Cursor, Windsurf, and GitHub Copilot.
The four guiding principles of OpenSpec:
In traditional development, there is often a gap between what stakeholders want and what gets built. This gap leads to expensive rework, missed deadlines, and products that don't meet expectations.
OpenSpec closes this gap by making you start with clear, structured specifications. These specs become the single source of truth understood by both your team and your AI agents.
Key benefits:
Before starting with OpenSpec, ensure you have:
node --version
Install OpenSpec globally using your preferred package manager.
Using npm (Recommended):
npm install -g @fission-ai/openspec@latest
Using pnpm:
pnpm add -g @fission-ai/openspec@latest
Using yarn:
yarn global add @fission-ai/openspec@latest
Verify the installation:
openspec --version
Navigate to your project folder and run:
openspec init
During initialization, you will be prompted to:
propose, explore, apply, sync, archive.new, continue, ff, verify, bulk-archive, onboard.For this codelab, select the Core profile.
After initialization, OpenSpec creates this structure in your project:
your-project/
├── specs/ # Source of truth for current system behavior
├── changes/ # Proposed modifications (one folder per change)
│ └── change-name/
│ ├── proposal.md
│ ├── specs/ # Delta specs (ADDED / MODIFIED / REMOVED)
│ ├── design.md
│ └── tasks.md
├── archive/ # Completed and archived changes
└── openspec/
├── config.yaml # Project configuration
└── schemas/ # Custom workflow schemas (optional)
The core workflow in OpenSpec follows four steps: propose → apply → sync → archive.
All OpenSpec slash commands are run inside your Antigravity Agent Manager session using the /opsx: prefix.
If your requirements are unclear, start with the explore command. This investigates ideas without creating any artifacts yet.
/opsx:explore
Describe what you are thinking about. The agent will ask clarifying questions and help you define the problem before you commit to a change.
Once you know what you want to build, use the propose command. This creates a complete set of planning artifacts in one step — the fastest way to start a new feature.
/opsx:propose "Your feature description"
Example:
/opsx:propose "As a user, I want to register with my email and password so I can log in to the app."
OpenSpec will generate four interconnected artifacts inside a new changes/ folder:
Artifact | Purpose |
proposal.md | Intent, scope, and high-level approach |
specs/ | Delta specifications: ADDED, MODIFIED, REMOVED sections |
design.md | Technical decisions and architecture |
tasks.md | Implementation checklist with concrete steps |
Each artifact builds on the previous one. Review them before moving forward — you can edit any artifact at any time.
Once the artifacts look good, instruct the agent to start building:
/opsx:apply
The agent works through the tasks.md checklist, writing code task by task. You can update artifacts during implementation as you discover new information — there are no rigid phase gates.
If you are using the Expanded profile, run verify before archiving. This validates your implementation against all artifacts across three dimensions:
tasks.md are implemented./opsx:verify
Once the feature is complete, archive the change. This finalizes the work and merges the delta specs back into your main specs/ folder, keeping the source of truth up to date.
/opsx:archive
The completed change moves to the archive/ folder and your main specs are updated.
Antigravity and OpenSpec work together as a powerful duo for modern software development. Antigravity provides an autonomous agent platform where you dispatch work and stay in control. OpenSpec provides the structured specification framework that makes AI output consistent, predictable, and aligned with your intent.
By mastering both tools, you will move from writing vague prompts to driving structured, spec-first development where agents know exactly what to build and why.
Welcome to the agent-first era of software development!
Now it's time to practice everything you have learned in a real collaborative scenario. In this exercise, we will build an Event Directory — a web app where the community can browse and register for upcoming events. This is something you can actually use after the workshop today!
The project is divided into parts so that each participant or team can work on one part in parallel — each in their own Antigravity Agent Manager session.
You are a developer for a community event organizer. The community needs a simple web application where members can discover events like Express Yourself with Vibe Coding, BWAI Series, and JuaraGCP — and register for them. Each team takes one part of the specification below and executes the full OpenSpec workflow: propose → apply → archive.
git clone https://github.com/iboen/eventapp-codelabs.git
openspec init
/opsx:propose <paste your spec here>
/opsx:apply
/opsx:archive
Below is the full specification. Each team copies only the part assigned to them.
/opsx:propose As a community member, I want to browse a list of upcoming events so that I can find workshops and talks that are relevant to my interests and register for them.
Stitch Design: https://stitch.withgoogle.com/projects/17978044013703626465?node-id=851f745b0d14477dbd7c8a6965d6bcef
Acceptance Criteria:
1. Given I open the Event Directory homepage, then I should see a list of upcoming events sorted by date (soonest first).
2. Given I am viewing the event list, then each event card should display the event title, date, location, type (Workshop / Talk / Online), and registration status (Open / Full / Closed).
3. Given I am viewing the event list, when I click on an event card, then I should be taken to the Event Detail page for that event.
4. Given there are no upcoming events, then a friendly message should be shown encouraging members to check back soon.
UI and Functionality:
- The homepage features a header with the organizer logo and name.
- Events are displayed as cards in a responsive grid (2 columns on desktop, 1 column on mobile).
- Each event card shows: title, date and time, location name, event type badge, and a registration status indicator.
- A search bar at the top allows filtering events by keyword.
- A category filter allows filtering by event type: All, Workshop, Talk, Online.
Error Handling:
- If events fail to load, display a user-friendly error message with a retry button.
/opsx:propose As a community member, I want to see full details about a specific event so that I can decide whether to register and know what to expect.
Stitch Design: https://stitch.withgoogle.com/projects/17978044013703626465?node-id=4b6860fb49c746d4b2ac1e9ec8613e87
Acceptance Criteria:
1. Given I click on an event from the listing page, then I should be taken to that event's detail page.
2. Given I am on the Event Detail page, then I should see the full event title, date and time, location with address, description, speaker(s), event type, capacity, and current registration count.
3. Given registration is open and slots are available, then a prominent "Register Now" button should be visible.
4. Given the event is full (capacity reached), then the "Register Now" button should be replaced with a "Join Waitlist" button.
5. Given registration is closed, then both buttons should be hidden and a "Registration Closed" message should be shown.
UI and Functionality:
- The page displays a hero section with the event title and a cover image (or a default banner if none is provided).
- Speaker section shows speaker name, title/role (e.g., "Google Developer Expert - Web"), and a short bio.
- An embedded map or address block shows the event venue.
- A "Back to Events" link returns the user to the listing page.
- The current registration count is shown as "X / Y registered" (e.g., "17 / 50 registered").
Error Handling:
- If the event is not found, show an "Event Not Found" page with a link back to the listing.
- If details fail to load, show a generic error message.
/opsx:propose As a community member, I want to create an account and log in so that I can register for events and track my registrations.
Stitch Design: https://stitch.withgoogle.com/projects/17978044013703626465?node-id=fc7f93fee3bd4f87b13fbc33f0420f7b
Acceptance Criteria:
1. Given I am a new user, when I fill in my name, email, and password on the Signup page and submit, then my account should be created and I should be logged in automatically.
2. Given I am a returning user, when I enter my correct email and password on the Login page, then I should be logged in and redirected to the homepage.
3. Given I enter an incorrect email or password, then I should see an error message that does not specify which field was wrong (for security).
4. Given I am logged in, when I click Logout, then my session should end and I should be redirected to the homepage.
UI and Functionality:
- Signup form fields: Name, Email, Password, Confirm Password.
- Password must be at least 8 characters with at least one uppercase letter, one number, and one special character. Password field has a show/hide toggle.
- Login form fields: Email, Password.
- Both forms show inline validation errors.
- A "Forgot Password?" link on the login form leads to a password reset flow.
- Logout button is accessible from the navigation bar for logged-in users.
Error Handling:
- Display clear inline error messages for invalid input.
- If the server returns an unexpected error, show a generic message.
/opsx:propose As a logged-in community member, I want to register for an event so that I can secure my spot and receive confirmation.
Stitch Design: https://stitch.withgoogle.com/projects/17978044013703626465?node-id=c7194ca7612944bcb860a3c1feb39170
Acceptance Criteria:
1. Given I am logged in and on an Event Detail page with open registration, when I click "Register Now", then a registration confirmation dialog should appear.
2. Given I confirm registration, then my registration should be saved, the registered count should increment, and I should see a success message.
3. Given I have already registered for an event, then the "Register Now" button should be replaced with a "You're Registered" indicator and a "Cancel Registration" option.
4. Given I am not logged in and click "Register Now", then I should be redirected to the Login page and returned to the event registration flow after login.
5. Given the event is full, when I click "Join Waitlist", then I should be added to the waitlist and see a confirmation message.
UI and Functionality:
- The registration confirmation dialog shows: event name, date, location, and a Confirm / Cancel button pair.
- After successful registration, a confirmation banner appears at the top of the Event Detail page.
- A "Cancel Registration" link appears for already-registered members; clicking it asks for confirmation before cancelling.
- Waitlist registration follows the same confirmation dialog pattern.
Error Handling:
- If registration fails due to a race condition (event just became full), show an error and update the UI to reflect the full status.
- If the server returns an error, show a generic retry message.
/opsx:propose As a logged-in community member, I want to see all the events I have registered for so that I can keep track of my schedule and manage my registrations.
Stitch Design: https://stitch.withgoogle.com/projects/17978044013703626465?node-id=9bf78536e7224ae08a4aab6feba08578
Acceptance Criteria:
1. Given I am logged in and navigate to "My Events", then I should see a list of events I have registered for.
2. Given I am viewing "My Events", then each event entry should show the event name, date, location, and a status badge (Upcoming / Past / Waitlisted).
3. Given I click on an event entry, then I should be taken to that event's detail page.
4. Given I am viewing a registered upcoming event, when I click "Cancel Registration", then the registration should be cancelled and removed from my list.
5. Given I have no registrations, then a friendly empty state should be shown encouraging me to browse upcoming events.
UI and Functionality:
- "My Events" is accessible from the user navigation menu when logged in.
- Events are grouped into two tabs: Upcoming and Past.
- Each event entry shows a status badge: Upcoming (green), Past (grey), Waitlisted (yellow).
- A "Cancel Registration" button is shown only for upcoming events.
- A confirmation dialog appears before cancellation is processed.
Error Handling:
- If the list fails to load, show a user-friendly error with a retry option.
- If cancellation fails, show an error message and keep the registration in the list.
/opsx:propose As a community member, I want to learn more about the speakers at each event so that I can understand their background and expertise before attending.
Stitch Design: https://stitch.withgoogle.com/projects/17978044013703626465?node-id=a0f3d8247f3a4c28b7f8292b68b3f4fd
Acceptance Criteria:
1. Given I am on an Event Detail page, when I click a speaker's name or photo, then I should be taken to that speaker's profile page.
2. Given I am on a Speaker Profile page, then I should see the speaker's name, role/title (e.g., "Google Developer Expert - Web"), organization, bio, profile photo, and links to their social profiles (LinkedIn, GitHub, or website).
3. Given I am on a Speaker Profile page, then I should see a list of past and upcoming events where this speaker has presented or will present.
UI and Functionality:
- Speaker profile page has a header with photo, name, role, and organization.
- A bio section displays a short paragraph about the speaker.
- Social links are shown as icon buttons (LinkedIn, GitHub, personal website).
- An "Events" section lists the events associated with this speaker, each linking to the Event Detail page.
- A "Back" button returns the user to the previous page.
Error Handling:
- If a speaker profile is not found, show a "Profile Not Found" message with a link back to the event listing.
/opsx:propose As an organizer, I want to create new events and manage existing ones so that the community always has up-to-date information.
Acceptance Criteria:
1. Given I am logged in as an organizer, when I navigate to the Admin Dashboard, then I should see a list of all events (past and upcoming) with options to edit or delete each one.
2. Given I click "Create New Event", then I should see a form to fill in the event details.
3. Given I fill in all required fields and submit, then the new event should appear in the public event listing.
4. Given I edit an existing event and save, then the changes should be reflected immediately on the public listing and detail page.
5. Given I delete an event, then a confirmation dialog should appear; upon confirmation the event should be removed from all public views.
UI and Functionality:
- The Admin Dashboard is only accessible to users with the "organizer" role.
- The event creation/edit form includes: Title, Description, Date and Time, Location (name + address), Event Type (Workshop / Talk / Online), Capacity, Registration Deadline, Cover Image upload, and Speaker selection.
- All required fields must be filled before the form can be submitted.
- The dashboard shows a summary card for each event: title, date, registered count vs capacity, and action buttons (Edit / Delete).
Error Handling:
- If a non-organizer tries to access the Admin Dashboard, redirect them to the homepage with an "Access Denied" message.
- If event creation or editing fails, show a specific error message and keep the form data intact so the organizer does not have to re-enter it.
/opsx:propose As a community member, I want to search and filter events by keyword, type, and date so that I can quickly find events relevant to me without scrolling through the entire list.
Acceptance Criteria:
1. Given I type a keyword into the search bar, then the event list should update in real-time to show only events whose title or description contains that keyword.
2. Given I select an event type filter (Workshop, Talk, Online), then the list should show only events of that type.
3. Given I select a date range, then the list should show only events within that range.
4. Given I combine a keyword search with a type filter, then both conditions should apply simultaneously.
5. Given no events match the search or filter criteria, then a "No events found" message should be shown with a suggestion to clear filters.
UI and Functionality:
- Search bar is prominently placed at the top of the listing page.
- Filter controls appear below the search bar: Type (chip/toggle buttons for All / Workshop / Talk / Online) and Date Range (start and end date pickers).
- Filters and search update results immediately without requiring a page reload.
- An "X Clear Filters" button appears when any filter is active, resetting all filters and the search bar in one click.
- The URL updates to reflect the current search and filter state so results can be shared via link.
Error Handling:
- If the search API fails, show a retry message.
- Debounce keyword input by 300ms to avoid excessive API calls.
/opsx:propose As a community member, I want to receive an email confirmation when I register for an event so that I have a record of my registration and a reminder of the event details.
Acceptance Criteria:
1. Given I successfully register for an event, then I should receive a confirmation email within a few minutes to the email address on my account.
2. Given the confirmation email is sent, then it should contain: event title, date and time, location, a link to the event detail page, and a link to cancel my registration.
3. Given I cancel my registration, then I should receive a cancellation confirmation email.
4. Given I am added to a waitlist, then I should receive a waitlist confirmation email.
5. Given a spot opens up and I am next on the waitlist, then I should receive an email notifying me that I have been moved from the waitlist to registered.
UI and Functionality:
- Email sending is handled server-side using a transactional email service.
- Confirmation emails use a clean HTML template with the organizer's branding (logo and colors).
- All emails include a footer: "You are receiving this because you registered at gdg.cloudbandung.id" and an unsubscribe link.
- The cancel registration link in the email works without requiring the user to log in (uses a secure one-time token).
Error Handling:
- If the email service fails, the registration should still succeed. Log the failure and retry sending up to 3 times with exponential backoff.
- Do not block the registration flow waiting for the email to send.
/opsx:propose As a community member, I want to view a recap and photo gallery for past events so that I can see what happened and feel connected to the community even if I could not attend.
Acceptance Criteria:
1. Given I am on the Event Detail page of a past event, then I should see a "Recap" section below the main event information.
2. Given a recap has been published, then the Recap section should show a summary text, key highlights, and a photo gallery.
3. Given I click on a photo in the gallery, then it should open in a full-screen lightbox; when I press the next/previous arrows or keyboard arrow keys, then I should be able to navigate between photos.
4. Given no recap has been published yet for a past event, then the Recap section should not appear.
UI and Functionality:
- The Recap section appears only on past event pages and only when recap content exists.
- Summary text is a rich-text block (supports bold, links, and bullet points).
- Key highlights are displayed as a bulleted list (e.g., "50 participants attended", "3 hands-on demos").
- The photo gallery uses a masonry or grid layout showing thumbnails.
- The lightbox supports keyboard navigation (arrow keys, Escape to close).
- Organizers can add/edit recap content from the Admin Dashboard.
Error Handling:
- If photos fail to load, show placeholder thumbnails with a retry option.
- If the lightbox fails to open, fall back to opening the image in a new browser tab.