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,594 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CORE_CLI_COMMANDS,
|
|
3
|
+
MCP_VERBS,
|
|
4
|
+
SKILL_VERBS,
|
|
5
|
+
TRADE_VERBS,
|
|
6
|
+
UPGRADE_TARGETS,
|
|
7
|
+
} from "./cli-schema.mjs";
|
|
8
|
+
import { ENGINES, ENGINE_ALIASES } from "./engines.mjs";
|
|
9
|
+
import { TOOLS } from "./tools.mjs";
|
|
10
|
+
import { moshVocabulary } from "./commands.mjs";
|
|
11
|
+
|
|
12
|
+
export const COMPLETION_SHELLS = ["bash", "zsh", "fish", "powershell"];
|
|
13
|
+
|
|
14
|
+
function entry(name, description) {
|
|
15
|
+
const value = String(name);
|
|
16
|
+
if (!/^-{0,2}[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(value)) {
|
|
17
|
+
throw new Error(`completion name is not shell-safe: ${JSON.stringify(value)}`);
|
|
18
|
+
}
|
|
19
|
+
return { name: value, description: String(description).replace(/\s+/g, " ").trim() };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function uniqueEntries(entries) {
|
|
23
|
+
const found = new Map();
|
|
24
|
+
for (const item of entries) {
|
|
25
|
+
const normalized = entry(item.name, item.description);
|
|
26
|
+
if (!found.has(normalized.name)) found.set(normalized.name, normalized);
|
|
27
|
+
}
|
|
28
|
+
return [...found.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function completionModel() {
|
|
32
|
+
const engines = Object.entries(ENGINES).map(([name, engine]) => entry(name, engine.desc));
|
|
33
|
+
const engineAliases = Object.entries(ENGINE_ALIASES).map(([name, target]) => (
|
|
34
|
+
entry(name, `alias for ${target}`)
|
|
35
|
+
));
|
|
36
|
+
const tools = Object.entries(TOOLS).map(([name, tool]) => entry(name, tool.desc));
|
|
37
|
+
const install = uniqueEntries([...engines, ...tools]);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
top: uniqueEntries([...CORE_CLI_COMMANDS, ...engines, ...engineAliases, ...tools]),
|
|
41
|
+
engines: uniqueEntries([...engines, ...engineAliases]),
|
|
42
|
+
install,
|
|
43
|
+
// `uninstall <engine|tool>` resolves its target against the same ENGINES and
|
|
44
|
+
// TOOLS rosters `install` does, so it offers the same targets. Kept as its
|
|
45
|
+
// own key rather than reusing `install` so the two can diverge without a
|
|
46
|
+
// silent surprise in one of them.
|
|
47
|
+
uninstall: install,
|
|
48
|
+
upgrade: uniqueEntries([
|
|
49
|
+
...UPGRADE_TARGETS,
|
|
50
|
+
...engines,
|
|
51
|
+
...engineAliases,
|
|
52
|
+
...tools,
|
|
53
|
+
]),
|
|
54
|
+
mcp: uniqueEntries(MCP_VERBS),
|
|
55
|
+
mcpServerSpecs: uniqueEntries(MCP_VERBS.filter(({ acceptsServerSpec }) => acceptsServerSpec)),
|
|
56
|
+
skills: uniqueEntries(SKILL_VERBS),
|
|
57
|
+
trade: uniqueEntries(TRADE_VERBS),
|
|
58
|
+
tradeOrderOptions: uniqueEntries([
|
|
59
|
+
entry("--submit", "place the order instead of previewing"),
|
|
60
|
+
entry("--qty", "share quantity"),
|
|
61
|
+
entry("--notional", "dollar amount"),
|
|
62
|
+
entry("--type", "market, limit, stop, stop_limit, or trailing_stop"),
|
|
63
|
+
entry("--limit-price", "limit price"),
|
|
64
|
+
entry("--stop-price", "stop price"),
|
|
65
|
+
entry("--time-in-force", "order time in force"),
|
|
66
|
+
]),
|
|
67
|
+
skillSources: uniqueEntries(SKILL_VERBS.filter(({ acceptsSource }) => acceptsSource)),
|
|
68
|
+
shells: COMPLETION_SHELLS.map((name) => entry(name, `generate ${name} completion`)),
|
|
69
|
+
// `moshcode help <topic>` accepts anything help can answer for: a command,
|
|
70
|
+
// an engine, a tool, or a moshscript verb (PRD 0006 R16). Offering the same
|
|
71
|
+
// set here is what keeps tab-completion and help one discoverability
|
|
72
|
+
// surface rather than two that disagree.
|
|
73
|
+
helpTopics: uniqueEntries([
|
|
74
|
+
...CORE_CLI_COMMANDS.filter(({ name }) => !name.startsWith("-")),
|
|
75
|
+
...engines,
|
|
76
|
+
...tools,
|
|
77
|
+
...moshVocabulary().all().map((c) => entry(c.name, c.summary || "moshscript verb")),
|
|
78
|
+
]),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function names(entries) {
|
|
83
|
+
return entries.map(({ name }) => name).join(" ");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function shellQuote(value) {
|
|
87
|
+
return `'${String(value).replaceAll("'", "'\\''")}'`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function zshValues(entries) {
|
|
91
|
+
return entries.map(({ name, description }) => shellQuote(`${name}:${description}`)).join(" ");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function shellMatches(variable, entries) {
|
|
95
|
+
return `[[ ${entries.map(({ name }) => `"$${variable}" == "${name}"`).join(" || ")} ]]`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function fishQuote(value) {
|
|
99
|
+
return `'${String(value).replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function fishEntries(condition, entries) {
|
|
103
|
+
return entries.map(({ name, description }) => (
|
|
104
|
+
`complete -c moshcode -n ${fishQuote(condition)} -a ${fishQuote(name)} -d ${fishQuote(description)}`
|
|
105
|
+
)).join("\n");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function powershellQuote(value) {
|
|
109
|
+
return `'${String(value).replaceAll("'", "''")}'`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function powershellEntries(variable, entries) {
|
|
113
|
+
const rows = entries.map(({ name, description }) => (
|
|
114
|
+
` [pscustomobject]@{ Name = ${powershellQuote(name)}; Description = ${powershellQuote(description)} }`
|
|
115
|
+
));
|
|
116
|
+
return `$script:${variable} = @(\n${rows.join("\n")}\n)`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function powershellCompletion(model) {
|
|
120
|
+
const optionEntries = (values, description = "option") => (
|
|
121
|
+
values.split(" ").filter(Boolean).map((name) => entry(name, description))
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
return `# PowerShell completion for moshcode
|
|
125
|
+
${powershellEntries("MoshcodeCompletionTop", model.top)}
|
|
126
|
+
${powershellEntries("MoshcodeCompletionEngines", model.engines)}
|
|
127
|
+
${powershellEntries("MoshcodeCompletionInstall", model.install)}
|
|
128
|
+
${powershellEntries("MoshcodeCompletionUninstall", model.uninstall)}
|
|
129
|
+
${powershellEntries("MoshcodeCompletionUpgrade", model.upgrade)}
|
|
130
|
+
${powershellEntries("MoshcodeCompletionMcp", model.mcp)}
|
|
131
|
+
${powershellEntries("MoshcodeCompletionMcpServerSpecs", model.mcpServerSpecs)}
|
|
132
|
+
${powershellEntries("MoshcodeCompletionSkills", model.skills)}
|
|
133
|
+
${powershellEntries("MoshcodeCompletionTrade", model.trade)}
|
|
134
|
+
${powershellEntries("MoshcodeCompletionTradeOrderOptions", model.tradeOrderOptions)}
|
|
135
|
+
${powershellEntries("MoshcodeCompletionSkillSources", model.skillSources)}
|
|
136
|
+
${powershellEntries("MoshcodeCompletionShells", model.shells)}
|
|
137
|
+
${powershellEntries("MoshcodeCompletionHelpTopics", model.helpTopics)}
|
|
138
|
+
${powershellEntries("MoshcodeCompletionJson", optionEntries("--json", "print JSON"))}
|
|
139
|
+
${powershellEntries("MoshcodeCompletionLogin", optionEntries("--browser -b --device -d", "authentication mode"))}
|
|
140
|
+
${powershellEntries("MoshcodeCompletionRun", optionEntries("--dry-run --max -n", "run option"))}
|
|
141
|
+
${powershellEntries("MoshcodeCompletionUninstallOptions", optionEntries("--yes -y --dry-run", "uninstall option"))}
|
|
142
|
+
${powershellEntries("MoshcodeCompletionConsole", optionEntries("serve --url", "console command"))}
|
|
143
|
+
${powershellEntries("MoshcodeCompletionConsoleServe", optionEntries("--port --ttyd --bind", "console serve option"))}
|
|
144
|
+
${powershellEntries("MoshcodeCompletionTemplate", optionEntries("list install", "template command"))}
|
|
145
|
+
${powershellEntries("MoshcodeCompletionTemplateInstall", optionEntries("--into --force --dry-run", "template install option"))}
|
|
146
|
+
${powershellEntries("MoshcodeCompletionMcpOptions", optionEntries("--name --transport -t --env -e --header -H", "MCP option"))}
|
|
147
|
+
${powershellEntries("MoshcodeCompletionSkillOptions", optionEntries("--name", "skill option"))}
|
|
148
|
+
|
|
149
|
+
Register-ArgumentCompleter -Native -CommandName moshcode -ScriptBlock {
|
|
150
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
151
|
+
|
|
152
|
+
$tokens = @($commandAst.CommandElements | ForEach-Object { $_.Extent.Text })
|
|
153
|
+
$argumentIndex = if ([string]::IsNullOrEmpty($wordToComplete)) {
|
|
154
|
+
$tokens.Count
|
|
155
|
+
} else {
|
|
156
|
+
$tokens.Count - 1
|
|
157
|
+
}
|
|
158
|
+
$command = if ($tokens.Count -gt 1) { $tokens[1] } else { '' }
|
|
159
|
+
$nested = if ($tokens.Count -gt 2) { $tokens[2] } else { '' }
|
|
160
|
+
$choices = @()
|
|
161
|
+
|
|
162
|
+
if ($argumentIndex -eq 1) {
|
|
163
|
+
$choices = $script:MoshcodeCompletionTop
|
|
164
|
+
} else {
|
|
165
|
+
switch ($command) {
|
|
166
|
+
{ $_ -in @('agents', 'start') } {
|
|
167
|
+
if ($argumentIndex -eq 2) {
|
|
168
|
+
$choices = if ($command -eq 'agents' -and $wordToComplete.StartsWith('-')) {
|
|
169
|
+
$script:MoshcodeCompletionJson
|
|
170
|
+
} else { $script:MoshcodeCompletionEngines }
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
'install' {
|
|
174
|
+
if ($argumentIndex -eq 2) { $choices = $script:MoshcodeCompletionInstall }
|
|
175
|
+
}
|
|
176
|
+
{ $_ -in @('uninstall', 'remove') } {
|
|
177
|
+
if ($argumentIndex -eq 2 -and -not $wordToComplete.StartsWith('-')) {
|
|
178
|
+
$choices = $script:MoshcodeCompletionUninstall
|
|
179
|
+
} elseif ($wordToComplete.StartsWith('-')) {
|
|
180
|
+
$choices = $script:MoshcodeCompletionUninstallOptions
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
{ $_ -in @('upgrade', 'update') } {
|
|
184
|
+
$choices = $script:MoshcodeCompletionUpgrade
|
|
185
|
+
}
|
|
186
|
+
'help' {
|
|
187
|
+
if ($argumentIndex -eq 2) { $choices = $script:MoshcodeCompletionHelpTopics }
|
|
188
|
+
}
|
|
189
|
+
'completion' {
|
|
190
|
+
if ($argumentIndex -eq 2) { $choices = $script:MoshcodeCompletionShells }
|
|
191
|
+
}
|
|
192
|
+
'mcp' {
|
|
193
|
+
if ($argumentIndex -eq 2) {
|
|
194
|
+
$choices = $script:MoshcodeCompletionMcp
|
|
195
|
+
} elseif ($nested -eq 'list' -and $wordToComplete.StartsWith('-')) {
|
|
196
|
+
$choices = $script:MoshcodeCompletionJson
|
|
197
|
+
} elseif ($script:MoshcodeCompletionMcpServerSpecs.Name -contains $nested -and $wordToComplete.StartsWith('-')) {
|
|
198
|
+
$choices = $script:MoshcodeCompletionMcpOptions
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
{ $_ -in @('skill', 'skills') } {
|
|
202
|
+
if ($argumentIndex -eq 2) {
|
|
203
|
+
$choices = $script:MoshcodeCompletionSkills
|
|
204
|
+
} elseif ($nested -eq 'list' -and $wordToComplete.StartsWith('-')) {
|
|
205
|
+
$choices = $script:MoshcodeCompletionJson
|
|
206
|
+
} elseif ($script:MoshcodeCompletionSkillSources.Name -contains $nested -and $wordToComplete.StartsWith('-')) {
|
|
207
|
+
$choices = $script:MoshcodeCompletionSkillOptions
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
'trade' {
|
|
211
|
+
if ($argumentIndex -eq 2) {
|
|
212
|
+
$choices = $script:MoshcodeCompletionTrade
|
|
213
|
+
} elseif ($nested -in @('buy', 'sell') -and $wordToComplete.StartsWith('-')) {
|
|
214
|
+
$choices = $script:MoshcodeCompletionTradeOrderOptions
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
'login' { if ($wordToComplete.StartsWith('-')) { $choices = $script:MoshcodeCompletionLogin } }
|
|
218
|
+
{ $_ -in @('engines', 'tools', 'commands') } {
|
|
219
|
+
if ($wordToComplete.StartsWith('-')) { $choices = $script:MoshcodeCompletionJson }
|
|
220
|
+
}
|
|
221
|
+
'run' { if ($wordToComplete.StartsWith('-')) { $choices = $script:MoshcodeCompletionRun } }
|
|
222
|
+
'console' {
|
|
223
|
+
if ($argumentIndex -eq 2) {
|
|
224
|
+
$choices = $script:MoshcodeCompletionConsole
|
|
225
|
+
} elseif ($nested -eq 'serve' -and $wordToComplete.StartsWith('-')) {
|
|
226
|
+
$choices = $script:MoshcodeCompletionConsoleServe
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
{ $_ -in @('template', 'templates') } {
|
|
230
|
+
if ($argumentIndex -eq 2) {
|
|
231
|
+
$choices = $script:MoshcodeCompletionTemplate
|
|
232
|
+
} elseif ($nested -eq 'list' -and $wordToComplete.StartsWith('-')) {
|
|
233
|
+
$choices = $script:MoshcodeCompletionJson
|
|
234
|
+
} elseif ($nested -eq 'install' -and $wordToComplete.StartsWith('-')) {
|
|
235
|
+
$choices = $script:MoshcodeCompletionTemplateInstall
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
foreach ($candidate in $choices) {
|
|
242
|
+
if ($candidate.Name.StartsWith($wordToComplete, [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
243
|
+
[System.Management.Automation.CompletionResult]::new(
|
|
244
|
+
$candidate.Name,
|
|
245
|
+
$candidate.Name,
|
|
246
|
+
[System.Management.Automation.CompletionResultType]::ParameterValue,
|
|
247
|
+
$candidate.Description
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
`;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function bashCompletion(model) {
|
|
256
|
+
return `# bash completion for moshcode
|
|
257
|
+
_moshcode_completion() {
|
|
258
|
+
local cur subcommand nested choices
|
|
259
|
+
COMPREPLY=()
|
|
260
|
+
cur="\${COMP_WORDS[COMP_CWORD]-}"
|
|
261
|
+
subcommand="\${COMP_WORDS[1]-}"
|
|
262
|
+
nested="\${COMP_WORDS[2]-}"
|
|
263
|
+
choices=""
|
|
264
|
+
|
|
265
|
+
if (( COMP_CWORD == 1 )); then
|
|
266
|
+
choices="${names(model.top)}"
|
|
267
|
+
else
|
|
268
|
+
case "$subcommand" in
|
|
269
|
+
agents)
|
|
270
|
+
if (( COMP_CWORD == 2 )); then
|
|
271
|
+
if [[ "$cur" == -* ]]; then choices="--json"; else choices="${names(model.engines)}"; fi
|
|
272
|
+
fi
|
|
273
|
+
;;
|
|
274
|
+
start)
|
|
275
|
+
(( COMP_CWORD == 2 )) && choices="${names(model.engines)}"
|
|
276
|
+
;;
|
|
277
|
+
install)
|
|
278
|
+
(( COMP_CWORD == 2 )) && choices="${names(model.install)}"
|
|
279
|
+
;;
|
|
280
|
+
uninstall|remove)
|
|
281
|
+
if (( COMP_CWORD == 2 )); then
|
|
282
|
+
choices="${names(model.uninstall)}"
|
|
283
|
+
elif [[ "$cur" == -* ]]; then
|
|
284
|
+
choices="--yes -y --dry-run"
|
|
285
|
+
fi
|
|
286
|
+
;;
|
|
287
|
+
upgrade|update)
|
|
288
|
+
choices="${names(model.upgrade)}"
|
|
289
|
+
;;
|
|
290
|
+
completion)
|
|
291
|
+
(( COMP_CWORD == 2 )) && choices="${names(model.shells)}"
|
|
292
|
+
;;
|
|
293
|
+
help)
|
|
294
|
+
(( COMP_CWORD == 2 )) && choices="${names(model.helpTopics)}"
|
|
295
|
+
;;
|
|
296
|
+
mcp)
|
|
297
|
+
if (( COMP_CWORD == 2 )); then
|
|
298
|
+
choices="${names(model.mcp)}"
|
|
299
|
+
elif [[ "$nested" == "list" && "$cur" == -* ]]; then
|
|
300
|
+
choices="--json"
|
|
301
|
+
elif ${shellMatches("nested", model.mcpServerSpecs)} && [[ "$cur" == -* ]]; then
|
|
302
|
+
choices="--name --transport -t --env -e --header -H --"
|
|
303
|
+
fi
|
|
304
|
+
;;
|
|
305
|
+
skill|skills)
|
|
306
|
+
if (( COMP_CWORD == 2 )); then
|
|
307
|
+
choices="${names(model.skills)}"
|
|
308
|
+
elif [[ "$nested" == "list" && "$cur" == -* ]]; then
|
|
309
|
+
choices="--json"
|
|
310
|
+
elif ${shellMatches("nested", model.skillSources)} && [[ "$cur" == -* ]]; then
|
|
311
|
+
choices="--name"
|
|
312
|
+
fi
|
|
313
|
+
;;
|
|
314
|
+
trade)
|
|
315
|
+
if (( COMP_CWORD == 2 )); then
|
|
316
|
+
choices="${names(model.trade)}"
|
|
317
|
+
elif [[ "$nested" == "buy" || "$nested" == "sell" ]] && [[ "$cur" == -* ]]; then
|
|
318
|
+
choices="${names(model.tradeOrderOptions)}"
|
|
319
|
+
fi
|
|
320
|
+
;;
|
|
321
|
+
login)
|
|
322
|
+
[[ "$cur" == -* ]] && choices="--browser -b --device -d"
|
|
323
|
+
;;
|
|
324
|
+
engines|tools|commands)
|
|
325
|
+
[[ "$cur" == -* ]] && choices="--json"
|
|
326
|
+
;;
|
|
327
|
+
run)
|
|
328
|
+
[[ "$cur" == -* ]] && choices="--dry-run --max -n"
|
|
329
|
+
;;
|
|
330
|
+
console)
|
|
331
|
+
if (( COMP_CWORD == 2 )); then
|
|
332
|
+
choices="serve --url"
|
|
333
|
+
elif [[ "$nested" == "serve" && "$cur" == -* ]]; then
|
|
334
|
+
choices="--port --ttyd --bind"
|
|
335
|
+
fi
|
|
336
|
+
;;
|
|
337
|
+
dns)
|
|
338
|
+
if (( COMP_CWORD == 2 )); then
|
|
339
|
+
choices="enable disable status tlds resolve start install trust"
|
|
340
|
+
elif [[ "$nested" == "resolve" && "$cur" == -* ]]; then
|
|
341
|
+
choices="--json --open --registry"
|
|
342
|
+
fi
|
|
343
|
+
;;
|
|
344
|
+
template|templates)
|
|
345
|
+
if (( COMP_CWORD == 2 )); then
|
|
346
|
+
choices="list install"
|
|
347
|
+
elif [[ "$nested" == "list" && "$cur" == -* ]]; then
|
|
348
|
+
choices="--json"
|
|
349
|
+
elif [[ "$nested" == "install" && "$cur" == -* ]]; then
|
|
350
|
+
choices="--into --force --dry-run"
|
|
351
|
+
fi
|
|
352
|
+
;;
|
|
353
|
+
esac
|
|
354
|
+
fi
|
|
355
|
+
|
|
356
|
+
if [[ -n "$choices" ]]; then
|
|
357
|
+
COMPREPLY=( $(compgen -W "$choices" -- "$cur") )
|
|
358
|
+
fi
|
|
359
|
+
}
|
|
360
|
+
complete -o bashdefault -o default -F _moshcode_completion moshcode
|
|
361
|
+
`;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function zshCompletion(model) {
|
|
365
|
+
return `#compdef moshcode
|
|
366
|
+
# zsh completion for moshcode
|
|
367
|
+
_moshcode() {
|
|
368
|
+
local -a choices
|
|
369
|
+
|
|
370
|
+
if (( CURRENT == 2 )); then
|
|
371
|
+
choices=(${zshValues(model.top)})
|
|
372
|
+
_describe "moshcode command" choices
|
|
373
|
+
return
|
|
374
|
+
fi
|
|
375
|
+
|
|
376
|
+
case "\${words[2]}" in
|
|
377
|
+
agents)
|
|
378
|
+
if (( CURRENT == 3 )); then
|
|
379
|
+
if [[ "$PREFIX" == -* ]]; then
|
|
380
|
+
_values "agent option" --json
|
|
381
|
+
else
|
|
382
|
+
choices=(${zshValues(model.engines)})
|
|
383
|
+
_describe "engine" choices
|
|
384
|
+
fi
|
|
385
|
+
else
|
|
386
|
+
_files
|
|
387
|
+
fi
|
|
388
|
+
;;
|
|
389
|
+
start)
|
|
390
|
+
if (( CURRENT == 3 )); then
|
|
391
|
+
choices=(${zshValues(model.engines)})
|
|
392
|
+
_describe "engine" choices
|
|
393
|
+
else
|
|
394
|
+
_files
|
|
395
|
+
fi
|
|
396
|
+
;;
|
|
397
|
+
install)
|
|
398
|
+
if (( CURRENT == 3 )); then
|
|
399
|
+
choices=(${zshValues(model.install)})
|
|
400
|
+
_describe "install target" choices
|
|
401
|
+
else
|
|
402
|
+
_files
|
|
403
|
+
fi
|
|
404
|
+
;;
|
|
405
|
+
uninstall|remove)
|
|
406
|
+
if (( CURRENT == 3 )); then
|
|
407
|
+
choices=(${zshValues(model.uninstall)})
|
|
408
|
+
_describe "uninstall target" choices
|
|
409
|
+
else
|
|
410
|
+
_values "uninstall option" --yes -y --dry-run
|
|
411
|
+
fi
|
|
412
|
+
;;
|
|
413
|
+
upgrade|update)
|
|
414
|
+
choices=(${zshValues(model.upgrade)})
|
|
415
|
+
_describe "upgrade target" choices
|
|
416
|
+
;;
|
|
417
|
+
completion)
|
|
418
|
+
if (( CURRENT == 3 )); then
|
|
419
|
+
choices=(${zshValues(model.shells)})
|
|
420
|
+
_describe "shell" choices
|
|
421
|
+
fi
|
|
422
|
+
;;
|
|
423
|
+
help)
|
|
424
|
+
if (( CURRENT == 3 )); then
|
|
425
|
+
choices=(${zshValues(model.helpTopics)})
|
|
426
|
+
_describe "help topic" choices
|
|
427
|
+
fi
|
|
428
|
+
;;
|
|
429
|
+
mcp)
|
|
430
|
+
if (( CURRENT == 3 )); then
|
|
431
|
+
choices=(${zshValues(model.mcp)})
|
|
432
|
+
_describe "mcp command" choices
|
|
433
|
+
elif [[ "\${words[3]}" == "list" && "$PREFIX" == -* ]]; then
|
|
434
|
+
_values "mcp list option" --json
|
|
435
|
+
elif ${shellMatches("{words[3]}", model.mcpServerSpecs)}; then
|
|
436
|
+
if [[ "$PREFIX" == -* ]]; then
|
|
437
|
+
_values "mcp option" --name --transport -t --env -e --header -H --
|
|
438
|
+
else
|
|
439
|
+
_files
|
|
440
|
+
fi
|
|
441
|
+
fi
|
|
442
|
+
;;
|
|
443
|
+
skill|skills)
|
|
444
|
+
if (( CURRENT == 3 )); then
|
|
445
|
+
choices=(${zshValues(model.skills)})
|
|
446
|
+
_describe "skill command" choices
|
|
447
|
+
elif [[ "\${words[3]}" == "list" && "$PREFIX" == -* ]]; then
|
|
448
|
+
_values "skill list option" --json
|
|
449
|
+
elif ${shellMatches("{words[3]}", model.skillSources)}; then
|
|
450
|
+
if [[ "$PREFIX" == -* ]]; then _values "skill option" --name; else _files; fi
|
|
451
|
+
fi
|
|
452
|
+
;;
|
|
453
|
+
trade)
|
|
454
|
+
if (( CURRENT == 3 )); then
|
|
455
|
+
choices=(${zshValues(model.trade)})
|
|
456
|
+
_describe "trade command" choices
|
|
457
|
+
elif [[ "\${words[3]}" == "buy" || "\${words[3]}" == "sell" ]] && [[ "$PREFIX" == -* ]]; then
|
|
458
|
+
choices=(${zshValues(model.tradeOrderOptions)})
|
|
459
|
+
_describe "trade order option" choices
|
|
460
|
+
else
|
|
461
|
+
_files
|
|
462
|
+
fi
|
|
463
|
+
;;
|
|
464
|
+
login)
|
|
465
|
+
_values "login option" --browser -b --device -d
|
|
466
|
+
;;
|
|
467
|
+
engines|tools|commands)
|
|
468
|
+
_values "option" --json
|
|
469
|
+
;;
|
|
470
|
+
run)
|
|
471
|
+
if [[ "$PREFIX" == -* ]]; then
|
|
472
|
+
_values "run option" --dry-run --max -n
|
|
473
|
+
else
|
|
474
|
+
_files
|
|
475
|
+
fi
|
|
476
|
+
;;
|
|
477
|
+
console)
|
|
478
|
+
if (( CURRENT == 3 )); then
|
|
479
|
+
_values "console command" serve --url
|
|
480
|
+
elif [[ "\${words[3]}" == "serve" && "$PREFIX" == -* ]]; then
|
|
481
|
+
_values "console option" --port --ttyd --bind
|
|
482
|
+
else
|
|
483
|
+
_files
|
|
484
|
+
fi
|
|
485
|
+
;;
|
|
486
|
+
dns)
|
|
487
|
+
if (( CURRENT == 3 )); then
|
|
488
|
+
_values "dns command" enable disable status tlds resolve start install trust
|
|
489
|
+
elif [[ "\${words[3]}" == "resolve" && "$PREFIX" == -* ]]; then
|
|
490
|
+
_values "dns resolve option" --json --open --registry
|
|
491
|
+
else
|
|
492
|
+
_files
|
|
493
|
+
fi
|
|
494
|
+
;;
|
|
495
|
+
template|templates)
|
|
496
|
+
if (( CURRENT == 3 )); then
|
|
497
|
+
_values "template command" list install
|
|
498
|
+
elif [[ "\${words[3]}" == "list" && "$PREFIX" == -* ]]; then
|
|
499
|
+
_values "template list option" --json
|
|
500
|
+
elif [[ "\${words[3]}" == "install" && "$PREFIX" == -* ]]; then
|
|
501
|
+
_values "template install option" --into --force --dry-run
|
|
502
|
+
else
|
|
503
|
+
_files
|
|
504
|
+
fi
|
|
505
|
+
;;
|
|
506
|
+
*)
|
|
507
|
+
_files
|
|
508
|
+
;;
|
|
509
|
+
esac
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
if (( ! $+functions[compdef] )); then
|
|
513
|
+
autoload -Uz compinit
|
|
514
|
+
compinit
|
|
515
|
+
fi
|
|
516
|
+
compdef _moshcode moshcode
|
|
517
|
+
`;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function fishCompletion(model) {
|
|
521
|
+
const atFirstArgument = "__fish_use_subcommand";
|
|
522
|
+
const atSecondToken = (commands) => (
|
|
523
|
+
`__moshcode_command_is ${commands}; and __moshcode_arg_index 2`
|
|
524
|
+
);
|
|
525
|
+
const nestedCondition = (command, entries) => (
|
|
526
|
+
entries.map(({ name }) => `__moshcode_nested_is ${command} ${name}`).join("; or ")
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
return `# fish completion for moshcode
|
|
530
|
+
function __moshcode_command_is
|
|
531
|
+
set -l tokens (commandline -opc)
|
|
532
|
+
test (count $tokens) -ge 2; and contains -- $tokens[2] $argv
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
function __moshcode_nested_is
|
|
536
|
+
set -l tokens (commandline -opc)
|
|
537
|
+
test (count $tokens) -ge 3; and test "$tokens[2]" = "$argv[1]"; and test "$tokens[3]" = "$argv[2]"
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
function __moshcode_arg_index
|
|
541
|
+
test (count (commandline -opc)) -eq $argv[1]
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
${fishEntries(atFirstArgument, model.top)}
|
|
545
|
+
${fishEntries(atSecondToken("agents start"), model.engines)}
|
|
546
|
+
${fishEntries(atSecondToken("install"), model.install)}
|
|
547
|
+
${fishEntries(atSecondToken("uninstall remove"), model.uninstall)}
|
|
548
|
+
${fishEntries("__moshcode_command_is upgrade update", model.upgrade)}
|
|
549
|
+
${fishEntries(atSecondToken("completion"), model.shells)}
|
|
550
|
+
${fishEntries(atSecondToken("help"), model.helpTopics)}
|
|
551
|
+
${fishEntries(atSecondToken("mcp"), model.mcp)}
|
|
552
|
+
${fishEntries(atSecondToken("skill skills"), model.skills)}
|
|
553
|
+
${fishEntries(atSecondToken("trade"), model.trade)}
|
|
554
|
+
${fishEntries("__moshcode_nested_is trade buy; or __moshcode_nested_is trade sell", model.tradeOrderOptions)}
|
|
555
|
+
complete -c moshcode -n '__moshcode_nested_is mcp list' -l json -d 'print JSON'
|
|
556
|
+
complete -c moshcode -n '__moshcode_nested_is skill list; or __moshcode_nested_is skills list' -l json -d 'print JSON'
|
|
557
|
+
complete -c moshcode -n '__moshcode_command_is login' -l browser -s b -d 'use browser authentication'
|
|
558
|
+
complete -c moshcode -n '__moshcode_command_is login' -l device -s d -d 'use device-code authentication'
|
|
559
|
+
complete -c moshcode -n '${atSecondToken("agents engines tools commands")}' -l json -d 'print JSON'
|
|
560
|
+
complete -c moshcode -n '__moshcode_command_is run' -l dry-run -d 'show actions without executing'
|
|
561
|
+
complete -c moshcode -n '__moshcode_command_is run' -l max -s n -r -d 'maximum loop count'
|
|
562
|
+
complete -c moshcode -n '__moshcode_command_is uninstall remove' -l yes -s y -d 'confirm deleting a binary'
|
|
563
|
+
complete -c moshcode -n '__moshcode_command_is uninstall remove' -l dry-run -d 'show the plan without removing'
|
|
564
|
+
complete -c moshcode -n '${atSecondToken("console")}' -a 'serve' -d 'serve a browser terminal'
|
|
565
|
+
complete -c moshcode -n '${atSecondToken("console")}' -a '--url' -d 'print a gateway URL'
|
|
566
|
+
complete -c moshcode -n '__moshcode_nested_is console serve' -l port -r -d 'local HTTP port'
|
|
567
|
+
complete -c moshcode -n '__moshcode_nested_is console serve' -l ttyd -r -d 'ttyd host and port'
|
|
568
|
+
complete -c moshcode -n '__moshcode_nested_is console serve' -l bind -r -d 'bind address'
|
|
569
|
+
complete -c moshcode -n '${atSecondToken("dns")}' -a 'enable disable status tlds resolve start install trust' -d 'dns command'
|
|
570
|
+
complete -c moshcode -n '__moshcode_nested_is dns resolve' -l json -d 'print JSON'
|
|
571
|
+
complete -c moshcode -n '__moshcode_nested_is dns resolve' -l open -d 'open a parked name in the Pit'
|
|
572
|
+
complete -c moshcode -n '__moshcode_nested_is dns resolve' -l registry -r -d 'registry base URL'
|
|
573
|
+
complete -c moshcode -n '${atSecondToken("template templates")}' -a 'list install' -d 'template command'
|
|
574
|
+
complete -c moshcode -n '__moshcode_nested_is template list; or __moshcode_nested_is templates list' -l json -d 'print JSON'
|
|
575
|
+
complete -c moshcode -n '__moshcode_nested_is template install; or __moshcode_nested_is templates install' -l into -r -d 'target directory'
|
|
576
|
+
complete -c moshcode -n '__moshcode_nested_is template install; or __moshcode_nested_is templates install' -l force -d 'overwrite existing files'
|
|
577
|
+
complete -c moshcode -n '__moshcode_nested_is template install; or __moshcode_nested_is templates install' -l dry-run -d 'preview without writing'
|
|
578
|
+
complete -c moshcode -n '${nestedCondition("mcp", model.mcpServerSpecs)}' -l name -r -d 'server name'
|
|
579
|
+
complete -c moshcode -n '${nestedCondition("mcp", model.mcpServerSpecs)}' -l transport -s t -r -d 'MCP transport'
|
|
580
|
+
complete -c moshcode -n '${nestedCondition("mcp", model.mcpServerSpecs)}' -l env -s e -r -d 'environment KEY=VALUE'
|
|
581
|
+
complete -c moshcode -n '${nestedCondition("mcp", model.mcpServerSpecs)}' -l header -s H -r -d 'HTTP Name: Value header'
|
|
582
|
+
complete -c moshcode -n '${nestedCondition("skill", model.skillSources)}; or ${nestedCondition("skills", model.skillSources)}' -l name -r -d 'installed skill name'
|
|
583
|
+
`;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
export function completionScript(shell) {
|
|
587
|
+
const normalized = String(shell || "").trim().toLowerCase();
|
|
588
|
+
const model = completionModel();
|
|
589
|
+
if (normalized === "bash") return bashCompletion(model);
|
|
590
|
+
if (normalized === "zsh") return zshCompletion(model);
|
|
591
|
+
if (normalized === "fish") return fishCompletion(model);
|
|
592
|
+
if (normalized === "powershell" || normalized === "pwsh") return powershellCompletion(model);
|
|
593
|
+
throw new Error(`unsupported shell ${JSON.stringify(shell)}; choose: ${COMPLETION_SHELLS.join(", ")}`);
|
|
594
|
+
}
|