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.
- package/LICENSE +21 -0
- package/README.md +90 -14
- package/agents/fos-executor.md +105 -39
- package/agents/fos-plan-checker.md +62 -25
- package/agents/fos-planner.md +80 -72
- package/agents/fos-researcher.md +26 -15
- package/agents/fos-verifier.md +96 -27
- package/bin/fos-tools.cjs +146 -42
- package/bin/install.js +8 -5
- package/commands/fos/add-feature.md +1 -2
- package/commands/fos/discuss.md +0 -1
- package/commands/fos/new-app.md +2 -4
- package/commands/fos/new-milestone.md +1 -1
- package/commands/fos/plan.md +0 -2
- package/package.json +7 -1
- package/references/app-patterns.md +128 -21
- package/references/deployment.md +40 -124
- package/references/module-index.md +32 -0
- package/references/sdk/chain.md +92 -0
- package/references/sdk/communities.md +159 -0
- package/references/sdk/events.md +212 -0
- package/references/sdk/init.md +126 -0
- package/references/sdk/navigation.md +49 -0
- package/references/sdk/offices.md +76 -0
- package/references/sdk/partnerships.md +111 -0
- package/references/sdk/storage.md +44 -0
- package/references/sdk/thirdparty.md +240 -0
- package/references/sdk/token-amount.md +99 -0
- package/references/sdk/types.md +27 -0
- package/references/sdk/ui-utils.md +39 -0
- package/references/sdk/user.md +208 -0
- package/references/sdk/wallet.md +334 -0
- package/references/verification-rules.md +111 -50
- package/templates/app/frontier-services.tsx +871 -0
- package/templates/app/layout-standalone.tsx +8 -0
- package/templates/app/layout.tsx +19 -9
- package/templates/app/package-standalone.json +35 -0
- package/templates/app/package.json +2 -1
- package/templates/app/public/favicon.svg +3 -0
- package/templates/app/sdk-context.tsx +7 -9
- package/templates/app/sdk-services.tsx +98 -0
- package/templates/app/vercel-standalone.json +5 -0
- package/templates/app/vercel.json +8 -95
- package/templates/state/plan.md +32 -14
- package/templates/state/requirements.md +1 -1
- package/templates/state/roadmap.md +57 -24
- package/templates/state/summary.md +27 -30
- package/workflows/add-feature.md +6 -1
- package/workflows/discuss.md +126 -11
- package/workflows/execute-plan.md +21 -14
- package/workflows/execute.md +204 -24
- package/workflows/new-app.md +64 -23
- package/workflows/new-milestone.md +10 -3
- package/workflows/plan.md +16 -5
- package/workflows/ship.md +91 -34
- package/workflows/status.md +1 -2
- package/references/module-inference.md +0 -349
- package/references/sdk-surface.md +0 -1622
- package/templates/app/main-simple.tsx +0 -19
- 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
|
-
|
|
3
|
+
[](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
|
-
##
|
|
28
|
+
## Quick Start
|
|
20
29
|
|
|
21
|
-
Create a
|
|
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 "
|
|
35
|
+
/fos:new-app "A tip jar app where members can tip baristas and staff with FND"
|
|
25
36
|
```
|
|
26
37
|
|
|
27
|
-
|
|
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.
|
|
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
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
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
|
-
##
|
|
103
|
+
## Frontier Studio
|
|
78
104
|
|
|
79
|
-
|
|
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
|
package/agents/fos-executor.md
CHANGED
|
@@ -27,7 +27,26 @@ Before executing, discover project context:
|
|
|
27
27
|
|
|
28
28
|
<execution_flow>
|
|
29
29
|
|
|
30
|
-
<step name="
|
|
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
|
-
| `
|
|
111
|
-
| `layout.tsx` | `./src/views/Layout.tsx` |
|
|
112
|
-
| `main-router.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/
|
|
120
|
-
- `src/views/Layout.tsx` —
|
|
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` —
|
|
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
|
-
###
|
|
169
|
+
### Services Code Patterns
|
|
135
170
|
|
|
136
171
|
**Always use these exact patterns:**
|
|
137
172
|
|
|
138
|
-
**Import
|
|
173
|
+
**Import services:**
|
|
139
174
|
```typescript
|
|
140
|
-
import {
|
|
175
|
+
import { useServices } from '../lib/frontier-services';
|
|
141
176
|
```
|
|
142
177
|
|
|
143
178
|
**Access module:**
|
|
144
179
|
```typescript
|
|
145
|
-
const
|
|
146
|
-
const wallet =
|
|
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 {
|
|
153
|
-
|
|
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
|
|
156
|
-
const
|
|
157
|
-
const [data, setData] = useState<
|
|
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
|
|
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
|
-
}, [
|
|
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
|
-
|
|
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`, `
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
##
|
|
468
|
+
## Service Methods Used
|
|
404
469
|
|
|
405
470
|
| Method | Module | Permission | Files |
|
|
406
471
|
|--------|--------|------------|-------|
|
|
407
|
-
|
|
|
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
|
-
|
|
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 `
|
|
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
|
|
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 `
|
|
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()
|
|
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
|
|
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().
|
|
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:
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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`
|
|
184
|
+
- `vercel.json`
|
|
180
185
|
- `vite.config.ts`
|
|
181
186
|
- `src/main.tsx`
|
|
182
|
-
- `src/lib/
|
|
183
|
-
- `src/views/Layout.tsx` (with
|
|
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
|
-
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
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: "
|
|
217
|
+
description: "Phase 1 plan creates sdk-context.tsx — this belongs to SDK Integration phase, not scaffold"
|
|
201
218
|
plan: "01-01"
|
|
202
|
-
fix_hint: "
|
|
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 (
|
|
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
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
Router --> View: Does
|
|
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
|
-
|
|
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>
|