@mason-data/cli 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -73
- package/dist/src/api/error.js +3 -0
- package/dist/src/api/postgres/catalog-worker.js +49 -2
- package/dist/src/api/postgres/catalog.js +368 -25
- package/dist/src/api/postgres/encode.js +3 -1
- package/dist/src/api/postgres/explain.js +3 -2
- package/dist/src/api/postgres/listener.js +11 -3
- package/dist/src/api/postgres/protocol.js +39 -23
- package/dist/src/api/postgres/proxy.js +283 -0
- package/dist/src/api/postgres/schema.js +6 -0
- package/dist/src/api/postgres/server.js +1617 -245
- package/dist/src/api/postgres/translate.js +127 -10
- package/dist/src/api/request-log.js +18 -5
- package/dist/src/cdc/poll.js +5 -5
- package/dist/src/cli/background.js +47 -25
- package/dist/src/cli/bridge-stdin.js +101 -0
- package/dist/src/cli/cancel.js +75 -0
- package/dist/src/cli/command.js +170 -11
- package/dist/src/cli/commands.js +804 -209
- package/dist/src/cli/control.js +59 -0
- package/dist/src/cli/credentials.js +182 -0
- package/dist/src/cli/demo.js +20 -11
- package/dist/src/cli/deploy.js +574 -0
- package/dist/src/cli/dev.js +491 -130
- package/dist/src/cli/doctor.js +131 -38
- package/dist/src/cli/generated-files.js +143 -0
- package/dist/src/cli/guides.js +175 -36
- package/dist/src/cli/hosted.js +850 -0
- package/dist/src/cli/init.js +162 -65
- package/dist/src/cli/login.js +289 -0
- package/dist/src/cli/machine.js +13 -12
- package/dist/src/cli/main.js +11 -5
- package/dist/src/cli/mason.cjs +17 -0
- package/dist/src/cli/mcp.js +31 -22
- package/dist/src/cli/metrics.js +79 -0
- package/dist/src/cli/output-gate.js +176 -0
- package/dist/src/cli/page-share.js +96 -0
- package/dist/src/cli/pg-tls.js +14 -4
- package/dist/src/cli/pg-url.js +4 -0
- package/dist/src/cli/pin.js +19 -14
- package/dist/src/cli/pool-size.cjs +85 -0
- package/dist/src/cli/ports.js +2 -0
- package/dist/src/cli/preflight.js +138 -46
- package/dist/src/cli/project.js +142 -4
- package/dist/src/cli/readiness.js +76 -6
- package/dist/src/cli/registry.js +65 -38
- package/dist/src/cli/replica-hosted.js +665 -0
- package/dist/src/cli/replica.js +76 -0
- package/dist/src/cli/replication-checks.js +7 -5
- package/dist/src/cli/replication-mode.js +105 -26
- package/dist/src/cli/request-filter.js +134 -0
- package/dist/src/cli/roles.js +585 -0
- package/dist/src/cli/run-server.js +637 -48
- package/dist/src/cli/runs.js +1 -1
- package/dist/src/cli/security.js +67 -18
- package/dist/src/cli/serve.js +204 -46
- package/dist/src/cli/share-run.js +329 -0
- package/dist/src/cli/share.js +286 -0
- package/dist/src/cli/source-edit.js +75 -17
- package/dist/src/cli/source-role.js +344 -0
- package/dist/src/cli/sources.js +306 -47
- package/dist/src/cli/style.js +2 -1
- package/dist/src/cli/supervise.js +27 -24
- package/dist/src/cli/sync.js +55 -25
- package/dist/src/cli/token-hosted.js +337 -0
- package/dist/src/cli/tunnel.js +200 -0
- package/dist/src/cli/ui-ssh.js +460 -0
- package/dist/src/cli/ui.js +124 -17
- package/dist/src/cli/usage.js +128 -0
- package/dist/src/cli/user-hosted.js +299 -0
- package/dist/src/cli/user.js +573 -65
- package/dist/src/cli/version.js +9 -7
- package/dist/src/demo/seed.js +29 -0
- package/dist/src/duck/analyze.js +36 -20
- package/dist/src/duck/cancel.js +10 -1
- package/dist/src/duck/collation.js +266 -0
- package/dist/src/duck/constant-key.js +94 -0
- package/dist/src/duck/distinct-key.js +283 -26
- package/dist/src/duck/events.js +165 -0
- package/dist/src/duck/executor-worker.js +20 -11
- package/dist/src/duck/executor.js +47 -33
- package/dist/src/duck/explain.js +60 -46
- package/dist/src/duck/extensions.js +160 -0
- package/dist/src/duck/functions.js +461 -63
- package/dist/src/duck/gaps.js +48 -21
- package/dist/src/duck/generated-plan.js +1070 -0
- package/dist/src/duck/generated.js +906 -0
- package/dist/src/duck/grants.js +176 -0
- package/dist/src/duck/held-types.js +64 -0
- package/dist/src/duck/history.js +127 -0
- package/dist/src/duck/jsonb-order.js +9 -12
- package/dist/src/duck/kept-route.js +6 -5
- package/dist/src/duck/kept.js +15 -13
- package/dist/src/duck/late.js +1469 -40
- package/dist/src/duck/libc-bound.js +341 -0
- package/dist/src/duck/libc-order.js +892 -126
- package/dist/src/duck/pg-eval-worker.js +7 -1
- package/dist/src/duck/pg-eval.js +6 -4
- package/dist/src/duck/pgtree.js +774 -23
- package/dist/src/duck/plan.js +369 -47
- package/dist/src/duck/publication.js +20 -6
- package/dist/src/duck/requests.js +269 -93
- package/dist/src/duck/resolved.js +117 -2
- package/dist/src/duck/rewrite.js +4584 -580
- package/dist/src/duck/row-filter.js +655 -0
- package/dist/src/duck/statement.js +19 -0
- package/dist/src/duck/store.js +439 -177
- package/dist/src/duck/stream.js +19 -10
- package/dist/src/duck/sync.js +1411 -368
- package/dist/src/duck/token.js +4 -1
- package/dist/src/duck/types.js +69 -12
- package/dist/src/duck/usage.js +326 -0
- package/dist/src/duck/users.js +69 -15
- package/dist/src/duck/verified.js +161 -1
- package/dist/src/duck/views.js +5 -5
- package/dist/src/lib/database-name.js +62 -0
- package/dist/src/lib/database-url.js +55 -10
- package/dist/src/lib/dotenv.js +17 -4
- package/dist/src/lib/instant.js +50 -0
- package/dist/src/lib/log-buffer.js +77 -0
- package/dist/src/lib/log-read.js +196 -0
- package/dist/src/lib/pg-numeric.js +390 -49
- package/dist/src/lib/project-version.js +23 -23
- package/dist/src/lib/secret-mask.js +142 -0
- package/dist/src/lib/table-sync.js +282 -0
- package/dist/src/web/app.css +706 -66
- package/dist/src/web/app.js +331 -409
- package/dist/src/web/charts.js +229 -0
- package/dist/src/web/index.html +82 -18
- package/dist/src/web/pages/queries.js +192 -0
- package/dist/src/web/pages/status.js +611 -0
- package/dist/src/web/pages/syncs.js +155 -0
- package/dist/src/web/pages/tables.js +439 -0
- package/dist/src/web/pages/usage.js +397 -0
- package/dist/src/web/pages/users.js +219 -0
- package/dist/src/web/shared.js +584 -0
- package/dist/src/web/vendor/README.md +25 -0
- package/dist/src/web/vendor/geist-1.7.2/Geist-Variable.woff2 +0 -0
- package/dist/src/web/vendor/geist-1.7.2/GeistMono-Variable.woff2 +0 -0
- package/dist/src/web/vendor/geist-1.7.2/LICENSE.txt +92 -0
- package/dist/src/web/vendor/lucide-1.56.0/LICENSE.txt +43 -0
- package/dist/src/web/vendor/lucide-1.56.0/chart-column.mjs +29 -0
- package/dist/src/web/vendor/lucide-1.56.0/layout-dashboard.mjs +29 -0
- package/dist/src/web/vendor/lucide-1.56.0/logs.mjs +34 -0
- package/dist/src/web/vendor/lucide-1.56.0/menu.mjs +28 -0
- package/dist/src/web/vendor/lucide-1.56.0/square-terminal.mjs +28 -0
- package/dist/src/web/vendor/lucide-1.56.0/table.mjs +29 -0
- package/dist/src/web/vendor/lucide-1.56.0/users.mjs +29 -0
- package/dist/src/web/vendor/lucide-1.56.0/x.mjs +27 -0
- package/dist/src/web/vendor/uplot-1.6.32/LICENSE.txt +21 -0
- package/dist/src/web/vendor/uplot-1.6.32/uPlot.esm.js +6140 -0
- package/dist/src/web/vendor/uplot-1.6.32/uPlot.min.css +1 -0
- package/dist/src/web/vendor/zilla-slab-5.3.0/LICENSE.txt +93 -0
- package/dist/src/web/vendor/zilla-slab-5.3.0/zilla-slab-latin-700-normal.woff2 +0 -0
- package/package.json +12 -4
package/dist/src/cli/registry.js
CHANGED
|
@@ -3,19 +3,29 @@
|
|
|
3
3
|
* command's summary, in this order — so a command cannot exist without being listed, and tests/cli-help.test.ts holds
|
|
4
4
|
* each one to src/cli/command.ts's rules (its own --help, an example, every option documented).
|
|
5
5
|
*/
|
|
6
|
-
import { failed, parseCommand, reportText } from "./command.js";
|
|
6
|
+
import { failed, parseCommand, reportText, wantsJson } from "./command.js";
|
|
7
|
+
import { removedStartFlags } from "../lib/table-sync.js";
|
|
8
|
+
import { sourcesTop } from "./sources.js";
|
|
7
9
|
import { dev } from "./dev.js";
|
|
8
10
|
import { devInBackground } from "./background.js";
|
|
9
11
|
import { ADD, LOGS, REMOVE, STATUS, STOP, TABLES, WAIT, add, logs, remove, status, stop, tables, wait } from "./commands.js";
|
|
10
12
|
import { USER, user } from "./user.js";
|
|
11
13
|
import { MCP, mcp } from "./mcp.js";
|
|
14
|
+
import { SHARE, share } from "./share.js";
|
|
15
|
+
import { DEFAULT_UI_PORT } from "./ports.js";
|
|
12
16
|
import { UI, ui } from "./ui.js";
|
|
13
17
|
import { GUIDES, guideText } from "./guides.js";
|
|
14
18
|
import { DOCTOR, NODE_MIN, doctor } from "./doctor.js";
|
|
15
19
|
import { DESTROY, destroy } from "./machine.js";
|
|
16
20
|
import { INIT, init } from "./init.js";
|
|
17
21
|
import { SYNC, sync } from "./sync.js";
|
|
22
|
+
import { USAGE, usage } from "./usage.js";
|
|
23
|
+
import { CANCEL, cancel } from "./cancel.js";
|
|
18
24
|
import { SERVE, serve } from "./serve.js";
|
|
25
|
+
import { LOGIN, LOGOUT, login, logout } from "./login.js";
|
|
26
|
+
import { DEPLOY, deploy } from "./deploy.js";
|
|
27
|
+
import { REPLICA, replica } from "./replica-hosted.js";
|
|
28
|
+
import { TOKEN, token } from "./token-hosted.js";
|
|
19
29
|
import { PROJECT_LINE } from "./dev.js";
|
|
20
30
|
import { version } from "./version.js";
|
|
21
31
|
import { didYouMean } from "../lib/did-you-mean.js";
|
|
@@ -27,21 +37,31 @@ export const DEV = {
|
|
|
27
37
|
needs: "project",
|
|
28
38
|
name: "start",
|
|
29
39
|
summary: "start Mason for this folder's project, in the background (mason init makes the project)",
|
|
30
|
-
usage: `usage: mason start [--attach] [--
|
|
40
|
+
usage: `usage: mason start [--attach] [--self-signed-tls] [--port <n>] [--json]
|
|
31
41
|
|
|
32
|
-
Starts Mason for the project of this folder (mason init made it): one process, which
|
|
33
|
-
(mason add) from the project's database into its own file, keeps them current, and answers
|
|
34
|
-
for BI tools and your app. It only reads the database (SELECT
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
Starts Mason for the project of this folder (mason init made it): one process, which syncs the tables you add
|
|
43
|
+
(mason add) from the project's database into its own file, keeps them current as the sources file says, and answers
|
|
44
|
+
the Postgres protocol for BI tools and your app. It only reads the database (SELECT, and a table's change log when
|
|
45
|
+
its sync: says replication). It returns once Mason is up; run it again any time (it says so when Mason is
|
|
46
|
+
already running). The synced data and Mason's state stay between runs: the next start resumes.
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
After its first sync, each table is kept current as the sources file's sync: says — at the top for every table, or
|
|
49
|
+
on a table's entry: off (the default, which mason init writes) reads it again only when you run mason sync <table>;
|
|
50
|
+
poll <interval> (poll 5s, poll 5m, poll 1h) polls it with SELECTs at that interval; replication reads its changes
|
|
51
|
+
from the database's change log, as they are made. Each poll scans its table whole
|
|
52
|
+
on your database, and the next waits at least four times as long as that poll took, so the polls never take more
|
|
53
|
+
than a fifth of your database's time. The start says the file's default once; mason status says how each table is
|
|
54
|
+
kept current and when it was last synced. A table whose sync: changed keeps its synced data and is caught up by one poll.
|
|
55
|
+
|
|
56
|
+
A table under sync: replication needs wal_level = logical, a user that may replicate, and a primary key (a key:
|
|
57
|
+
table is polled): Mason makes one replication slot for the project and its own publication, carrying the replicated
|
|
58
|
+
tables alone, and drops them, verified gone, when no table's sync is replication any more (and at mason destroy).
|
|
59
|
+
publication: <name> at the top of the sources file (\${PG_PUBLICATION} reads it from .env) names a publication that
|
|
60
|
+
is the database owner's: it is read as it is, verified to carry every replicated table and column, and never
|
|
61
|
+
created, altered or dropped — Mason makes only its slot. A read replica needs one (it takes no CREATE PUBLICATION).
|
|
62
|
+
|
|
63
|
+
--replication, --poll and --publication are gone: each answers with the line to write at the top of the sources
|
|
64
|
+
file (sync: replication, sync: poll 5m, publication: <name>) and exit 2, and starts nothing.
|
|
45
65
|
|
|
46
66
|
The Postgres API's port is the project's: the first start takes 5433, or the next port free on every address when a
|
|
47
67
|
second Postgres holds it, and records it; every later start listens on the same port, so a BI tool's saved connection
|
|
@@ -53,53 +73,56 @@ export const DEV = {
|
|
|
53
73
|
MASON_PG_TLS_KEY (PEM files), or --self-signed-tls, which makes a certificate for the project in .mason/ and serves
|
|
54
74
|
it again at every later start with the flag. Every client then connects with sslmode=require. A team whose own proxy
|
|
55
75
|
or load balancer terminates TLS keeps it on 127.0.0.1, or sets MASON_PG_PLAIN=1 for a private network.
|
|
76
|
+
Behind a TCP proxy that sends the PROXY protocol v2, MASON_PG_PROXY_FROM=<cidr>[,<cidr>…] names the proxy's own
|
|
77
|
+
addresses: a connection from one must begin with the header, whose client the request log names, and a header from
|
|
78
|
+
any other address is refused.
|
|
56
79
|
|
|
57
80
|
${PROJECT_LINE}
|
|
58
81
|
|
|
59
82
|
mason start
|
|
60
83
|
mason start --attach in the foreground: Ctrl-C stops it
|
|
61
|
-
mason start --replication read the change log, as production does
|
|
62
|
-
mason start --replication --publication app_pub through the database owner's publication
|
|
63
84
|
MASON_PG_HOST=0.0.0.0 mason start --self-signed-tls the Postgres API for other machines, over TLS
|
|
64
85
|
|
|
65
86
|
--attach stay in the foreground (Ctrl-C stops Mason)
|
|
66
|
-
--replication read the database's changes from its change log (logical replication), as production does
|
|
67
|
-
--publication <name> with --replication: the publication to read, the owner's, never altered (PG_PUBLICATION;
|
|
68
|
-
default: Mason's own, mason_dev_<project>_<source>)
|
|
69
|
-
--poll read them with SELECTs (the default; takes back --replication)
|
|
70
87
|
--self-signed-tls the Postgres API requires TLS, from a certificate made for this project in .mason/ (kept and
|
|
71
88
|
served again by every later start with the flag); not with MASON_PG_TLS_CERT / _KEY
|
|
72
|
-
--port <n> the port the mason commands reach it on (default
|
|
89
|
+
--port <n> the port the mason commands reach it on (default ${DEFAULT_UI_PORT}, or the next free one)
|
|
73
90
|
--json as data, once it is up: { running, pid, postgres: { url, host, port, database, sslmode }, next }
|
|
74
91
|
`,
|
|
75
92
|
options: {
|
|
76
93
|
port: { type: "string" }, attach: { type: "boolean", default: false }, json: { type: "boolean", default: false },
|
|
77
|
-
replication: { type: "boolean", default: false }, poll: { type: "boolean", default: false }, publication: { type: "string" },
|
|
78
94
|
"self-signed-tls": { type: "boolean", default: false },
|
|
79
95
|
},
|
|
80
96
|
json: ["running", "pid", "postgres", "next"],
|
|
81
97
|
};
|
|
82
98
|
async function runDev(argv) {
|
|
99
|
+
// --replication, --poll and --publication are gone (issue 33): each answered with the edit to make in the sources
|
|
100
|
+
// file, exit 2, before the options are parsed (it would be an unknown option there) and before anything starts. The
|
|
101
|
+
// file is read only when one is given. A decision: `mason start --replication --help` answers the refusal, not the
|
|
102
|
+
// usage — the flag is wrong whatever else the line asks
|
|
103
|
+
const removed = removedStartFlags(argv, () => startSourcesTop(process.cwd()));
|
|
104
|
+
if (removed !== null)
|
|
105
|
+
return failed("start", { code: "usage", ...removed, next: [["mason start", "each table kept current as its sync: says"], ["mason help production", "sync: and publication:, and what each needs"]] }, { json: wantsJson(argv, DEV) });
|
|
83
106
|
const f = parseCommand(DEV, argv);
|
|
84
107
|
if (typeof f === "number")
|
|
85
108
|
return f;
|
|
86
109
|
const v = f.values;
|
|
87
|
-
if (v.replication && v.poll)
|
|
88
|
-
return failed("start", { message: "--replication or --poll, not both", code: "usage", usage: DEV.usage }, { json: v.json });
|
|
89
|
-
if (v.publication !== undefined && v.poll)
|
|
90
|
-
return failed("start", { message: "--publication goes with --replication, not --poll", code: "usage", usage: DEV.usage }, { json: v.json });
|
|
91
|
-
if (v.publication !== undefined && !/^\S+$/.test(v.publication))
|
|
92
|
-
return failed("start", { message: `--publication must name a publication, not ${JSON.stringify(v.publication)}`, code: "usage", usage: DEV.usage }, { json: v.json });
|
|
93
110
|
if (f.positionals.length) {
|
|
94
111
|
// the database is the project's now: a URL here is the old habit, answered with the new way
|
|
95
112
|
return failed("start", { message: "it takes no database URL: the project has one", code: "usage", why: "mason init <url> made it; .mason/config.json holds it", usage: DEV.usage }, { json: v.json });
|
|
96
113
|
}
|
|
97
|
-
const port = v.port === undefined ?
|
|
114
|
+
const port = v.port === undefined ? DEFAULT_UI_PORT : Number(v.port);
|
|
98
115
|
if (!Number.isInteger(port) || port < 1 || port > 65_535)
|
|
99
116
|
return failed("start", { message: `--port must be a port number (1-65535), not ${JSON.stringify(v.port)}`, code: "usage" }, { json: v.json });
|
|
100
117
|
if (!v.attach)
|
|
101
|
-
return devInBackground(argv, { json: v.json, selfSignedTls: v["self-signed-tls"]
|
|
102
|
-
return dev({ port, version: version(),
|
|
118
|
+
return devInBackground(argv, { json: v.json, selfSignedTls: v["self-signed-tls"] });
|
|
119
|
+
return dev({ port, version: version(), selfSignedTls: v["self-signed-tls"] });
|
|
120
|
+
}
|
|
121
|
+
/** The project's sources file as a person names it (`mason/sources/app.yml`), for a removed flag's answer: the one file
|
|
122
|
+
* of the project of this folder, else the name every project's has. */
|
|
123
|
+
function startSourcesTop(cwd) {
|
|
124
|
+
const t = theProject(cwd);
|
|
125
|
+
return "problem" in t ? { shown: "mason/sources/<name>.yml", sync: null, publication: null } : sourcesTop(t.project.root, t.project.folder);
|
|
103
126
|
}
|
|
104
127
|
export const HELP = {
|
|
105
128
|
name: "help",
|
|
@@ -152,9 +175,9 @@ export const STEPS = [
|
|
|
152
175
|
["Learn", [{ ...HELP, run: runHelp }]],
|
|
153
176
|
["Set up", [{ ...DOCTOR, run: (argv) => doctor(argv) }, { ...INIT, run: (argv) => init(argv) }, { ...DEV, run: runDev }]],
|
|
154
177
|
["Add your tables", [{ ...TABLES, run: tables }, { ...ADD, run: add }, { ...REMOVE, run: remove }, { ...WAIT, run: wait }]],
|
|
155
|
-
["Connect", [{ ...USER, run: user }, { ...MCP, run: mcp }]],
|
|
156
|
-
["Run", [{ ...STATUS, run: status }, { ...UI, run: ui }, { ...SYNC, run: sync }, { ...LOGS, run: logs }, { ...STOP, run: stop }, { ...DESTROY, run: (argv) => destroy(argv) }]],
|
|
157
|
-
["Go to production", [{ ...SERVE, run: serve }]],
|
|
178
|
+
["Connect", [{ ...USER, run: user }, { ...MCP, run: mcp }, { ...SHARE, run: share }]],
|
|
179
|
+
["Run", [{ ...STATUS, run: status }, { ...UI, run: ui }, { ...SYNC, run: sync }, { ...LOGS, run: logs }, { ...CANCEL, run: cancel }, { ...USAGE, run: (argv) => usage(argv) }, { ...STOP, run: stop }, { ...DESTROY, run: (argv) => destroy(argv) }]],
|
|
180
|
+
["Go to production", [{ ...SERVE, run: serve }, { ...LOGIN, run: login }, { ...LOGOUT, run: logout }, { ...REPLICA, run: replica }, { ...TOKEN, run: token }, { ...DEPLOY, run: deploy }]],
|
|
158
181
|
];
|
|
159
182
|
/** Every command, in the order `mason --help` lists them. */
|
|
160
183
|
export const COMMANDS = STEPS.flatMap(([, commands]) => commands);
|
|
@@ -164,6 +187,9 @@ export const COMMANDS = STEPS.flatMap(([, commands]) => commands);
|
|
|
164
187
|
* it, then the next command for that moment — and mason help, every command. `mason help` and `mason --help` are the
|
|
165
188
|
* whole list (topUsage).
|
|
166
189
|
*/
|
|
190
|
+
/** WHAT MASON IS, in one line: the first `mason` alone and `mason --help` print, in the words its reader was told it
|
|
191
|
+
* in ("a drop-in read replica for analytics"). */
|
|
192
|
+
export const TAGLINE = "Mason: a drop-in read replica of your Postgres, for analytics — the tables you add, synced, kept current and served to psql, BI tools and your app.";
|
|
167
193
|
export async function orientation(cwd, s = styleOut()) {
|
|
168
194
|
const t = theProject(cwd);
|
|
169
195
|
const project = "project" in t ? t.project : null;
|
|
@@ -172,12 +198,12 @@ export async function orientation(cwd, s = styleOut()) {
|
|
|
172
198
|
? [["Project", `${project.config.name}, files in ${project.folder}`], ["Mason", run ? `running (pid ${run.pid})` : "not running"]]
|
|
173
199
|
: [["Project", "none here: mason init makes this folder one"]];
|
|
174
200
|
const next = !project
|
|
175
|
-
? [["mason init", "make this folder a project (DATABASE_URL from .env, or mason init postgres://…)"],
|
|
201
|
+
? [["mason init", "make this folder a project (MASON_DATABASE_URL or DATABASE_URL from .env, or mason init postgres://…)"],
|
|
176
202
|
["mason init demo", "or try it on a demo database Mason makes itself: nothing to install"],
|
|
177
203
|
["mason doctor", "what this machine needs for Mason, and whether it has it"]]
|
|
178
204
|
: !run ? [["mason start", "start Mason for this project, in the background"], ["mason status", "the project and its tables"]]
|
|
179
205
|
: [["mason status", "what Mason is doing: its tables, and the last day's slow and refused statements"], ["mason user add <name>", "a user for a BI tool or your app: its password and URL, printed once"]];
|
|
180
|
-
return `${reportText({ headline:
|
|
206
|
+
return `${reportText({ headline: TAGLINE, details: rows,
|
|
181
207
|
next: [...next, ["mason help", "every command, and the guides"]] }, s)}\n`;
|
|
182
208
|
}
|
|
183
209
|
/** `mason --help`: what Mason is, every command with its summary, and where each one's help is. On a terminal the steps are
|
|
@@ -204,8 +230,9 @@ export function topUsage(s = styleOut()) {
|
|
|
204
230
|
return [
|
|
205
231
|
`${s.bold("usage:")} mason <command> [options]`,
|
|
206
232
|
"",
|
|
207
|
-
para(
|
|
233
|
+
para(`${TAGLINE} Make your app's folder a project (mason init), ` +
|
|
208
234
|
`add tables (mason add, before or after the start), start Mason (mason start), connect a tool (mason user add). It needs Node ${NODE_MIN} or later; mason doctor checks.`),
|
|
235
|
+
para("Try it first with nothing to install: mason init demo, then mason start and mason ui (a demo shop database, hosted by Mason itself)."),
|
|
209
236
|
para(PROJECT_LINE),
|
|
210
237
|
"",
|
|
211
238
|
listed.map(([step, es]) => ` ${s.bold(step)}\n${block(es)}`).join("\n\n"),
|
|
@@ -214,7 +241,7 @@ export function topUsage(s = styleOut()) {
|
|
|
214
241
|
para("A command means the project of the folder it runs in (or above it)."),
|
|
215
242
|
para("Every command but help and mcp (whose stdout is the MCP protocol's) takes --json: one JSON object for a program, always with next (what to run " +
|
|
216
243
|
"next); a failure is { error: { code, message, why, fix }, next }. The exit code says how it went: 0 done, 1 failed " +
|
|
217
|
-
"with the reason, 2 a wrong command line, 124
|
|
244
|
+
"with the reason, 2 a wrong command line, 124 a wait timed out (mason wait, mason deploy, mason replica create). Driving Mason from a coding agent: mason help agent."),
|
|
218
245
|
"",
|
|
219
246
|
].join("\n");
|
|
220
247
|
}
|