frontier-os-app-builder 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -14
  3. package/agents/fos-executor.md +105 -39
  4. package/agents/fos-plan-checker.md +62 -25
  5. package/agents/fos-planner.md +80 -72
  6. package/agents/fos-researcher.md +26 -15
  7. package/agents/fos-verifier.md +96 -27
  8. package/bin/fos-tools.cjs +146 -42
  9. package/bin/install.js +8 -5
  10. package/commands/fos/add-feature.md +1 -2
  11. package/commands/fos/discuss.md +0 -1
  12. package/commands/fos/new-app.md +2 -4
  13. package/commands/fos/new-milestone.md +1 -1
  14. package/commands/fos/plan.md +0 -2
  15. package/package.json +7 -1
  16. package/references/app-patterns.md +128 -21
  17. package/references/deployment.md +40 -124
  18. package/references/module-index.md +32 -0
  19. package/references/sdk/chain.md +92 -0
  20. package/references/sdk/communities.md +159 -0
  21. package/references/sdk/events.md +212 -0
  22. package/references/sdk/init.md +126 -0
  23. package/references/sdk/navigation.md +49 -0
  24. package/references/sdk/offices.md +76 -0
  25. package/references/sdk/partnerships.md +111 -0
  26. package/references/sdk/storage.md +44 -0
  27. package/references/sdk/thirdparty.md +240 -0
  28. package/references/sdk/token-amount.md +99 -0
  29. package/references/sdk/types.md +27 -0
  30. package/references/sdk/ui-utils.md +39 -0
  31. package/references/sdk/user.md +208 -0
  32. package/references/sdk/wallet.md +334 -0
  33. package/references/verification-rules.md +111 -50
  34. package/templates/app/frontier-services.tsx +871 -0
  35. package/templates/app/layout-standalone.tsx +8 -0
  36. package/templates/app/layout.tsx +19 -9
  37. package/templates/app/package-standalone.json +35 -0
  38. package/templates/app/package.json +2 -1
  39. package/templates/app/public/favicon.svg +3 -0
  40. package/templates/app/sdk-context.tsx +7 -9
  41. package/templates/app/sdk-services.tsx +98 -0
  42. package/templates/app/vercel-standalone.json +5 -0
  43. package/templates/app/vercel.json +8 -95
  44. package/templates/state/plan.md +32 -14
  45. package/templates/state/requirements.md +1 -1
  46. package/templates/state/roadmap.md +57 -24
  47. package/templates/state/summary.md +27 -30
  48. package/workflows/add-feature.md +6 -1
  49. package/workflows/discuss.md +126 -11
  50. package/workflows/execute-plan.md +21 -14
  51. package/workflows/execute.md +204 -24
  52. package/workflows/new-app.md +64 -23
  53. package/workflows/new-milestone.md +10 -3
  54. package/workflows/plan.md +16 -5
  55. package/workflows/ship.md +91 -34
  56. package/workflows/status.md +1 -2
  57. package/references/module-inference.md +0 -349
  58. package/references/sdk-surface.md +0 -1622
  59. package/templates/app/main-simple.tsx +0 -19
  60. package/templates/state/manifest.json +0 -11
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BerlinhouseLabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Frontier OS App Builder
2
2
 
3
- A meta-prompting framework for building Frontier OS apps with Claude Code. Provides a guided workflow from idea to deployed app, with built-in knowledge of the Frontier SDK, app patterns, and deployment requirements.
3
+ [![npm version](https://img.shields.io/npm/v/frontier-os-app-builder.svg)](https://www.npmjs.com/package/frontier-os-app-builder)
4
+
5
+ A meta-prompting framework for building [Frontier OS](https://os.frontiertower.io) apps with [Claude Code](https://claude.ai/code). Provides a guided workflow from idea to deployed app, with built-in knowledge of the Frontier SDK, app patterns, and deployment requirements.
6
+
7
+ ## Prerequisites
8
+
9
+ - [Claude Code](https://claude.ai/code) installed
10
+ - Node.js 18+
4
11
 
5
12
  ## Install
6
13
 
@@ -10,21 +17,25 @@ npx frontier-os-app-builder
10
17
 
11
18
  That's it. This installs `/fos:*` commands into your Claude Code environment.
12
19
 
20
+ > Running `npx frontier-os-app-builder` executes the installer automatically. If you install globally instead (`npm i -g frontier-os-app-builder`), run `frontier-os-app-builder` once afterward to populate `~/.claude`.
21
+
13
22
  To uninstall:
14
23
 
15
24
  ```bash
16
25
  npx frontier-os-app-builder --uninstall
17
26
  ```
18
27
 
19
- ## Usage
28
+ ## Quick Start
20
29
 
21
- Create a new directory for your app, then run:
30
+ 1. Create a directory for your new app
31
+ 2. Open Claude Code in that directory
32
+ 3. Run:
22
33
 
23
34
  ```
24
- /fos:new-app "a room booking app for Frontier members"
35
+ /fos:new-app "A tip jar app where members can tip baristas and staff with FND"
25
36
  ```
26
37
 
27
- The framework guides you through each step, telling you when to `/clear` and what command to run next:
38
+ 4. Follow the guided workflow the framework tells you what to do next after each step:
28
39
 
29
40
  ```
30
41
  /fos:new-app "description" → gather requirements, infer SDK modules, create roadmap
@@ -39,6 +50,16 @@ The framework guides you through each step, telling you when to `/clear` and wha
39
50
  /fos:ship → deploy to Vercel + register in app store
40
51
  ```
41
52
 
53
+ 5. Keep building — add features or start a new version:
54
+
55
+ ```
56
+ /fos:add-feature "leaderboard" → adds a new phase to the current milestone
57
+ /clear
58
+ /fos:discuss N → /fos:plan N → /fos:execute N → same loop
59
+
60
+ /fos:new-milestone "v2 features" → archives v1, creates new phases for v2
61
+ ```
62
+
42
63
  ## Commands
43
64
 
44
65
  | Command | Purpose |
@@ -53,6 +74,12 @@ The framework guides you through each step, telling you when to `/clear` and wha
53
74
  | `/fos:next` | Auto-route to the next step in the workflow |
54
75
  | `/fos:status` | Show current project state |
55
76
 
77
+ ## Configuration
78
+
79
+ | Environment variable | Used by | Effect |
80
+ |---|---|---|
81
+ | `FOS_GITHUB_ORG` | `/fos:ship` | Creates the deployed app's GitHub repo under this organization. When unset (the default), the repo is created under your authenticated `gh` user account. |
82
+
56
83
  ## How it works
57
84
 
58
85
  The framework is a multi-layered meta-prompting system:
@@ -63,20 +90,53 @@ The framework is a multi-layered meta-prompting system:
63
90
  - **References** — built-in Frontier SDK and app pattern knowledge
64
91
  - **Templates** — production-tested boilerplate from existing Frontier OS apps
65
92
 
66
- Each command reads state from `.frontier-app/` on disk, does its work, writes updated state, and tells you what to do next. The `/clear` between steps keeps your context window fresh.
93
+ Each command reads state from `.frontier-app/` on disk, does its work, writes updated state, and tells you what to do next. Running `/clear` between steps keeps your context window fresh — the file-based state bridges the gap.
67
94
 
68
95
  ## Key features
69
96
 
70
- - Infers SDK modules from your app description ("room booking" → Events + Wallet)
71
- - Asks smart domain questions, not generic ones
72
- - Researches patterns from production Frontier OS apps
73
- - Uses proven templates instead of generating code from scratch
74
- - Verifies against Frontier-specific rules (CORS, iframe detection, permissions)
75
- - Milestone system for iterative development (v1 → v2 → v3)
97
+ - **Module inference** describe your app in plain English and the framework maps it to the right SDK modules ("room booking" → Events + Wallet + User)
98
+ - **Smart questions** — asks domain questions ("Should bookings require FND payment?"), not technical ones ("Which SDK modules?")
99
+ - **Production templates** — boilerplate extracted from real Frontier OS apps, not generated from scratch
100
+ - **Frontier-specific verification** checks CORS origins, iframe detection, standalone fallback, SDK permissions, dark theme
101
+ - **Milestones** iterative development with `/fos:new-milestone` for v2, v3, and beyond
76
102
 
77
- ## State
103
+ ## Frontier Studio
78
104
 
79
- All project state lives in `.frontier-app/` as human-readable Markdown and JSON:
105
+ Frontier Studio is a live companion dashboard that runs alongside Claude Code. It watches your `.frontier-app/` state files and shows a visual dashboard with a live app preview in your browser.
106
+
107
+ ```bash
108
+ cd your-app-directory
109
+ npx frontier-studio
110
+ ```
111
+
112
+ Opens `http://localhost:4983` with:
113
+
114
+ - **Project dashboard** — phases, status, SDK modules, progress, next action
115
+ - **Live preview** — your app rendered via Vite HMR in an iframe (desktop/tablet/mobile)
116
+ - **Activity stream** — file changes, git commits, phase transitions in real time
117
+
118
+ See [studio/README.md](./studio/README.md) for development details.
119
+
120
+ ## SDK Coverage
121
+
122
+ The framework has built-in knowledge of all 10 Frontier SDK modules:
123
+
124
+ | Module | What it does |
125
+ |---|---|
126
+ | Wallet | Balances, FND transfers, token swaps, fiat on/off-ramp |
127
+ | User | Profiles, referrals, KYC, access controls |
128
+ | Events | Event management, room listings, bookings |
129
+ | Communities | Community management, internship passes |
130
+ | Partnerships | Sponsor passes |
131
+ | Offices | Building access passes |
132
+ | Storage | Persistent key-value storage |
133
+ | Chain | Network config, contract addresses |
134
+ | ThirdParty | App registration, webhooks, developer accounts |
135
+ | Navigation | App-to-app deep linking |
136
+
137
+ ## Project State
138
+
139
+ All state lives in `.frontier-app/` as human-readable Markdown and JSON — no database, no server:
80
140
 
81
141
  ```
82
142
  .frontier-app/
@@ -90,3 +150,19 @@ All project state lives in `.frontier-app/` as human-readable Markdown and JSON:
90
150
  ├── 02-feature/
91
151
  └── ...
92
152
  ```
153
+
154
+ ## Example Apps
155
+
156
+ Ideas to get started:
157
+
158
+ | App | Description | SDK Modules |
159
+ |---|---|---|
160
+ | Tip Jar | Members tip baristas with FND | Wallet, User |
161
+ | Visitor Check-in | Kiosk for building access passes | Offices, User |
162
+ | Room Booking | Book coworking rooms with payment | Events, Wallet, User |
163
+ | Event Organizer | Create and manage community events | Events, Communities, User |
164
+ | Sponsor Dashboard | Manage partnership passes | Partnerships, User |
165
+
166
+ ## License
167
+
168
+ MIT
@@ -27,7 +27,26 @@ Before executing, discover project context:
27
27
 
28
28
  <execution_flow>
29
29
 
30
- <step name="load_project_state" priority="first">
30
+ <step name="verify_cwd" priority="first">
31
+ **CRITICAL — Verify working directory before anything else.**
32
+
33
+ When spawned in a worktree, your CWD may be the worktree root, not the app directory. Check:
34
+
35
+ ```bash
36
+ ls .frontier-app/manifest.json 2>/dev/null && echo "CWD OK" || echo "CWD WRONG"
37
+ ```
38
+
39
+ If `CWD WRONG`: look for the app directory inside the current directory. The worktree contains a copy of the repo — `cd` into it:
40
+ ```bash
41
+ # Find the app directory (has .frontier-app/)
42
+ APP_DIR=$(find . -maxdepth 2 -name "manifest.json" -path "*/.frontier-app/*" -exec dirname {} \; | head -1 | sed 's|/.frontier-app||')
43
+ cd "$APP_DIR"
44
+ ```
45
+
46
+ **All subsequent commands and file paths must be relative to the app root (where `.frontier-app/` exists).** Never use absolute worktree paths in git add commands — use paths relative to the repo root (e.g., `git add .frontier-app/phases/01-scaffold/01-01-SUMMARY.md`, NOT `git add frontier-os-app-name/.frontier-app/...`).
47
+ </step>
48
+
49
+ <step name="load_project_state">
31
50
  Load execution context:
32
51
 
33
52
  1. Read `.frontier-app/PROJECT.md` — app name, description, SDK modules
@@ -102,27 +121,43 @@ node $HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs scaffold <template>
102
121
  | Template | Destination |
103
122
  |----------|-------------|
104
123
  | `index.html` | `./index.html` |
105
- | `package.json` | `./package.json` |
124
+ | `package-standalone.json` | `./package.json` |
106
125
  | `postcss.config.js` | `./postcss.config.js` |
107
126
  | `tsconfig.json` | `./tsconfig.json` |
108
- | `vercel.json` | `./vercel.json` |
127
+ | `vercel-standalone.json` | `./vercel.json` |
109
128
  | `vite.config.ts` | `./vite.config.ts` |
110
- | `sdk-context.tsx` | `./src/lib/sdk-context.tsx` |
111
- | `layout.tsx` | `./src/views/Layout.tsx` |
112
- | `main-router.tsx` or `main-simple.tsx` | `./src/main.tsx` |
129
+ | `frontier-services.tsx` | `./src/lib/frontier-services.tsx` |
130
+ | `layout-standalone.tsx` | `./src/views/Layout.tsx` |
131
+ | `main-router.tsx` | `./src/main.tsx` |
113
132
  | `router.tsx` | `./src/router.tsx` |
114
133
  | `index.css` | `./src/styles/index.css` |
115
134
  | `test-setup.ts` | `./src/test/setup.ts` |
116
135
  | `gitignore` | `./.gitignore` |
136
+ | `public/` | `./public/` |
117
137
 
118
138
  **Critical scaffold requirements:**
119
- - `src/lib/sdk-context.tsx` — NEVER modify after scaffold. Identical across all apps.
120
- - `src/views/Layout.tsx` — Must include `isInFrontierApp()` detection, `createStandaloneHTML()` fallback, `SdkProvider` wrapping children
139
+ - `src/lib/frontier-services.tsx` — Exports `useServices()` with mock backend. Modified only during SDK Integration phase.
140
+ - `src/views/Layout.tsx` — Dark-themed shell wrapping Outlet with FrontierServicesProvider. SdkProvider added during SDK Integration phase.
121
141
  - `src/styles/index.css` — Must include `@import "tailwindcss"`, complete `@theme` block with ALL CSS variables, `@layer base` with body styles
122
142
  - `index.html` — Must have `<body class="dark">`, Plus Jakarta Sans font links
123
- - `vercel.json` — Must have all 5 CORS origin blocks + SPA rewrite
143
+ - `vercel.json` — SPA rewrite only at scaffold time. CORS origins added during SDK Integration phase.
124
144
  - `package.json` — Must have correct scripts (dev, build, preview, lint, test) and all required dependencies
125
145
 
146
+ **Phase 1 scaffold BLOCKLIST — If any of these exist after scaffold, you have a bug. Fix it before committing:**
147
+ - ❌ `src/lib/sdk-context.tsx` — DELETE if created. This file belongs to SDK Integration phase only.
148
+ - ❌ `@frontiertower/frontier-sdk` in package.json — REMOVE from dependencies. SDK is added in SDK Integration phase.
149
+ - ❌ `isInFrontierApp` or `createStandaloneHTML` in Layout.tsx — REWRITE Layout to use simple FrontierServicesProvider + Outlet pattern.
150
+ - ❌ `SdkProvider` anywhere — REPLACE with FrontierServicesProvider.
151
+ - ❌ `useSdk` anywhere — REPLACE with useServices.
152
+ - ❌ Any import from `@frontiertower/frontier-sdk` — REMOVE. The SDK package does not exist in Phase 1.
153
+ - ❌ CORS headers in vercel.json — REMOVE. Use SPA rewrite only.
154
+
155
+ **Self-check after scaffold (run before committing):**
156
+ ```bash
157
+ # All of these must return NO matches. If any match, fix before committing.
158
+ grep -r "sdk-context\|useSdk\|SdkProvider\|@frontiertower/frontier-sdk\|isInFrontierApp\|createStandaloneHTML" src/ package.json vercel.json --include="*.tsx" --include="*.ts" --include="*.json" 2>/dev/null | grep -v node_modules || echo "CLEAN: No SDK artifacts in Phase 1"
159
+ ```
160
+
126
161
  </scaffold_execution>
127
162
 
128
163
  <feature_execution>
@@ -131,37 +166,41 @@ node $HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs scaffold <template>
131
166
 
132
167
  For feature tasks (Phase 2+), write actual TypeScript/React code.
133
168
 
134
- ### SDK Code Patterns
169
+ ### Services Code Patterns
135
170
 
136
171
  **Always use these exact patterns:**
137
172
 
138
- **Import SDK:**
173
+ **Import services:**
139
174
  ```typescript
140
- import { useSdk } from '../lib/sdk-context';
175
+ import { useServices } from '../lib/frontier-services';
141
176
  ```
142
177
 
143
178
  **Access module:**
144
179
  ```typescript
145
- const sdk = useSdk();
146
- const wallet = sdk.getWallet();
180
+ const services = useServices();
181
+ const wallet = services.wallet;
147
182
  ```
148
183
 
149
184
  **Create hooks with loading/error states:**
150
185
  ```typescript
151
186
  import { useState, useEffect } from 'react';
152
- import { useSdk } from '../lib/sdk-context';
153
- import type { ReturnType } from '@frontiertower/frontier-sdk';
187
+ import { useServices, type FrontierServices } from '../lib/frontier-services';
188
+
189
+ // Derive feature data types from the FrontierServices seam — NEVER import the
190
+ // SDK in feature code (it isn't installed in scaffold/feature phases and fails
191
+ // verification rule M-03). `ReturnType` here is the TypeScript built-in.
192
+ type Balance = Awaited<ReturnType<FrontierServices['wallet']['getBalance']>>;
154
193
 
155
- export function useFeature() {
156
- const sdk = useSdk();
157
- const [data, setData] = useState<ReturnType | null>(null);
194
+ export function useBalance() {
195
+ const services = useServices();
196
+ const [data, setData] = useState<Balance | null>(null);
158
197
  const [loading, setLoading] = useState(true);
159
198
  const [error, setError] = useState<string | null>(null);
160
199
 
161
200
  useEffect(() => {
162
201
  const fetchData = async () => {
163
202
  try {
164
- const result = await sdk.getModule().method();
203
+ const result = await services.wallet.getBalance();
165
204
  setData(result);
166
205
  } catch (err) {
167
206
  setError(err instanceof Error ? err.message : 'Failed to load data');
@@ -170,7 +209,7 @@ export function useFeature() {
170
209
  }
171
210
  };
172
211
  fetchData();
173
- }, [sdk]);
212
+ }, [services]);
174
213
 
175
214
  return { data, loading, error };
176
215
  }
@@ -207,25 +246,51 @@ export default function FeatureView() {
207
246
 
208
247
  ### Tailwind Dark Theme Classes
209
248
 
210
- Always use these semantic classes (defined in index.css @theme block):
211
- - **Backgrounds:** `bg-background`, `bg-card`, `bg-muted-background`
212
- - **Text:** `text-foreground`, `text-card-foreground`, `text-muted-foreground`
213
- - **Borders:** `border-border`
214
- - **Interactive:** `bg-primary text-primary-foreground`, `bg-accent text-accent-foreground`
215
- - **Status:** `text-success`, `text-danger`, `text-alert`
216
- - **Inputs:** `bg-input`, `ring-ring`, `outline-outline`
217
-
218
- **NEVER use hardcoded colors** (no `bg-white`, `text-black`, `bg-gray-900`). Always use the semantic CSS variable classes.
249
+ Use semantic Tailwind classes from the app's index.css @theme block (bg-background, text-foreground, etc.). See app-patterns.md "Dark Theme CSS Variables" section for the full token list. **NEVER use hardcoded colors** (no `bg-white`, `text-black`, `bg-gray-900`).
219
250
 
220
251
  ### Type Safety
221
252
 
222
253
  - Always use the SDK types from `@frontiertower/frontier-sdk`
223
- - Never invent types — use `WalletBalance`, `WalletBalanceFormatted`, `UserOperationReceipt`, `SmartAccount`, etc.
254
+ - Never invent types — use `WalletBalance`, `UserOperationReceipt`, `SmartAccount`, etc.
224
255
  - If a type is not exported by the SDK, define a local interface that matches the SDK's return shape
225
256
  - Always use `strict: true` TypeScript
226
257
 
258
+ ### Module Access
259
+
260
+ Access modules via `services.<module>` from `useServices()`. Property names match SDK module names in lowercase (`services.wallet`, `services.events`, etc.).
261
+
227
262
  </feature_execution>
228
263
 
264
+ <frontier_os_rules>
265
+ **CRITICAL — These rules apply to ALL code written for Frontier OS apps.**
266
+
267
+ **Read the current phase and sdkPhase from manifest.json to determine which tier applies.**
268
+
269
+ **TIER 1 — ALL PHASES:**
270
+ 1. **Dark theme:** Tailwind dark theme. Backgrounds: `bg-background`, `bg-card`, `bg-muted-background`. Text: `text-foreground`, `text-card-foreground`, `text-muted-foreground`. No hardcoded colors (no bg-white, text-black, bg-gray-900).
271
+ 2. **Error handling:** All service calls wrapped in try/catch. Loading states for async operations. Error states with user-friendly messages.
272
+ 3. **TypeScript strict:** All code in TypeScript strict mode. No `any` types unless explicitly justified.
273
+ 4. **Testing:** Vitest for unit tests. Test files in `src/test/`.
274
+ 5. **Service access:** Feature phases use `useServices()` from `src/lib/frontier-services.tsx`. Never import SDK directly in feature hooks or views.
275
+ 6. **Mock layer:** Mock services return realistic data matching SDK return types. Hooks must work identically whether backed by mocks or real SDK.
276
+
277
+ **TIER 2 — SDK INTEGRATION PHASE ONLY:**
278
+ 7. **SDK access:** `useSdk()` hook from `src/lib/sdk-context.tsx`, used only inside `sdk-services.tsx` and `Layout.tsx`.
279
+ 8. **Iframe detection:** `isInFrontierApp()` check in Layout.tsx. Standalone mode shows fallback banner.
280
+ 9. **Provider wrapping:** In-frame, Layout wraps the app in `SdkProvider` AND bridges the SDK into `FrontierServicesProvider` (so `useServices()` resolves). SDK created once in an effect and exposed via `useState`, destroyed on unmount.
281
+ 10. **Permissions:** Every SDK method used must have permission declared in manifest.json.
282
+ 11. **CORS:** vercel.json sets CORS for the production origin plus a CSP `frame-ancestors` listing the 3 Frontier OS origins (os.frontiertower.io, sandbox.os.frontiertower.io, localhost:5173) and security headers. Copy templates/app/vercel.json verbatim.
283
+ 12. **SDK imports:** Use `@frontiertower/frontier-sdk` for SDK classes. Exact import paths, not barrel imports.
284
+ </frontier_os_rules>
285
+
286
+ <sdk_integration_execution>
287
+
288
+ ### SDK Integration Phase Execution
289
+
290
+ Follow the SDK Integration pattern from app-patterns.md "SDK Integration Pattern" section. The steps are: add SDK dependency; create sdk-context.tsx; create sdk-services.tsx (wire the modules your app uses); swap in templates/app/layout.tsx (it bridges the SDK into FrontierServicesProvider so useServices() works in-frame); swap in the full vercel.json. Leave frontier-services.tsx unchanged — it stays the SDK-free mock seam; do NOT add SDK imports or detection to it. Use templates from templates/app/ for each file.
291
+
292
+ </sdk_integration_execution>
293
+
229
294
  <deviation_rules>
230
295
  **While executing, you WILL discover work not in the plan.** Apply these rules automatically. Track all deviations for Summary.
231
296
 
@@ -239,7 +304,7 @@ No user permission needed for Rules 1-3.
239
304
 
240
305
  **Trigger:** Code doesn't work as intended (broken behavior, errors, incorrect output)
241
306
 
242
- **Examples:** Wrong SDK method call, type errors, null pointer exceptions, broken imports, incorrect hook dependencies, missing await on SDK promises
307
+ **Examples:** Wrong service method call, type errors, null pointer exceptions, broken imports, incorrect hook dependencies, missing await on service promises
243
308
 
244
309
  ---
245
310
 
@@ -247,7 +312,7 @@ No user permission needed for Rules 1-3.
247
312
 
248
313
  **Trigger:** Code missing essential features for correctness, security, or basic operation
249
314
 
250
- **Examples:** Missing error handling on SDK calls, no loading states, missing null checks on SDK responses, no standalone fallback in Layout, missing CORS headers in vercel.json, no dark theme on new components
315
+ **Examples:** Missing error handling on service calls, no loading states, missing null checks on service responses, no dark theme on new components
251
316
 
252
317
  ---
253
318
 
@@ -255,7 +320,7 @@ No user permission needed for Rules 1-3.
255
320
 
256
321
  **Trigger:** Something prevents completing current task
257
322
 
258
- **Examples:** Missing dependency, wrong import path, build error, TypeScript error, missing SDK type export, Vite config issue
323
+ **Examples:** Missing dependency, wrong import path, build error, TypeScript error, missing type export, Vite config issue
259
324
 
260
325
  ---
261
326
 
@@ -263,7 +328,7 @@ No user permission needed for Rules 1-3.
263
328
 
264
329
  **Trigger:** Fix requires significant structural modification
265
330
 
266
- **Examples:** Changing SDK module approach, switching from single view to router, changing state management strategy, adding a new SDK module not in manifest
331
+ **Examples:** Changing service module approach, switching from single view to router, changing state management strategy, adding a new service module not in manifest
267
332
 
268
333
  **Action:** STOP --> return checkpoint with: what found, proposed change, why needed, impact, alternatives. **User decision required.**
269
334
 
@@ -388,7 +453,7 @@ tasks_completed: N/N
388
453
 
389
454
  # Phase [X] Plan [Y]: [Name] Summary
390
455
 
391
- [One-liner must be substantive: "Balance display with useBalance hook calling getBalanceFormatted(), card-based UI with loading/error states" NOT "Balance feature implemented"]
456
+ [One-liner must be substantive: "Balance display with useBalance hook calling getBalance() and formatting via formatAmount(), card-based UI with loading/error states" NOT "Balance feature implemented"]
392
457
 
393
458
  ## Tasks Completed
394
459
 
@@ -400,11 +465,11 @@ tasks_completed: N/N
400
465
 
401
466
  - [Decision and rationale]
402
467
 
403
- ## SDK Methods Used
468
+ ## Service Methods Used
404
469
 
405
470
  | Method | Module | Permission | Files |
406
471
  |--------|--------|------------|-------|
407
- | getBalanceFormatted() | Wallet | wallet:getBalanceFormatted | src/hooks/useBalance.ts |
472
+ | wallet.getBalance() | Wallet | wallet:getBalance | src/hooks/useBalance.ts |
408
473
 
409
474
  ## Deviations from Plan
410
475
 
@@ -452,7 +517,8 @@ Do NOT skip. Do NOT proceed to state updates if self-check fails.
452
517
  </self_check>
453
518
 
454
519
  <sdk_reference>
455
- @frontier-os-app-builder/references/sdk-surface.md
520
+ Focused SDK reference is provided via <files_to_read> in the spawn prompt.
521
+ Contains only modules relevant to this app (from references/sdk/*.md).
456
522
  </sdk_reference>
457
523
 
458
524
  <app_patterns_reference>
@@ -48,7 +48,7 @@ Before verifying, load project context:
48
48
  <core_principle>
49
49
  **Plan completeness =/= Goal achievement**
50
50
 
51
- A task "create balance display" can be in the plan while the SDK method `getBalanceFormatted()` is called with wrong arguments. The task exists but the goal "show user's balance" won't be achieved.
51
+ A task "create balance display" can be in the plan while the SDK method `getBalance()` is called with wrong arguments. The task exists but the goal "show user's balance" won't be achieved.
52
52
 
53
53
  Goal-backward verification works backwards from outcome:
54
54
 
@@ -74,8 +74,10 @@ Then verify each level against the actual plan files.
74
74
  3. Check method signatures match (parameter types, return types)
75
75
  4. Verify the correct module accessor is used (e.g., `getWallet()` not `wallet()`)
76
76
 
77
+ Feature phases access methods via `services.module.method()` (not `sdk.getModule().method()`). The method NAMES are the same — validate against the per-module SDK reference files (references/sdk/*.md) for correctness. The import path should be `../lib/frontier-services`, not `../lib/sdk-context`.
78
+
77
79
  **Validation rules:**
78
- - Method must exist in @frontier-os-app-builder/references/sdk-surface.md
80
+ - Method must exist in the focused SDK reference (provided via <files_to_read>)
79
81
  - Module accessor must use the correct getter: `sdk.getWallet()`, `sdk.getStorage()`, etc.
80
82
  - Parameter types must match SDK definitions (e.g., `bigint` for amounts, `string` for addresses)
81
83
  - Return types referenced in task must match SDK definitions
@@ -84,23 +86,25 @@ Then verify each level against the actual plan files.
84
86
  - Method name doesn't exist in SDK (e.g., `getTokenBalance()` instead of `getBalance()`)
85
87
  - Wrong module (e.g., `sdk.getUser().getBalance()` instead of `sdk.getWallet().getBalance()`)
86
88
  - Wrong parameter types (e.g., `number` instead of `bigint` for token amounts)
87
- - Invented types not in SDK (e.g., `BalanceInfo` instead of `WalletBalanceFormatted`)
89
+ - Invented types not in SDK (e.g., `BalanceInfo` instead of `WalletBalance`)
88
90
 
89
91
  **Example issue:**
90
92
  ```yaml
91
93
  issue:
92
94
  dimension: sdk_method_correctness
93
95
  severity: blocker
94
- description: "Task 2 references sdk.getWallet().getTokenBalance() — method does not exist. Use getBalance() or getBalanceFormatted()"
96
+ description: "Task 2 references sdk.getWallet().getTokenBalance() — method does not exist. Use getBalance()"
95
97
  plan: "02-01"
96
98
  task: 2
97
- fix_hint: "Replace getTokenBalance() with getBalanceFormatted() — returns WalletBalanceFormatted with .total, .fnd, .internalFnd string fields"
99
+ fix_hint: "Replace getTokenBalance() with getBalance() — returns WalletBalance with .total, .fnd, .internalFnd bigint fields; format each with formatAmount() from '@frontiertower/frontier-sdk'"
98
100
  ```
99
101
 
100
102
  ## Dimension 2: Permission Alignment
101
103
 
102
104
  **Question:** Do SDK methods used in plans have corresponding permissions in manifest.json?
103
105
 
106
+ For feature phases: permission mismatches are severity **warning** (permissions are enforced at SDK Integration). For SDK Integration phase: permission mismatches are severity **blocker** (permissions must match real SDK calls).
107
+
104
108
  **Process:**
105
109
  1. Extract all SDK method calls from plan tasks
106
110
  2. Map each to its required permission using the pattern: `sdk.getModule().method()` --> `module:method`
@@ -124,10 +128,10 @@ issue:
124
128
  issue:
125
129
  dimension: permission_alignment
126
130
  severity: blocker
127
- description: "Task 1 calls sdk.getWallet().getBalanceFormatted() but manifest.json does not declare wallet:getBalanceFormatted permission"
131
+ description: "Task 1 calls sdk.getWallet().getBalance() but manifest.json does not declare wallet:getBalance permission"
128
132
  plan: "02-01"
129
133
  task: 1
130
- fix_hint: "Add 'wallet:getBalanceFormatted' to permissions array in manifest.json, or add a task to update manifest"
134
+ fix_hint: "Add 'wallet:getBalance' to permissions array in manifest.json, or add a task to update manifest"
131
135
  ```
132
136
 
133
137
  ## Dimension 3: File Structure Compliance
@@ -147,13 +151,14 @@ issue:
147
151
  - Files outside `src/` that should be inside
148
152
  - Wrong casing (lowercase views, PascalCase hooks)
149
153
  - Tests not in `src/test/`
150
- - SDK-context.tsx modification (it must be identical across apps)
154
+ - Feature phase tasks importing from `sdk-context` instead of `frontier-services`
151
155
 
152
156
  **Red flags:**
153
157
  - `src/components/layout.tsx` (wrong case — should be `Layout.tsx`)
154
158
  - `src/useBalance.ts` (wrong location — should be `src/hooks/useBalance.ts`)
155
159
  - `tests/` at root (wrong — should be `src/test/`)
156
- - Any task modifying `src/lib/sdk-context.tsx`
160
+ - Feature phase task importing from `src/lib/sdk-context` (should be `src/lib/frontier-services`)
161
+ - Any task modifying `src/lib/sdk-context.tsx` (only created during SDK Integration phase)
157
162
 
158
163
  **Example issue:**
159
164
  ```yaml
@@ -176,30 +181,42 @@ issue:
176
181
  - `package.json` (correct scripts, dependencies)
177
182
  - `postcss.config.js` (imports @tailwindcss/postcss)
178
183
  - `tsconfig.json` (strict mode, correct types)
179
- - `vercel.json` (all 5 CORS origins)
184
+ - `vercel.json`
180
185
  - `vite.config.ts`
181
186
  - `src/main.tsx`
182
- - `src/lib/sdk-context.tsx`
183
- - `src/views/Layout.tsx` (with isInFrontierApp, createStandaloneHTML, SdkProvider)
187
+ - `src/lib/frontier-services.tsx` (with `useServices()` export and `createMockServices()` export)
188
+ - `src/views/Layout.tsx` (with `FrontierServicesProvider`)
184
189
  - `src/styles/index.css` (Tailwind import, @theme block with all CSS variables, @layer base)
185
190
  - `.gitignore`
186
191
  2. Check that task actions mention key requirements:
187
- - iframe detection via `isInFrontierApp()`
188
- - Standalone fallback via `createStandaloneHTML()`
189
- - SdkProvider wrapping children
192
+ - `useServices()` export in frontier-services.tsx
193
+ - `createMockServices()` export in frontier-services.tsx
194
+ - `FrontierServicesProvider` wrapping children in Layout
190
195
  - Dark theme CSS variables (all variables from T-01)
191
196
  - Plus Jakarta Sans font loading (T-03)
192
- - 5 CORS origins in vercel.json (C-01)
193
197
  - Correct package.json scripts: dev, build, preview, lint, test (C-04)
194
198
 
199
+ 3. **BLOCKLIST CHECK** — Scan the plan for any of these. If found, it is a **blocker**:
200
+ - ❌ `sdk-context.tsx` referenced as a file to create — belongs to SDK Integration phase only
201
+ - ❌ `@frontiertower/frontier-sdk` in dependencies — SDK not installed until SDK Integration
202
+ - ❌ `isInFrontierApp` or `createStandaloneHTML` in any task action — SDK Integration concerns
203
+ - ❌ `SdkProvider` in any task action — use `FrontierServicesProvider` instead
204
+ - ❌ `useSdk` in any task action — use `useServices` instead
205
+ - ❌ `layout.tsx` template (without `-standalone`) — use `layout-standalone.tsx`
206
+ - ❌ `package.json` template (without `-standalone`) — use `package-standalone.json`
207
+ - ❌ `vercel.json` template (without `-standalone`) — use `vercel-standalone.json`
208
+ - ❌ single-component entries — use `main-router.tsx` instead (all apps use the router)
209
+
210
+ If the researcher recommended SDK patterns from production apps, the planner should NOT have included them in Phase 1. Flag as blocker with fix hint: "Phase 1 is standalone-first. Remove SDK artifacts and use standalone templates."
211
+
195
212
  **Example issue:**
196
213
  ```yaml
197
214
  issue:
198
215
  dimension: scaffold_completeness
199
216
  severity: blocker
200
- description: "Scaffold plan missing vercel.json creation required for CORS and SPA routing"
217
+ description: "Phase 1 plan creates sdk-context.tsxthis belongs to SDK Integration phase, not scaffold"
201
218
  plan: "01-01"
202
- fix_hint: "Add task or expand existing task to create vercel.json with all 5 CORS origin blocks and SPA rewrite"
219
+ fix_hint: "Remove sdk-context.tsx from plan. Phase 1 uses frontier-services.tsx for the services layer."
203
220
  ```
204
221
 
205
222
  ## Dimension 5: Task Completeness
@@ -227,7 +244,7 @@ issue:
227
244
  issue:
228
245
  dimension: task_completeness
229
246
  severity: blocker
230
- description: "Task 2 action says 'create payment handler' without specifying which SDK method (payWithFrontierDollar? transferOverallFrontierDollar?)"
247
+ description: "Task 2 action says 'create payment handler' without specifying which SDK method (transferFrontierDollar? transferOverallFrontierDollar?)"
231
248
  plan: "02-01"
232
249
  task: 2
233
250
  fix_hint: "Specify exact SDK method, parameters, return type, and error handling in action"
@@ -244,13 +261,14 @@ issue:
244
261
 
245
262
  **Frontier OS specific wiring patterns:**
246
263
  ```
247
- Hook --> Component: Does a view import and call the hook?
248
- Component --> SdkProvider: Is the view rendered inside SdkProvider?
249
- SDK call --> Error handling: Does the action mention try/catch?
250
- Router --> View: Does the router import the view component?
251
- Layout --> SdkProvider: Does Layout wrap children with SdkProvider?
264
+ Hook --> Component: Does view import and call hook?
265
+ Hook --> Services: Does hook import useServices() from frontier-services?
266
+ Service call --> Error handling: Does action mention try/catch?
267
+ Router --> View: Does router import view component?
252
268
  ```
253
269
 
270
+ Note: SdkProvider wiring is checked only for SDK Integration phase plans.
271
+
254
272
  **Red flags:**
255
273
  - Hook created but no view imports it
256
274
  - View created but not added to router
@@ -329,6 +347,23 @@ issue:
329
347
  - Test files in wrong location
330
348
  - Test task with vague action ("write tests") instead of specific test cases
331
349
 
350
+ ## Dimension 10: SDK Integration Phase Completeness
351
+
352
+ **Applies to:** SDK Integration phase plans only. Skip for feature phase plans.
353
+
354
+ **Question:** Does the plan cover all mechanical steps for SDK Integration?
355
+
356
+ **Checklist:**
357
+ 1. Plan includes task to add `@frontiertower/frontier-sdk` dependency (`npm install`)
358
+ 2. Plan includes task to create `src/lib/sdk-context.tsx` from template
359
+ 3. Plan includes task to create `src/lib/sdk-services.tsx` adapter
360
+ 4. Plan keeps `src/lib/frontier-services.tsx` as the SDK-free mock seam (NO task to add SDK imports/detection there)
361
+ 5. Plan includes task to swap in `src/views/Layout.tsx` from the template (iframe detection + `SdkProvider` + `FrontierServicesProvider` bridge so `useServices()` resolves)
362
+ 6. Plan includes task to add CORS origins to `vercel.json`
363
+ 7. Plan includes verification task (build, typecheck, full validation)
364
+
365
+ **Severity:** blocker for any missing step — SDK Integration is standardized and every step is required.
366
+
332
367
  </verification_dimensions>
333
368
 
334
369
  <output_format>
@@ -357,6 +392,7 @@ Return structured PASS/FAIL with issues list:
357
392
  | 7 | Context Compliance | PASS/FAIL/N/A | [count] |
358
393
  | 8 | Scope Sanity | PASS/FAIL | [count] |
359
394
  | 9 | Test Coverage | PASS/FAIL | [count] |
395
+ | 10 | SDK Integration Completeness | PASS/FAIL/N/A | [count] |
360
396
 
361
397
  ### Issues
362
398
 
@@ -378,7 +414,8 @@ Return structured PASS/FAIL with issues list:
378
414
  </output_format>
379
415
 
380
416
  <sdk_reference>
381
- @frontier-os-app-builder/references/sdk-surface.md
417
+ Focused SDK reference is provided via <files_to_read> in the spawn prompt.
418
+ Contains only modules relevant to this app (from references/sdk/*.md).
382
419
  </sdk_reference>
383
420
 
384
421
  <verification_rules_reference>