moshcode 0.24.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/LICENSE +21 -0
- package/README.md +580 -0
- package/bin/moshcode.mjs +674 -0
- package/bin/moshscript.mjs +29 -0
- package/examples/alive.mosh +6 -0
- package/examples/scripting-the-cli.mosh +21 -0
- package/examples/team-secrets.mosh +20 -0
- package/examples/templates/bun-caddy-sqlite/.env.example +14 -0
- package/examples/templates/bun-caddy-sqlite/Caddyfile +18 -0
- package/examples/templates/bun-caddy-sqlite/README.md +97 -0
- package/examples/templates/bun-caddy-sqlite/deploy/moshcode-dns.service +39 -0
- package/examples/templates/bun-caddy-sqlite/deploy/moshpit-service.service +38 -0
- package/examples/templates/bun-caddy-sqlite/package.json +15 -0
- package/examples/templates/bun-caddy-sqlite/src/db.ts +47 -0
- package/examples/templates/bun-caddy-sqlite/src/server.ts +44 -0
- package/examples/templates/bun-caddy-sqlite/template.json +10 -0
- package/examples/templates/caddy-proxy/Caddyfile +36 -0
- package/examples/templates/caddy-proxy/README.md +104 -0
- package/examples/templates/caddy-proxy/deploy/moshcode-dns.service +39 -0
- package/examples/templates/caddy-proxy/template.json +8 -0
- package/examples/templates/caddy-static/Caddyfile +16 -0
- package/examples/templates/caddy-static/README.md +90 -0
- package/examples/templates/caddy-static/deploy/moshcode-dns.service +39 -0
- package/examples/templates/caddy-static/site/index.html +11 -0
- package/examples/templates/caddy-static/template.json +8 -0
- package/install.sh +194 -0
- package/package.json +28 -0
- package/prd/0000-template.md +49 -0
- package/prd/0001-wrap-ugig-and-coinpay-clis.md +121 -0
- package/prd/0002-separate-agent-and-raw-engine-launches.md +113 -0
- package/prd/0003-cross-engine-mcp-and-skill-installation.md +165 -0
- package/prd/0004-moshscript-run-programmable-moshcode.md +344 -0
- package/prd/0005-hosted-moshpit-resolver.md +192 -0
- package/prd/0006-help.md +359 -0
- package/prd/0007-profullstack-site-init.md +1183 -0
- package/prd/README.md +26 -0
- package/src/ads.mjs +58 -0
- package/src/auth.mjs +193 -0
- package/src/cli-schema.mjs +533 -0
- package/src/cli.mjs +118 -0
- package/src/commands.mjs +259 -0
- package/src/completion.mjs +594 -0
- package/src/console.mjs +244 -0
- package/src/dns-system.mjs +404 -0
- package/src/dns.mjs +2872 -0
- package/src/doh-server.mjs +256 -0
- package/src/doh.mjs +218 -0
- package/src/engines.mjs +385 -0
- package/src/escalate.mjs +85 -0
- package/src/help.mjs +443 -0
- package/src/integrations.mjs +265 -0
- package/src/mcp-catalog.mjs +50 -0
- package/src/mcp.mjs +155 -0
- package/src/mirror.mjs +187 -0
- package/src/notify.mjs +86 -0
- package/src/open-url.mjs +34 -0
- package/src/parking-http.mjs +65 -0
- package/src/pins.mjs +190 -0
- package/src/pit-url.mjs +13 -0
- package/src/prd.mjs +341 -0
- package/src/pty.mjs +176 -0
- package/src/pwd.mjs +103 -0
- package/src/registry.mjs +37 -0
- package/src/release-install.mjs +191 -0
- package/src/runtime.mjs +161 -0
- package/src/selfupdate.mjs +215 -0
- package/src/serve.mjs +502 -0
- package/src/skills.mjs +93 -0
- package/src/tabs.mjs +144 -0
- package/src/templates.mjs +456 -0
- package/src/tools.mjs +231 -0
- package/src/trade.mjs +137 -0
- package/src/trust.mjs +712 -0
- package/src/tui.mjs +736 -0
- package/src/ui.mjs +49 -0
- package/src/uninstall.mjs +113 -0
- package/src/upgrade.mjs +217 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
// The command table, and everything help needs to describe it.
|
|
2
|
+
//
|
|
3
|
+
// One table, three consumers: the dispatcher in bin/moshcode.mjs, shell
|
|
4
|
+
// completion (src/completion.mjs), and help (src/help.mjs). Help used to be an
|
|
5
|
+
// 87-line template literal that re-typed all of this by hand, which is why
|
|
6
|
+
// `dns` and `version` were dispatchable, completable, and absent from `moshcode
|
|
7
|
+
// help` at the same time (PRD 0006).
|
|
8
|
+
//
|
|
9
|
+
// `description` stays the one-line summary completion already renders. The rest
|
|
10
|
+
// — synopsis, flags, examples — exists so per-command help can be rendered
|
|
11
|
+
// rather than written. A flag that is parsed but not listed here is a flag
|
|
12
|
+
// nobody can discover, so test/help.test.mjs greps the parsers and fails when
|
|
13
|
+
// the two disagree.
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Groups for the one-screen overview.
|
|
17
|
+
*
|
|
18
|
+
* The top-level help is a menu, not an index: 30-odd verbs in one flat list is
|
|
19
|
+
* the wall this replaces. Order is the order they appear.
|
|
20
|
+
*/
|
|
21
|
+
export const COMMAND_GROUPS = [
|
|
22
|
+
{ key: "engines", title: "engines" },
|
|
23
|
+
{ key: "tools", title: "tools" },
|
|
24
|
+
{ key: "extend", title: "extend" },
|
|
25
|
+
{ key: "script", title: "script" },
|
|
26
|
+
{ key: "account", title: "account" },
|
|
27
|
+
{ key: "hosting", title: "hosting" },
|
|
28
|
+
{ key: "system", title: "system" },
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
export const CORE_CLI_COMMANDS = [
|
|
32
|
+
{
|
|
33
|
+
name: "agents",
|
|
34
|
+
group: "engines",
|
|
35
|
+
description: "list engines or launch one autonomously",
|
|
36
|
+
synopsis: [
|
|
37
|
+
["moshcode agents", "list engines and their install status"],
|
|
38
|
+
["moshcode agents --json", "list engine status as machine-readable JSON"],
|
|
39
|
+
["moshcode agents <engine> [args…]", "open the engine's agent view, or start it autonomously"],
|
|
40
|
+
],
|
|
41
|
+
flags: [
|
|
42
|
+
["--json", "print engine status as JSON", ""],
|
|
43
|
+
],
|
|
44
|
+
examples: [
|
|
45
|
+
["moshcode agents", "which engines are here"],
|
|
46
|
+
["moshcode agents --json", "pipe engine status into a script"],
|
|
47
|
+
["moshcode agents claude", "claude's agent list"],
|
|
48
|
+
],
|
|
49
|
+
seeAlso: ["start", "engines", "install"],
|
|
50
|
+
note: "autonomous modes bypass approval prompts — use them in a container or a workspace you trust.",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "start",
|
|
54
|
+
group: "engines",
|
|
55
|
+
description: "launch an engine with its native defaults",
|
|
56
|
+
synopsis: [["moshcode start <engine> [args…]", "no bypass flags, no agent view"]],
|
|
57
|
+
examples: [["moshcode start opencode", ""]],
|
|
58
|
+
seeAlso: ["agents", "engines"],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "install",
|
|
62
|
+
group: "engines",
|
|
63
|
+
description: "install an engine or workflow tool",
|
|
64
|
+
synopsis: [["moshcode install <engine|tool>", ""]],
|
|
65
|
+
examples: [
|
|
66
|
+
["moshcode install claude", "an engine"],
|
|
67
|
+
["moshcode install gh", "a workflow tool"],
|
|
68
|
+
],
|
|
69
|
+
seeAlso: ["uninstall", "upgrade", "engines", "tools"],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "uninstall",
|
|
73
|
+
group: "engines",
|
|
74
|
+
description: "take an engine or workflow tool off this machine",
|
|
75
|
+
synopsis: [["moshcode uninstall <engine|tool> [--yes] [--dry-run]", ""]],
|
|
76
|
+
flags: [
|
|
77
|
+
["-y, --yes", "actually delete a binary this did not install", ""],
|
|
78
|
+
["--dry-run", "print the plan and stop", ""],
|
|
79
|
+
],
|
|
80
|
+
examples: [
|
|
81
|
+
["moshcode uninstall codex --dry-run", "what would happen"],
|
|
82
|
+
["moshcode uninstall codex --yes", "do it"],
|
|
83
|
+
],
|
|
84
|
+
seeAlso: ["install"],
|
|
85
|
+
note: "removing a plain binary needs --yes; a package-manager uninstall does not.",
|
|
86
|
+
},
|
|
87
|
+
{ name: "remove", aliasOf: "uninstall", description: "alias for uninstall" },
|
|
88
|
+
{
|
|
89
|
+
name: "upgrade",
|
|
90
|
+
group: "engines",
|
|
91
|
+
description: "update moshcode, engines, or tools",
|
|
92
|
+
synopsis: [
|
|
93
|
+
["moshcode upgrade [target…]", "default: everything installed"],
|
|
94
|
+
["moshcode upgrade --check", "report what is stale and exit"],
|
|
95
|
+
],
|
|
96
|
+
flags: [
|
|
97
|
+
["--check", "report available updates without installing", ""],
|
|
98
|
+
["--if-newer", "install only when the remote is newer", ""],
|
|
99
|
+
["--timer <interval>", "install a scheduled self-update", ""],
|
|
100
|
+
],
|
|
101
|
+
verbs: "UPGRADE_TARGETS",
|
|
102
|
+
examples: [
|
|
103
|
+
["moshcode upgrade", "moshcode + engines + tools"],
|
|
104
|
+
["moshcode upgrade engines", "just the engines"],
|
|
105
|
+
],
|
|
106
|
+
seeAlso: ["install", "version"],
|
|
107
|
+
},
|
|
108
|
+
{ name: "update", aliasOf: "upgrade", description: "alias for upgrade" },
|
|
109
|
+
{
|
|
110
|
+
name: "mcp",
|
|
111
|
+
group: "extend",
|
|
112
|
+
description: "register and inspect MCP servers",
|
|
113
|
+
synopsis: [["moshcode mcp <verb> [args…]", ""]],
|
|
114
|
+
verbs: "MCP_VERBS",
|
|
115
|
+
examples: [
|
|
116
|
+
["moshcode mcp list --json", "support and install status"],
|
|
117
|
+
["moshcode mcp install https://mcp.example.com", "a remote server"],
|
|
118
|
+
],
|
|
119
|
+
seeAlso: ["skill", "engines"],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "skill",
|
|
123
|
+
group: "extend",
|
|
124
|
+
description: "install and inspect agent skills",
|
|
125
|
+
synopsis: [["moshcode skill <verb> [args…]", ""]],
|
|
126
|
+
verbs: "SKILL_VERBS",
|
|
127
|
+
examples: [["moshcode skill list", ""]],
|
|
128
|
+
seeAlso: ["mcp"],
|
|
129
|
+
},
|
|
130
|
+
{ name: "skills", aliasOf: "skill", description: "alias for skill" },
|
|
131
|
+
{
|
|
132
|
+
name: "prd",
|
|
133
|
+
group: "script",
|
|
134
|
+
description: "publish or list product requirement documents",
|
|
135
|
+
synopsis: [
|
|
136
|
+
["moshcode prd", "list the PRDs in this repo"],
|
|
137
|
+
["moshcode prd list [--json]", "the same, explicitly"],
|
|
138
|
+
["moshcode prd <idea…>", "publish prd/NNNN-slug.md (Draft) and hand it to an engine"],
|
|
139
|
+
],
|
|
140
|
+
flags: [["--json", "machine-readable listing", ""]],
|
|
141
|
+
examples: [
|
|
142
|
+
["moshcode prd", "the index"],
|
|
143
|
+
['moshcode prd "a --help that works"', "publish + author"],
|
|
144
|
+
],
|
|
145
|
+
seeAlso: ["run", "commands"],
|
|
146
|
+
note: "publishing writes a file and commits it. `moshcode prd --help` does neither.",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "login",
|
|
150
|
+
group: "account",
|
|
151
|
+
description: "authenticate with app.moshcode.sh",
|
|
152
|
+
synopsis: [["moshcode login [--device] [--browser]", ""]],
|
|
153
|
+
flags: [
|
|
154
|
+
["-d, --device", "device-code flow", "default when stdin is not a TTY"],
|
|
155
|
+
["-b, --browser", "force the browser flow", ""],
|
|
156
|
+
],
|
|
157
|
+
examples: [["moshcode login --device", "on a headless box"]],
|
|
158
|
+
seeAlso: ["whoami", "logout", "console"],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "whoami",
|
|
162
|
+
group: "account",
|
|
163
|
+
description: "show the logged-in account",
|
|
164
|
+
synopsis: [["moshcode whoami", ""]],
|
|
165
|
+
seeAlso: ["login", "logout"],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: "logout",
|
|
169
|
+
group: "account",
|
|
170
|
+
description: "clear the logged-in account",
|
|
171
|
+
synopsis: [["moshcode logout", ""]],
|
|
172
|
+
seeAlso: ["login"],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "console",
|
|
176
|
+
group: "account",
|
|
177
|
+
description: "serve or connect to the browser terminal",
|
|
178
|
+
synopsis: [["moshcode console [--port N] [--bind addr] [--ttyd host:port] [--url u]", ""]],
|
|
179
|
+
flags: [
|
|
180
|
+
["--port <n>", "port to serve on", ""],
|
|
181
|
+
["--bind <addr>", "interface to bind", ""],
|
|
182
|
+
["--ttyd <host:port>", "front an existing ttyd", ""],
|
|
183
|
+
["--url <url>", "connect to a console already running", ""],
|
|
184
|
+
],
|
|
185
|
+
examples: [["moshcode console --port 7681", ""]],
|
|
186
|
+
seeAlso: ["login"],
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "dns",
|
|
190
|
+
group: "hosting",
|
|
191
|
+
description: "resolve Moshpit names on this machine",
|
|
192
|
+
synopsis: [["moshcode dns <verb> [args…]", ""]],
|
|
193
|
+
verbs: "DNS_VERBS",
|
|
194
|
+
flags: [
|
|
195
|
+
["--port <n>", "port for the bridge", "5354"],
|
|
196
|
+
["--registry <url>", "registry to resolve against", "https://pit.moshcode.sh"],
|
|
197
|
+
["--no-trust", "with enable: route names but skip the local CA", ""],
|
|
198
|
+
],
|
|
199
|
+
examples: [
|
|
200
|
+
["sudo moshcode dns enable", "route Moshpit endings here"],
|
|
201
|
+
["moshcode dns resolve blue.eggs", "what a machine actually gets"],
|
|
202
|
+
],
|
|
203
|
+
seeAlso: ["doh", "site"],
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: "doh",
|
|
207
|
+
group: "hosting",
|
|
208
|
+
description: "run the DNS-over-HTTPS resolver",
|
|
209
|
+
synopsis: [
|
|
210
|
+
["moshcode doh [--port N]", "serve DoH"],
|
|
211
|
+
["moshcode doh --nginx <name> [--tls]", "print an nginx site and exit"],
|
|
212
|
+
],
|
|
213
|
+
flags: [
|
|
214
|
+
["--port <n>", "port to listen on", ""],
|
|
215
|
+
["--nginx <name>", "emit an nginx server block instead of serving", ""],
|
|
216
|
+
["--tls", "include TLS directives in the emitted block", ""],
|
|
217
|
+
["--no-guards", "disable rate limiting and bans", "guards on"],
|
|
218
|
+
],
|
|
219
|
+
examples: [["moshcode doh --nginx dns.example", ""]],
|
|
220
|
+
seeAlso: ["dns"],
|
|
221
|
+
note: "has no TLS of its own and trusts X-Forwarded-For — never expose it directly.",
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
name: "site",
|
|
225
|
+
group: "hosting",
|
|
226
|
+
description: "install web-server config for a Moshpit name",
|
|
227
|
+
synopsis: [["moshcode site <name> [args…]", ""]],
|
|
228
|
+
examples: [["moshcode site blue.eggs", ""]],
|
|
229
|
+
seeAlso: ["template", "dns"],
|
|
230
|
+
},
|
|
231
|
+
{ name: "serve", aliasOf: "site", description: "alias for site" },
|
|
232
|
+
{
|
|
233
|
+
name: "template",
|
|
234
|
+
group: "hosting",
|
|
235
|
+
description: "scaffold a stack for a Moshpit-hosted service",
|
|
236
|
+
synopsis: [
|
|
237
|
+
["moshcode template list [--json]", "what there is"],
|
|
238
|
+
["moshcode template install <name>", "write it here"],
|
|
239
|
+
],
|
|
240
|
+
flags: [
|
|
241
|
+
["--into <dir>", "write somewhere other than the current directory", ""],
|
|
242
|
+
["--force", "overwrite files that are already there", ""],
|
|
243
|
+
["--dry-run", "show changes without writing anything", ""],
|
|
244
|
+
["--json", "machine-readable template list", ""],
|
|
245
|
+
],
|
|
246
|
+
examples: [["moshcode template install bun-caddy-sqlite", ""]],
|
|
247
|
+
seeAlso: ["site"],
|
|
248
|
+
},
|
|
249
|
+
{ name: "templates", aliasOf: "template", description: "alias for template" },
|
|
250
|
+
{
|
|
251
|
+
name: "pwd",
|
|
252
|
+
group: "system",
|
|
253
|
+
description: "show the current directory and git context",
|
|
254
|
+
synopsis: [["moshcode pwd [--json]", ""]],
|
|
255
|
+
flags: [["--json", "machine-readable", ""]],
|
|
256
|
+
seeAlso: ["commands"],
|
|
257
|
+
},
|
|
258
|
+
{ name: "where", aliasOf: "pwd", description: "alias for pwd" },
|
|
259
|
+
{
|
|
260
|
+
name: "engines",
|
|
261
|
+
group: "engines",
|
|
262
|
+
description: "list engines and installation status",
|
|
263
|
+
synopsis: [["moshcode engines [--json]", ""]],
|
|
264
|
+
flags: [["--json", "machine-readable", ""]],
|
|
265
|
+
seeAlso: ["agents", "install"],
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "tools",
|
|
269
|
+
group: "tools",
|
|
270
|
+
description: "list workflow tools and installation status",
|
|
271
|
+
synopsis: [["moshcode tools [--json]", ""]],
|
|
272
|
+
flags: [["--json", "machine-readable, and suppresses the trailing note", ""]],
|
|
273
|
+
seeAlso: ["install"],
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
name: "trade",
|
|
277
|
+
group: "tools",
|
|
278
|
+
description: "look up markets and trade through Alpaca",
|
|
279
|
+
synopsis: [["moshcode trade <verb> [args…]", "paper trading is Alpaca's default"]],
|
|
280
|
+
verbs: "TRADE_VERBS",
|
|
281
|
+
examples: [
|
|
282
|
+
["moshcode trade ticker AAPL", "asset lookup"],
|
|
283
|
+
["moshcode trade analysis AAPL", "quote/trade/bar snapshot"],
|
|
284
|
+
["moshcode trade buy AAPL 1", "preview a market order"],
|
|
285
|
+
["moshcode trade buy AAPL 1 --submit", "place it"],
|
|
286
|
+
],
|
|
287
|
+
seeAlso: ["tools", "install"],
|
|
288
|
+
note: "buy/sell inject --dry-run unless --submit is present. Alpaca defaults to paper trading; live trading requires its separate --live opt-in.",
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
name: "commands",
|
|
292
|
+
group: "script",
|
|
293
|
+
description: "list built-in moshscript commands",
|
|
294
|
+
synopsis: [["moshcode commands [--json]", ""]],
|
|
295
|
+
flags: [["--json", "machine-readable", ""]],
|
|
296
|
+
seeAlso: ["run", "prd"],
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: "completion",
|
|
300
|
+
group: "extend",
|
|
301
|
+
description: "print a shell completion script",
|
|
302
|
+
synopsis: [["moshcode completion <bash|zsh|fish|powershell>", ""]],
|
|
303
|
+
examples: [["moshcode completion zsh > ~/.moshcode-completion.zsh", ""]],
|
|
304
|
+
seeAlso: ["help"],
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: "run",
|
|
308
|
+
group: "script",
|
|
309
|
+
description: "run a moshscript",
|
|
310
|
+
synopsis: [
|
|
311
|
+
["moshcode run [flags] [file] [args…]", "no file → the bundled example"],
|
|
312
|
+
["moshcode run -", "read the script from stdin"],
|
|
313
|
+
],
|
|
314
|
+
flags: [
|
|
315
|
+
["-n, --max <n>", "loop ceiling", "3"],
|
|
316
|
+
["--dry-run", "parse and report without side effects", ""],
|
|
317
|
+
["--", "everything after this reaches the script as argv", ""],
|
|
318
|
+
],
|
|
319
|
+
examples: [
|
|
320
|
+
["moshcode run deploy.mosh", ""],
|
|
321
|
+
["moshcode run deploy.mosh -- --verbose", "--verbose goes to the script"],
|
|
322
|
+
],
|
|
323
|
+
seeAlso: ["commands", "prd"],
|
|
324
|
+
note: "--help before the file is the runner's; after it, it belongs to the script.",
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
name: "help",
|
|
328
|
+
group: "system",
|
|
329
|
+
description: "show command help",
|
|
330
|
+
synopsis: [
|
|
331
|
+
["moshcode help", "the one-screen overview"],
|
|
332
|
+
["moshcode help <command> [verb]", "drill into one"],
|
|
333
|
+
["moshcode help --all", "every command, in full"],
|
|
334
|
+
["moshcode help --json", "the machine-readable model"],
|
|
335
|
+
],
|
|
336
|
+
flags: [
|
|
337
|
+
["--all", "render every command instead of the overview", ""],
|
|
338
|
+
["--json", "emit the help model as JSON", ""],
|
|
339
|
+
["--markdown", "emit the command table for README.md", ""],
|
|
340
|
+
],
|
|
341
|
+
examples: [
|
|
342
|
+
["moshcode help mcp install", "a sub-verb"],
|
|
343
|
+
["moshcode help --json | jq '.commands[].name'", "for an agent"],
|
|
344
|
+
],
|
|
345
|
+
seeAlso: ["commands", "completion"],
|
|
346
|
+
},
|
|
347
|
+
{ name: "--help", aliasOf: "help", description: "show command help" },
|
|
348
|
+
{ name: "-h", aliasOf: "help", description: "show command help" },
|
|
349
|
+
{
|
|
350
|
+
name: "version",
|
|
351
|
+
group: "system",
|
|
352
|
+
description: "show the installed version",
|
|
353
|
+
synopsis: [["moshcode version", ""]],
|
|
354
|
+
seeAlso: ["upgrade"],
|
|
355
|
+
},
|
|
356
|
+
{ name: "--version", aliasOf: "version", description: "show the installed version" },
|
|
357
|
+
{ name: "-v", aliasOf: "version", description: "show the installed version" },
|
|
358
|
+
];
|
|
359
|
+
|
|
360
|
+
export const CORE_CLI_COMMAND_NAMES = CORE_CLI_COMMANDS.map(({ name }) => name);
|
|
361
|
+
|
|
362
|
+
export const MCP_VERBS = [
|
|
363
|
+
{
|
|
364
|
+
name: "install",
|
|
365
|
+
description: "register an MCP server across engines",
|
|
366
|
+
acceptsServerSpec: true,
|
|
367
|
+
synopsis: [
|
|
368
|
+
["moshcode mcp install <url>", "remote server (http/sse)"],
|
|
369
|
+
["moshcode mcp install --name <n> -- <cmd…>", "local stdio server"],
|
|
370
|
+
["moshcode mcp install <catalog-name>", "e.g. porkbun, sentry"],
|
|
371
|
+
],
|
|
372
|
+
flags: [
|
|
373
|
+
["--name <n>", "override the derived server name", ""],
|
|
374
|
+
["-t, --transport <t>", "http | sse | stdio", "inferred from the target"],
|
|
375
|
+
["-e, --env K=V", "repeatable", ""],
|
|
376
|
+
["-H, --header 'K: V'", "repeatable", ""],
|
|
377
|
+
["--", "everything after this is the server's argv", ""],
|
|
378
|
+
],
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
name: "add",
|
|
382
|
+
description: "register a named MCP server",
|
|
383
|
+
acceptsServerSpec: true,
|
|
384
|
+
synopsis: [["moshcode mcp add --name <n> <target>", ""]],
|
|
385
|
+
},
|
|
386
|
+
{ name: "catalog", description: "show known MCP servers", synopsis: [["moshcode mcp catalog", ""]] },
|
|
387
|
+
{
|
|
388
|
+
name: "list",
|
|
389
|
+
description: "show MCP support and install status",
|
|
390
|
+
synopsis: [["moshcode mcp list [--json]", ""]],
|
|
391
|
+
flags: [["--json", "machine-readable", ""]],
|
|
392
|
+
},
|
|
393
|
+
];
|
|
394
|
+
|
|
395
|
+
export const SKILL_VERBS = [
|
|
396
|
+
{
|
|
397
|
+
name: "install",
|
|
398
|
+
description: "install a skill across supported engines",
|
|
399
|
+
acceptsSource: true,
|
|
400
|
+
synopsis: [["moshcode skill install <source>", ""]],
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
name: "list",
|
|
404
|
+
description: "show skills support and install status",
|
|
405
|
+
synopsis: [["moshcode skill list [--json]", ""]],
|
|
406
|
+
flags: [["--json", "machine-readable", ""]],
|
|
407
|
+
},
|
|
408
|
+
];
|
|
409
|
+
|
|
410
|
+
export const UPGRADE_TARGETS = [
|
|
411
|
+
{ name: "all", description: "update moshcode and all installed integrations" },
|
|
412
|
+
{ name: "self", description: "update moshcode itself" },
|
|
413
|
+
{ name: "moshcode", description: "alias for self" },
|
|
414
|
+
{ name: "engines", description: "update all installed engines" },
|
|
415
|
+
{ name: "tools", description: "update all installed workflow tools" },
|
|
416
|
+
];
|
|
417
|
+
|
|
418
|
+
export const TRADE_VERBS = [
|
|
419
|
+
{ name: "ticker", description: "look up an asset by ticker", synopsis: [["moshcode trade ticker <symbol> [flags…]", ""]] },
|
|
420
|
+
{ name: "quote", description: "get the latest quote", synopsis: [["moshcode trade quote <symbol> [flags…]", ""]] },
|
|
421
|
+
{ name: "analysis", description: "get an analysis-ready market snapshot", synopsis: [["moshcode trade analysis <symbol> [flags…]", ""]] },
|
|
422
|
+
{
|
|
423
|
+
name: "buy", description: "preview or submit a buy order",
|
|
424
|
+
synopsis: [
|
|
425
|
+
["moshcode trade buy <symbol> <qty> [alpaca flags…] [--submit]", "share quantity"],
|
|
426
|
+
["moshcode trade buy <symbol> --notional <usd> [--submit]", "dollar amount"],
|
|
427
|
+
],
|
|
428
|
+
flags: [["--submit", "place the order instead of injecting --dry-run", "preview"]],
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
name: "sell", description: "preview or submit a sell order",
|
|
432
|
+
synopsis: [
|
|
433
|
+
["moshcode trade sell <symbol> <qty> [alpaca flags…] [--submit]", "share quantity"],
|
|
434
|
+
["moshcode trade sell <symbol> --notional <usd> [--submit]", "dollar amount"],
|
|
435
|
+
],
|
|
436
|
+
flags: [["--submit", "place the order instead of injecting --dry-run", "preview"]],
|
|
437
|
+
},
|
|
438
|
+
{ name: "watch", description: "manage watchlists", synopsis: [["moshcode trade watch [list|create|get|add|remove|delete] [args…]", ""]] },
|
|
439
|
+
{ name: "positions", description: "list, inspect, or close positions", synopsis: [["moshcode trade positions [verb] [args…]", "default: list"]] },
|
|
440
|
+
{ name: "orders", description: "list, inspect, replace, or cancel orders", synopsis: [["moshcode trade orders [verb] [args…]", "default: list"]] },
|
|
441
|
+
{ name: "account", description: "show account details", synopsis: [["moshcode trade account [args…]", ""]] },
|
|
442
|
+
{ name: "login", description: "authenticate an Alpaca profile", synopsis: [["moshcode trade login [alpaca profile flags…]", "paper by default"]] },
|
|
443
|
+
{ name: "clock", description: "show market status and next open/close", synopsis: [["moshcode trade clock [args…]", ""]] },
|
|
444
|
+
{ name: "raw", description: "invoke the native Alpaca command tree", synopsis: [["moshcode trade raw <alpaca args…>", ""]] },
|
|
445
|
+
];
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* `dns` sub-verbs.
|
|
449
|
+
*
|
|
450
|
+
* New here rather than in completion, which never had them: the bridge grew
|
|
451
|
+
* these verbs after the completion table was written, so they were dispatchable
|
|
452
|
+
* and invisible to both help and the shell.
|
|
453
|
+
*/
|
|
454
|
+
export const DNS_VERBS = [
|
|
455
|
+
{ name: "enable", description: "route Moshpit endings to the local bridge (needs sudo)" },
|
|
456
|
+
{ name: "disable", description: "undo enable" },
|
|
457
|
+
{ name: "status", description: "what is running, what is routed, does it work" },
|
|
458
|
+
{ name: "refresh", description: "re-apply routing for endings claimed since" },
|
|
459
|
+
{ name: "start", description: "run the bridge in the foreground" },
|
|
460
|
+
{ name: "install", description: "print the resolver config without applying it" },
|
|
461
|
+
{ name: "service", description: "install or remove the background service" },
|
|
462
|
+
{ name: "tlds", description: "list the endings claimed in the Pit" },
|
|
463
|
+
{ name: "resolve", description: "what a name resolves to, and why" },
|
|
464
|
+
{ name: "trust", description: "trust one name's certificate, after checking it against the registry pin" },
|
|
465
|
+
];
|
|
466
|
+
|
|
467
|
+
/** Sub-verb tables, by the name a command's `verbs` field refers to. */
|
|
468
|
+
export const VERB_TABLES = {
|
|
469
|
+
MCP_VERBS,
|
|
470
|
+
SKILL_VERBS,
|
|
471
|
+
UPGRADE_TARGETS,
|
|
472
|
+
DNS_VERBS,
|
|
473
|
+
TRADE_VERBS,
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* The pit's own command surface (PRD 0006 R12).
|
|
478
|
+
*
|
|
479
|
+
* Separate from CORE_CLI_COMMANDS because it genuinely is: the pit dispatches
|
|
480
|
+
* `/shell` and `/quit`, which have no CLI equivalent, and does not dispatch
|
|
481
|
+
* `dns`, `console`, `doh`, `site`, `template`, `completion` or `uninstall`,
|
|
482
|
+
* which do. `/help` used to imply otherwise by omission — it listed neither the
|
|
483
|
+
* commands it lacked nor `/logout`, which it has.
|
|
484
|
+
*
|
|
485
|
+
* `cli` points at the CORE_CLI_COMMANDS entry that documents the same verb, so
|
|
486
|
+
* `/help <command>` renders the flags and examples already written there rather
|
|
487
|
+
* than a second, thinner copy that drifts.
|
|
488
|
+
*/
|
|
489
|
+
export const PIT_COMMANDS = [
|
|
490
|
+
{ name: "new", pitOnly: true,
|
|
491
|
+
description: "open and switch to another moshcode tab" },
|
|
492
|
+
{ name: "agents", aliases: ["agent", "engines"], args: "[name]", cli: "agents",
|
|
493
|
+
description: "list engines, or launch one autonomously" },
|
|
494
|
+
{ name: "start", args: "<engine> [args…]", cli: "start",
|
|
495
|
+
description: "raw launch; inject no engine arguments" },
|
|
496
|
+
{ name: "tools", args: "[name] [args…]", cli: "tools",
|
|
497
|
+
description: "list workflow tools, or run one" },
|
|
498
|
+
{ name: "trade", args: "<verb> [args…]", cli: "trade",
|
|
499
|
+
description: "look up markets and preview/place Alpaca orders" },
|
|
500
|
+
{ name: "install", args: "<engine|tool>", cli: "install",
|
|
501
|
+
description: "install an engine or workflow tool" },
|
|
502
|
+
{ name: "upgrade", aliases: ["update"], args: "[name…]", cli: "upgrade",
|
|
503
|
+
description: "update moshcode + installed engines/tools" },
|
|
504
|
+
{ name: "mcp", args: "<verb> [args…]", cli: "mcp",
|
|
505
|
+
description: "register and inspect MCP servers" },
|
|
506
|
+
{ name: "skill", aliases: ["skills"], args: "<verb> [args…]", cli: "skill",
|
|
507
|
+
description: "install and inspect agent skills" },
|
|
508
|
+
{ name: "prd", args: "[idea…]", cli: "prd",
|
|
509
|
+
description: "publish a numbered PRD, or list them with no argument" },
|
|
510
|
+
{ name: "run", args: "<file.mosh> [--max N] [--dry-run]", cli: "run",
|
|
511
|
+
description: "run a moshscript" },
|
|
512
|
+
{ name: "login", args: "[--device] [--browser]", cli: "login",
|
|
513
|
+
description: "connect this machine to app.moshcode.sh" },
|
|
514
|
+
{ name: "whoami", cli: "whoami", description: "who this machine is logged in as" },
|
|
515
|
+
// Dispatched since forever and missing from /help until now.
|
|
516
|
+
{ name: "logout", cli: "logout", description: "clear the logged-in account" },
|
|
517
|
+
{ name: "pwd", aliases: ["where"], cli: "pwd",
|
|
518
|
+
description: "show the current dir + git repo/branch/origin" },
|
|
519
|
+
{ name: "shell", aliases: ["sh"], args: "[cmd]", pitOnly: true,
|
|
520
|
+
description: "drop into $SHELL (exit → back to the pit); also !cmd" },
|
|
521
|
+
{ name: "help", aliases: ["?", "h"], args: "[command]", pitOnly: true,
|
|
522
|
+
description: "this, or one command in detail" },
|
|
523
|
+
{ name: "quit", aliases: ["exit", "q"], pitOnly: true,
|
|
524
|
+
description: "leave the pit (or Ctrl-D)" },
|
|
525
|
+
];
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* CLI verbs the pit does not have.
|
|
529
|
+
*
|
|
530
|
+
* Named rather than silently absent: "it isn't here" is a different answer from
|
|
531
|
+
* "you typed it wrong", and only one of them tells you to use the CLI instead.
|
|
532
|
+
*/
|
|
533
|
+
export const NOT_IN_PIT = ["uninstall", "dns", "doh", "site", "template", "console", "completion", "commands", "version"];
|
package/src/cli.mjs
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// The CLI-scripting seam: moshscript verbs that are "just" the moshcode CLI.
|
|
2
|
+
//
|
|
3
|
+
// moshscript is scripting the moshcode command line. A verb like `agents("claude")`
|
|
4
|
+
// runs `moshcode agents claude` — the exact same command a human would type — so
|
|
5
|
+
// there is one implementation of every capability (the CLI) and moshscript is a
|
|
6
|
+
// second caller of it, not a reimplementation.
|
|
7
|
+
//
|
|
8
|
+
// cliVerb(name) builds a vocabulary command whose run() shells out to
|
|
9
|
+
// moshcode <name> <...args>
|
|
10
|
+
//
|
|
11
|
+
// It uses spawnSync with inherited stdio, so the call BLOCKS until the CLI
|
|
12
|
+
// finishes — which is exactly right for "scripting the CLI":
|
|
13
|
+
// - the simple no-`await` style works: `install("claude"); agents("claude");`
|
|
14
|
+
// runs one after the other, in order;
|
|
15
|
+
// - interactive engine/tool sessions own the real terminal and hand control
|
|
16
|
+
// back to the script when they exit.
|
|
17
|
+
// Under --dry-run it narrates the argv instead of spawning.
|
|
18
|
+
import { spawnSync } from "node:child_process";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
import { ENGINES, aiExecArgs, pickAiEngine, resolveEngine } from "./engines.mjs";
|
|
21
|
+
|
|
22
|
+
// Resolve THIS package's own moshcode entrypoint, so scripting stays
|
|
23
|
+
// self-referential and doesn't depend on `moshcode` being on PATH.
|
|
24
|
+
const MOSHCODE_BIN = fileURLToPath(new URL("../bin/moshcode.mjs", import.meta.url));
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Run `moshcode <cmd> ...args`, blocking until it exits.
|
|
28
|
+
*
|
|
29
|
+
* Returns { ok, code } — always. A non-zero exit returns { ok: false, code }
|
|
30
|
+
* so scripts can branch on outcomes (`if (!install("foo").ok) …`) without a
|
|
31
|
+
* try/catch. Only truly fatal errors (spawn failures like ENOENT) throw.
|
|
32
|
+
* This is the R8 convention from PRD 0004.
|
|
33
|
+
*/
|
|
34
|
+
export function runMoshcode(cmd, args, ctx) {
|
|
35
|
+
const argv = [cmd, ...args.map(String)];
|
|
36
|
+
const printable = `moshcode ${argv.join(" ")}`.trimEnd();
|
|
37
|
+
|
|
38
|
+
if (ctx.dryRun) {
|
|
39
|
+
ctx.out(` ▶ ${cmd}(${args.join(", ")}) → would run: ${printable}`);
|
|
40
|
+
// `code` is part of the R8 contract above ("always"), so dry-run has to
|
|
41
|
+
// carry it too — otherwise `if (install("x").code !== 0)` reads undefined
|
|
42
|
+
// and takes the failure branch on a run where nothing was even spawned.
|
|
43
|
+
return { ok: true, code: 0, dryRun: true };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
ctx.out(` ▶ ${printable}`);
|
|
47
|
+
const res = spawnSync(process.execPath, [MOSHCODE_BIN, ...argv], {
|
|
48
|
+
stdio: "inherit",
|
|
49
|
+
env: { ...process.env, MOSHCODE_NESTED: "1" },
|
|
50
|
+
});
|
|
51
|
+
if (res.error) throw res.error; // truly fatal: spawn itself failed (ENOENT etc.)
|
|
52
|
+
|
|
53
|
+
const code = res.status ?? 1;
|
|
54
|
+
if (code !== 0) {
|
|
55
|
+
ctx.out(` ✗ ${cmd}() exited ${res.signal || code}`);
|
|
56
|
+
return { ok: false, code, signal: res.signal || null };
|
|
57
|
+
}
|
|
58
|
+
return { ok: true, code: 0 };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** A vocabulary command mapping `name(...args)` → `moshcode name ...args`. */
|
|
62
|
+
export function cliVerb(name, summary) {
|
|
63
|
+
// `usage` is the call signature `moshcode help <verb>` renders (PRD 0006
|
|
64
|
+
// R14). Every CLI verb has the same one — it forwards its arguments to
|
|
65
|
+
// `moshcode <name>` — so deriving it here means a verb added below is
|
|
66
|
+
// documented by the act of adding it.
|
|
67
|
+
return {
|
|
68
|
+
name,
|
|
69
|
+
summary,
|
|
70
|
+
usage: `${name}(...args)`,
|
|
71
|
+
detail: `runs \`moshcode ${name} ...args\` and returns { ok, code }`,
|
|
72
|
+
run: (ctx, ...args) => runMoshcode(name, args, ctx),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* ai(prompt, opts?) — run a coding engine HEADLESSLY on `prompt` and RETURN its
|
|
78
|
+
* output as a string (unlike agents()/start(), which hand over the terminal and
|
|
79
|
+
* return nothing). Blocking (spawnSync, stdout captured). opts.engine picks the
|
|
80
|
+
* engine; otherwise the first installed one. Honors dry-run (returns "").
|
|
81
|
+
*/
|
|
82
|
+
export function runAi(ctx, prompt, opts = {}) {
|
|
83
|
+
if (ctx.dryRun) {
|
|
84
|
+
// narrate without requiring an installed engine — so the fallback has to
|
|
85
|
+
// resolve an alias itself: with nothing installed pickAiEngine() returns
|
|
86
|
+
// null, and handing the raw alias to aiExecArgs threw instead of narrating.
|
|
87
|
+
const engine = pickAiEngine(opts.engine) || resolveEngine(opts.engine)?.[0] || opts.engine || "claude";
|
|
88
|
+
const args = aiExecArgs(engine, prompt); // throws only on an unknown engine name
|
|
89
|
+
ctx.out(` 🧠 ai(${JSON.stringify(String(prompt).slice(0, 48))}) → would run: ${engine} ${args.join(" ")}`);
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const engine = pickAiEngine(opts.engine);
|
|
94
|
+
if (!engine) {
|
|
95
|
+
throw new Error(`moshscript: ai() needs an installed engine — try install("claude")`);
|
|
96
|
+
}
|
|
97
|
+
const e = ENGINES[engine];
|
|
98
|
+
const args = aiExecArgs(engine, prompt);
|
|
99
|
+
ctx.out(` 🧠 ai() → ${engine}: ${String(prompt).slice(0, 60)}${String(prompt).length > 60 ? "…" : ""}`);
|
|
100
|
+
|
|
101
|
+
const env = { ...process.env };
|
|
102
|
+
for (const k of e.stripEnv || []) delete env[k];
|
|
103
|
+
const res = spawnSync(e.bin, args, { encoding: "utf8", env, maxBuffer: 16 * 1024 * 1024 });
|
|
104
|
+
if (res.error) throw res.error;
|
|
105
|
+
if (res.status !== 0) {
|
|
106
|
+
throw new Error(`moshscript: ai() → ${engine} exited with ${res.signal || res.status}${res.stderr ? `: ${res.stderr.trim().slice(0, 200)}` : ""}`);
|
|
107
|
+
}
|
|
108
|
+
return (res.stdout || "").trim();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** The ai() shortcut as a vocabulary command. */
|
|
112
|
+
export const aiVerb = {
|
|
113
|
+
name: "ai",
|
|
114
|
+
summary: "run a coding engine on a prompt and return its output (shortcut)",
|
|
115
|
+
usage: "ai(prompt, { engine })",
|
|
116
|
+
detail: "blocking; returns the engine's stdout as a string. engine defaults to the first installed one. needs await",
|
|
117
|
+
run: (ctx, prompt, opts) => runAi(ctx, prompt, opts),
|
|
118
|
+
};
|