3 files changed
+50
-41
.agents/skills/smbcloud-deploy-monorepo/SKILL.md
+28
-26
@@ -22,12 +22,14 @@ A monorepo is a repository where `[project]` has `runner = 255` (the `Monorepo`
22
23
Keep the deploy hierarchy straight:
24
25
-- root `[project]` = umbrella workspace in smbCloud
26
-- repo = the monorepo itself
27
-- each `[[projects]]` entry = one deployable app target inside that repo
28
-- each deployment record = one release of one app target
25
+- root `[project]` = umbrella workspace in smbCloud (not deployable)
26
+- repo = the monorepo itself, represented by a `DeployRepo` record
27
+- each `[[projects]]` entry = one deployable `FrontendApp` inside that repo, identified by `frontend_app_id`
28
+- each deployment record = one release of one `FrontendApp`, linked via `frontend_app_id`
29
30
-The config format still uses `[[projects]]` for historical reasons, but conceptually those entries are app targets, not separate umbrella workspaces.
30
+The canonical chain is: Deployment → FrontendApp → DeployRepo → Project
31
+
32
+The config format still uses `[[projects]]` for historical reasons, but conceptually those entries are app targets, not separate umbrella workspaces. Each entry should include `frontend_app_id` and `deploy_repo_id` so deployments are attributed to the correct app.
33
34
The CLI detects this in `process_deploy.rs`:
35
@@ -123,27 +125,27 @@ updated_at = "2025-09-20T16:33:05.154Z"
125
126
## Sub-project field reference
127
126
-| Field | Required | Description |
127
-| ------------------- | -------- | ------------------------------------------------------------------------------------------- |
128
-| `id` | yes | umbrella workspace ID in smbCloud |
129
-| `frontend_app_id` | no | deployable app ID for precise deployment tracking |
130
-| `deploy_repo_id` | no | repo ID backing the deploy target |
131
-| `name` | yes | unique identifier, used with `--project` flag and in the selection prompt |
132
-| `repository` | yes | remote repository name on the smbCloud server (used for git deploy and SSH paths) |
133
-| `description` | no | human-readable description |
134
-| `source` | yes | local path to the sub-project directory, relative to the monorepo root |
135
-| `path` | depends | remote directory on the server, relative to `~/` — required for `nextjs-ssr` and `vite-spa` |
136
-| `runner` | yes | server tier: `0` (NodeJs), `1` (Static), `2` (Ruby), `3` (Swift) |
137
-| `kind` | depends | deploy strategy: `"nextjs-ssr"`, `"vite-spa"`, `"rails"`, or omitted for generic deploy |
138
-| `package_manager` | depends | `"pnpm"` or `"npm"` — required for `nextjs-ssr` and `vite-spa` |
139
-| `pm2_app` | depends | PM2 process name — required for `nextjs-ssr` |
140
-| `port` | depends | runtime port — required for `nextjs-ssr`, defaults to `3000` if omitted |
141
-| `output` | depends | build output directory — required for `vite-spa`, typically `"dist"` |
142
-| `shared_lib` | no | path to shared library directory to rsync before deploy — used by `rails` |
143
-| `compile_cmd` | no | SSH command to run on the server after syncing shared libs — used by `rails` |
144
-| `deployment_method` | no | `0` (Git) or `1` (Rsync) — only matters when `kind` is not set |
145
-| `created_at` | yes | ISO 8601 timestamp |
146
-| `updated_at` | yes | ISO 8601 timestamp |
128
+| Field | Required | Description |
129
+| ------------------- | ----------- | ------------------------------------------------------------------------------------------- |
130
+| `id` | yes | umbrella workspace ID in smbCloud |
131
+| `frontend_app_id` | recommended | FrontendApp UUID — include so deployments are attributed to the correct app |
132
+| `deploy_repo_id` | recommended | DeployRepo ID — links the deploy target to its git repository record |
133
+| `name` | yes | unique identifier, used with `--project` flag and in the selection prompt |
134
+| `repository` | yes | remote repository name on the smbCloud server (used for git deploy and SSH paths) |
135
+| `description` | no | human-readable description |
136
+| `source` | yes | local path to the sub-project directory, relative to the monorepo root |
137
+| `path` | depends | remote directory on the server, relative to `~/` — required for `nextjs-ssr` and `vite-spa` |
138
+| `runner` | yes | server tier: `0` (NodeJs), `1` (Static), `2` (Ruby), `3` (Swift) |
139
+| `kind` | depends | deploy strategy: `"nextjs-ssr"`, `"vite-spa"`, `"rails"`, or omitted for generic deploy |
140
+| `package_manager` | depends | `"pnpm"` or `"npm"` — required for `nextjs-ssr` and `vite-spa` |
141
+| `pm2_app` | depends | PM2 process name — required for `nextjs-ssr` |
142
+| `port` | depends | runtime port — required for `nextjs-ssr`, defaults to `3000` if omitted |
143
+| `output` | depends | build output directory — required for `vite-spa`, typically `"dist"` |
144
+| `shared_lib` | no | path to shared library directory to rsync before deploy — used by `rails` |
145
+| `compile_cmd` | no | SSH command to run on the server after syncing shared libs — used by `rails` |
146
+| `deployment_method` | no | `0` (Git) or `1` (Rsync) — only matters when `kind` is not set |
147
+| `created_at` | yes | ISO 8601 timestamp |
148
+| `updated_at` | yes | ISO 8601 timestamp |
149
150
## Deploy routing
151
.agents/skills/smbcloud-deploy-nextjs/SKILL.md
+13
-8
@@ -20,10 +20,12 @@ Applies to:
20
21
Keep the deploy hierarchy straight:
22
23
-- `Project` = umbrella workspace in smbCloud
24
-- `DeployRepo` = repo or monorepo root inside that workspace
25
-- Next.js deploy target in `.smb/config.toml` = the deployable app unit
26
-- deployment record = one release of that app
23
+- `Project` = umbrella workspace in smbCloud (not deployable)
24
+- `DeployRepo` = the git repository inside that workspace
25
+- `FrontendApp` = the deployable app unit, identified by `frontend_app_id` in config
26
+- `Deployment` = one release event, linked to a FrontendApp via `frontend_app_id`
27
+
28
+The canonical chain is: Deployment → FrontendApp → DeployRepo → Project
29
30
For `nextjs-ssr`, smbCloud does not use git-push deploy.
31
@@ -69,8 +71,9 @@ Minimum `.smb/config.toml` for SSR:
71
72
```toml
73
[project]
72
-id = 28 # workspace id
73
-frontend_app_id = "uuid" # deployable app id (preferred when available)
74
+id = 28 # workspace id (for API routing)
75
+frontend_app_id = "uuid" # FrontendApp id (for deployment tracking)
76
+deploy_repo_id = 123 # DeployRepo id (links to git repository record)
77
deployment_method = 1
78
kind = "nextjs-ssr"
79
source = "."
@@ -83,8 +86,9 @@ port = 3028
86
Important rules:
87
88
- `kind = "nextjs-ssr"` is what activates the SSR deploy path
86
-- `id` remains the umbrella workspace id used for auth and API routing
87
-- `frontend_app_id` should be present when the API exposes it so deployment tracking is app-specific
89
+- `id` is the umbrella workspace ID, used for auth and API routing
90
+- `frontend_app_id` identifies the FrontendApp record for this deploy target — include it so deployments are attributed to the correct app, not just the workspace
91
+- `deploy_repo_id` identifies the DeployRepo record backing this app — include it when available
92
- `source` is the local Next.js app directory
93
- `path` is the remote destination directory on the server
94
- `pm2_app` is mandatory because the CLI restarts PM2 by name
@@ -357,3 +361,4 @@ Use the smallest checks that prove the contract.
361
- leaving port values inconsistent across PM2, Nginx, and `.smb/config.toml`
362
- forgetting to set `frontend_app_id` on the deploy target once app-level deployment tracking is available
363
- treating browser CORS failures as real internet outages
364
+- deploying without `frontend_app_id` in config — the API will try to infer the app, but explicit is better than implicit
.agents/skills/smbcloud-deploy-rsync/SKILL.md
+9
-7
@@ -50,10 +50,12 @@ Generic rsync deploy uses smbCloud config and runner metadata.
50
51
Keep the deploy model straight:
52
53
-- `Project` = umbrella workspace in smbCloud
54
-- `DeployRepo` = the git/source repository inside that workspace
55
-- deploy target entry in `.smb/config.toml` = the deployable app unit
56
-- deployment record = one release event for that app
53
+- `Project` = umbrella workspace in smbCloud (not deployable)
54
+- `DeployRepo` = the git repository inside that workspace
55
+- `FrontendApp` = the deployable app unit, identified by `frontend_app_id` in config
56
+- `Deployment` = one release event, linked to a FrontendApp via `frontend_app_id`
57
+
58
+The canonical chain is: Deployment → FrontendApp → DeployRepo → Project
59
60
The CLI config still uses `[project]` / `[[projects]]` entries for deploy targets during the migration, but they should be thought of as app targets, not umbrella workspaces.
61
@@ -64,7 +66,7 @@ Expect these responsibilities:
66
- determine the runner host, usually through `runner.rsync_host()`
67
- build the remote destination from configured project `path`
68
- deploy the current source tree or configured source directory
67
-- when present, pass `frontend_app_id` into deployment tracking payloads so the API can attribute the deploy to the correct app inside a repo or monorepo
69
+- pass `frontend_app_id` into deployment tracking payloads so the API attributes the deploy to the correct FrontendApp — this should always be present in new configs
70
71
The user-visible output may still mention the SSH key path. Preserve useful diagnostics, but avoid misleading claims about git deploy.
72
@@ -137,7 +139,7 @@ If replacing subprocess `rsync`, confirm parity for:
139
- deletion behavior, if smbCloud depends on it
140
- stdout/stderr capture
141
- non-zero status mapping
140
-- deploy tracking still posts against the workspace `project_id` while carrying the optional `frontend_app_id` for app-level attribution
142
+- deploy tracking posts against the workspace `project_id` and includes `frontend_app_id` for app-level attribution — both should be present
143
144
## Validation
145
@@ -167,4 +169,4 @@ If it migrates to the embedding crate, validate equivalent output and error hand
169
- assuming the embedding crate automatically supports ssh remote syntax without checking
170
- hiding transport stderr that the user needs to debug deploy failures
171
- hardcoding local paths instead of using smbCloud config and user-derived SSH identity
170
-- treating the workspace `project.id` as the deployable app identity once app-level deploy tracking is available
172
+- treating the workspace `project.id` as the deployable app identity — always use `frontend_app_id` for app-level deploy tracking