nerdsystem 0.0.23 → 0.0.24
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/api.d.ts +2 -0
- package/dist/commands/deploy.d.ts +2 -0
- package/dist/commands/deploy.js +7 -4
- package/dist/commands/init.js +1 -1
- package/dist/commands/org.js +11 -1
- package/package.json +1 -1
- package/template/.claude/skills/nerdsystem/SKILL.md +1 -1
- package/template/.cursor/rules/nerdsystem.mdc +2 -2
- package/template/.github/copilot-instructions.md +2 -2
- package/template/AGENTS.md +2 -2
- package/template/GEMINI.md +2 -2
package/dist/api.d.ts
CHANGED
|
@@ -53,6 +53,8 @@ export interface Project {
|
|
|
53
53
|
name: string;
|
|
54
54
|
scriptName: string;
|
|
55
55
|
url: string;
|
|
56
|
+
/** The address on the owner's own domain, once one is verified. Absent from an older platform. */
|
|
57
|
+
customUrl?: string | null;
|
|
56
58
|
}
|
|
57
59
|
export interface Deployment {
|
|
58
60
|
id: string;
|
|
@@ -46,6 +46,8 @@ export declare function checksMetadata(results: GateResult[]): {
|
|
|
46
46
|
export interface ShipResult {
|
|
47
47
|
deployment: Deployment;
|
|
48
48
|
url: string;
|
|
49
|
+
/** The app's address on the owner's own domain, once one is verified; null otherwise. */
|
|
50
|
+
customUrl: string | null;
|
|
49
51
|
migrations: {
|
|
50
52
|
applied: string[];
|
|
51
53
|
skipped: string[];
|
package/dist/commands/deploy.js
CHANGED
|
@@ -185,11 +185,14 @@ export async function shipBuild(args) {
|
|
|
185
185
|
}
|
|
186
186
|
const { deployment } = await api.post(projectPath(nerd, "/deployments"), form);
|
|
187
187
|
const { project } = await api.get(projectPath(nerd));
|
|
188
|
-
log.ok(`Deployed ${deployment.id} (${deployment.status}) → ${project.url}`);
|
|
188
|
+
log.ok(`Deployed ${deployment.id} (${deployment.status}) → ${project.customUrl ?? project.url}`);
|
|
189
|
+
// The owner knows the app by their own domain; the platform address is the one that is probed, because it always resolves.
|
|
190
|
+
if (project.customUrl)
|
|
191
|
+
log.info(`Also at ${project.url}`);
|
|
189
192
|
if (!opts["skip-probe"] && deployment.status === "live")
|
|
190
193
|
log.step(`Probing ${project.url}`);
|
|
191
194
|
const probes = await probeAfterDeploy(root, deployment, project.url, Boolean(opts["skip-probe"]));
|
|
192
|
-
return { deployment, url: project.url, migrations: mig, probes, source, sourceSkipped, lineage, warnings: pack.warnings };
|
|
195
|
+
return { deployment, url: project.url, customUrl: project.customUrl ?? null, migrations: mig, probes, source, sourceSkipped, lineage, warnings: pack.warnings };
|
|
193
196
|
}
|
|
194
197
|
/** The one line about the code after a live deploy, keyed on what the API recorded, not on what we sent. */
|
|
195
198
|
export function sourceLine(r) {
|
|
@@ -230,7 +233,7 @@ export async function deploy(opts) {
|
|
|
230
233
|
const wantReview = r.deployment.status === "live" && Boolean(r.source);
|
|
231
234
|
if (opts.json) {
|
|
232
235
|
const review = wantReview ? await platformReview(api, `${projectPath(nerd)}/sources/${r.source.id}`, reviewPage) : null;
|
|
233
|
-
return printJson({ deployment: r.deployment, url: r.url, migrations: r.migrations, probes: r.probes, source: r.source, sourceSkipped: r.sourceSkipped, lineage: r.lineage.passed, warnings: r.warnings, review });
|
|
236
|
+
return printJson({ deployment: r.deployment, url: r.url, customUrl: r.customUrl, migrations: r.migrations, probes: r.probes, source: r.source, sourceSkipped: r.sourceSkipped, lineage: r.lineage.passed, warnings: r.warnings, review });
|
|
234
237
|
}
|
|
235
238
|
printProbe(r.url, r.probes);
|
|
236
239
|
if (r.deployment.status === "live") {
|
|
@@ -243,7 +246,7 @@ export async function deploy(opts) {
|
|
|
243
246
|
log.step("Your app is live. Asking for a model review of how it is put together (up to a minute or two; safe to stop waiting)");
|
|
244
247
|
printReview(await platformReview(api, `${projectPath(nerd)}/sources/${r.source.id}`, reviewPage));
|
|
245
248
|
}
|
|
246
|
-
log.info(`First time? Sign up on your app at ${r.url}, then make yourself admin in the dashboard's Auth tab: ${dashboardUrl(api.apiUrl)}/app/${nerd.org}/projects/${nerd.project}/auth`);
|
|
249
|
+
log.info(`First time? Sign up on your app at ${r.customUrl ?? r.url}, then make yourself admin in the dashboard's Auth tab: ${dashboardUrl(api.apiUrl)}/app/${nerd.org}/projects/${nerd.project}/auth`);
|
|
247
250
|
}
|
|
248
251
|
export async function deployments(opts) {
|
|
249
252
|
const nerd = readNerdJson(findProjectRoot());
|
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.24";
|
package/dist/commands/org.js
CHANGED
|
@@ -52,6 +52,16 @@ export function setupText(s) {
|
|
|
52
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
53
|
].join("\n");
|
|
54
54
|
}
|
|
55
|
+
/** Whether the domain without www forwards to the app yet, in words an agent can pass on. */
|
|
56
|
+
function bareText(b) {
|
|
57
|
+
if (!b)
|
|
58
|
+
return "";
|
|
59
|
+
if (b.status === "forwarding")
|
|
60
|
+
return `${b.hostname} forwards here`;
|
|
61
|
+
if (b.status === "starting")
|
|
62
|
+
return `${b.hostname} is starting (certificate, under a minute)`;
|
|
63
|
+
return `${b.hostname} does not point here yet`;
|
|
64
|
+
}
|
|
55
65
|
export async function domainsList(opts) {
|
|
56
66
|
const nerd = readNerdJson(findProjectRoot());
|
|
57
67
|
const r = await ApiClient.fromConfig().get(projectPath(nerd, "/domains"));
|
|
@@ -59,7 +69,7 @@ export async function domainsList(opts) {
|
|
|
59
69
|
return printJson(r);
|
|
60
70
|
if (!r.domains.length)
|
|
61
71
|
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"]);
|
|
72
|
+
table(r.domains.map((d) => ({ hostname: d.hostname, status: d.status, ssl: d.sslStatus ?? "", does: d.redirectTo ? `forwards to ${d.redirectTo}` : "the app", "bare name": bareText(d.bare), error: d.lastError ?? "", id: d.id })), ["hostname", "status", "ssl", "does", "bare name", "error", "id"]);
|
|
63
73
|
// Only addresses still waiting for their DNS records have steps left to do.
|
|
64
74
|
for (const s of r.setups ?? [])
|
|
65
75
|
log.info(`\n${setupText(s)}`);
|
package/package.json
CHANGED
|
@@ -184,7 +184,7 @@ Paid plans only; on Free the command answers with the plan that includes it, so
|
|
|
184
184
|
|
|
185
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
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
|
|
187
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active` and the "bare name" column says it forwards here, then open both addresses and confirm they load 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
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
189
|
|
|
190
190
|
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
|
@@ -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 (e9b33e090df6); edit the skill, then run: nerd agents sync -->
|
|
6
6
|
|
|
7
7
|
# Building on nerdsystem
|
|
8
8
|
|
|
@@ -185,7 +185,7 @@ Paid plans only; on Free the command answers with the plan that includes it, so
|
|
|
185
185
|
|
|
186
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
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
|
|
188
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active` and the "bare name" column says it forwards here, then open both addresses and confirm they load 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
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
190
|
|
|
191
191
|
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- generated from .claude/skills/nerdsystem/SKILL.md (
|
|
1
|
+
<!-- generated from .claude/skills/nerdsystem/SKILL.md (e9b33e090df6); edit the skill, then run: nerd agents sync -->
|
|
2
2
|
|
|
3
3
|
# Building on nerdsystem
|
|
4
4
|
|
|
@@ -181,7 +181,7 @@ Paid plans only; on Free the command answers with the plan that includes it, so
|
|
|
181
181
|
|
|
182
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
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
|
|
184
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active` and the "bare name" column says it forwards here, then open both addresses and confirm they load 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
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
186
|
|
|
187
187
|
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
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 (e9b33e090df6); edit the skill, then run: nerd agents sync -->
|
|
2
2
|
|
|
3
3
|
# Building on nerdsystem
|
|
4
4
|
|
|
@@ -181,7 +181,7 @@ Paid plans only; on Free the command answers with the plan that includes it, so
|
|
|
181
181
|
|
|
182
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
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
|
|
184
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active` and the "bare name" column says it forwards here, then open both addresses and confirm they load 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
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
186
|
|
|
187
187
|
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|
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 (e9b33e090df6); edit the skill, then run: nerd agents sync -->
|
|
2
2
|
|
|
3
3
|
# Building on nerdsystem
|
|
4
4
|
|
|
@@ -181,7 +181,7 @@ Paid plans only; on Free the command answers with the plan that includes it, so
|
|
|
181
181
|
|
|
182
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
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
|
|
184
|
+
3. When they say it is done, run `nerd domains` every minute or two until the status is `active` and the "bare name" column says it forwards here, then open both addresses and confirm they load 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
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
186
|
|
|
187
187
|
For a subdomain such as `app.example.com`, the same command gives a single record to add.
|