nerdsystem 0.0.22 → 0.0.23
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/dist/cli.js +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/org.d.ts +18 -0
- package/dist/commands/org.js +27 -4
- package/package.json +1 -1
- package/template/.claude/skills/nerdsystem/SKILL.md +11 -0
- package/template/.cursor/rules/nerdsystem.mdc +12 -1
- package/template/.github/copilot-instructions.md +12 -1
- package/template/AGENTS.md +12 -1
- package/template/GEMINI.md +12 -1
package/dist/cli.js
CHANGED
|
@@ -67,7 +67,7 @@ const HELP = `nerd: start, check, and deploy a web app on nerdsystem
|
|
|
67
67
|
nerd billing portal Manage cards, invoices, and plan
|
|
68
68
|
nerd members [invite <email> --role r | remove <userId>] Org members and invitations
|
|
69
69
|
nerd clients [create <slug> --name n | release <slug>] Studio: one org per client, billed through yours
|
|
70
|
-
nerd domains [add <
|
|
70
|
+
nerd domains [add <domain> | remove <id>] The app on your own domain, with the DNS steps for it
|
|
71
71
|
nerd logs [--since 30m] [--limit 100] [--q text] [--pr n] Logs from the deployed app
|
|
72
72
|
nerd audit [--out file.csv] Export deployments and builds (Studio)
|
|
73
73
|
|
package/dist/commands/init.js
CHANGED
|
@@ -192,4 +192,4 @@ export async function init(dir, args) {
|
|
|
192
192
|
log.ok(`Ready. Next:\n cd ${dir}\n pnpm install\n nerd dev\n\nThen open the folder in your coding agent and ask it to build the first feature; the nerdsystem skill walks it through.\nDeploys go to ${project.url}`);
|
|
193
193
|
}
|
|
194
194
|
// Kept in sync with packages/sdk/package.json by the release script.
|
|
195
|
-
const SDK_VERSION = "0.0.
|
|
195
|
+
const SDK_VERSION = "0.0.23";
|
package/dist/commands/org.d.ts
CHANGED
|
@@ -11,6 +11,23 @@ export declare function membersRemove(userId: string | undefined, opts: {
|
|
|
11
11
|
json: boolean;
|
|
12
12
|
org?: string;
|
|
13
13
|
}): Promise<void>;
|
|
14
|
+
/** The platform's steps for the company that runs the domain's DNS. Absent from an older platform. */
|
|
15
|
+
interface DomainSetup {
|
|
16
|
+
address: string;
|
|
17
|
+
forwards: string | null;
|
|
18
|
+
dnsHost: {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
22
|
+
method: string;
|
|
23
|
+
steps: string[];
|
|
24
|
+
after: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The steps as the platform wrote them, numbered, with a line telling an agent how to pass them on. The person
|
|
28
|
+
* who owns the domain is usually not technical: they get these steps and nothing to choose between.
|
|
29
|
+
*/
|
|
30
|
+
export declare function setupText(s: DomainSetup): string;
|
|
14
31
|
export declare function domainsList(opts: {
|
|
15
32
|
json: boolean;
|
|
16
33
|
}): Promise<void>;
|
|
@@ -45,3 +62,4 @@ export declare function clientsRelease(slug: string | undefined, opts: {
|
|
|
45
62
|
json: boolean;
|
|
46
63
|
org?: string;
|
|
47
64
|
}): Promise<void>;
|
|
65
|
+
export {};
|
package/dist/commands/org.js
CHANGED
|
@@ -35,23 +35,46 @@ export async function membersRemove(userId, opts) {
|
|
|
35
35
|
return printJson(r);
|
|
36
36
|
log.ok("Removed.");
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* The steps as the platform wrote them, numbered, with a line telling an agent how to pass them on. The person
|
|
40
|
+
* who owns the domain is usually not technical: they get these steps and nothing to choose between.
|
|
41
|
+
*/
|
|
42
|
+
export function setupText(s) {
|
|
43
|
+
const known = s.dnsHost.id !== "unknown";
|
|
44
|
+
return [
|
|
45
|
+
`The app's address will be https://${s.address}${s.forwards ? `, and ${s.forwards} forwards to it` : ""}.`,
|
|
46
|
+
known ? `This domain's DNS is run by ${s.dnsHost.name}${s.method === "move-dns" ? ", which cannot point a bare domain name at another service, so the DNS moves to Cloudflare (free) first" : ""}. The steps for the domain's owner:` : "The steps for the domain's owner:",
|
|
47
|
+
"",
|
|
48
|
+
...s.steps.map((step, i) => ` ${i + 1}. ${step}`),
|
|
49
|
+
"",
|
|
50
|
+
s.after,
|
|
51
|
+
"",
|
|
52
|
+
"If you are a coding agent: give the owner these steps as they are, numbered, and nothing else to decide. Do not ask which company they use (it was looked up) and do not offer other record types. When they say it is done, run `nerd domains` until the status is active, then open the address to confirm.",
|
|
53
|
+
].join("\n");
|
|
54
|
+
}
|
|
38
55
|
export async function domainsList(opts) {
|
|
39
56
|
const nerd = readNerdJson(findProjectRoot());
|
|
40
57
|
const r = await ApiClient.fromConfig().get(projectPath(nerd, "/domains"));
|
|
41
58
|
if (opts.json)
|
|
42
59
|
return printJson(r);
|
|
43
60
|
if (!r.domains.length)
|
|
44
|
-
return log.info(`No custom domains. Add one: nerd domains add
|
|
45
|
-
table(r.domains.map((d) => ({ hostname: d.hostname, status: d.status, ssl: d.sslStatus ?? "", error: d.lastError ?? "", id: d.id })), ["hostname", "status", "ssl", "error", "id"]);
|
|
46
|
-
|
|
61
|
+
return log.info(`No custom domains. Add one: nerd domains add example.com`);
|
|
62
|
+
table(r.domains.map((d) => ({ hostname: d.hostname, status: d.status, ssl: d.sslStatus ?? "", does: d.redirectTo ? `forwards to ${d.redirectTo}` : "the app", error: d.lastError ?? "", id: d.id })), ["hostname", "status", "ssl", "does", "error", "id"]);
|
|
63
|
+
// Only addresses still waiting for their DNS records have steps left to do.
|
|
64
|
+
for (const s of r.setups ?? [])
|
|
65
|
+
log.info(`\n${setupText(s)}`);
|
|
66
|
+
if (!r.setups && r.domains.some((d) => d.status !== "active"))
|
|
67
|
+
log.info(`\nPoint each hostname at ${r.cnameTarget} with a CNAME record.`);
|
|
47
68
|
}
|
|
48
69
|
export async function domainsAdd(hostname, opts) {
|
|
49
70
|
if (!hostname)
|
|
50
|
-
throw new CliError("Usage: nerd domains add
|
|
71
|
+
throw new CliError("Usage: nerd domains add example.com");
|
|
51
72
|
const nerd = readNerdJson(findProjectRoot());
|
|
52
73
|
const r = await ApiClient.fromConfig().post(projectPath(nerd, "/domains"), { hostname });
|
|
53
74
|
if (opts.json)
|
|
54
75
|
return printJson(r);
|
|
76
|
+
if (r.setup)
|
|
77
|
+
return log.ok(`Added ${r.domain.hostname}.\n\n${setupText(r.setup)}`);
|
|
55
78
|
log.ok(`Added ${r.domain.hostname}. Create this DNS record, then check with \`nerd domains\`:\n\n ${r.domain.hostname} CNAME ${r.cnameTarget}`);
|
|
56
79
|
}
|
|
57
80
|
export async function domainsRemove(idOrHostname, opts) {
|
package/package.json
CHANGED
|
@@ -178,6 +178,17 @@ After a deploy is live, `nerd deploy` asks the platform for a model review of th
|
|
|
178
178
|
- **Secrets** (Stripe keys, API tokens): never in code or in the client. Locally they live in `.dev.vars` (gitignored). For production, ask the person to add it under the app's Settings tab in the dashboard, or to run `nerd secret set NAME` and paste the value; it reaches the app as `c.env.NAME` on the next deploy. Pull request previews do not get it unless it was set with `--previews` (use that only for keys that are safe in a preview, such as a test-mode key). `nerd secret list` shows names only. Do not put a real secret value in any command you run yourself.
|
|
179
179
|
- **Email**: `sendEmail(c.env, { to, subject, text, html?, replyTo? })` from `@nerdsystem/sdk` sends through the platform. The relay only sends to addresses that have an account on this app (someone who signed up); any other recipient is refused with a 400, and the sender name is always the app's name. On the Free plan the recipient must also have confirmed their address by finishing a password reset (403 otherwise); paid plans can write to every signed-up user. It is limited per day by plan (50 on Free, 1,000 on Pro at $39 a month, 2,000 on Studio at $99 a month), so use it for transactional mail such as receipts and notifications, not bulk. Plans can be paid monthly or yearly at ten times the monthly price. Pass `replyTo` (the owner's address, or one they give you) whenever a person might answer the message; without it replies go to a mailbox nobody reads. Mail goes out under the app's name from the platform's address; on Pro and Studio the owner can switch it to their own domain in the dashboard under Settings, which needs no code change.
|
|
180
180
|
|
|
181
|
+
## Putting the app on the owner's own domain
|
|
182
|
+
|
|
183
|
+
Paid plans only; on Free the command answers with the plan that includes it, so say that and stop.
|
|
184
|
+
|
|
185
|
+
1. Run `nerd domains add example.com` with the bare domain the owner gives you. The platform makes `www.example.com` the app's address and sets the bare name up to forward to it. It also looks up which company runs the domain's DNS and prints the exact steps for that company.
|
|
186
|
+
2. Give the owner those steps as printed, numbered. Do not ask who their registrar is, do not show a table of record types, and do not offer alternatives: the platform already chose. The steps are things only they can do (signing in where the domain is managed).
|
|
187
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active`, then open the address and confirm it loads with https. If it is still pending after an hour, run `nerd domains` and read the steps again with them; the usual cause is a leftover parking record.
|
|
188
|
+
4. Tell them two things once it is live: they sign in once more on the new address (same account, same data), and links to the old `.nerdsystem.app` address keep working.
|
|
189
|
+
|
|
190
|
+
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
|
191
|
+
|
|
181
192
|
## Debugging production
|
|
182
193
|
|
|
183
194
|
When something is wrong on the deployed app: `nerd logs --since 1h` (add `--q "text"` to search, `--pr 12` for a preview) shows errors with the request that caused them. Reproduce locally with `nerd dev` using the same input, fix it, run `nerd verify`, and deploy or open a pull request. If a deploy made things worse, `nerd rollback` puts the previous production bundle back without touching the database. Write a one-line note on every deploy (`nerd deploy --note "fix: todos query filtered by user"`); the dashboard shows these as a changelog people can read.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: How to build, run, and deploy this app on nerdsystem. Applies to server, database, auth, and deploy work.
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
|
-
<!-- generated from .claude/skills/nerdsystem/SKILL.md (
|
|
5
|
+
<!-- generated from .claude/skills/nerdsystem/SKILL.md (1794b8a1a530); edit the skill, then run: nerd agents sync -->
|
|
6
6
|
|
|
7
7
|
# Building on nerdsystem
|
|
8
8
|
|
|
@@ -179,6 +179,17 @@ After a deploy is live, `nerd deploy` asks the platform for a model review of th
|
|
|
179
179
|
- **Secrets** (Stripe keys, API tokens): never in code or in the client. Locally they live in `.dev.vars` (gitignored). For production, ask the person to add it under the app's Settings tab in the dashboard, or to run `nerd secret set NAME` and paste the value; it reaches the app as `c.env.NAME` on the next deploy. Pull request previews do not get it unless it was set with `--previews` (use that only for keys that are safe in a preview, such as a test-mode key). `nerd secret list` shows names only. Do not put a real secret value in any command you run yourself.
|
|
180
180
|
- **Email**: `sendEmail(c.env, { to, subject, text, html?, replyTo? })` from `@nerdsystem/sdk` sends through the platform. The relay only sends to addresses that have an account on this app (someone who signed up); any other recipient is refused with a 400, and the sender name is always the app's name. On the Free plan the recipient must also have confirmed their address by finishing a password reset (403 otherwise); paid plans can write to every signed-up user. It is limited per day by plan (50 on Free, 1,000 on Pro at $39 a month, 2,000 on Studio at $99 a month), so use it for transactional mail such as receipts and notifications, not bulk. Plans can be paid monthly or yearly at ten times the monthly price. Pass `replyTo` (the owner's address, or one they give you) whenever a person might answer the message; without it replies go to a mailbox nobody reads. Mail goes out under the app's name from the platform's address; on Pro and Studio the owner can switch it to their own domain in the dashboard under Settings, which needs no code change.
|
|
181
181
|
|
|
182
|
+
## Putting the app on the owner's own domain
|
|
183
|
+
|
|
184
|
+
Paid plans only; on Free the command answers with the plan that includes it, so say that and stop.
|
|
185
|
+
|
|
186
|
+
1. Run `nerd domains add example.com` with the bare domain the owner gives you. The platform makes `www.example.com` the app's address and sets the bare name up to forward to it. It also looks up which company runs the domain's DNS and prints the exact steps for that company.
|
|
187
|
+
2. Give the owner those steps as printed, numbered. Do not ask who their registrar is, do not show a table of record types, and do not offer alternatives: the platform already chose. The steps are things only they can do (signing in where the domain is managed).
|
|
188
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active`, then open the address and confirm it loads with https. If it is still pending after an hour, run `nerd domains` and read the steps again with them; the usual cause is a leftover parking record.
|
|
189
|
+
4. Tell them two things once it is live: they sign in once more on the new address (same account, same data), and links to the old `.nerdsystem.app` address keep working.
|
|
190
|
+
|
|
191
|
+
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
|
192
|
+
|
|
182
193
|
## Debugging production
|
|
183
194
|
|
|
184
195
|
When something is wrong on the deployed app: `nerd logs --since 1h` (add `--q "text"` to search, `--pr 12` for a preview) shows errors with the request that caused them. Reproduce locally with `nerd dev` using the same input, fix it, run `nerd verify`, and deploy or open a pull request. If a deploy made things worse, `nerd rollback` puts the previous production bundle back without touching the database. Write a one-line note on every deploy (`nerd deploy --note "fix: todos query filtered by user"`); the dashboard shows these as a changelog people can read.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- generated from .claude/skills/nerdsystem/SKILL.md (
|
|
1
|
+
<!-- generated from .claude/skills/nerdsystem/SKILL.md (1794b8a1a530); edit the skill, then run: nerd agents sync -->
|
|
2
2
|
|
|
3
3
|
# Building on nerdsystem
|
|
4
4
|
|
|
@@ -175,6 +175,17 @@ After a deploy is live, `nerd deploy` asks the platform for a model review of th
|
|
|
175
175
|
- **Secrets** (Stripe keys, API tokens): never in code or in the client. Locally they live in `.dev.vars` (gitignored). For production, ask the person to add it under the app's Settings tab in the dashboard, or to run `nerd secret set NAME` and paste the value; it reaches the app as `c.env.NAME` on the next deploy. Pull request previews do not get it unless it was set with `--previews` (use that only for keys that are safe in a preview, such as a test-mode key). `nerd secret list` shows names only. Do not put a real secret value in any command you run yourself.
|
|
176
176
|
- **Email**: `sendEmail(c.env, { to, subject, text, html?, replyTo? })` from `@nerdsystem/sdk` sends through the platform. The relay only sends to addresses that have an account on this app (someone who signed up); any other recipient is refused with a 400, and the sender name is always the app's name. On the Free plan the recipient must also have confirmed their address by finishing a password reset (403 otherwise); paid plans can write to every signed-up user. It is limited per day by plan (50 on Free, 1,000 on Pro at $39 a month, 2,000 on Studio at $99 a month), so use it for transactional mail such as receipts and notifications, not bulk. Plans can be paid monthly or yearly at ten times the monthly price. Pass `replyTo` (the owner's address, or one they give you) whenever a person might answer the message; without it replies go to a mailbox nobody reads. Mail goes out under the app's name from the platform's address; on Pro and Studio the owner can switch it to their own domain in the dashboard under Settings, which needs no code change.
|
|
177
177
|
|
|
178
|
+
## Putting the app on the owner's own domain
|
|
179
|
+
|
|
180
|
+
Paid plans only; on Free the command answers with the plan that includes it, so say that and stop.
|
|
181
|
+
|
|
182
|
+
1. Run `nerd domains add example.com` with the bare domain the owner gives you. The platform makes `www.example.com` the app's address and sets the bare name up to forward to it. It also looks up which company runs the domain's DNS and prints the exact steps for that company.
|
|
183
|
+
2. Give the owner those steps as printed, numbered. Do not ask who their registrar is, do not show a table of record types, and do not offer alternatives: the platform already chose. The steps are things only they can do (signing in where the domain is managed).
|
|
184
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active`, then open the address and confirm it loads with https. If it is still pending after an hour, run `nerd domains` and read the steps again with them; the usual cause is a leftover parking record.
|
|
185
|
+
4. Tell them two things once it is live: they sign in once more on the new address (same account, same data), and links to the old `.nerdsystem.app` address keep working.
|
|
186
|
+
|
|
187
|
+
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
|
188
|
+
|
|
178
189
|
## Debugging production
|
|
179
190
|
|
|
180
191
|
When something is wrong on the deployed app: `nerd logs --since 1h` (add `--q "text"` to search, `--pr 12` for a preview) shows errors with the request that caused them. Reproduce locally with `nerd dev` using the same input, fix it, run `nerd verify`, and deploy or open a pull request. If a deploy made things worse, `nerd rollback` puts the previous production bundle back without touching the database. Write a one-line note on every deploy (`nerd deploy --note "fix: todos query filtered by user"`); the dashboard shows these as a changelog people can read.
|
package/template/AGENTS.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- generated from .claude/skills/nerdsystem/SKILL.md (
|
|
1
|
+
<!-- generated from .claude/skills/nerdsystem/SKILL.md (1794b8a1a530); edit the skill, then run: nerd agents sync -->
|
|
2
2
|
|
|
3
3
|
# Building on nerdsystem
|
|
4
4
|
|
|
@@ -175,6 +175,17 @@ After a deploy is live, `nerd deploy` asks the platform for a model review of th
|
|
|
175
175
|
- **Secrets** (Stripe keys, API tokens): never in code or in the client. Locally they live in `.dev.vars` (gitignored). For production, ask the person to add it under the app's Settings tab in the dashboard, or to run `nerd secret set NAME` and paste the value; it reaches the app as `c.env.NAME` on the next deploy. Pull request previews do not get it unless it was set with `--previews` (use that only for keys that are safe in a preview, such as a test-mode key). `nerd secret list` shows names only. Do not put a real secret value in any command you run yourself.
|
|
176
176
|
- **Email**: `sendEmail(c.env, { to, subject, text, html?, replyTo? })` from `@nerdsystem/sdk` sends through the platform. The relay only sends to addresses that have an account on this app (someone who signed up); any other recipient is refused with a 400, and the sender name is always the app's name. On the Free plan the recipient must also have confirmed their address by finishing a password reset (403 otherwise); paid plans can write to every signed-up user. It is limited per day by plan (50 on Free, 1,000 on Pro at $39 a month, 2,000 on Studio at $99 a month), so use it for transactional mail such as receipts and notifications, not bulk. Plans can be paid monthly or yearly at ten times the monthly price. Pass `replyTo` (the owner's address, or one they give you) whenever a person might answer the message; without it replies go to a mailbox nobody reads. Mail goes out under the app's name from the platform's address; on Pro and Studio the owner can switch it to their own domain in the dashboard under Settings, which needs no code change.
|
|
177
177
|
|
|
178
|
+
## Putting the app on the owner's own domain
|
|
179
|
+
|
|
180
|
+
Paid plans only; on Free the command answers with the plan that includes it, so say that and stop.
|
|
181
|
+
|
|
182
|
+
1. Run `nerd domains add example.com` with the bare domain the owner gives you. The platform makes `www.example.com` the app's address and sets the bare name up to forward to it. It also looks up which company runs the domain's DNS and prints the exact steps for that company.
|
|
183
|
+
2. Give the owner those steps as printed, numbered. Do not ask who their registrar is, do not show a table of record types, and do not offer alternatives: the platform already chose. The steps are things only they can do (signing in where the domain is managed).
|
|
184
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active`, then open the address and confirm it loads with https. If it is still pending after an hour, run `nerd domains` and read the steps again with them; the usual cause is a leftover parking record.
|
|
185
|
+
4. Tell them two things once it is live: they sign in once more on the new address (same account, same data), and links to the old `.nerdsystem.app` address keep working.
|
|
186
|
+
|
|
187
|
+
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
|
188
|
+
|
|
178
189
|
## Debugging production
|
|
179
190
|
|
|
180
191
|
When something is wrong on the deployed app: `nerd logs --since 1h` (add `--q "text"` to search, `--pr 12` for a preview) shows errors with the request that caused them. Reproduce locally with `nerd dev` using the same input, fix it, run `nerd verify`, and deploy or open a pull request. If a deploy made things worse, `nerd rollback` puts the previous production bundle back without touching the database. Write a one-line note on every deploy (`nerd deploy --note "fix: todos query filtered by user"`); the dashboard shows these as a changelog people can read.
|
package/template/GEMINI.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- generated from .claude/skills/nerdsystem/SKILL.md (
|
|
1
|
+
<!-- generated from .claude/skills/nerdsystem/SKILL.md (1794b8a1a530); edit the skill, then run: nerd agents sync -->
|
|
2
2
|
|
|
3
3
|
# Building on nerdsystem
|
|
4
4
|
|
|
@@ -175,6 +175,17 @@ After a deploy is live, `nerd deploy` asks the platform for a model review of th
|
|
|
175
175
|
- **Secrets** (Stripe keys, API tokens): never in code or in the client. Locally they live in `.dev.vars` (gitignored). For production, ask the person to add it under the app's Settings tab in the dashboard, or to run `nerd secret set NAME` and paste the value; it reaches the app as `c.env.NAME` on the next deploy. Pull request previews do not get it unless it was set with `--previews` (use that only for keys that are safe in a preview, such as a test-mode key). `nerd secret list` shows names only. Do not put a real secret value in any command you run yourself.
|
|
176
176
|
- **Email**: `sendEmail(c.env, { to, subject, text, html?, replyTo? })` from `@nerdsystem/sdk` sends through the platform. The relay only sends to addresses that have an account on this app (someone who signed up); any other recipient is refused with a 400, and the sender name is always the app's name. On the Free plan the recipient must also have confirmed their address by finishing a password reset (403 otherwise); paid plans can write to every signed-up user. It is limited per day by plan (50 on Free, 1,000 on Pro at $39 a month, 2,000 on Studio at $99 a month), so use it for transactional mail such as receipts and notifications, not bulk. Plans can be paid monthly or yearly at ten times the monthly price. Pass `replyTo` (the owner's address, or one they give you) whenever a person might answer the message; without it replies go to a mailbox nobody reads. Mail goes out under the app's name from the platform's address; on Pro and Studio the owner can switch it to their own domain in the dashboard under Settings, which needs no code change.
|
|
177
177
|
|
|
178
|
+
## Putting the app on the owner's own domain
|
|
179
|
+
|
|
180
|
+
Paid plans only; on Free the command answers with the plan that includes it, so say that and stop.
|
|
181
|
+
|
|
182
|
+
1. Run `nerd domains add example.com` with the bare domain the owner gives you. The platform makes `www.example.com` the app's address and sets the bare name up to forward to it. It also looks up which company runs the domain's DNS and prints the exact steps for that company.
|
|
183
|
+
2. Give the owner those steps as printed, numbered. Do not ask who their registrar is, do not show a table of record types, and do not offer alternatives: the platform already chose. The steps are things only they can do (signing in where the domain is managed).
|
|
184
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active`, then open the address and confirm it loads with https. If it is still pending after an hour, run `nerd domains` and read the steps again with them; the usual cause is a leftover parking record.
|
|
185
|
+
4. Tell them two things once it is live: they sign in once more on the new address (same account, same data), and links to the old `.nerdsystem.app` address keep working.
|
|
186
|
+
|
|
187
|
+
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
|
188
|
+
|
|
178
189
|
## Debugging production
|
|
179
190
|
|
|
180
191
|
When something is wrong on the deployed app: `nerd logs --since 1h` (add `--q "text"` to search, `--pr 12` for a preview) shows errors with the request that caused them. Reproduce locally with `nerd dev` using the same input, fix it, run `nerd verify`, and deploy or open a pull request. If a deploy made things worse, `nerd rollback` puts the previous production bundle back without touching the database. Write a one-line note on every deploy (`nerd deploy --note "fix: todos query filtered by user"`); the dashboard shows these as a changelog people can read.
|