minutework 0.1.19 → 0.1.21

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 (71) hide show
  1. package/EXTERNAL_ALPHA.md +15 -4
  2. package/README.md +48 -6
  3. package/assets/claude-local/CLAUDE.md.template +56 -3
  4. package/assets/claude-local/bundle.json +4 -1
  5. package/assets/claude-local/skills/README.md +5 -1
  6. package/assets/claude-local/skills/app-pack-authoring/SKILL.md +57 -0
  7. package/assets/claude-local/skills/contract-first-public-intake/SKILL.md +22 -0
  8. package/assets/claude-local/skills/generated-workspace-architecture/SKILL.md +16 -2
  9. package/assets/claude-local/skills/published-web-and-mw-core-site/SKILL.md +12 -0
  10. package/assets/claude-local/skills/runtime-capability-inventory/SKILL.md +17 -0
  11. package/assets/claude-local/skills/schema-engine/SKILL.md +18 -0
  12. package/assets/claude-local/skills/shell-architecture/SKILL.md +3 -0
  13. package/assets/claude-local/skills/standalone-mobile-client/SKILL.md +105 -0
  14. package/assets/claude-local/skills/vuilder-discovery-output-contract/SKILL.md +136 -0
  15. package/assets/claude-local/skills/vuilder-public-site-authoring/SKILL.md +76 -0
  16. package/assets/templates/fastapi-sidecar/README.md +7 -1
  17. package/assets/templates/fastapi-sidecar/template.schema.json +4 -2
  18. package/assets/templates/mobile-app/.env.example +16 -0
  19. package/assets/templates/mobile-app/AGENTS.md +44 -0
  20. package/assets/templates/mobile-app/README.md +123 -0
  21. package/assets/templates/mobile-app/app/(app)/_layout.tsx +10 -0
  22. package/assets/templates/mobile-app/app/(app)/index.tsx +72 -0
  23. package/assets/templates/mobile-app/app/(auth)/login.tsx +91 -0
  24. package/assets/templates/mobile-app/app/_layout.tsx +15 -0
  25. package/assets/templates/mobile-app/app.json +31 -0
  26. package/assets/templates/mobile-app/babel.config.js +7 -0
  27. package/assets/templates/mobile-app/eas.json +24 -0
  28. package/assets/templates/mobile-app/expo-env.d.ts +5 -0
  29. package/assets/templates/mobile-app/metro.config.js +7 -0
  30. package/assets/templates/mobile-app/package.json +32 -0
  31. package/assets/templates/mobile-app/src/mw/client.ts +251 -0
  32. package/assets/templates/mobile-app/src/mw/contracts.ts +79 -0
  33. package/assets/templates/mobile-app/src/mw/endpoints.ts +42 -0
  34. package/assets/templates/mobile-app/src/mw/env.ts +59 -0
  35. package/assets/templates/mobile-app/src/mw/session.ts +50 -0
  36. package/assets/templates/mobile-app/template.json +18 -0
  37. package/assets/templates/mobile-app/tools/template/validate-template.mjs +69 -0
  38. package/assets/templates/mobile-app/tsconfig.json +16 -0
  39. package/assets/templates/next-tenant-app/README.md +15 -4
  40. package/assets/templates/next-tenant-app/template.schema.json +4 -2
  41. package/dist/cli-json.d.ts +28 -0
  42. package/dist/cli-json.js +20 -0
  43. package/dist/cli-json.js.map +1 -0
  44. package/dist/compile.js +71 -7
  45. package/dist/compile.js.map +1 -1
  46. package/dist/deploy.js +147 -14
  47. package/dist/deploy.js.map +1 -1
  48. package/dist/developer-client.d.ts +22 -0
  49. package/dist/developer-client.js +9 -0
  50. package/dist/developer-client.js.map +1 -1
  51. package/dist/index.js +43 -14
  52. package/dist/index.js.map +1 -1
  53. package/dist/init-prompt.js +10 -2
  54. package/dist/init-prompt.js.map +1 -1
  55. package/dist/init.d.ts +2 -1
  56. package/dist/init.js +59 -2
  57. package/dist/init.js.map +1 -1
  58. package/dist/publish.d.ts +29 -0
  59. package/dist/publish.js +254 -0
  60. package/dist/publish.js.map +1 -0
  61. package/dist/runtime-package.d.ts +3 -1
  62. package/dist/runtime-package.js +13 -0
  63. package/dist/runtime-package.js.map +1 -1
  64. package/dist/workspace-assets.js +37 -5
  65. package/dist/workspace-assets.js.map +1 -1
  66. package/dist/workspace-bootstrap.d.ts +1 -0
  67. package/dist/workspace-bootstrap.js.map +1 -1
  68. package/dist/workspace.js +2 -0
  69. package/dist/workspace.js.map +1 -1
  70. package/package.json +2 -2
  71. package/vendor/workspace-mcp/types.d.ts +10 -0
package/EXTERNAL_ALPHA.md CHANGED
@@ -58,9 +58,16 @@ The broker fails closed when a live session is already active, the selected
58
58
  engine is missing, a prior running record has gone stale, or the launch is
59
59
  interrupted or fails mid-session.
60
60
 
61
- Generated workspaces receive a root `CLAUDE.md` plus exported `skills/`
62
- guidance so the local coding agent sees the combined-web, snapshot-delivery,
63
- and `mw.core.site` baseline workflow.
61
+ Generated workspaces receive a root `CLAUDE.md` and `AGENTS.md` (rendered from
62
+ the same source so they cannot drift) plus exported `skills/` guidance so the
63
+ local coding agent sees the combined-web, snapshot-delivery, and `mw.core.site`
64
+ baseline workflow. Claude Code reads `CLAUDE.md`; Codex and other IDE agents read
65
+ `AGENTS.md`.
66
+
67
+ The workspace MCP (read-only context tools) is wired for Cursor
68
+ (`.cursor/mcp.json`) and Codex (`.codex/config.toml`, which Codex loads for
69
+ trusted projects); `mcp/claude-desktop.sample.json` is included for Claude
70
+ Desktop.
64
71
 
65
72
  Generated guidance and MCP wiring can be reconciled later with
66
73
  `minutework workspace sync-assets`.
@@ -131,6 +138,10 @@ If the workspace cannot compile hosted preview release metadata for the linked p
131
138
 
132
139
  The CLI does not fabricate success. If the backend cannot materialize a hosted preview deployment provider, the receipt reports a typed failure and the CLI exits non-zero.
133
140
 
141
+ ## Machine-readable output (`--json`)
142
+
143
+ `validate`, `compile`, `codegen`, `deploy --preview`, and `publish` accept `--json` for unattended, agent-driven use. The command prints a single result envelope to stdout (`{ cliJsonVersion, command, ok, status, result, error }`) and nothing else; `ok` mirrors the exit code (fail-closed). `deploy --preview --json` and `publish --json` never prompt — pair them with `--yes` to authorize, otherwise they return `status: "confirmation_required"` and exit non-zero. For `publish`, a rejected publication-review attestation is reported as `ok: false` with the gate findings in `result.findings` (a real review outcome, not a transport error). The automatic bug report is suppressed in `--json` mode.
144
+
134
145
  ## Failure semantics
135
146
 
136
147
  - Missing auth: run `minutework login`
@@ -145,7 +156,7 @@ The CLI does not fabricate success. If the backend cannot materialize a hosted p
145
156
 
146
157
  ## CLI bug reports
147
158
 
148
- - The CLI automatically submits a sanitized bug report for failed commands unless `MW_CLI_BUG_REPORTS=never` is set.
159
+ - The CLI automatically submits a sanitized bug report for failed commands unless `MW_CLI_BUG_REPORTS=never` is set (machine-readable `--json` verbs suppress this automatically).
149
160
  - Automatic reports keep a local JSON bundle under the MinuteWork CLI state root for retry and support follow-up.
150
161
  - `minutework report-bug --note "..."` sends a manual report for UX issues or suspicious behavior that did not crash.
151
162
  - `minutework report-bug --last --note "..."` resends the last saved bundle with extra context.
package/README.md CHANGED
@@ -1,16 +1,17 @@
1
1
  # `minutework`
2
2
 
3
- MinuteWork CLI for initializing a workspace, authenticating against a MinuteWork platform, linking a repo to a tenant-scoped public-site property, launching developer-local session broker flows, running local preview/test loops, and submitting hosted preview deploys.
3
+ MinuteWork CLI for initializing a workspace, authenticating against a MinuteWork platform, linking a repo to a tenant-scoped public-site property, launching developer-local session broker flows, running local preview/test loops, submitting hosted preview deploys, and publishing app packs to the marketplace through the publication-review gate.
4
4
 
5
5
  ## External alpha scope
6
6
 
7
7
  The current external alpha is intentionally narrow:
8
8
 
9
- - Starter: `tenant-app`
9
+ - Starters: `tenant-app` (the deployable web surface) and `mobile` (init-only)
10
10
  - Developer-local broker surface: `minutework session start|resume|status`
11
11
  - Hosted release class: `ssr_container`
12
12
  - Deploy surface: `minutework deploy --preview`
13
- - Deferred: `--live`, additional local coding engines, sidecar/runtime-backed deploys, marketplace publish flows
13
+ - Deferred: `--live`, additional local coding engines, sidecar/runtime-backed deploys, and the commercial marketplace listing/pricing layer
14
+ - Marketplace publish: `minutework publish` submits the compiled, digest-bound app pack through the platform publication-review + attestation gate and publishes it to the public marketplace catalog **only** on an approved (or approved-with-warnings) attestation; a rejected attestation prints the review findings and exits 1 without publishing
14
15
 
15
16
  The shipped `tenant-app` starter is the combined web surface: public routes at
16
17
  the root plus a private `/app` workspace. Public-site content follows the
@@ -43,7 +44,20 @@ npx minutework login
43
44
  npx minutework link
44
45
  ```
45
46
 
46
- After `link`, the current alpha has two supported lanes.
47
+ After `link`, the current alpha has two supported lanes (both `tenant-app`).
48
+
49
+ For a native mobile client, scaffold the **`mobile`** starter instead:
50
+
51
+ ```bash
52
+ npx minutework init my-app --starter mobile
53
+ ```
54
+
55
+ It is **init-only** and bring-your-own-UI: a minimal Expo (React Native) client
56
+ that authenticates **directly** against the platform with a native device-flow
57
+ session token (PKCE authorize -> exchange -> bearer + refresh in the device
58
+ keychain), not the `tenant-app` BFF cookie path. There is no `link`/`deploy`
59
+ lane for it — distribution is your own EAS pipeline (`eas build`/`eas submit`,
60
+ EAS Update), not `minutework deploy`.
47
61
 
48
62
  ### Developer-local broker lane
49
63
 
@@ -74,8 +88,14 @@ minutework session resume
74
88
  - The broker fails closed on live overlap, missing engine binaries, stale
75
89
  session records, interrupts, and launch failures instead of allowing
76
90
  overlapping phantom sessions.
77
- - Generated workspaces receive a root `CLAUDE.md` plus exported `skills/`
78
- guidance tailored to the combined web and published-site workflow.
91
+ - Generated workspaces receive a root `CLAUDE.md` and `AGENTS.md` (rendered from
92
+ the same source so they cannot drift) plus exported `skills/` guidance tailored
93
+ to the combined web and published-site workflow. Claude Code reads `CLAUDE.md`;
94
+ Codex and other IDE agents read `AGENTS.md`.
95
+ - The workspace MCP (read-only context tools) is wired for Cursor
96
+ (`.cursor/mcp.json`) and Codex (`.codex/config.toml`, which Codex loads for
97
+ trusted projects); `mcp/claude-desktop.sample.json` is included for Claude
98
+ Desktop.
79
99
  - Managed guidance and MCP wiring can be refreshed later with
80
100
  `minutework workspace sync-assets`.
81
101
  - Runtime-only Claude hooks are not exported into the generated workspace.
@@ -99,10 +119,32 @@ For direct third-party web hosts such as Vercel, deploy `tenant-app` only. In Ve
99
119
 
100
120
  `deploy --preview` always revalidates and recompiles before submit, prints a local-vs-remote diff, requires confirmation unless `--yes` is passed, polls typed receipts until a terminal state, and persists the last known preview deploy state under `.minutework/deploy/preview/status.json`. This alpha is preview-first; live public delivery remains follow-on.
101
121
 
122
+ ## Machine-readable output (`--json`)
123
+
124
+ `validate`, `compile`, `codegen`, and `deploy --preview` accept `--json` so an IDE coding agent can drive them unattended and parse one stable shape. With `--json` the command prints a single result envelope to stdout and nothing else:
125
+
126
+ ```json
127
+ {
128
+ "cliJsonVersion": 1,
129
+ "command": "validate | compile | codegen | deploy",
130
+ "ok": true,
131
+ "status": "ok | compiled | generated | activated | failed | rolled_back | confirmation_required | not_implemented | error",
132
+ "result": {},
133
+ "error": null
134
+ }
135
+ ```
136
+
137
+ - `ok` mirrors the process exit code: `0` when `ok` is `true`, non-zero otherwise (fail-closed).
138
+ - `result` is the typed payload — the validate report (`validate`), the compile graph (`compile` / `codegen`), or the terminal deploy receipt (`deploy`).
139
+ - `deploy --preview --json` runs unattended and never prompts. Pair it with `--yes` to authorize the deploy; without `--yes` it returns `status: "confirmation_required"` (exit 1) instead of blocking on a prompt.
140
+ - In `--json` mode the automatic diagnostic report is suppressed — the envelope and exit code are the whole contract.
141
+
102
142
  ## Bug reporting
103
143
 
104
144
  CLI failures automatically send a sanitized diagnostic report to the MinuteWork platform unless `MW_CLI_BUG_REPORTS=never` is set.
105
145
 
146
+ - Machine-readable verbs run with `--json` suppress automatic reporting; rely on the result envelope and exit code instead.
147
+
106
148
  - Automatic reports never include raw `.env` contents, tokens, source files, or full local paths.
107
149
  - The CLI keeps a local report bundle under the MinuteWork state root so you can retry or inspect what was sent.
108
150
  - Use `minutework report-bug --note "what happened"` for manual reports.
@@ -13,11 +13,23 @@ If this workspace's exported guidance looks stale or a newly added skill is
13
13
  missing, run `minutework workspace sync-assets` from the workspace root. See
14
14
  `skills/workspace-guidance-refresh/SKILL.md` for the managed refresh flow.
15
15
 
16
+ ## Workspace MCP
17
+
18
+ The MinuteWork workspace MCP server exposes read-only context tools (workspace
19
+ snapshot, schema status, capability inventory, deploy status, and a workspace
20
+ doctor; tool names are prefixed `minutework_`). Prefer these over guessing at
21
+ workspace state. It is wired for Cursor (`.cursor/mcp.json`) and Codex
22
+ (`.codex/config.toml`, loaded for trusted projects); for Claude Desktop, copy
23
+ `mcp/claude-desktop.sample.json`. Refresh all of this with
24
+ `minutework workspace sync-assets`.
25
+
16
26
  ## Skills
17
27
 
18
- This workspace includes MinuteWork architecture skills under `skills/`. Claude
19
- loads them automatically when relevant to your request. Run `/skill-name` to
20
- invoke one directly, or ask "What skills are available?" to see the full list.
28
+ This workspace includes MinuteWork architecture skills under `skills/`. Your IDE
29
+ coding agent can use them as reference: browse `skills/` and read the relevant
30
+ `SKILL.md` when a topic matches your task. In Claude Code these skills load
31
+ automatically and `/skill-name` invokes one directly; other agents (Codex,
32
+ Cursor) can open the files directly or ask "What skills are available?".
21
33
 
22
34
  ## Shell-First UI Default
23
35
 
@@ -50,6 +62,7 @@ implementation surfaces inside that pack.
50
62
  | --- | --- | --- |
51
63
  | Authenticated standalone web UI, separate tenant portal, custom client, or other explicit shell exception | `tenant-app` | This is the Next.js UI/BFF surface after shell fit has been checked. |
52
64
  | Public website, pricing, docs, blog, landing pages | `tenant-app` | Public web belongs in the web app surface; do not create a sidecar just to render pages. |
65
+ | Vuilder-owned public website, landing/blog/onboarding routes, or public-dj CMS-backed vertical site | `vuilder-public-site` | This is the Vuilder public-site template; code lives in the workspace and content comes from public-dj manifest revisions. |
53
66
  | Internal API, webhook handler, worker, cron, queue consumer, ingestion, Python-heavy compute | `sidecar` | This is backend/runtime logic, not a browser app concern. |
54
67
  | Web app plus background jobs, integrations, AI processing, or internal APIs | `both` | Put UI in `tenant-app`; put backend execution in `sidecar`. |
55
68
  | No UI, only runtime automation or processing | `sidecar` | A web app is unnecessary. |
@@ -115,11 +128,25 @@ a concrete backend responsibility such as:
115
128
 
116
129
  - Payload-aware drafting and generation should default to the runtime's existing
117
130
  AI capability, not direct browser/provider integrations.
131
+ - App-pack-owned runtime agents should be installed with `mw.runtime.agent`
132
+ seed records. Use `logical_key` as `Agent.slug`, keep prompts in installed
133
+ manifest data with trace metadata, and declare domain behavior through
134
+ `capabilities.runtime_kind`.
135
+ - Runtime-kind behavior must be implemented as a namespaced adapter/tool pack
136
+ registered with the generic runtime-kind registry. Do not put tenant or
137
+ vertical-specific branches in generic thread, intake, or conversation
138
+ services.
118
139
  - When the runtime already provides an AI capability, reuse it before adding
119
140
  bespoke model SDK calls in `tenant-app` or `sidecar`.
120
141
  - `tenant-app` should collect inputs, review/edit outputs, and call typed
121
142
  platform/runtime surfaces; do not put provider credentials or direct
122
143
  browser-to-model calls in the web app.
144
+ - Shell and `tenant-app` should render hydrated thread posts and artifacts only.
145
+ They should not run agent logic, execute tools, call providers, or infer
146
+ access policy from raw metadata.
147
+ - Agent drafts, analysis, and operator cards should carry explicit runtime
148
+ visibility such as `internal_note` or `member_only`; guest-safe content must
149
+ be server-filtered and explicitly marked safe.
123
150
  - Do not add a bespoke AI sidecar for MVP drafting/generation unless you can
124
151
  name a concrete gap in the existing runtime AI capability.
125
152
  - If runtime AI availability is unclear, inspect the linked runtime/workspace
@@ -130,6 +157,15 @@ a concrete backend responsibility such as:
130
157
 
131
158
  ## Public Site Defaults
132
159
 
160
+ - If `Template: {template_kind}` is `vuilder-public-site`, or the request says
161
+ Vuilder public site / public-dj CMS, load
162
+ `skills/vuilder-public-site-authoring/SKILL.md`.
163
+ - Vuilder public sites use public-dj `PublicSiteManifestRevision` as the CMS
164
+ content source and platform `SiteRelease.content_source` set to
165
+ `shared_public_content`; they do not use runtime `mw.core.site` as their CMS.
166
+ - Vuilder customer signup routes must create platform onboarding intents from
167
+ server-pinned release context. Browser labels must not decide runtime
168
+ provisioning behavior.
133
169
  - Treat `mw.core.site` as a runtime baseline capability that already exists. Do
134
170
  not model site work as "installing" or "reconciling" the baseline.
135
171
  - `mw.core.site` already includes `config`, `page`, `nav`, `form`, and
@@ -188,6 +224,23 @@ a concrete backend responsibility such as:
188
224
  Builder/codegen task when the installed product should render it from runtime
189
225
  data/content/workflow.
190
226
  - `sidecar` is internal-first by default.
227
+ - Do not add tenant-hardcoded code (Django management commands, seeders,
228
+ fixtures, scripts) to shared platform or runtime modules such as
229
+ `apps/runtime_app_host/management/commands/`. Tenant-shaped seeders in
230
+ shared infra are an anti-pattern. Author baseline-extending seed records
231
+ as workspace-local declarative source and let the runtime App Host's
232
+ generic install/reconcile path apply them.
233
+ - Do not gate public intake render on a hardcoded client-side token
234
+ allowlist. Public handoff tokens are platform-validated server-side
235
+ (Django-signed self-contained payloads); the workspace UI should pass
236
+ the token through to the BFF and let the platform decide validity.
237
+ - Do not put generated React or component code in public-dj database rows;
238
+ public-dj stores Vuilder CMS content and immutable manifest revisions.
239
+ - Do not use tenant `/app`, `/w/*`, or runtime `mw.core.site` as the serving or
240
+ CMS model for `vuilder-public-site`.
241
+ - Do not infer Vuilder authoring, Vuilder operator runtime, or customer tenant
242
+ provisioning from browser-provided labels. Use platform-owned onboarding
243
+ intents.
191
244
 
192
245
  See the files under `skills/` for deeper guidance on schema authoring,
193
246
  app-pack structure, published web, content sections, sidecar generation, event
@@ -2,7 +2,10 @@
2
2
  "bundle_version": 1,
3
3
  "render": {
4
4
  "template": "CLAUDE.md.template",
5
- "output": "CLAUDE.md"
5
+ "outputs": [
6
+ "CLAUDE.md",
7
+ "AGENTS.md"
8
+ ]
6
9
  },
7
10
  "directories": {
8
11
  "skills": "skills"
@@ -16,7 +16,9 @@ receive:
16
16
  - Builder should compose shared substrate before generating bespoke tenant code
17
17
  - `tenant-app` is the combined public plus private web starter
18
18
  - `mw.core.site` is a runtime baseline capability
19
- - public authoring is runtime/CMS-backed
19
+ - tenant public authoring is runtime/CMS-backed through `mw.core.site`
20
+ - Vuilder-owned public sites use `vuilder-public-site` and public-dj CMS
21
+ manifests
20
22
  - anonymous live delivery should prefer published snapshots
21
23
  - AI drafting/generation should reuse existing runtime AI capability before new
22
24
  model/provider integrations
@@ -27,8 +29,10 @@ receive:
27
29
  Generated-workspace-first guidance should live here, especially:
28
30
 
29
31
  - `generated-workspace-architecture/SKILL.md`
32
+ - `vuilder-public-site-authoring/SKILL.md`
30
33
  - `workspace-guidance-refresh/SKILL.md`
31
34
  - `shell-architecture/SKILL.md`
35
+ - `standalone-mobile-client/SKILL.md`
32
36
  - `runtime-capability-inventory/SKILL.md`
33
37
  - `layering-and-import-modes/SKILL.md`
34
38
  - `capability-gap-reporting/SKILL.md`
@@ -33,6 +33,12 @@ An `app pack` is the shipped product unit.
33
33
  - For AI-assisted drafting MVPs, let `tenant-app` collect/edit inputs and
34
34
  outputs while an existing runtime AI capability produces the draft when
35
35
  available; ask or inspect context if that availability is unclear.
36
+ - For app-pack-owned agents, prefer a declarative `mw.runtime.agent` seed plus
37
+ a namespaced `capabilities.runtime_kind` adapter over tenant-specific
38
+ branches in shared runtime services.
39
+ - Shell and `tenant-app` surfaces should render hydrated thread posts and
40
+ artifacts; they should not run agent logic, execute tools, call providers, or
41
+ infer access policy from artifact metadata.
36
42
  - Public-site authoring should stay CMS/runtime-backed, while anonymous live
37
43
  delivery should prefer published snapshots.
38
44
  - Prefer this decision order before writing greenfield code:
@@ -52,3 +58,54 @@ An `app pack` is the shipped product unit.
52
58
  extension that can later collapse into a reusable primitive, baseline
53
59
  capability, reviewed skill, or app pack.
54
60
  - Keep platform-owned runtime source untouched; author only workspace-local generated source.
61
+
62
+ ## Baseline-Extending Seed Records
63
+
64
+ - Builder authors records the runtime should hold (e.g. `mw.core.site.form`,
65
+ `mw.core.site.page`, `mw.core.site.nav`) as workspace-local declarative
66
+ source under `schemas/`, collected into a `SeedDataManifest` that the
67
+ compiler discovers and the CLI ships to the tenant runtime via the
68
+ install pipe. Treat these as durable Builder artifacts even when no
69
+ install pipe has applied them yet.
70
+ - Concrete authoring convention (envelope pinned in
71
+ `runtime_app_pack_contract.md` sec 5.3): a single named
72
+ `seedDataManifest` export on the schema entrypoint module namespace,
73
+ either directly in `schemas/schema.ts` or re-exported from a
74
+ per-domain sibling (e.g. `export { seedDataManifest } from
75
+ "./site-forms.js"`). Records are `{ schema_key; logical_key; data }`;
76
+ only `schema_key` values registered in the runtime's
77
+ `SCHEMA_KEY_UPSERT_REGISTRY` may ship in the active manifest.
78
+ - For `mw.core.site.form`, do not author `form_key` or `app_pack_ref` inside
79
+ `data`; the install pipe injects both. Keep `surface_key == form_key` for
80
+ public intake BFFs.
81
+ - For `mw.runtime.agent`, use `logical_key` as the runtime `Agent.slug`.
82
+ Author stable agent fields in `data` such as `name`, `system_instruction`,
83
+ `enabled_tools`, `trigger_intents`, `channels_enabled`, and
84
+ `capabilities.runtime_kind`. The install pipe injects tenant/app-pack
85
+ ownership and prompt trace metadata. Same app-pack lineage may update the
86
+ slug; a different pack claiming the same tenant slug fails transactionally.
87
+ - Runtime-kind behavior must live behind a namespaced adapter/tool pack
88
+ registered with the runtime-kind registry. Generic runtime services call the
89
+ registry and must not branch on tenant names, app names, or domain-specific
90
+ runtime kinds.
91
+ - Agent outputs meant for operator/member review should be written as hydrated
92
+ thread posts/artifacts with explicit visibility such as `internal_note` or
93
+ `member_only`. Guest/public surfaces only receive guest-safe visibility after
94
+ server-side filtering.
95
+ - The install path onto a tenant runtime is the runtime App Host's generic
96
+ reconcile loop (designed in `runtime_app_pack_contract.md` sec 3, 5, 11),
97
+ invoked from the workspace via the CLI deploy verb. Per-schema upsert
98
+ services on the runtime (e.g. `upsert_site_form`) are the building blocks
99
+ that loop calls; they are not directly Builder-callable.
100
+ - Do not bypass the install pipe by writing a tenant-hardcoded Django
101
+ management command, seeder, or fixture in shared platform/runtime modules.
102
+ That is an anti-pattern; the right Builder response when the install pipe
103
+ is missing or unshipped is to author the seed source here and file the
104
+ missing-pipe gap (see `capability-gap-reporting/SKILL.md`).
105
+ - An operator may apply a one-shot Django shell call to a runtime DB as a
106
+ stopgap to unblock end-to-end testing; treat it as out-of-band, not as
107
+ Builder-committed source, and do not codify it as a recurring path.
108
+ - The v1 invariant `surface_key == form_key` (see
109
+ `contract-first-public-intake/SKILL.md`) constrains the `form_key` value
110
+ on `mw.core.site.form` seeds: it must equal the public surface key the
111
+ BFF sends.
@@ -63,6 +63,28 @@ guest-continuity threads, public submission routing, or claim-after-auth flows.
63
63
  on retries.
64
64
  - For follow-on automation, treat the runtime submission record as the durable
65
65
  source that can drive later `action:` or `flow:` execution.
66
+ - Do not gate public intake render on a hardcoded client-side token
67
+ allowlist. The handoff token is a platform-issued, server-validated
68
+ payload; the workspace UI should pass it through to the BFF and let the
69
+ platform decide validity. A client-side allowlist drifts from the real
70
+ token registry and silently breaks once real tokens are minted.
71
+
72
+ ## Vuilder Vertical Onboarding
73
+
74
+ - For customer onboarding from a Vuilder public site, also read
75
+ `vuilder-public-site-authoring/SKILL.md`.
76
+ - Use the platform-owned `OnboardingIntent` contract. Supported intent kinds
77
+ are `vuilder_authoring`, `vuilder_operator_runtime`, and
78
+ `customer_vertical_signup`.
79
+ - A Vuilder public-site BFF should create `customer_vertical_signup` intents
80
+ from server-pinned release context, not from browser-provided provisioning
81
+ labels.
82
+ - Trusted fields such as Vuilder workspace, published property/release,
83
+ public-dj manifest ref/digest, vertical package ref/digest, and onboarding
84
+ flow ref/digest must come from platform/publication context.
85
+ - Browser clients may submit intake answers only. They must not submit trusted
86
+ package refs, manifest refs, workspace identity, runtime provisioning kind, or
87
+ billing disposition.
66
88
 
67
89
  ## Use This Skill To Decide
68
90
 
@@ -19,9 +19,23 @@ the monorepo or a live tenant runtime.
19
19
  - app packs
20
20
  - skills
21
21
  - tenant overlays
22
- - `tenant-app` and optional `sidecar` are implementation surfaces inside the
23
- tenant product, not the whole architecture.
22
+ - `tenant-app`, optional `sidecar`, and the optional `mobile` starter are
23
+ implementation surfaces inside the tenant product, not the whole architecture.
24
24
  - `tenant-app` is the combined public plus private web starter.
25
+ - A mobile / native client (Expo, React Native, native iOS/Android) is a
26
+ standalone-client exception authored in the `mobile` starter, not in
27
+ `tenant-app` or `sidecar`. It is a direct platform API client that consumes
28
+ the platform native-token API (`/api/v1/native/...`) directly with a
29
+ platform-issued native session token, rather than the `tenant-app` BFF cookie
30
+ session.
31
+ - If the `mobile` starter is enabled (`starters.mobile.enabled`), read
32
+ `standalone-mobile-client/SKILL.md` before proposing the mobile surface.
33
+ - `vuilder-public-site` is a Vuilder-owned public-site authoring workspace for
34
+ landing, blog, and onboarding routes backed by public-dj CMS manifests.
35
+ - If `template_kind` is `vuilder-public-site`, or the workspace profile says
36
+ `public_dj_cms`, read `vuilder-public-site-authoring/SKILL.md`.
37
+ - `vuilder-public-site` does not own tenant `/app`, `/w/*`, or runtime
38
+ `mw.core.site`; it renders public-dj content pinned by manifest ref/digest.
25
39
  - For member-facing collaboration and operator work, the primary product surface
26
40
  is the gateway shell under `/w/[workspace_slug]`. Do not default to a bespoke
27
41
  standalone tenant frontend when the work belongs in shell threads, cards, or
@@ -9,6 +9,15 @@ Use this skill when the request touches public-site delivery, published-web
9
9
  flows, or the default MinuteWork site model.
10
10
 
11
11
  - Treat `mw.core.site` as a runtime baseline capability that already exists.
12
+ - For Vuilder-owned public websites, read
13
+ `vuilder-public-site-authoring/SKILL.md`; public-dj
14
+ `PublicSiteManifestRevision` is the CMS/release content source instead of
15
+ runtime `mw.core.site`.
16
+ - Vuilder public-site releases use
17
+ `SiteRelease.content_source = shared_public_content`, with shared public
18
+ content refs pointing to an immutable public-dj manifest ref and digest.
19
+ - Tenant/customer content created after customer provisioning remains
20
+ runtime-canonical through `mw.core.site` and installed app-pack data.
12
21
  - `tenant-app` is the combined web starter for public routes plus the private
13
22
  `/app` workspace.
14
23
  - Author public content against runtime/CMS records, not a fixed in-repo site
@@ -56,6 +65,9 @@ flows, or the default MinuteWork site model.
56
65
  form/submission model.
57
66
  - Form and submission records already carry routing, identity-resolution, and
58
67
  continuity fields for public intake and follow-up flows.
68
+ - Seed dispatch and install-time seed manifests that target `mw.core.site.form`
69
+ require the baseline `mw.core.site` pack to be installed first so `SCHEMA_FORM`
70
+ is registered before upsert handling runs.
59
71
 
60
72
  ## Current Baseline Catalog
61
73
 
@@ -44,6 +44,23 @@ generated Builder workspace.
44
44
  - installed app packs and their class/status
45
45
  - sidecar processes, entrypoints, ports, and health state
46
46
  - live runtime descriptor outputs such as public-site route prefixes
47
+ - In the native Builder Harness path, the platform-dispatched
48
+ `RuntimeHarnessDiagnosticsV1` snapshot is a safe linked-runtime surface for
49
+ Builder workspace/session status, engine readiness, primitive inventory,
50
+ installed app-pack status counts, app-host baseline readiness, database
51
+ migration counts, event-bus counts, and warnings. Treat it as planning
52
+ context, not as an install or provisioning authority.
53
+ - In the Vuilder Harness path, workspace kickoff uses the platform-dispatched
54
+ `/api/v1/builder/workspaces/ensure/` runtime endpoint to create or reuse the
55
+ hosted `BuilderWorkspace` and context snapshot only. Do not infer sandbox
56
+ files, engine sessions, Claude execution, or app-pack installs from this
57
+ kickoff.
58
+ - `BuilderMaterializationPreflightV1` from
59
+ `/api/v1/builder/materialization/preflight/` is a safe readiness report for a
60
+ digest-reviewed architecture and template key. Treat its findings, policy
61
+ digest, preflight digest, sandbox driver, and artifact counts as preflight
62
+ context only; actual sandbox writes, codegen, installation, activation, and
63
+ publication remain separate effectful actions.
47
64
  - Linked runtime surfaces are the authoritative source for live runtime
48
65
  inspection, but do not assume every generated workspace has them.
49
66
  - Use the more specific workspace MCP tools as needed:
@@ -20,6 +20,24 @@ Use this skill when the request needs tenant-defined data structures.
20
20
  `platform_submission_ref` and preserve the original record on retry.
21
21
  - The default lookup fields that usually deserve indexes for public intake are
22
22
  `platform_submission_ref`, `form_key`, and `continuity_ref`.
23
+ - Seed manifests or install-time seeds that upsert `mw.core.site.form` depend on
24
+ the baseline `mw.core.site` pack already being present so `SCHEMA_FORM` is
25
+ registered before dispatch.
26
+ - Seed manifests may also install app-pack-owned runtime agents through
27
+ `mw.runtime.agent`; use `logical_key` as the `Agent.slug`, put stable agent
28
+ fields under `data`, and let the runtime inject tenant/app-pack ownership.
29
+ - For `mw.runtime.agent`, declare `capabilities.runtime_kind` when the agent
30
+ needs domain behavior. The runtime resolves that value through the generic
31
+ runtime-kind adapter registry; do not encode domain branching in generic
32
+ thread, intake, or conversation services.
33
+ - Agent prompts should be installed as versioned manifest data with traceable
34
+ source metadata. Do not rely on live workspace file paths at runtime.
35
+ - Runtime posts and artifacts carry first-class visibility. Guest-safe
36
+ serializers fail closed, so author internal drafts, analysis, and operator
37
+ cards as `internal_note` or `member_only` until explicitly made guest-safe.
38
+ - Runtime Builder diagnostics may expose safe schema/app-host readiness summaries
39
+ such as active schema registration counts; treat them as planning context, not
40
+ as schema definitions or install authority.
23
41
 
24
42
  ## Current mw.core.site Baseline
25
43
 
@@ -44,6 +44,9 @@ threads, channels, inboxes, guest collaboration, approvals, dashboards, or
44
44
  - the surface is public marketing
45
45
  - the surface is public intake for non-members
46
46
  - the surface is an embeddable widget
47
+ - the surface is a mobile app (Expo / React Native / native iOS/Android) ->
48
+ author in the `mobile` starter, not `tenant-app`; see
49
+ `standalone-mobile-client/SKILL.md`
47
50
  - If shell fit is correct but this generated workspace cannot directly author
48
51
  the shell extension, keep the shell-first recommendation and record a
49
52
  capability gap instead of silently converting the request into standalone
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: standalone-mobile-client
3
+ description: "Building a native mobile app (Expo / React Native / native iOS/Android). It is a standalone-client exception authored in the mobile starter as a direct platform API client using a native session token, not in tenant-app or sidecar."
4
+ ---
5
+
6
+ # Standalone Mobile Client
7
+
8
+ Use this skill when the request is "can I build a mobile app?", or anything
9
+ that involves a native iOS/Android surface (Expo, React Native, or fully native).
10
+ The answer is yes, and the shape is fixed. Do not flip-flop on it.
11
+
12
+ ## Where it lives
13
+
14
+ - A native mobile app is a **standalone-client exception**. It is authored in
15
+ the `mobile` starter (`destinationDirectory: mobile`), enabled via the
16
+ workspace config key `starters.mobile = { enabled: true, path: "mobile" }`.
17
+ - It is **not** part of `tenant-app`, and **not** part of `sidecar`. Do not put
18
+ native code, Expo config, or React Native screens inside either of those
19
+ surfaces.
20
+ - `tenant-app` stays web-only. The mobile app is a sibling client, not a tab or
21
+ route inside the web BFF.
22
+
23
+ ## What it is
24
+
25
+ - The mobile app is a **direct platform API client**. It talks to the platform
26
+ HTTP API at `/api/v1/native/session/...` and nothing else. It does not go
27
+ through the `tenant-app` BFF.
28
+ - Authentication uses a platform-issued **native session token** -- a distinct
29
+ principal class, the "native app session token holder". This is exactly what
30
+ the auth contract anticipates: non-browser clients must mint explicit scoped
31
+ tokens after browser-assisted login or a device flow
32
+ (`reference/mwv3-dj6-docs/auth_and_credential_contract.md`, Rule 7).
33
+ - The app reads the platform base URL from `EXPO_PUBLIC_MW_PLATFORM_BASE_URL`.
34
+
35
+ ## Endpoints (shipped)
36
+
37
+ All native endpoints live under `/api/v1/native/session/`:
38
+
39
+ - `authorize/` -- browser-assisted consent (GET renders the login/consent page
40
+ or redirects to the onboarding host; POST confirms and 302-redirects to the
41
+ app `redirect_uri` with `?code=...&state=...`).
42
+ - `token-exchange/` -- POST `{code, code_verifier, redirect_uri}` -> `{access,
43
+ refresh, expires_at, ...}`. No bearer required.
44
+ - `refresh/` -- POST `{refresh_token}` -> a new `{access, refresh}` pair. No
45
+ bearer required.
46
+ - `me/` and `context/` -- GET (bearer) -> the tenant session payload for the
47
+ bound user/tenant. `context/` is currently identical to `me/`.
48
+ - `logout/` -- POST (bearer) -> revokes the presented token's access/refresh
49
+ family.
50
+
51
+ ## Auth flow
52
+
53
+ The native token flow mirrors the existing CLI developer-token flow
54
+ (PKCE authorize -> exchange -> opaque scoped tokens):
55
+
56
+ 1. **Authorize (browser-assisted device flow):** the app generates a PKCE
57
+ verifier and opens `GET /api/v1/native/session/authorize/` (with
58
+ `code_challenge`, `state`, `redirect_uri`) in a system browser. The user logs
59
+ in and confirms on the platform; the platform POSTs the confirmation and
60
+ 302-redirects back to the app's `redirect_uri` with a one-time `code` and the
61
+ `state`.
62
+ 2. **Exchange:** the app POSTs that one-time `code` plus the matching PKCE
63
+ `code_verifier` and the same `redirect_uri` to
64
+ `/api/v1/native/session/token-exchange/`, receiving an **access token +
65
+ refresh token** (opaque, scoped; access ~15 min, refresh ~30 days).
66
+ 3. **Store:** both tokens are persisted in `expo-secure-store` (the device
67
+ keystore), never in plain React/web state.
68
+ 4. **Call:** every request to `/api/v1/native/session/...` carries
69
+ `Authorization: Bearer <access>`.
70
+ 5. **Refresh:** on access-token expiry (`401`), POST the refresh token to
71
+ `/api/v1/native/session/refresh/` to mint a new pair, then retry. Refresh is
72
+ **rotating** -- the old access/refresh family is revoked, so persist the
73
+ freshly returned pair. Re-run the browser-assisted authorize step only when
74
+ the refresh token itself is invalid or revoked.
75
+
76
+ The browser/BFF cookie path belongs to `tenant-app` and is **web-only**. The
77
+ mobile app does not ride the `tenant-app` cookie jar, and it does not read or
78
+ forward CSRF -- native uses the bearer token directly against the platform.
79
+
80
+ ### Token binding (what is and isn't enforced)
81
+
82
+ The token is bound to one tenant + membership, and that binding **is** enforced:
83
+ a request that names a different tenant is rejected, and a token whose membership
84
+ has been deactivated stops authenticating. The optional `audience` and
85
+ `device_id` fields are **informational only** -- the platform carries them
86
+ through authorize -> exchange (and preserves them across refresh) but does **not**
87
+ validate or compare them. Do not treat `audience` or `device_id` as a security
88
+ boundary.
89
+
90
+ ## What not to do
91
+
92
+ - Do not build a parallel auth stack.
93
+ - Do not mint a JWT inside the app or stand up a local user table / token issuer.
94
+ - Do not expose access or refresh tokens to web pages or generic React state;
95
+ keep them in `expo-secure-store`.
96
+ - Do not route the mobile app through the `tenant-app` BFF cookie session.
97
+ - Do not read or forward CSRF from native; bearer-token auth does not use it.
98
+ - Do not put native code inside `tenant-app` or `sidecar`.
99
+
100
+ ## Distribution
101
+
102
+ - The `mobile` starter is **init-only**. Scaffolding it lands the app in the
103
+ workspace; it does not deploy it.
104
+ - Distribution is the developer's own pipeline: EAS Build, TestFlight, and the
105
+ Play Store. It is **not** `minutework deploy`.