frontier-os-app-builder 1.0.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 (55) hide show
  1. package/README.md +92 -0
  2. package/agents/fos-executor.md +460 -0
  3. package/agents/fos-plan-checker.md +386 -0
  4. package/agents/fos-planner.md +416 -0
  5. package/agents/fos-researcher.md +358 -0
  6. package/agents/fos-verifier.md +491 -0
  7. package/bin/fos-tools.cjs +794 -0
  8. package/bin/install.js +234 -0
  9. package/commands/fos/add-feature.md +29 -0
  10. package/commands/fos/discuss.md +31 -0
  11. package/commands/fos/execute.md +35 -0
  12. package/commands/fos/new-app.md +39 -0
  13. package/commands/fos/new-milestone.md +28 -0
  14. package/commands/fos/next.md +29 -0
  15. package/commands/fos/plan.md +37 -0
  16. package/commands/fos/ship.md +29 -0
  17. package/commands/fos/status.md +22 -0
  18. package/package.json +30 -0
  19. package/references/app-patterns.md +501 -0
  20. package/references/deployment.md +395 -0
  21. package/references/module-inference.md +349 -0
  22. package/references/sdk-surface.md +1622 -0
  23. package/references/verification-rules.md +404 -0
  24. package/templates/app/gitignore +25 -0
  25. package/templates/app/index.css +111 -0
  26. package/templates/app/index.html +19 -0
  27. package/templates/app/layout.tsx +45 -0
  28. package/templates/app/main-router.tsx +17 -0
  29. package/templates/app/main-simple.tsx +19 -0
  30. package/templates/app/package.json +36 -0
  31. package/templates/app/postcss.config.js +5 -0
  32. package/templates/app/router.tsx +22 -0
  33. package/templates/app/sdk-context.tsx +33 -0
  34. package/templates/app/test-setup.ts +19 -0
  35. package/templates/app/tsconfig.json +22 -0
  36. package/templates/app/vercel.json +127 -0
  37. package/templates/app/vite.config.ts +15 -0
  38. package/templates/state/context.md +248 -0
  39. package/templates/state/manifest.json +11 -0
  40. package/templates/state/plan.md +187 -0
  41. package/templates/state/project.md +118 -0
  42. package/templates/state/requirements.md +133 -0
  43. package/templates/state/roadmap.md +129 -0
  44. package/templates/state/state.md +131 -0
  45. package/templates/state/summary.md +273 -0
  46. package/workflows/add-feature.md +234 -0
  47. package/workflows/discuss.md +310 -0
  48. package/workflows/execute-plan.md +222 -0
  49. package/workflows/execute.md +338 -0
  50. package/workflows/new-app.md +331 -0
  51. package/workflows/new-milestone.md +258 -0
  52. package/workflows/next.md +157 -0
  53. package/workflows/plan.md +310 -0
  54. package/workflows/ship.md +296 -0
  55. package/workflows/status.md +145 -0
@@ -0,0 +1,22 @@
1
+ import { createBrowserRouter } from 'react-router-dom';
2
+ import { Layout } from './views/Layout';
3
+
4
+ // {{ROUTES}}
5
+ // Import your view components and define routes below.
6
+ // Pattern:
7
+ // import { Home } from './views/Home';
8
+ // import { Detail } from './views/Detail';
9
+ //
10
+ // Then add route objects to the children array:
11
+ // { index: true, element: <Home /> },
12
+ // { path: 'detail/:id', element: <Detail /> },
13
+
14
+ export const router = createBrowserRouter([
15
+ {
16
+ path: '/',
17
+ element: <Layout />,
18
+ children: [
19
+ // {{ROUTES}}
20
+ ],
21
+ },
22
+ ]);
@@ -0,0 +1,33 @@
1
+ import { createContext, useContext, useEffect, useRef, useState, type ReactNode } from 'react';
2
+ import { FrontierSDK } from '@frontiertower/frontier-sdk';
3
+
4
+ const SdkContext = createContext<FrontierSDK | null>(null);
5
+
6
+ export const useSdk = (): FrontierSDK => {
7
+ const sdk = useContext(SdkContext);
8
+ if (!sdk) throw new Error('useSdk must be used within SdkProvider');
9
+ return sdk;
10
+ };
11
+
12
+ export const SdkProvider = ({ children }: { children: ReactNode }) => {
13
+ const sdkRef = useRef<FrontierSDK | null>(null);
14
+ const [ready, setReady] = useState(false);
15
+
16
+ useEffect(() => {
17
+ const sdk = new FrontierSDK();
18
+ sdkRef.current = sdk;
19
+ setReady(true);
20
+
21
+ return () => {
22
+ sdk.destroy();
23
+ };
24
+ }, []);
25
+
26
+ if (!ready) return null;
27
+
28
+ return (
29
+ <SdkContext.Provider value={sdkRef.current}>
30
+ {children}
31
+ </SdkContext.Provider>
32
+ );
33
+ };
@@ -0,0 +1,19 @@
1
+ import '@testing-library/jest-dom';
2
+ import { vi } from 'vitest';
3
+
4
+ // Mock window.open for external links
5
+ vi.stubGlobal('open', vi.fn());
6
+
7
+ // Mock ResizeObserver
8
+ vi.stubGlobal('ResizeObserver', vi.fn().mockImplementation(() => ({
9
+ observe: vi.fn(),
10
+ unobserve: vi.fn(),
11
+ disconnect: vi.fn(),
12
+ })));
13
+
14
+ // Mock IntersectionObserver
15
+ vi.stubGlobal('IntersectionObserver', vi.fn().mockImplementation(() => ({
16
+ observe: vi.fn(),
17
+ unobserve: vi.fn(),
18
+ disconnect: vi.fn(),
19
+ })));
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
7
+ "skipLibCheck": true,
8
+ "jsx": "react-jsx",
9
+ "moduleResolution": "bundler",
10
+ "allowImportingTsExtensions": true,
11
+ "resolveJsonModule": true,
12
+ "isolatedModules": true,
13
+ "noEmit": true,
14
+ "strict": true,
15
+ "noUnusedLocals": true,
16
+ "noUnusedParameters": true,
17
+ "noFallthroughCasesInSwitch": true,
18
+ "types": ["vitest/globals", "@testing-library/jest-dom"]
19
+ },
20
+ "include": ["src"],
21
+ "exclude": ["src/test", "**/*.test.ts", "**/*.test.tsx"]
22
+ }
@@ -0,0 +1,127 @@
1
+ {
2
+ "rewrites": [
3
+ { "source": "/(.*)", "destination": "/index.html" }
4
+ ],
5
+ "headers": [
6
+ {
7
+ "source": "/(.*)",
8
+ "has": [
9
+ {
10
+ "type": "header",
11
+ "key": "Origin",
12
+ "value": "https://os.frontiertower.io"
13
+ }
14
+ ],
15
+ "headers": [
16
+ {
17
+ "key": "Access-Control-Allow-Origin",
18
+ "value": "https://os.frontiertower.io"
19
+ },
20
+ {
21
+ "key": "Access-Control-Allow-Methods",
22
+ "value": "GET, OPTIONS"
23
+ },
24
+ {
25
+ "key": "Access-Control-Allow-Headers",
26
+ "value": "Content-Type"
27
+ }
28
+ ]
29
+ },
30
+ {
31
+ "source": "/(.*)",
32
+ "has": [
33
+ {
34
+ "type": "header",
35
+ "key": "Origin",
36
+ "value": "https://alpha.os.frontiertower.io"
37
+ }
38
+ ],
39
+ "headers": [
40
+ {
41
+ "key": "Access-Control-Allow-Origin",
42
+ "value": "https://alpha.os.frontiertower.io"
43
+ },
44
+ {
45
+ "key": "Access-Control-Allow-Methods",
46
+ "value": "GET, OPTIONS"
47
+ },
48
+ {
49
+ "key": "Access-Control-Allow-Headers",
50
+ "value": "Content-Type"
51
+ }
52
+ ]
53
+ },
54
+ {
55
+ "source": "/(.*)",
56
+ "has": [
57
+ {
58
+ "type": "header",
59
+ "key": "Origin",
60
+ "value": "https://beta.os.frontiertower.io"
61
+ }
62
+ ],
63
+ "headers": [
64
+ {
65
+ "key": "Access-Control-Allow-Origin",
66
+ "value": "https://beta.os.frontiertower.io"
67
+ },
68
+ {
69
+ "key": "Access-Control-Allow-Methods",
70
+ "value": "GET, OPTIONS"
71
+ },
72
+ {
73
+ "key": "Access-Control-Allow-Headers",
74
+ "value": "Content-Type"
75
+ }
76
+ ]
77
+ },
78
+ {
79
+ "source": "/(.*)",
80
+ "has": [
81
+ {
82
+ "type": "header",
83
+ "key": "Origin",
84
+ "value": "https://sandbox.os.frontiertower.io"
85
+ }
86
+ ],
87
+ "headers": [
88
+ {
89
+ "key": "Access-Control-Allow-Origin",
90
+ "value": "https://sandbox.os.frontiertower.io"
91
+ },
92
+ {
93
+ "key": "Access-Control-Allow-Methods",
94
+ "value": "GET, OPTIONS"
95
+ },
96
+ {
97
+ "key": "Access-Control-Allow-Headers",
98
+ "value": "Content-Type"
99
+ }
100
+ ]
101
+ },
102
+ {
103
+ "source": "/(.*)",
104
+ "has": [
105
+ {
106
+ "type": "header",
107
+ "key": "Origin",
108
+ "value": "http://localhost:5173"
109
+ }
110
+ ],
111
+ "headers": [
112
+ {
113
+ "key": "Access-Control-Allow-Origin",
114
+ "value": "http://localhost:5173"
115
+ },
116
+ {
117
+ "key": "Access-Control-Allow-Methods",
118
+ "value": "GET, OPTIONS"
119
+ },
120
+ {
121
+ "key": "Access-Control-Allow-Headers",
122
+ "value": "Content-Type"
123
+ }
124
+ ]
125
+ }
126
+ ]
127
+ }
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from 'vitest/config';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ port: {{DEV_PORT}},
8
+ },
9
+ test: {
10
+ globals: true,
11
+ environment: 'jsdom',
12
+ setupFiles: ['./src/test/setup.ts'],
13
+ include: ['src/test/**/*.test.{ts,tsx}'],
14
+ },
15
+ });
@@ -0,0 +1,248 @@
1
+ # Context Template
2
+
3
+ Template for `.frontier-app/phases/XX-name/{phase_num}-CONTEXT.md` — captures implementation decisions for a phase.
4
+
5
+ **Purpose:** Document decisions that downstream agents need. Planner uses this to know what choices are locked vs flexible. Executor uses this to know what to build.
6
+
7
+ **Key principle:** Categories emerge from what was actually discussed for THIS phase. An events phase has events-relevant sections, a payments phase has payments-relevant sections.
8
+
9
+ ---
10
+
11
+ ## File Template
12
+
13
+ ```markdown
14
+ # Phase {{PHASE_NUM}}: {{PHASE_NAME}} — Context
15
+
16
+ **Gathered:** {{DATE}}
17
+ **Status:** Ready for planning
18
+
19
+ <domain>
20
+ ## Phase Boundary
21
+
22
+ [Clear statement of what this phase delivers — the scope anchor.
23
+ This comes from ROADMAP.md and is fixed.
24
+ Discussion during /fos:discuss clarifies implementation within this boundary.]
25
+
26
+ </domain>
27
+
28
+ <decisions>
29
+ ## Implementation Decisions
30
+
31
+ ### [Area 1 that was discussed]
32
+ - **D-01:** [Specific decision made]
33
+ - **D-02:** [Another decision if applicable]
34
+
35
+ ### [Area 2 that was discussed]
36
+ - **D-03:** [Specific decision made]
37
+
38
+ ### SDK Usage
39
+ - **D-XX:** [Which SDK module methods to use and how]
40
+ - **D-YY:** [Data flow: SDK → component state → UI]
41
+
42
+ ### Claude's Discretion
43
+ [Areas where user explicitly said "you decide" — Claude has flexibility here during planning/implementation]
44
+
45
+ - [Area Claude can decide]
46
+ - [Area Claude can decide]
47
+
48
+ </decisions>
49
+
50
+ <specifics>
51
+ ## Specific Ideas
52
+
53
+ [Any particular references, examples, or "I want it like X" moments from discussion.
54
+ Product references, specific behaviors, interaction patterns, visual references.]
55
+
56
+ [If none: "No specific requirements — open to standard Frontier OS app patterns"]
57
+
58
+ </specifics>
59
+
60
+ <sdk_context>
61
+ ## SDK Module Context
62
+
63
+ ### Modules Used in This Phase
64
+
65
+ | Module | Methods | Purpose |
66
+ |--------|---------|---------|
67
+ | [Module] | [method1(), method2()] | [What they enable] |
68
+
69
+ ### Integration Pattern
70
+ [How SDK data flows into the UI for this phase.
71
+ Example: "Events.list() → React Query → EventList component → EventCard"]
72
+
73
+ ### Known SDK Constraints
74
+ [Any SDK limitations that affect this phase's implementation.
75
+ Example: "Events.list() returns max 50 items — need pagination"]
76
+
77
+ [If no SDK modules: "No SDK modules in this phase — UI/scaffold only"]
78
+
79
+ </sdk_context>
80
+
81
+ <references>
82
+ ## References to Read
83
+
84
+ **Planner and executor MUST read these before working on this phase.**
85
+
86
+ ### SDK Documentation
87
+ - `frontier-sdk/docs/[module].md` — [What this doc covers]
88
+
89
+ ### Existing App Patterns
90
+ - `[app-name]/src/[path]` — [What pattern to reference]
91
+
92
+ ### Project State
93
+ - `.frontier-app/PROJECT.md` — App vision, constraints, SDK modules
94
+ - `.frontier-app/REQUIREMENTS.md` — Requirements this phase addresses
95
+
96
+ [If no external references: "No external references — requirements fully captured in decisions above"]
97
+
98
+ </references>
99
+
100
+ <deferred>
101
+ ## Deferred Ideas
102
+
103
+ [Ideas that came up during /fos:discuss but belong in other phases.
104
+ Captured here so they're not lost, but explicitly out of scope for this phase.]
105
+
106
+ [If none: "None — discussion stayed within phase scope"]
107
+
108
+ </deferred>
109
+
110
+ ---
111
+
112
+ *Phase: XX-name*
113
+ *Context gathered: {{DATE}}*
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Good Examples
119
+
120
+ **Example: Events feature phase**
121
+
122
+ ```markdown
123
+ # Phase 2: Event Listing — Context
124
+
125
+ **Gathered:** 2026-03-27
126
+ **Status:** Ready for planning
127
+
128
+ <domain>
129
+ ## Phase Boundary
130
+
131
+ Display upcoming events from the Frontier Events module in a browsable list. Users can view event details and RSVP. Event creation is a separate phase.
132
+
133
+ </domain>
134
+
135
+ <decisions>
136
+ ## Implementation Decisions
137
+
138
+ ### Layout
139
+ - **D-01:** Card grid layout, responsive — 1 column mobile, 2 tablet, 3 desktop
140
+ - **D-02:** Each card shows: event name, date/time, location, attendee count, RSVP button
141
+ - **D-03:** Cards sorted by date (soonest first), past events filtered out
142
+
143
+ ### RSVP Flow
144
+ - **D-04:** Single-tap RSVP — no confirmation modal (keep it fast)
145
+ - **D-05:** Optimistic UI update — show RSVP immediately, revert on error
146
+ - **D-06:** RSVP count updates in real-time for all viewers
147
+
148
+ ### Empty State
149
+ - **D-07:** "No upcoming events" with illustration — no CTA to create (that's a different phase)
150
+
151
+ ### SDK Usage
152
+ - **D-08:** Use Events.list() for fetching, Events.rsvp() for RSVP action
153
+ - **D-09:** Poll every 30 seconds for new events (no WebSocket available)
154
+
155
+ ### Claude's Discretion
156
+ - Loading skeleton design
157
+ - Exact card spacing and border radius
158
+ - Error toast styling
159
+ - Animation for RSVP button state change
160
+
161
+ </decisions>
162
+
163
+ <specifics>
164
+ ## Specific Ideas
165
+
166
+ - "I want the event cards to feel like Luma's event pages — clean, focused on the key info"
167
+ - RSVP should feel instant — "tap and done, like a Like button"
168
+
169
+ </specifics>
170
+
171
+ <sdk_context>
172
+ ## SDK Module Context
173
+
174
+ ### Modules Used in This Phase
175
+
176
+ | Module | Methods | Purpose |
177
+ |--------|---------|---------|
178
+ | Events | Events.list(), Events.rsvp(), Events.get() | Fetch events, handle RSVP |
179
+
180
+ ### Integration Pattern
181
+ Events.list() → React Query with 30s refetch → EventGrid component → EventCard with RSVP button → Events.rsvp() on click → optimistic update
182
+
183
+ ### Known SDK Constraints
184
+ - Events.list() returns max 50 items — sufficient for v1, pagination deferred
185
+ - Events.rsvp() requires user identity from SDK — no anonymous RSVP
186
+
187
+ </sdk_context>
188
+
189
+ <references>
190
+ ## References to Read
191
+
192
+ ### SDK Documentation
193
+ - `frontier-sdk/docs/events.md` — Events module API, method signatures, return types
194
+
195
+ ### Existing App Patterns
196
+ - `frontier-tower-pwa/src/components/EventCard.tsx` — Card pattern from the main PWA
197
+
198
+ ### Project State
199
+ - `.frontier-app/PROJECT.md` — App vision and SDK modules
200
+ - `.frontier-app/REQUIREMENTS.md` — REQ-01 through REQ-03
201
+
202
+ </references>
203
+
204
+ <deferred>
205
+ ## Deferred Ideas
206
+
207
+ - Event creation form — Phase 3
208
+ - Event categories/filtering — add to backlog
209
+ - Calendar view — future milestone
210
+
211
+ </deferred>
212
+
213
+ ---
214
+
215
+ *Phase: 02-event-listing*
216
+ *Context gathered: 2026-03-27*
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Guidelines
222
+
223
+ **This template captures DECISIONS for downstream planning and execution.**
224
+
225
+ The output should answer: "What choices are locked? What's flexible? Which SDK methods to use?"
226
+
227
+ **Good content (concrete decisions):**
228
+ - "Card grid, 1/2/3 columns responsive"
229
+ - "Use Events.list() with 30s polling"
230
+ - "Optimistic UI for RSVP"
231
+ - "Sort by date, filter out past events"
232
+
233
+ **Bad content (too vague):**
234
+ - "Should look nice"
235
+ - "Good user experience"
236
+ - "Fast loading"
237
+ - "Use the SDK"
238
+
239
+ **SDK Module Context is mandatory:**
240
+ - Every Frontier OS app phase that touches SDK modules must document which methods are used
241
+ - Include the data flow: SDK call → state management → UI
242
+ - Note any SDK constraints that affect implementation
243
+
244
+ **After creation:**
245
+ - File lives in phase directory: `.frontier-app/phases/XX-name/{phase_num}-CONTEXT.md`
246
+ - /fos:plan reads this to create specific tasks
247
+ - /fos:execute reads this to know what choices are locked
248
+ - Downstream agents should NOT need to ask the user again about captured decisions
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "{{APP_NAME}}",
3
+ "packageName": "{{PACKAGE_NAME}}",
4
+ "description": "{{APP_DESCRIPTION}}",
5
+ "sdkVersion": "{{SDK_VERSION}}",
6
+ "devPort": {{DEV_PORT}},
7
+ "modules": [],
8
+ "permissions": [],
9
+ "milestone": "v1",
10
+ "phases": []
11
+ }
@@ -0,0 +1,187 @@
1
+ # Plan Template
2
+
3
+ Template for `.frontier-app/phases/XX-name/{phase}-{plan}-PLAN.md` — executable plans for Frontier OS app phases.
4
+
5
+ **Naming:** Use `{phase}-{plan}-PLAN.md` format (e.g., `01-01-PLAN.md` for Phase 1, Plan 1)
6
+
7
+ ---
8
+
9
+ ## File Template
10
+
11
+ ```markdown
12
+ ---
13
+ phase: XX-name
14
+ plan: NN
15
+ wave: N
16
+ depends_on: []
17
+ requirements: []
18
+ files_modified: []
19
+ autonomous: true
20
+
21
+ must_haves:
22
+ truths: []
23
+ artifacts: []
24
+ key_links: []
25
+ ---
26
+
27
+ <objective>
28
+ [What this plan accomplishes for the Frontier OS app]
29
+
30
+ Purpose: [Why this matters — which feature/capability it delivers]
31
+ Output: [What artifacts will be created]
32
+ SDK Modules: [Which SDK modules are used in this plan, if any]
33
+ </objective>
34
+
35
+ <execution_context>
36
+ @frontier-os-app-builder/workflows/execute-plan.md
37
+ @frontier-os-app-builder/templates/state/summary.md
38
+ </execution_context>
39
+
40
+ <context>
41
+ @.frontier-app/PROJECT.md
42
+ @.frontier-app/ROADMAP.md
43
+ @.frontier-app/STATE.md
44
+
45
+ # SDK reference for modules used in this plan:
46
+ @frontier-sdk/docs/[module].md
47
+
48
+ # Only reference prior plan SUMMARYs if genuinely needed:
49
+ # - This plan uses types/exports from prior plan
50
+ # - Prior plan made decision affecting this plan
51
+
52
+ [Relevant source files:]
53
+ @src/path/to/relevant.ts
54
+ </context>
55
+
56
+ <tasks>
57
+
58
+ <task type="auto">
59
+ <name>Task 1: [Action-oriented name]</name>
60
+ <files>path/to/file.ext, another/file.ext</files>
61
+ <read_first>path/to/reference.ext, path/to/source-of-truth.ext</read_first>
62
+ <action>[Specific implementation — what to do, how to do it, what to avoid and WHY.
63
+ Include CONCRETE values: exact identifiers, parameters, SDK method names, file paths.
64
+ For SDK usage: specify exact import path, method signature, expected return type.
65
+ Never say "align X with Y" without specifying the exact target state.]</action>
66
+ <verify>[Command or check to prove it worked]</verify>
67
+ <acceptance_criteria>
68
+ - [Grep-verifiable: "file.ext contains 'FrontierSDK'"]
69
+ - [Measurable: "component renders without console errors"]
70
+ </acceptance_criteria>
71
+ <done>[Measurable acceptance criteria]</done>
72
+ </task>
73
+
74
+ <task type="auto">
75
+ <name>Task 2: [Action-oriented name]</name>
76
+ <files>path/to/file.ext</files>
77
+ <read_first>path/to/reference.ext</read_first>
78
+ <action>[Specific implementation with concrete values]</action>
79
+ <verify>[Command or check]</verify>
80
+ <acceptance_criteria>
81
+ - [Grep-verifiable condition]
82
+ </acceptance_criteria>
83
+ <done>[Acceptance criteria]</done>
84
+ </task>
85
+
86
+ <task type="checkpoint:human-verify" gate="blocking">
87
+ <what-built>[What Claude built] — dev server at http://localhost:{{DEV_PORT}}</what-built>
88
+ <how-to-verify>Visit http://localhost:{{DEV_PORT}} and verify:
89
+ - [Visual check 1]
90
+ - [Visual check 2]
91
+ Open Frontier OS at localhost:3000 and verify app loads in iframe.</how-to-verify>
92
+ <resume-signal>Type "approved" or describe issues</resume-signal>
93
+ </task>
94
+
95
+ </tasks>
96
+
97
+ <verification>
98
+ Before declaring plan complete:
99
+ - [ ] `npm run build` succeeds with no errors
100
+ - [ ] `npm run dev` starts without errors on port {{DEV_PORT}}
101
+ - [ ] No TypeScript errors (`npx tsc --noEmit`)
102
+ - [ ] [Plan-specific verification]
103
+ </verification>
104
+
105
+ <success_criteria>
106
+
107
+ - All tasks completed
108
+ - All verification checks pass
109
+ - No console errors in browser
110
+ - App renders correctly in dark theme
111
+ - [Plan-specific criteria]
112
+
113
+ </success_criteria>
114
+
115
+ <output>
116
+ After completion, create `.frontier-app/phases/XX-name/{phase}-{plan}-SUMMARY.md`
117
+ </output>
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Frontmatter Fields
123
+
124
+ | Field | Required | Purpose |
125
+ |-------|----------|---------|
126
+ | `phase` | Yes | Phase identifier (e.g., `01-scaffold`) |
127
+ | `plan` | Yes | Plan number within phase (e.g., `01`, `02`) |
128
+ | `wave` | Yes | Execution wave (1, 2, 3...) for parallel scheduling |
129
+ | `depends_on` | Yes | Plan IDs this plan requires (e.g., `["01-01"]`) |
130
+ | `requirements` | Yes | Requirement IDs this plan addresses (PLAT-01, REQ-03, etc.) |
131
+ | `files_modified` | Yes | Files this plan creates or modifies |
132
+ | `autonomous` | Yes | `true` if no checkpoints, `false` if has user verification |
133
+ | `must_haves` | Yes | Goal-backward verification criteria |
134
+
135
+ ---
136
+
137
+ ## Frontier OS Specifics
138
+
139
+ **Phase 1 plans always include:**
140
+ - Vite scaffold from `templates/app/vite.config.ts`
141
+ - SdkProvider from `templates/app/sdk-context.tsx`
142
+ - Layout with iframe detection from `templates/app/layout.tsx`
143
+ - Dark theme setup via Tailwind
144
+ - Standalone fallback UI
145
+ - Dev server on assigned port
146
+
147
+ **SDK usage in tasks:**
148
+ - Always specify the exact import: `import { FrontierSDK } from '@frontiertower/frontier-sdk'`
149
+ - Always use `useSdk()` hook, never instantiate SDK directly in components
150
+ - Always wrap SDK calls in try/catch — SDK may not be available in standalone mode
151
+ - Reference the specific SDK module docs in `<context>` section
152
+
153
+ **Verification always includes:**
154
+ - Build succeeds (`npm run build`)
155
+ - Dev server starts on correct port
156
+ - No TypeScript errors
157
+ - Dark theme renders correctly (no white backgrounds)
158
+ - App works in both iframe and standalone modes
159
+
160
+ ---
161
+
162
+ ## Task Types
163
+
164
+ | Type | Use For | Autonomy |
165
+ |------|---------|----------|
166
+ | `auto` | Everything Claude can do independently | Fully autonomous |
167
+ | `checkpoint:human-verify` | Visual verification in browser/iframe | Pauses for user |
168
+ | `checkpoint:decision` | Implementation choices needing user input | Pauses for user |
169
+
170
+ ---
171
+
172
+ ## Scope Guidance
173
+
174
+ **Plan sizing:**
175
+ - 2-3 tasks per plan
176
+ - Phase 1 (scaffold): Always 1 plan
177
+ - Feature phases: 1-3 plans depending on complexity
178
+
179
+ **Vertical slices preferred:**
180
+ ```
181
+ PREFER: Plan 01 = Event listing (model + API hook + UI component)
182
+ Plan 02 = Event creation (form + validation + SDK call)
183
+
184
+ AVOID: Plan 01 = All data models
185
+ Plan 02 = All API hooks
186
+ Plan 03 = All UI components
187
+ ```