frontier-os-app-builder 1.1.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 +25 -0
- package/agents/fos-executor.md +22 -65
- package/agents/fos-plan-checker.md +13 -12
- package/agents/fos-planner.md +20 -67
- package/agents/fos-researcher.md +14 -10
- package/agents/fos-verifier.md +11 -5
- package/bin/fos-tools.cjs +48 -11
- 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 +1 -3
- 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 +46 -28
- package/references/deployment.md +40 -74
- 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 +18 -18
- package/templates/app/frontier-services.tsx +75 -18
- package/templates/app/layout.tsx +19 -9
- 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 +92 -117
- package/templates/app/vercel.json +8 -47
- package/templates/state/plan.md +32 -14
- package/templates/state/roadmap.md +2 -2
- package/templates/state/summary.md +26 -29
- package/workflows/add-feature.md +6 -1
- package/workflows/discuss.md +9 -3
- package/workflows/execute-plan.md +3 -3
- package/workflows/execute.md +17 -6
- package/workflows/new-app.md +54 -18
- package/workflows/new-milestone.md +9 -2
- package/workflows/plan.md +14 -5
- package/workflows/ship.md +26 -10
- package/workflows/status.md +0 -1
- package/references/module-inference.md +0 -348
- package/references/sdk-surface.md +0 -1600
- package/templates/app/main-simple-standalone.tsx +0 -19
- package/templates/app/main-simple.tsx +0 -19
- package/templates/state/manifest.json +0 -12
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.
|
|
@@ -139,13 +146,13 @@ For each plan file in `incomplete_plans`:
|
|
|
139
146
|
<execution_context>
|
|
140
147
|
@$HOME/.claude/frontier-os-app-builder/workflows/execute-plan.md
|
|
141
148
|
@$HOME/.claude/frontier-os-app-builder/templates/state/summary.md
|
|
142
|
-
@$HOME/.claude/frontier-os-app-builder/references/sdk-surface.md
|
|
143
149
|
@$HOME/.claude/frontier-os-app-builder/references/app-patterns.md
|
|
144
150
|
@$HOME/.claude/frontier-os-app-builder/references/verification-rules.md
|
|
145
151
|
</execution_context>
|
|
146
152
|
|
|
147
153
|
<files_to_read>
|
|
148
154
|
Read these files at execution start using the Read tool:
|
|
155
|
+
- $SDK_REF_PATH (focused SDK reference for this app's modules)
|
|
149
156
|
- $PHASE_DIR/[plan_file] (The plan to execute)
|
|
150
157
|
- .frontier-app/PROJECT.md (App vision, SDK modules)
|
|
151
158
|
- .frontier-app/manifest.json (Permissions)
|
|
@@ -256,12 +263,14 @@ When an executor agent returns a structured checkpoint (output contains `## CHEC
|
|
|
256
263
|
[Awaiting section from agent return]
|
|
257
264
|
```
|
|
258
265
|
|
|
259
|
-
Use AskUserQuestion:
|
|
266
|
+
Use AskUserQuestion (if available):
|
|
260
267
|
- header: "Checkpoint: [Type]"
|
|
261
268
|
- question: "[Awaiting section content]"
|
|
262
269
|
- If human-verify: options: ["Approved", "Issues found — describe below"]
|
|
263
270
|
- If decision: options from checkpoint details
|
|
264
271
|
|
|
272
|
+
If AskUserQuestion denied: default to "Approved" for human-verify, or the first/recommended option for decisions.
|
|
273
|
+
|
|
265
274
|
3. **Spawn a FRESH continuation executor:**
|
|
266
275
|
|
|
267
276
|
```
|
|
@@ -292,13 +301,13 @@ When an executor agent returns a structured checkpoint (output contains `## CHEC
|
|
|
292
301
|
<execution_context>
|
|
293
302
|
@$HOME/.claude/frontier-os-app-builder/workflows/execute-plan.md
|
|
294
303
|
@$HOME/.claude/frontier-os-app-builder/templates/state/summary.md
|
|
295
|
-
@$HOME/.claude/frontier-os-app-builder/references/sdk-surface.md
|
|
296
304
|
@$HOME/.claude/frontier-os-app-builder/references/app-patterns.md
|
|
297
305
|
@$HOME/.claude/frontier-os-app-builder/references/verification-rules.md
|
|
298
306
|
</execution_context>
|
|
299
307
|
|
|
300
308
|
<files_to_read>
|
|
301
309
|
Read these files at execution start using the Read tool:
|
|
310
|
+
- $SDK_REF_PATH (focused SDK reference for this app's modules)
|
|
302
311
|
- $PHASE_DIR/[plan_file] (The plan to execute)
|
|
303
312
|
- .frontier-app/PROJECT.md (App vision, SDK modules)
|
|
304
313
|
- .frontier-app/manifest.json (Permissions)
|
|
@@ -341,8 +350,8 @@ Task(
|
|
|
341
350
|
|
|
342
351
|
<verification_commands>
|
|
343
352
|
Run these checks:
|
|
344
|
-
- node '$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs' validate structure
|
|
345
|
-
- 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"
|
|
346
355
|
- npx tsc --noEmit (if app source exists)
|
|
347
356
|
- npm run build (if package.json exists)
|
|
348
357
|
</verification_commands>
|
|
@@ -385,7 +394,7 @@ Phase [N]: [Name] — [checks_passed] checks passed, gaps remain.
|
|
|
385
394
|
[Gap details from VERIFICATION.md Gaps section]
|
|
386
395
|
```
|
|
387
396
|
|
|
388
|
-
Use AskUserQuestion:
|
|
397
|
+
Use AskUserQuestion (if available):
|
|
389
398
|
- header: "Verification Gaps"
|
|
390
399
|
- question: "How do you want to handle these gaps?"
|
|
391
400
|
- options:
|
|
@@ -402,6 +411,8 @@ Use AskUserQuestion:
|
|
|
402
411
|
**If "Fix manually":** Exit with message: "Fix the gaps listed in `$VERIFICATION_FILE`, then run `/fos:execute [N]` to re-verify."
|
|
403
412
|
|
|
404
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".
|
|
405
416
|
</step>
|
|
406
417
|
|
|
407
418
|
<step name="update_state_and_roadmap">
|
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
|
|
|
@@ -156,7 +171,7 @@ N. **Phase N: SDK Integration** — Wire SDK, create adapter, upgrade Layout for
|
|
|
156
171
|
Total permissions: [N]
|
|
157
172
|
```
|
|
158
173
|
|
|
159
|
-
Use AskUserQuestion:
|
|
174
|
+
Use AskUserQuestion (if available):
|
|
160
175
|
- header: "Confirm"
|
|
161
176
|
- question: "Does this look right?"
|
|
162
177
|
- options:
|
|
@@ -166,19 +181,48 @@ Use AskUserQuestion:
|
|
|
166
181
|
|
|
167
182
|
**If "Change something":** Ask what to change, adjust, and re-confirm.
|
|
168
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.
|
|
169
186
|
</step>
|
|
170
187
|
|
|
171
188
|
<step name="create_app_directory">
|
|
172
|
-
**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**:
|
|
173
198
|
|
|
174
199
|
```bash
|
|
175
|
-
|
|
176
|
-
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"
|
|
177
217
|
```
|
|
178
218
|
|
|
179
219
|
This creates:
|
|
220
|
+
- `frontier-os-app-[name]/` — The app project directory (auto-created)
|
|
180
221
|
- `.frontier-app/` — Project state directory
|
|
181
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.
|
|
182
226
|
</step>
|
|
183
227
|
|
|
184
228
|
<step name="create_roadmap">
|
|
@@ -278,27 +322,19 @@ Write to `.frontier-app/manifest.json`.
|
|
|
278
322
|
<step name="git_init_and_commit">
|
|
279
323
|
**Initialize git and create initial commit.**
|
|
280
324
|
|
|
325
|
+
All commands in this step MUST run inside `$APP_DIR`:
|
|
326
|
+
|
|
281
327
|
**If `has_git` is false:**
|
|
282
328
|
```bash
|
|
283
|
-
git init
|
|
329
|
+
cd "$APP_DIR" && git init
|
|
284
330
|
```
|
|
285
331
|
|
|
286
332
|
**Create .gitignore if it doesn't exist:**
|
|
287
|
-
|
|
288
|
-
cat > .gitignore << 'GITIGNORE'
|
|
289
|
-
node_modules/
|
|
290
|
-
dist/
|
|
291
|
-
.env
|
|
292
|
-
.env.local
|
|
293
|
-
*.log
|
|
294
|
-
.DS_Store
|
|
295
|
-
GITIGNORE
|
|
296
|
-
```
|
|
333
|
+
Write `.gitignore` to `$APP_DIR/.gitignore`.
|
|
297
334
|
|
|
298
335
|
**Commit all state files:**
|
|
299
336
|
```bash
|
|
300
|
-
git add .frontier-app/ .gitignore
|
|
301
|
-
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
|
|
302
338
|
|
|
303
339
|
SDK Modules: [comma-separated modules]
|
|
304
340
|
Phases: [count] phases planned for v1
|
|
@@ -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,10 +148,10 @@ Task(
|
|
|
139
148
|
</files_to_read>
|
|
140
149
|
|
|
141
150
|
<planning_rules>
|
|
142
|
-
- Phase 1 (Scaffold + Standalone Shell): ALWAYS exactly 1 plan. Uses standalone templates: `frontier-services.tsx`, `layout-standalone.tsx`, `package-standalone.json`, `main-
|
|
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`.
|
|
143
152
|
- SDK Integration phase: ALWAYS exactly 1 plan. Mechanical — adds SDK dependency, creates adapter, upgrades Layout. Minimal research needed.
|
|
144
153
|
- Feature phases: 1-3 plans. Prefer fewer, larger plans over many small ones.
|
|
145
|
-
- Feature phase tasks reference `useServices()` from `../lib/frontier-services` for all service access. Method names are validated against
|
|
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.
|
|
146
155
|
- Each plan gets 2-3 tasks. Tasks are atomic — one clear action each.
|
|
147
156
|
- Wave 1 = no dependencies. Wave 2 = depends on Wave 1. Usually 1 wave is enough.
|
|
148
157
|
- Vertical slices: Plan 01 = Event listing (hook + component + route), NOT Plan 01 = All hooks.
|
package/workflows/ship.md
CHANGED
|
@@ -43,7 +43,7 @@ Recommended: Run `/fos:status` to see which phases are incomplete.
|
|
|
43
43
|
Continue with deployment anyway? Some features may be missing.
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Use AskUserQuestion:
|
|
46
|
+
Use AskUserQuestion (if available):
|
|
47
47
|
- header: "Incomplete Phases"
|
|
48
48
|
- question: "Deploy with incomplete phases?"
|
|
49
49
|
- options:
|
|
@@ -52,6 +52,7 @@ Use AskUserQuestion:
|
|
|
52
52
|
- "Cancel" — Go back and finish phases
|
|
53
53
|
|
|
54
54
|
**If "Check status first" or "Cancel":** Exit workflow.
|
|
55
|
+
**If AskUserQuestion denied:** Default to "Deploy anyway".
|
|
55
56
|
|
|
56
57
|
**Display ship summary:**
|
|
57
58
|
```
|
|
@@ -90,14 +91,19 @@ else
|
|
|
90
91
|
TEST_STATUS=0
|
|
91
92
|
fi
|
|
92
93
|
|
|
94
|
+
# Read the SDK Integration phase from the manifest so the validators run their
|
|
95
|
+
# Tier-2 checks (CORS origins, SDK→services bridge, exact permissions). Empty
|
|
96
|
+
# when no sdkPhase is set — the validator then falls back to the STATE.md phase.
|
|
97
|
+
SDK_PHASE=$(node -e "const m=JSON.parse(require('fs').readFileSync('.frontier-app/manifest.json','utf8')); console.log(m.sdkPhase ?? '')")
|
|
98
|
+
|
|
93
99
|
# 4. FOS structure validation
|
|
94
100
|
echo "--- Structure ---"
|
|
95
|
-
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" validate structure
|
|
101
|
+
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" validate structure ${SDK_PHASE:+--phase "$SDK_PHASE"}
|
|
96
102
|
STRUCT_STATUS=$?
|
|
97
103
|
|
|
98
104
|
# 5. FOS permissions validation
|
|
99
105
|
echo "--- Permissions ---"
|
|
100
|
-
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" validate permissions
|
|
106
|
+
node "$HOME/.claude/frontier-os-app-builder/bin/fos-tools.cjs" validate permissions ${SDK_PHASE:+--phase "$SDK_PHASE"}
|
|
101
107
|
PERMS_STATUS=$?
|
|
102
108
|
```
|
|
103
109
|
|
|
@@ -172,9 +178,16 @@ Read the app name from manifest.json to construct the repo name.
|
|
|
172
178
|
PACKAGE_NAME=$(node -e "const m=JSON.parse(require('fs').readFileSync('.frontier-app/manifest.json','utf8')); console.log(m.packageName)")
|
|
173
179
|
REPO_NAME="frontier-os-${PACKAGE_NAME}"
|
|
174
180
|
APP_DESC=$(node -e "const m=JSON.parse(require('fs').readFileSync('.frontier-app/manifest.json','utf8')); console.log(m.description)")
|
|
175
|
-
|
|
181
|
+
# Org is optional. Set FOS_GITHUB_ORG to create the repo under a GitHub org;
|
|
182
|
+
# when it's empty the repo is created under the authenticated gh user.
|
|
183
|
+
ORG="${FOS_GITHUB_ORG:-}"
|
|
184
|
+
if [ -n "$ORG" ]; then
|
|
185
|
+
REPO_TARGET="$ORG/$REPO_NAME"
|
|
186
|
+
else
|
|
187
|
+
REPO_TARGET="$REPO_NAME"
|
|
188
|
+
fi
|
|
176
189
|
|
|
177
|
-
echo "Repo: $
|
|
190
|
+
echo "Repo: $REPO_TARGET"
|
|
178
191
|
```
|
|
179
192
|
|
|
180
193
|
**Check if remote already exists:**
|
|
@@ -184,16 +197,17 @@ git remote get-url origin 2>/dev/null
|
|
|
184
197
|
|
|
185
198
|
**If no remote:**
|
|
186
199
|
```bash
|
|
187
|
-
# Create private repo
|
|
188
|
-
gh repo create "$
|
|
200
|
+
# Create private repo (under $FOS_GITHUB_ORG if set, else the authed gh user)
|
|
201
|
+
gh repo create "$REPO_TARGET" --private --description "$APP_DESC" --source . --push
|
|
189
202
|
|
|
190
203
|
# Verify
|
|
191
|
-
gh repo view "$
|
|
204
|
+
gh repo view "$REPO_TARGET" --json url -q .url
|
|
192
205
|
```
|
|
193
206
|
|
|
194
207
|
**If remote already exists:** Just push.
|
|
195
208
|
```bash
|
|
196
|
-
git
|
|
209
|
+
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo main)
|
|
210
|
+
git push -u origin "$BRANCH"
|
|
197
211
|
```
|
|
198
212
|
</step>
|
|
199
213
|
|
|
@@ -247,7 +261,7 @@ This will prompt for team/project selection. After first deploy, subsequent depl
|
|
|
247
261
|
<step name="app_registration">
|
|
248
262
|
**Optionally register the app in the Frontier app store.**
|
|
249
263
|
|
|
250
|
-
Use AskUserQuestion:
|
|
264
|
+
Use AskUserQuestion (if available):
|
|
251
265
|
- header: "App Store"
|
|
252
266
|
- question: "Register this app in the Frontier app store? This makes it discoverable to Frontier OS users."
|
|
253
267
|
- options:
|
|
@@ -255,6 +269,8 @@ Use AskUserQuestion:
|
|
|
255
269
|
- "Later" — Skip registration, I'll do it manually
|
|
256
270
|
- "Not needed" — This is a private/internal app
|
|
257
271
|
|
|
272
|
+
If AskUserQuestion denied: default to "Later" — skip registration.
|
|
273
|
+
|
|
258
274
|
**If "Register now":**
|
|
259
275
|
```
|
|
260
276
|
## App Registration
|