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/workflows/execute.md
CHANGED
|
@@ -31,6 +31,13 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
|
31
31
|
|
|
32
32
|
Parse JSON for: `phase`, `phase_dir`, `plans`, `summaries`, `incomplete_plans`, `all_complete`, `manifest`, `state`, `project_path`, `roadmap_path`, `template_home`, `version`.
|
|
33
33
|
|
|
34
|
+
**Generate focused SDK reference for this app's modules:**
|
|
35
|
+
```bash
|
|
36
|
+
MODULES=$(node -e "const m=JSON.parse(require('fs').readFileSync('.frontier-app/manifest.json','utf8')); console.log(m.modules.join(','))")
|
|
37
|
+
SDK_REF=$(node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" sdk-ref --modules "$MODULES")
|
|
38
|
+
SDK_REF_PATH="${SDK_REF#@file:}"
|
|
39
|
+
```
|
|
40
|
+
|
|
34
41
|
**If .frontier-app/ not found:**
|
|
35
42
|
```
|
|
36
43
|
Error: No .frontier-app/ directory found.
|
|
@@ -123,22 +130,29 @@ For each plan file in `incomplete_plans`:
|
|
|
123
130
|
```
|
|
124
131
|
Task(
|
|
125
132
|
subagent_type="fos-executor",
|
|
133
|
+
isolation="worktree",
|
|
126
134
|
prompt="
|
|
127
135
|
<objective>
|
|
128
136
|
Execute plan [plan_number] of Phase [phase_number]-[phase_name].
|
|
129
137
|
Commit each task atomically. Create SUMMARY.md when done. Update STATE.md.
|
|
130
138
|
</objective>
|
|
131
139
|
|
|
140
|
+
<parallel_execution>
|
|
141
|
+
You are running as a PARALLEL executor agent. Use --no-verify on all git
|
|
142
|
+
commits to avoid pre-commit hook contention with other agents. The
|
|
143
|
+
orchestrator validates hooks once after all agents complete.
|
|
144
|
+
</parallel_execution>
|
|
145
|
+
|
|
132
146
|
<execution_context>
|
|
133
147
|
@$HOME/.claude/frontier-os-app-builder/workflows/execute-plan.md
|
|
134
148
|
@$HOME/.claude/frontier-os-app-builder/templates/state/summary.md
|
|
135
|
-
@$HOME/.claude/frontier-os-app-builder/references/sdk-surface.md
|
|
136
149
|
@$HOME/.claude/frontier-os-app-builder/references/app-patterns.md
|
|
137
150
|
@$HOME/.claude/frontier-os-app-builder/references/verification-rules.md
|
|
138
151
|
</execution_context>
|
|
139
152
|
|
|
140
153
|
<files_to_read>
|
|
141
154
|
Read these files at execution start using the Read tool:
|
|
155
|
+
- $SDK_REF_PATH (focused SDK reference for this app's modules)
|
|
142
156
|
- $PHASE_DIR/[plan_file] (The plan to execute)
|
|
143
157
|
- .frontier-app/PROJECT.md (App vision, SDK modules)
|
|
144
158
|
- .frontier-app/manifest.json (Permissions)
|
|
@@ -164,13 +178,33 @@ For each plan file in `incomplete_plans`:
|
|
|
164
178
|
**Completion verification (per plan):**
|
|
165
179
|
```bash
|
|
166
180
|
SUMMARY_FILE="$PHASE_DIR/[plan_prefix]-SUMMARY.md"
|
|
167
|
-
|
|
181
|
+
if [ ! -f "$SUMMARY_FILE" ]; then
|
|
182
|
+
echo "incomplete"
|
|
183
|
+
elif grep -q "Self-Check: FAILED" "$SUMMARY_FILE"; then
|
|
184
|
+
echo "self-check-failed"
|
|
185
|
+
else
|
|
186
|
+
echo "complete"
|
|
187
|
+
fi
|
|
168
188
|
```
|
|
169
189
|
|
|
170
|
-
|
|
171
|
-
|
|
190
|
+
- **complete:** SUMMARY.md exists, self-check passed, git log shows recent commits. Treat as successful.
|
|
191
|
+
- **self-check-failed:** SUMMARY.md exists but executor detected issues. Read the SUMMARY.md to extract what failed, then ask:
|
|
192
|
+
- "Retry this plan?" — re-spawn the executor
|
|
193
|
+
- "Fix manually?" — exit with pointer to SUMMARY.md
|
|
194
|
+
- "Continue anyway?" — note the gap for the verifier
|
|
195
|
+
- **incomplete:** SUMMARY.md missing after agent returns. Either the agent crashed or hit a checkpoint (see handle_checkpoints step). Report as failed.
|
|
196
|
+
|
|
197
|
+
4. **Post-wave hook validation (parallel mode):**
|
|
172
198
|
|
|
173
|
-
|
|
199
|
+
When agents committed with `--no-verify`, run pre-commit hooks once after the wave:
|
|
200
|
+
```bash
|
|
201
|
+
git stash --quiet 2>/dev/null || true
|
|
202
|
+
git hook run pre-commit 2>&1 || echo "Warning: Pre-commit hooks failed — review before continuing"
|
|
203
|
+
git stash pop --quiet 2>/dev/null || true
|
|
204
|
+
```
|
|
205
|
+
If hooks fail: report the failure and ask "Fix hook issues now?" or "Continue to next wave?"
|
|
206
|
+
|
|
207
|
+
5. **Report wave completion:**
|
|
174
208
|
|
|
175
209
|
For each completed plan, read its SUMMARY.md and extract:
|
|
176
210
|
- One-liner description
|
|
@@ -189,7 +223,7 @@ For each plan file in `incomplete_plans`:
|
|
|
189
223
|
---
|
|
190
224
|
```
|
|
191
225
|
|
|
192
|
-
|
|
226
|
+
6. **Handle failures:**
|
|
193
227
|
|
|
194
228
|
If a plan fails:
|
|
195
229
|
- Report which plan failed and why (from agent output or error)
|
|
@@ -199,6 +233,95 @@ For each plan file in `incomplete_plans`:
|
|
|
199
233
|
- If stop: save state and exit
|
|
200
234
|
</step>
|
|
201
235
|
|
|
236
|
+
<step name="handle_checkpoints">
|
|
237
|
+
**Handle executor agents that returned checkpoint state instead of completion.**
|
|
238
|
+
|
|
239
|
+
When an executor agent returns a structured checkpoint (output contains `## CHECKPOINT REACHED` and no SUMMARY.md was created), it means a `checkpoint:human-verify` or `checkpoint:decision` task was encountered.
|
|
240
|
+
|
|
241
|
+
**Detection:** After each executor returns in a wave, check:
|
|
242
|
+
- If SUMMARY.md exists for that plan: agent completed normally. Skip this step.
|
|
243
|
+
- If SUMMARY.md does NOT exist AND agent output contains `## CHECKPOINT REACHED`: checkpoint hit.
|
|
244
|
+
|
|
245
|
+
**For each checkpoint:**
|
|
246
|
+
|
|
247
|
+
1. **Parse the checkpoint return:**
|
|
248
|
+
- Type: `human-verify` or `decision`
|
|
249
|
+
- Plan ID and progress (completed/total tasks)
|
|
250
|
+
- Completed tasks table (with commit hashes)
|
|
251
|
+
- Checkpoint details (what to verify or decide)
|
|
252
|
+
- Awaiting section (what user needs to provide)
|
|
253
|
+
|
|
254
|
+
2. **Present to user:**
|
|
255
|
+
```
|
|
256
|
+
## Checkpoint: [Type]
|
|
257
|
+
|
|
258
|
+
**Plan:** [plan ID] — [plan name]
|
|
259
|
+
**Progress:** [completed]/[total] tasks complete
|
|
260
|
+
|
|
261
|
+
[Checkpoint details from agent return]
|
|
262
|
+
|
|
263
|
+
[Awaiting section from agent return]
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Use AskUserQuestion (if available):
|
|
267
|
+
- header: "Checkpoint: [Type]"
|
|
268
|
+
- question: "[Awaiting section content]"
|
|
269
|
+
- If human-verify: options: ["Approved", "Issues found — describe below"]
|
|
270
|
+
- If decision: options from checkpoint details
|
|
271
|
+
|
|
272
|
+
If AskUserQuestion denied: default to "Approved" for human-verify, or the first/recommended option for decisions.
|
|
273
|
+
|
|
274
|
+
3. **Spawn a FRESH continuation executor:**
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
Task(
|
|
278
|
+
subagent_type="fos-executor",
|
|
279
|
+
isolation="worktree",
|
|
280
|
+
prompt="
|
|
281
|
+
<objective>
|
|
282
|
+
Continue execution of plan [plan_number], Phase [phase_number]-[phase_name].
|
|
283
|
+
Previous agent completed [N] tasks before hitting a checkpoint.
|
|
284
|
+
Resume from Task [resume_task_number]: [resume_task_name].
|
|
285
|
+
</objective>
|
|
286
|
+
|
|
287
|
+
<completed_tasks>
|
|
288
|
+
[Completed tasks table from checkpoint return — task names + commit hashes]
|
|
289
|
+
</completed_tasks>
|
|
290
|
+
|
|
291
|
+
<user_response>
|
|
292
|
+
[User's response to checkpoint]
|
|
293
|
+
</user_response>
|
|
294
|
+
|
|
295
|
+
<resume_instructions>
|
|
296
|
+
Start from Task [resume_task_number]: [resume_task_name].
|
|
297
|
+
Verify previous commits exist before continuing.
|
|
298
|
+
Do NOT redo completed tasks.
|
|
299
|
+
</resume_instructions>
|
|
300
|
+
|
|
301
|
+
<execution_context>
|
|
302
|
+
@$HOME/.claude/frontier-os-app-builder/workflows/execute-plan.md
|
|
303
|
+
@$HOME/.claude/frontier-os-app-builder/templates/state/summary.md
|
|
304
|
+
@$HOME/.claude/frontier-os-app-builder/references/app-patterns.md
|
|
305
|
+
@$HOME/.claude/frontier-os-app-builder/references/verification-rules.md
|
|
306
|
+
</execution_context>
|
|
307
|
+
|
|
308
|
+
<files_to_read>
|
|
309
|
+
Read these files at execution start using the Read tool:
|
|
310
|
+
- $SDK_REF_PATH (focused SDK reference for this app's modules)
|
|
311
|
+
- $PHASE_DIR/[plan_file] (The plan to execute)
|
|
312
|
+
- .frontier-app/PROJECT.md (App vision, SDK modules)
|
|
313
|
+
- .frontier-app/manifest.json (Permissions)
|
|
314
|
+
- .frontier-app/STATE.md (Current state)
|
|
315
|
+
</files_to_read>
|
|
316
|
+
"
|
|
317
|
+
)
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
4. **Wait for continuation agent.** If it hits another checkpoint, repeat from step 1. If it completes (SUMMARY.md created), treat as normal completion.
|
|
321
|
+
|
|
322
|
+
**Why fresh agent, not resume:** Fresh agents with explicit completed-task state are more reliable than attempting to resume a paused agent context.
|
|
323
|
+
</step>
|
|
324
|
+
|
|
202
325
|
<step name="spawn_verifier">
|
|
203
326
|
**After all waves complete: verify the phase.**
|
|
204
327
|
|
|
@@ -211,6 +334,10 @@ Task(
|
|
|
211
334
|
Check all success criteria from ROADMAP.md are met.
|
|
212
335
|
Check all SUMMARY.md files for issues.
|
|
213
336
|
Run structural and permission validation.
|
|
337
|
+
|
|
338
|
+
Read sdkPhase from manifest.json. If current phase matches sdkPhase, run BOTH
|
|
339
|
+
Tier 1 (standalone app quality) and Tier 2 (SDK integration correctness) checks.
|
|
340
|
+
Otherwise, run Tier 1 checks only.
|
|
214
341
|
</objective>
|
|
215
342
|
|
|
216
343
|
<files_to_read>
|
|
@@ -223,15 +350,19 @@ Task(
|
|
|
223
350
|
|
|
224
351
|
<verification_commands>
|
|
225
352
|
Run these checks:
|
|
226
|
-
- node '$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs' validate structure
|
|
227
|
-
- node '$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs' validate permissions
|
|
353
|
+
- node '$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs' validate structure --phase "$PHASE"
|
|
354
|
+
- node '$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs' validate permissions --phase "$PHASE"
|
|
228
355
|
- npx tsc --noEmit (if app source exists)
|
|
229
356
|
- npm run build (if package.json exists)
|
|
230
357
|
</verification_commands>
|
|
231
358
|
|
|
232
359
|
<output>
|
|
233
|
-
|
|
234
|
-
|
|
360
|
+
Write VERIFICATION.md to $PHASE_DIR/{phase_num}-VERIFICATION.md using the Write tool,
|
|
361
|
+
following the output_format structure in your agent definition (frontmatter with status,
|
|
362
|
+
verified_date, checks_passed, gaps fields, then full check results by category).
|
|
363
|
+
|
|
364
|
+
Then return structured result to the orchestrator:
|
|
365
|
+
- verdict: PASSED or GAPS_FOUND
|
|
235
366
|
- criteria_results: each success criterion with pass/fail
|
|
236
367
|
- gaps: list of gaps found (if any)
|
|
237
368
|
- suggestions: optional improvements
|
|
@@ -240,24 +371,48 @@ Task(
|
|
|
240
371
|
)
|
|
241
372
|
```
|
|
242
373
|
|
|
243
|
-
**
|
|
374
|
+
**Parse verifier verdict from VERIFICATION.md:**
|
|
375
|
+
```bash
|
|
376
|
+
VERIFICATION_FILE="$PHASE_DIR/${PADDED}-VERIFICATION.md"
|
|
377
|
+
VERDICT=$(grep -m1 "^status:" "$VERIFICATION_FILE" | awk '{print $2}')
|
|
244
378
|
```
|
|
245
|
-
## Verification Issues
|
|
246
379
|
|
|
247
|
-
|
|
380
|
+
**If verdict is `passed`:**
|
|
381
|
+
Verifier confirmed phase delivers on its promises. Continue to update_state_and_roadmap.
|
|
382
|
+
|
|
383
|
+
**If verdict is `gaps_found`:**
|
|
384
|
+
```
|
|
385
|
+
## Verification: Gaps Found
|
|
248
386
|
|
|
249
|
-
|
|
250
|
-
2. [Issue description]
|
|
387
|
+
Phase [N]: [Name] — [checks_passed] checks passed, gaps remain.
|
|
251
388
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
389
|
+
| # | Check | Issue | Severity |
|
|
390
|
+
|---|-------|-------|----------|
|
|
391
|
+
| 1 | [Check ID] | [What failed] | Blocker/Warning |
|
|
392
|
+
| 2 | [Check ID] | [What failed] | Blocker/Warning |
|
|
393
|
+
|
|
394
|
+
[Gap details from VERIFICATION.md Gaps section]
|
|
256
395
|
```
|
|
257
396
|
|
|
258
|
-
Use AskUserQuestion
|
|
397
|
+
Use AskUserQuestion (if available):
|
|
398
|
+
- header: "Verification Gaps"
|
|
399
|
+
- question: "How do you want to handle these gaps?"
|
|
400
|
+
- options:
|
|
401
|
+
- "Generate gap-closure plans and re-execute" — Creates fix plans, executes them, then re-verifies
|
|
402
|
+
- "Fix manually and re-verify" — You address the issues, then run `/fos:execute [N]` again
|
|
403
|
+
- "Accept with gaps noted" — Mark phase as partial, gaps documented in VERIFICATION.md
|
|
404
|
+
|
|
405
|
+
**If "Generate gap-closure plans":**
|
|
406
|
+
1. Read the Gaps section from VERIFICATION.md
|
|
407
|
+
2. Spawn fos-planner with the gap list as context to create targeted fix plans
|
|
408
|
+
3. Execute the new plans (re-enter execute_waves for the gap-closure plans only)
|
|
409
|
+
4. Re-run verifier after gap-closure plans complete
|
|
259
410
|
|
|
260
|
-
**If "
|
|
411
|
+
**If "Fix manually":** Exit with message: "Fix the gaps listed in `$VERIFICATION_FILE`, then run `/fos:execute [N]` to re-verify."
|
|
412
|
+
|
|
413
|
+
**If "Accept with gaps":** Continue to update_state_and_roadmap. Update phase status to "partial" instead of "complete" in STATE.md. Gaps remain documented in VERIFICATION.md.
|
|
414
|
+
|
|
415
|
+
**If AskUserQuestion denied:** Default to "Generate gap-closure plans and re-execute".
|
|
261
416
|
</step>
|
|
262
417
|
|
|
263
418
|
<step name="update_state_and_roadmap">
|
|
@@ -273,11 +428,20 @@ Use AskUserQuestion to let user decide.
|
|
|
273
428
|
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" state update status "phase-complete"
|
|
274
429
|
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" state update phase "$PHASE"
|
|
275
430
|
|
|
431
|
+
# Read sdkPhase from manifest
|
|
432
|
+
SDK_PHASE=$(node -e "const m=JSON.parse(require('fs').readFileSync('.frontier-app/manifest.json','utf8')); console.log(m.sdkPhase || -1)")
|
|
433
|
+
|
|
276
434
|
# Set next action based on whether more phases remain
|
|
277
435
|
if [ "$PHASE" -lt "$TOTAL_PHASES" ]; then
|
|
278
436
|
NEXT_PHASE=$((PHASE + 1))
|
|
279
|
-
|
|
280
|
-
|
|
437
|
+
if [ "$NEXT_PHASE" -eq "$SDK_PHASE" ]; then
|
|
438
|
+
# SDK Integration phase is mechanical — skip discuss, go straight to plan
|
|
439
|
+
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" state update next_action "/fos:plan $NEXT_PHASE"
|
|
440
|
+
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" state update status "ready-to-plan"
|
|
441
|
+
else
|
|
442
|
+
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" state update next_action "/fos:discuss $NEXT_PHASE"
|
|
443
|
+
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" state update status "ready-to-discuss"
|
|
444
|
+
fi
|
|
281
445
|
else
|
|
282
446
|
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" state update next_action "/fos:ship"
|
|
283
447
|
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" state update status "milestone-complete"
|
|
@@ -317,7 +481,23 @@ Plans completed:
|
|
|
317
481
|
- [Plan 01]: [one-liner from SUMMARY.md]
|
|
318
482
|
- [Plan 02]: [one-liner from SUMMARY.md]
|
|
319
483
|
|
|
320
|
-
[If
|
|
484
|
+
[If completed phase was the SDK Integration phase (sdkPhase from manifest.json):]
|
|
485
|
+
────────────────────────────────────────
|
|
486
|
+
SDK Integration complete. App is now Frontier OS-ready.
|
|
487
|
+
Next up: `/fos:ship` — Deploy to Vercel and register in the Frontier app store.
|
|
488
|
+
|
|
489
|
+
Run `/clear` first to free your context window.
|
|
490
|
+
────────────────────────────────────────
|
|
491
|
+
|
|
492
|
+
[If more phases remain AND next phase is sdkPhase:]
|
|
493
|
+
────────────────────────────────────────
|
|
494
|
+
Next up: `/fos:plan [N+1]`
|
|
495
|
+
Plan Phase [N+1]: [Name] — SDK Integration is mechanical, skipping discuss.
|
|
496
|
+
|
|
497
|
+
Run `/clear` first to free your context window.
|
|
498
|
+
────────────────────────────────────────
|
|
499
|
+
|
|
500
|
+
[If more phases remain (default):]
|
|
321
501
|
────────────────────────────────────────
|
|
322
502
|
Next up: `/fos:discuss [N+1]`
|
|
323
503
|
Discuss Phase [N+1]: [Name] — capture implementation decisions before planning.
|
package/workflows/new-app.md
CHANGED
|
@@ -38,6 +38,14 @@ If you want to start fresh: delete .frontier-app/ and run /fos:new-app again
|
|
|
38
38
|
Exit workflow.
|
|
39
39
|
|
|
40
40
|
**If `has_git` is false:** Will initialize git after scaffolding (step 9).
|
|
41
|
+
|
|
42
|
+
**Check for Studio context file:**
|
|
43
|
+
Read `.frontier-studio-context.md` if it exists in the current directory or `../.frontier-studio-context.md` in the parent. This file contains Frontier Tower domain knowledge (floors, membership, events, governance, existing apps) selected by the developer in Frontier Studio. It complements the SDK technical references you already have — use it to inform module inference, domain questions, and requirements throughout the workflow. Skip if the file doesn't exist.
|
|
44
|
+
|
|
45
|
+
**After reading (if it existed):** Delete the file to prevent stale context from leaking into future app creations:
|
|
46
|
+
```bash
|
|
47
|
+
rm -f .frontier-studio-context.md ../.frontier-studio-context.md
|
|
48
|
+
```
|
|
41
49
|
</step>
|
|
42
50
|
|
|
43
51
|
<step name="gather_description">
|
|
@@ -50,10 +58,15 @@ Check if `$ARGUMENTS` contains a description (any text that isn't just flags).
|
|
|
50
58
|
Building: "[description from arguments]"
|
|
51
59
|
```
|
|
52
60
|
|
|
53
|
-
**If no description:** Use AskUserQuestion:
|
|
61
|
+
**If no description:** Use AskUserQuestion (if available):
|
|
54
62
|
- header: "App Idea"
|
|
55
63
|
- question: "What Frontier OS app do you want to build? Describe it in plain language — what it does, who uses it, and what Frontier features it needs."
|
|
56
64
|
|
|
65
|
+
If AskUserQuestion is denied (autonomous/don't-ask mode), output an error and exit — a description is required:
|
|
66
|
+
```
|
|
67
|
+
Error: No app description provided. Usage: /fos:new-app "describe your app"
|
|
68
|
+
```
|
|
69
|
+
|
|
57
70
|
**Store the description** for use in subsequent steps.
|
|
58
71
|
</step>
|
|
59
72
|
|
|
@@ -125,6 +138,8 @@ Generate 2-5 questions based on WHICH modules were inferred. These are DOMAIN qu
|
|
|
125
138
|
|
|
126
139
|
**Ask questions one batch at a time** using AskUserQuestion with appropriate options for each. Keep it to ONE round of questions — do not over-interrogate.
|
|
127
140
|
|
|
141
|
+
**If AskUserQuestion is denied (autonomous/don't-ask mode):** Skip this step entirely. Use reasonable defaults based on the description and any Studio context file. Briefly state the defaults you're choosing and why, then proceed to confirmation.
|
|
142
|
+
|
|
128
143
|
**For modules with no specific questions** (Storage, Chain): skip — these are utility modules with standard patterns.
|
|
129
144
|
</step>
|
|
130
145
|
|
|
@@ -148,14 +163,15 @@ Incorporate answers from smart questions to refine the module list. If the user'
|
|
|
148
163
|
|
|
149
164
|
### Phases Preview
|
|
150
165
|
|
|
151
|
-
1. **Phase 1: Scaffold +
|
|
166
|
+
1. **Phase 1: Scaffold + Standalone Shell** — Project setup, services layer, mock data, dark theme
|
|
152
167
|
2. **Phase 2: [Feature]** — [From description + smart question answers]
|
|
153
|
-
|
|
168
|
+
...
|
|
169
|
+
N. **Phase N: SDK Integration** — Wire SDK, create adapter, upgrade Layout for iframe
|
|
154
170
|
|
|
155
171
|
Total permissions: [N]
|
|
156
172
|
```
|
|
157
173
|
|
|
158
|
-
Use AskUserQuestion:
|
|
174
|
+
Use AskUserQuestion (if available):
|
|
159
175
|
- header: "Confirm"
|
|
160
176
|
- question: "Does this look right?"
|
|
161
177
|
- options:
|
|
@@ -165,31 +181,62 @@ Use AskUserQuestion:
|
|
|
165
181
|
|
|
166
182
|
**If "Change something":** Ask what to change, adjust, and re-confirm.
|
|
167
183
|
**If "Start over":** Return to step 2.
|
|
184
|
+
|
|
185
|
+
**If AskUserQuestion is denied (autonomous/don't-ask mode):** Display the summary and proceed directly to scaffolding. The user can adjust later via `/fos:add-feature` or by editing manifest.json.
|
|
168
186
|
</step>
|
|
169
187
|
|
|
170
188
|
<step name="create_app_directory">
|
|
171
|
-
**Create the app directory structure.**
|
|
189
|
+
**Create the app directory and project state structure.**
|
|
190
|
+
|
|
191
|
+
Generate the app directory name from the confirmed app name:
|
|
192
|
+
- Kebab-case the name: "Tip Jar" → "tip-jar"
|
|
193
|
+
- Prefix with `frontier-os-app-`: "tip-jar" → "frontier-os-app-tip-jar"
|
|
194
|
+
|
|
195
|
+
If the current directory already IS the app directory (user pre-created it and cd'd in), skip directory creation — just create `.frontier-app/` in place.
|
|
196
|
+
|
|
197
|
+
Otherwise, create the directory and **change into it immediately**:
|
|
172
198
|
|
|
173
199
|
```bash
|
|
174
|
-
|
|
175
|
-
mkdir -p
|
|
200
|
+
APP_SLUG="frontier-os-app-[kebab-name]"
|
|
201
|
+
mkdir -p "$APP_SLUG" && cd "$APP_SLUG"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**CRITICAL:** After creating the directory, ALL subsequent commands (file writes, git, scaffold, etc.) MUST use the new app directory as the working directory. Use absolute paths or `cd` into the directory in every Bash call. The `cd` in a single Bash call does NOT persist to subsequent Bash calls — so either:
|
|
205
|
+
- Prefix every Bash command with `cd "$APP_DIR" &&`, or
|
|
206
|
+
- Use absolute paths (`$APP_DIR/.frontier-app/...`) for all file operations
|
|
207
|
+
|
|
208
|
+
Set `APP_DIR` to the absolute path of the new app directory:
|
|
209
|
+
```bash
|
|
210
|
+
APP_DIR="$(pwd)/$APP_SLUG"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Then create the project state directory:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
mkdir -p "$APP_DIR/.frontier-app/phases/01-scaffold"
|
|
176
217
|
```
|
|
177
218
|
|
|
178
219
|
This creates:
|
|
220
|
+
- `frontier-os-app-[name]/` — The app project directory (auto-created)
|
|
179
221
|
- `.frontier-app/` — Project state directory
|
|
180
222
|
- `.frontier-app/phases/01-scaffold/` — Phase 1 directory (always created)
|
|
223
|
+
|
|
224
|
+
**How to detect if already in an app directory:**
|
|
225
|
+
If the user already created and cd'd into a directory named `frontier-os-app-*` that is empty (no files except maybe `.git`), treat it as the app directory and skip creation. Otherwise, create the subdirectory.
|
|
181
226
|
</step>
|
|
182
227
|
|
|
183
228
|
<step name="create_roadmap">
|
|
184
229
|
**Build the phased roadmap.**
|
|
185
230
|
|
|
186
|
-
Phase 1 is ALWAYS "Scaffold +
|
|
231
|
+
Phase 1 is ALWAYS "Scaffold + Standalone Shell" — this is non-negotiable for every Frontier OS app.
|
|
232
|
+
The LAST phase is ALWAYS "SDK Integration" — a mechanical phase that wires the real Frontier SDK. This phase is auto-added and has fixed success criteria (no user decisions needed). It is non-negotiable.
|
|
187
233
|
|
|
188
234
|
Additional phases come from the features identified in steps 3-5:
|
|
189
235
|
- Group related features into coherent phases
|
|
190
236
|
- Each phase should deliver something testable
|
|
191
237
|
- Keep to 3-6 total phases for v1 — ship fast
|
|
192
238
|
- Order phases by dependency (features that build on each other)
|
|
239
|
+
- The final phase is always "SDK Integration" — auto-added after all feature phases
|
|
193
240
|
|
|
194
241
|
**Phase sizing heuristics:**
|
|
195
242
|
- Simple feature (one SDK module, one view): 1 phase, 1-2 plans
|
|
@@ -260,10 +307,12 @@ Construct the manifest object:
|
|
|
260
307
|
"permissions": ["storage:get", "storage:set", ...all permissions...],
|
|
261
308
|
"milestone": "v1",
|
|
262
309
|
"phases": [
|
|
263
|
-
{"number": 1, "name": "Scaffold +
|
|
310
|
+
{"number": 1, "name": "Scaffold + Standalone Shell", "status": "not-started"},
|
|
264
311
|
{"number": 2, "name": "[Feature]", "status": "not-started"},
|
|
265
312
|
...
|
|
266
|
-
|
|
313
|
+
{"number": N, "name": "SDK Integration", "status": "not-started"}
|
|
314
|
+
],
|
|
315
|
+
"sdkPhase": N
|
|
267
316
|
}
|
|
268
317
|
```
|
|
269
318
|
|
|
@@ -273,27 +322,19 @@ Write to `.frontier-app/manifest.json`.
|
|
|
273
322
|
<step name="git_init_and_commit">
|
|
274
323
|
**Initialize git and create initial commit.**
|
|
275
324
|
|
|
325
|
+
All commands in this step MUST run inside `$APP_DIR`:
|
|
326
|
+
|
|
276
327
|
**If `has_git` is false:**
|
|
277
328
|
```bash
|
|
278
|
-
git init
|
|
329
|
+
cd "$APP_DIR" && git init
|
|
279
330
|
```
|
|
280
331
|
|
|
281
332
|
**Create .gitignore if it doesn't exist:**
|
|
282
|
-
|
|
283
|
-
cat > .gitignore << 'GITIGNORE'
|
|
284
|
-
node_modules/
|
|
285
|
-
dist/
|
|
286
|
-
.env
|
|
287
|
-
.env.local
|
|
288
|
-
*.log
|
|
289
|
-
.DS_Store
|
|
290
|
-
GITIGNORE
|
|
291
|
-
```
|
|
333
|
+
Write `.gitignore` to `$APP_DIR/.gitignore`.
|
|
292
334
|
|
|
293
335
|
**Commit all state files:**
|
|
294
336
|
```bash
|
|
295
|
-
git add .frontier-app/ .gitignore
|
|
296
|
-
git commit -m "feat: initialize [App Name] — Frontier OS app
|
|
337
|
+
cd "$APP_DIR" && git add .frontier-app/ .gitignore && git commit -m "feat: initialize [App Name] — Frontier OS app
|
|
297
338
|
|
|
298
339
|
SDK Modules: [comma-separated modules]
|
|
299
340
|
Phases: [count] phases planned for v1
|
|
@@ -65,7 +65,7 @@ Create or append to `.frontier-app/MILESTONES.md`:
|
|
|
65
65
|
|
|
66
66
|
| Phase | Name | Plans | Status |
|
|
67
67
|
|-------|------|-------|--------|
|
|
68
|
-
| 1 | Scaffold +
|
|
68
|
+
| 1 | Scaffold + Standalone Shell | 1/1 | Complete |
|
|
69
69
|
| 2 | [Name] | N/N | Complete |
|
|
70
70
|
| ... | ... | ... | ... |
|
|
71
71
|
|
|
@@ -91,10 +91,15 @@ Check if `$ARGUMENTS` contains feature descriptions.
|
|
|
91
91
|
|
|
92
92
|
**If description provided in $ARGUMENTS:** Use it directly.
|
|
93
93
|
|
|
94
|
-
**If no description:** Use AskUserQuestion:
|
|
94
|
+
**If no description:** Use AskUserQuestion (if available):
|
|
95
95
|
- header: "New Milestone"
|
|
96
96
|
- question: "What features should [App Name] [next version] include? Describe the new capabilities you want to add."
|
|
97
97
|
|
|
98
|
+
If AskUserQuestion denied: error and exit — a description is required:
|
|
99
|
+
```
|
|
100
|
+
Error: No feature descriptions provided. Usage: /fos:new-milestone "describe new features"
|
|
101
|
+
```
|
|
102
|
+
|
|
98
103
|
Parse the response into individual features. Each feature becomes a candidate for a phase.
|
|
99
104
|
</step>
|
|
100
105
|
|
|
@@ -154,13 +159,15 @@ Starting from Phase [N]:
|
|
|
154
159
|
- [ ] **Phase [N+2]: [Feature Name]** — [Description]
|
|
155
160
|
```
|
|
156
161
|
|
|
157
|
-
Use AskUserQuestion:
|
|
162
|
+
Use AskUserQuestion (if available):
|
|
158
163
|
- header: "Confirm"
|
|
159
164
|
- question: "Does this milestone plan look right?"
|
|
160
165
|
- options:
|
|
161
166
|
- "Looks good" — Create the phases
|
|
162
167
|
- "Change something" — Adjust phases
|
|
163
168
|
- "Cancel" — Don't start new milestone yet
|
|
169
|
+
|
|
170
|
+
If AskUserQuestion denied: display the plan and proceed with "Looks good".
|
|
164
171
|
</step>
|
|
165
172
|
|
|
166
173
|
<step name="update_all_state_files">
|
package/workflows/plan.md
CHANGED
|
@@ -27,6 +27,13 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
|
27
27
|
|
|
28
28
|
Parse JSON for: `phase`, `phase_dir`, `has_context`, `has_research`, `existing_plans`, `manifest`, `state`, `project_path`, `roadmap_path`, `template_home`, `version`.
|
|
29
29
|
|
|
30
|
+
**Generate focused SDK reference for this app's modules:**
|
|
31
|
+
```bash
|
|
32
|
+
MODULES=$(node -e "const m=JSON.parse(require('fs').readFileSync('.frontier-app/manifest.json','utf8')); console.log(m.modules.join(','))")
|
|
33
|
+
SDK_REF=$(node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" sdk-ref --modules "$MODULES")
|
|
34
|
+
SDK_REF_PATH="${SDK_REF#@file:}"
|
|
35
|
+
```
|
|
36
|
+
|
|
30
37
|
**If .frontier-app/ not found:**
|
|
31
38
|
```
|
|
32
39
|
Error: No .frontier-app/ directory found.
|
|
@@ -52,7 +59,7 @@ Continue anyway? (y/n)
|
|
|
52
59
|
```
|
|
53
60
|
|
|
54
61
|
**If `existing_plans` is not empty:**
|
|
55
|
-
Use AskUserQuestion:
|
|
62
|
+
Use AskUserQuestion (if available):
|
|
56
63
|
- header: "Existing Plans"
|
|
57
64
|
- question: "Phase [N] already has [count] plan(s). What do you want to do?"
|
|
58
65
|
- options:
|
|
@@ -60,6 +67,8 @@ Use AskUserQuestion:
|
|
|
60
67
|
- "View plans" — Show existing plans before deciding
|
|
61
68
|
- "Keep them" — Skip planning, proceed to execution
|
|
62
69
|
|
|
70
|
+
If AskUserQuestion denied: default to "Replan" — delete existing plans and create new ones.
|
|
71
|
+
|
|
63
72
|
**If "Keep them":** Exit with next-up `/fos:execute N`.
|
|
64
73
|
**If "Replan":** Continue (plans will be overwritten).
|
|
65
74
|
</step>
|
|
@@ -80,12 +89,12 @@ Task(
|
|
|
80
89
|
|
|
81
90
|
<execution_context>
|
|
82
91
|
@$HOME/.claude/frontier-os-app-builder/agents/fos-researcher.md
|
|
83
|
-
@$HOME/.claude/frontier-os-app-builder/references/sdk-surface.md
|
|
84
92
|
@$HOME/.claude/frontier-os-app-builder/references/app-patterns.md
|
|
85
93
|
</execution_context>
|
|
86
94
|
|
|
87
95
|
<files_to_read>
|
|
88
96
|
Read these files at execution start using the Read tool:
|
|
97
|
+
- $SDK_REF_PATH (focused SDK reference for this app's modules)
|
|
89
98
|
- .frontier-app/PROJECT.md (App vision, SDK modules, constraints)
|
|
90
99
|
- .frontier-app/manifest.json (Declared permissions and metadata)
|
|
91
100
|
- .frontier-app/ROADMAP.md (Phase goal and requirements)
|
|
@@ -124,13 +133,13 @@ Task(
|
|
|
124
133
|
|
|
125
134
|
<execution_context>
|
|
126
135
|
@$HOME/.claude/frontier-os-app-builder/templates/state/plan.md
|
|
127
|
-
@$HOME/.claude/frontier-os-app-builder/references/sdk-surface.md
|
|
128
136
|
@$HOME/.claude/frontier-os-app-builder/references/app-patterns.md
|
|
129
137
|
@$HOME/.claude/frontier-os-app-builder/references/verification-rules.md
|
|
130
138
|
</execution_context>
|
|
131
139
|
|
|
132
140
|
<files_to_read>
|
|
133
141
|
Read these files at execution start using the Read tool:
|
|
142
|
+
- $SDK_REF_PATH (focused SDK reference for this app's modules)
|
|
134
143
|
- .frontier-app/PROJECT.md (App vision, SDK modules, constraints)
|
|
135
144
|
- .frontier-app/manifest.json (Declared permissions and metadata)
|
|
136
145
|
- .frontier-app/ROADMAP.md (Phase goal, success criteria, requirements)
|
|
@@ -139,8 +148,10 @@ Task(
|
|
|
139
148
|
</files_to_read>
|
|
140
149
|
|
|
141
150
|
<planning_rules>
|
|
142
|
-
- Phase 1 (Scaffold): ALWAYS exactly 1 plan. Uses templates
|
|
151
|
+
- Phase 1 (Scaffold + Standalone Shell): ALWAYS exactly 1 plan. Uses standalone templates: `frontier-services.tsx`, `layout-standalone.tsx`, `package-standalone.json`, `main-router.tsx`, `vercel-standalone.json`.
|
|
152
|
+
- SDK Integration phase: ALWAYS exactly 1 plan. Mechanical — adds SDK dependency, creates adapter, upgrades Layout. Minimal research needed.
|
|
143
153
|
- Feature phases: 1-3 plans. Prefer fewer, larger plans over many small ones.
|
|
154
|
+
- Feature phase tasks reference `useServices()` from `../lib/frontier-services` for all service access. Method names are validated against the focused SDK reference for correctness.
|
|
144
155
|
- Each plan gets 2-3 tasks. Tasks are atomic — one clear action each.
|
|
145
156
|
- Wave 1 = no dependencies. Wave 2 = depends on Wave 1. Usually 1 wave is enough.
|
|
146
157
|
- Vertical slices: Plan 01 = Event listing (hook + component + route), NOT Plan 01 = All hooks.
|
|
@@ -192,7 +203,7 @@ Task(
|
|
|
192
203
|
5. **Verification:** Does every plan include build + typecheck verification?
|
|
193
204
|
6. **Dependencies:** Are wave assignments correct? No circular deps?
|
|
194
205
|
7. **File conflicts:** Do any plans modify the same files in the same wave?
|
|
195
|
-
8. **
|
|
206
|
+
8. **Tier compliance:** Dark theme, services layer, mock data — all covered? (Tier 1 for feature phases; full SDK check for SDK Integration phase only)
|
|
196
207
|
</check_criteria>
|
|
197
208
|
|
|
198
209
|
<output>
|