wp-typia 0.24.4 → 0.24.6
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 +8 -6
- package/bin/wp-typia.js +24 -103
- package/{dist-bunli/node-cli.js → dist/cli.js} +5086 -3693
- package/package.json +9 -36
- package/bin/routing-metadata.generated.d.ts +0 -8
- package/bin/routing-metadata.generated.js +0 -93
- package/bin/runtime-routing.d.ts +0 -34
- package/bin/runtime-routing.js +0 -124
- package/dist-bunli/.bunli/commands.gen.js +0 -304441
- package/dist-bunli/.bunli/highlights-eq9cgrbb.scm +0 -604
- package/dist-bunli/.bunli/highlights-ghv9g403.scm +0 -205
- package/dist-bunli/.bunli/highlights-hk7bwhj4.scm +0 -284
- package/dist-bunli/.bunli/highlights-r812a2qc.scm +0 -150
- package/dist-bunli/.bunli/highlights-x6tmsnaa.scm +0 -115
- package/dist-bunli/.bunli/injections-73j83es3.scm +0 -27
- package/dist-bunli/.bunli/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist-bunli/.bunli/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist-bunli/.bunli/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist-bunli/.bunli/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist-bunli/.bunli/tree-sitter-zig-e78zbjpm.wasm +0 -0
- package/dist-bunli/agents-91fpdyyt.js +0 -12
- package/dist-bunli/chunk-bdqvmfwv-f5qmzmxg.js +0 -16825
- package/dist-bunli/cli-03j0axbt.js +0 -163
- package/dist-bunli/cli-1170yyve.js +0 -106
- package/dist-bunli/cli-368d4cgy.js +0 -1235
- package/dist-bunli/cli-377p86mf.js +0 -191
- package/dist-bunli/cli-6v0pcxw6.js +0 -314
- package/dist-bunli/cli-84c7wff4.js +0 -198
- package/dist-bunli/cli-8hxf9qw6.js +0 -198
- package/dist-bunli/cli-9fx0qgb7.js +0 -3680
- package/dist-bunli/cli-ac2ebaf8.js +0 -3
- package/dist-bunli/cli-add-qjd3ba8j.js +0 -10671
- package/dist-bunli/cli-am5x7tb4.js +0 -192
- package/dist-bunli/cli-bajwv85z.js +0 -24
- package/dist-bunli/cli-ccax7s0s.js +0 -34
- package/dist-bunli/cli-cvxvcw7c.js +0 -46
- package/dist-bunli/cli-diagnostics-10drxh34.js +0 -34
- package/dist-bunli/cli-doctor-6fyxq940.js +0 -1446
- package/dist-bunli/cli-e4bwd81c.js +0 -1260
- package/dist-bunli/cli-fv4h3ydt.js +0 -173823
- package/dist-bunli/cli-hv2yedw2.js +0 -74591
- package/dist-bunli/cli-init-7avk42dh.js +0 -880
- package/dist-bunli/cli-kfm9mm68.js +0 -14679
- package/dist-bunli/cli-prompt-ncyg68rn.js +0 -12
- package/dist-bunli/cli-rdcga1bd.js +0 -135
- package/dist-bunli/cli-scaffold-0bb6pr3w.js +0 -538
- package/dist-bunli/cli-t73q5aqz.js +0 -103
- package/dist-bunli/cli-templates-g8t4fm11.js +0 -167
- package/dist-bunli/cli-tj7ajdvf.js +0 -2612
- package/dist-bunli/cli-tq730sqt.js +0 -344
- package/dist-bunli/cli-xnn9xjcy.js +0 -68
- package/dist-bunli/cli-z48frc8t.js +0 -229
- package/dist-bunli/cli.js +0 -2523
- package/dist-bunli/command-list-y3g7e9rb.js +0 -4013
- package/dist-bunli/create-template-validation-4fr851vg.js +0 -16
- package/dist-bunli/migrations-3vngdy51.js +0 -47
- package/dist-bunli/sync-k2k8svyc.js +0 -13
- package/dist-bunli/workspace-project-gmv2a71z.js +0 -22
package/dist-bunli/cli.js
DELETED
|
@@ -1,2523 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
ALL_COMMAND_OPTION_METADATA,
|
|
4
|
-
COMMAND_OPTION_METADATA_BY_GROUP,
|
|
5
|
-
COMMAND_ROUTING_METADATA,
|
|
6
|
-
GLOBAL_OPTION_METADATA,
|
|
7
|
-
WP_TYPIA_CANONICAL_CREATE_USAGE,
|
|
8
|
-
WP_TYPIA_COMMAND_OPTION_GROUP_NAMES_BY_TOP_LEVEL_COMMAND,
|
|
9
|
-
WP_TYPIA_CONFIG_SOURCES,
|
|
10
|
-
WP_TYPIA_RESERVED_TOP_LEVEL_COMMAND_NAMES,
|
|
11
|
-
buildCommandOptionParser,
|
|
12
|
-
collectOptionNamesByType,
|
|
13
|
-
collectPositionalIndexes,
|
|
14
|
-
createMissingOptionValueError,
|
|
15
|
-
createPlugin,
|
|
16
|
-
extractKnownOptionValuesFromArgv,
|
|
17
|
-
findFirstPositionalIndex,
|
|
18
|
-
loadWpTypiaUserConfig,
|
|
19
|
-
loadWpTypiaUserConfigFromSource,
|
|
20
|
-
mergeWpTypiaUserConfig,
|
|
21
|
-
normalizeCliOutputFormatArgv,
|
|
22
|
-
package_default,
|
|
23
|
-
validateCliOutputFormatArgv,
|
|
24
|
-
writeStructuredCliDiagnosticError
|
|
25
|
-
} from "./cli-368d4cgy.js";
|
|
26
|
-
import"./cli-03j0axbt.js";
|
|
27
|
-
import {
|
|
28
|
-
GLOBAL_FLAGS,
|
|
29
|
-
Result,
|
|
30
|
-
TaggedError,
|
|
31
|
-
createCLI,
|
|
32
|
-
deepMerge,
|
|
33
|
-
defineCommand,
|
|
34
|
-
defineConfig,
|
|
35
|
-
defineGroup,
|
|
36
|
-
exports_external
|
|
37
|
-
} from "./cli-hv2yedw2.js";
|
|
38
|
-
import"./cli-ac2ebaf8.js";
|
|
39
|
-
import"./cli-6v0pcxw6.js";
|
|
40
|
-
import"./cli-bajwv85z.js";
|
|
41
|
-
import {
|
|
42
|
-
CLI_DIAGNOSTIC_CODES,
|
|
43
|
-
createCliDiagnosticCodeError
|
|
44
|
-
} from "./cli-tq730sqt.js";
|
|
45
|
-
import {
|
|
46
|
-
__require
|
|
47
|
-
} from "./cli-xnn9xjcy.js";
|
|
48
|
-
|
|
49
|
-
// src/cli.ts
|
|
50
|
-
import fs from "fs";
|
|
51
|
-
import path2 from "path";
|
|
52
|
-
import { fileURLToPath } from "url";
|
|
53
|
-
|
|
54
|
-
// ../../node_modules/.bun/@bunli+plugin-ai-detect@0.6.4+44deef6f8e4a2f18/node_modules/@bunli/plugin-ai-detect/src/index.ts
|
|
55
|
-
var AI_AGENTS = [
|
|
56
|
-
{
|
|
57
|
-
name: "claude",
|
|
58
|
-
envVars: ["CLAUDECODE", "CLAUDE_CODE"],
|
|
59
|
-
detect: (env) => !!env.CLAUDECODE || !!env.CLAUDE_CODE
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
name: "cursor",
|
|
63
|
-
envVars: ["CURSOR_AGENT"],
|
|
64
|
-
detect: (env) => !!env.CURSOR_AGENT
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: "codex",
|
|
68
|
-
envVars: ["CODEX_CI", "CODEX_THREAD_ID", "CODEX_SANDBOX"],
|
|
69
|
-
detect: (env) => !!env.CODEX_CI || !!env.CODEX_THREAD_ID || !!env.CODEX_SANDBOX
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
name: "amp",
|
|
73
|
-
envVars: ["AMP_CURRENT_THREAD_ID", "AGENT"],
|
|
74
|
-
detect: (env) => !!env.AMP_CURRENT_THREAD_ID || env.AGENT === "amp"
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
name: "gemini",
|
|
78
|
-
envVars: ["GEMINI_CLI"],
|
|
79
|
-
detect: (env) => !!env.GEMINI_CLI
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: "opencode",
|
|
83
|
-
envVars: ["OPENCODE"],
|
|
84
|
-
detect: (env) => env.OPENCODE === "1"
|
|
85
|
-
}
|
|
86
|
-
];
|
|
87
|
-
var aiAgentPlugin = createPlugin((options = {}) => {
|
|
88
|
-
const agents = [...AI_AGENTS, ...options.customAgents || []];
|
|
89
|
-
return {
|
|
90
|
-
name: "@bunli/plugin-ai-detect",
|
|
91
|
-
version: "1.0.0",
|
|
92
|
-
store: {
|
|
93
|
-
isAIAgent: false,
|
|
94
|
-
aiAgents: [],
|
|
95
|
-
aiAgentEnvVars: []
|
|
96
|
-
},
|
|
97
|
-
beforeCommand(context) {
|
|
98
|
-
const env = process.env;
|
|
99
|
-
const detectedAgents = [];
|
|
100
|
-
const allDetectedEnvVars = [];
|
|
101
|
-
context.env.isAIAgent = false;
|
|
102
|
-
context.env.aiAgents = [];
|
|
103
|
-
for (const agent of agents) {
|
|
104
|
-
if (agent.detect(env)) {
|
|
105
|
-
detectedAgents.push(agent.name);
|
|
106
|
-
const detectedVars = agent.envVars.filter((v) => !!env[v]);
|
|
107
|
-
allDetectedEnvVars.push(...detectedVars);
|
|
108
|
-
if (options.verbose) {
|
|
109
|
-
console.log(`\uD83E\uDD16 AI agent detected: ${agent.name}`);
|
|
110
|
-
console.log(` Environment variables: ${detectedVars.join(", ")}`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (detectedAgents.length > 0) {
|
|
115
|
-
context.env.isAIAgent = true;
|
|
116
|
-
context.env.aiAgents = detectedAgents;
|
|
117
|
-
if (context.store) {
|
|
118
|
-
context.store.isAIAgent = true;
|
|
119
|
-
context.store.aiAgents = detectedAgents;
|
|
120
|
-
context.store.aiAgentEnvVars = allDetectedEnvVars;
|
|
121
|
-
}
|
|
122
|
-
if (options.verbose) {
|
|
123
|
-
if (detectedAgents.length === 1) {
|
|
124
|
-
console.log(`\uD83E\uDD16 AI agent detected: ${detectedAgents[0]}`);
|
|
125
|
-
} else {
|
|
126
|
-
console.log(`\uD83E\uDD16 Multiple AI agents detected: ${detectedAgents.join(", ")}`);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
} else {
|
|
130
|
-
if (context.store) {
|
|
131
|
-
context.store.isAIAgent = false;
|
|
132
|
-
context.store.aiAgents = [];
|
|
133
|
-
context.store.aiAgentEnvVars = [];
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// ../../node_modules/.bun/@bunli+plugin-completions@0.3.5+44deef6f8e4a2f18/node_modules/@bunli/plugin-completions/dist/index.js
|
|
141
|
-
import { resolve } from "path";
|
|
142
|
-
import { readFile } from "fs/promises";
|
|
143
|
-
import { pathToFileURL } from "url";
|
|
144
|
-
function generate(name, exec) {
|
|
145
|
-
return `#compdef ${name}
|
|
146
|
-
compdef _${name} ${name}
|
|
147
|
-
|
|
148
|
-
# zsh completion for ${name} -*- shell-script -*-
|
|
149
|
-
|
|
150
|
-
__${name}_debug() {
|
|
151
|
-
local file="$BASH_COMP_DEBUG_FILE"
|
|
152
|
-
if [[ -n \${file} ]]; then
|
|
153
|
-
echo "$*" >> "\${file}"
|
|
154
|
-
fi
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
_${name}() {
|
|
158
|
-
local shellCompDirectiveError=${ShellCompDirective.ShellCompDirectiveError}
|
|
159
|
-
local shellCompDirectiveNoSpace=${ShellCompDirective.ShellCompDirectiveNoSpace}
|
|
160
|
-
local shellCompDirectiveNoFileComp=${ShellCompDirective.ShellCompDirectiveNoFileComp}
|
|
161
|
-
local shellCompDirectiveFilterFileExt=${ShellCompDirective.ShellCompDirectiveFilterFileExt}
|
|
162
|
-
local shellCompDirectiveFilterDirs=${ShellCompDirective.ShellCompDirectiveFilterDirs}
|
|
163
|
-
local shellCompDirectiveKeepOrder=${ShellCompDirective.ShellCompDirectiveKeepOrder}
|
|
164
|
-
|
|
165
|
-
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
|
|
166
|
-
local -a completions
|
|
167
|
-
|
|
168
|
-
__${name}_debug "\\n========= starting completion logic =========="
|
|
169
|
-
__${name}_debug "CURRENT: \${CURRENT}, words[*]: \${words[*]}"
|
|
170
|
-
|
|
171
|
-
# The user could have moved the cursor backwards on the command-line.
|
|
172
|
-
# We need to trigger completion from the $CURRENT location, so we need
|
|
173
|
-
# to truncate the command-line ($words) up to the $CURRENT location.
|
|
174
|
-
# (We cannot use $CURSOR as its value does not work when a command is an alias.)
|
|
175
|
-
words=( "\${=words[1,CURRENT]}" )
|
|
176
|
-
__${name}_debug "Truncated words[*]: \${words[*]},"
|
|
177
|
-
|
|
178
|
-
lastParam=\${words[-1]}
|
|
179
|
-
lastChar=\${lastParam[-1]}
|
|
180
|
-
__${name}_debug "lastParam: \${lastParam}, lastChar: \${lastChar}"
|
|
181
|
-
|
|
182
|
-
# For zsh, when completing a flag with an = (e.g., ${name} -n=<TAB>)
|
|
183
|
-
# completions must be prefixed with the flag
|
|
184
|
-
setopt local_options BASH_REMATCH
|
|
185
|
-
if [[ "\${lastParam}" =~ '-.*=' ]]; then
|
|
186
|
-
# We are dealing with a flag with an =
|
|
187
|
-
flagPrefix="-P \${BASH_REMATCH}"
|
|
188
|
-
fi
|
|
189
|
-
|
|
190
|
-
# Prepare the command to obtain completions, ensuring arguments are quoted for eval
|
|
191
|
-
local -a args_to_quote=("\${(@)words[2,-1]}")
|
|
192
|
-
if [ "\${lastChar}" = "" ]; then
|
|
193
|
-
# If the last parameter is complete (there is a space following it)
|
|
194
|
-
# We add an extra empty parameter so we can indicate this to the go completion code.
|
|
195
|
-
__${name}_debug "Adding extra empty parameter"
|
|
196
|
-
args_to_quote+=("")
|
|
197
|
-
fi
|
|
198
|
-
|
|
199
|
-
# Use Zsh's (q) flag to quote each argument safely for eval
|
|
200
|
-
local quoted_args=("\${(@q)args_to_quote}")
|
|
201
|
-
|
|
202
|
-
# Join the main command and the quoted arguments into a single string for eval
|
|
203
|
-
requestComp="${exec} complete -- \${quoted_args[*]}"
|
|
204
|
-
|
|
205
|
-
__${name}_debug "About to call: eval \${requestComp}"
|
|
206
|
-
|
|
207
|
-
# Use eval to handle any environment variables and such
|
|
208
|
-
out=$(eval \${requestComp} 2>/dev/null)
|
|
209
|
-
__${name}_debug "completion output: \${out}"
|
|
210
|
-
|
|
211
|
-
# Extract the directive integer following a : from the last line
|
|
212
|
-
local lastLine
|
|
213
|
-
while IFS='
|
|
214
|
-
' read -r line; do
|
|
215
|
-
lastLine=\${line}
|
|
216
|
-
done < <(printf "%s
|
|
217
|
-
" "\${out[@]}")
|
|
218
|
-
__${name}_debug "last line: \${lastLine}"
|
|
219
|
-
|
|
220
|
-
if [ "\${lastLine[1]}" = : ]; then
|
|
221
|
-
directive=\${lastLine[2,-1]}
|
|
222
|
-
# Remove the directive including the : and the newline
|
|
223
|
-
local suffix
|
|
224
|
-
(( suffix=\${#lastLine}+2))
|
|
225
|
-
out=\${out[1,-$suffix]}
|
|
226
|
-
else
|
|
227
|
-
# There is no directive specified. Leave $out as is.
|
|
228
|
-
__${name}_debug "No directive found. Setting to default"
|
|
229
|
-
directive=0
|
|
230
|
-
fi
|
|
231
|
-
|
|
232
|
-
__${name}_debug "directive: \${directive}"
|
|
233
|
-
__${name}_debug "completions: \${out}"
|
|
234
|
-
__${name}_debug "flagPrefix: \${flagPrefix}"
|
|
235
|
-
|
|
236
|
-
if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
|
|
237
|
-
__${name}_debug "Completion received error. Ignoring completions."
|
|
238
|
-
return
|
|
239
|
-
fi
|
|
240
|
-
|
|
241
|
-
local activeHelpMarker="%"
|
|
242
|
-
local endIndex=\${#activeHelpMarker}
|
|
243
|
-
local startIndex=$((\${#activeHelpMarker}+1))
|
|
244
|
-
local hasActiveHelp=0
|
|
245
|
-
while IFS='
|
|
246
|
-
' read -r comp; do
|
|
247
|
-
# Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker)
|
|
248
|
-
if [ "\${comp[1,$endIndex]}" = "$activeHelpMarker" ];then
|
|
249
|
-
__${name}_debug "ActiveHelp found: $comp"
|
|
250
|
-
comp="\${comp[$startIndex,-1]}"
|
|
251
|
-
if [ -n "$comp" ]; then
|
|
252
|
-
compadd -x "\${comp}"
|
|
253
|
-
__${name}_debug "ActiveHelp will need delimiter"
|
|
254
|
-
hasActiveHelp=1
|
|
255
|
-
fi
|
|
256
|
-
continue
|
|
257
|
-
fi
|
|
258
|
-
|
|
259
|
-
if [ -n "$comp" ]; then
|
|
260
|
-
# If requested, completions are returned with a description.
|
|
261
|
-
# The description is preceded by a TAB character.
|
|
262
|
-
# For zsh's _describe, we need to use a : instead of a TAB.
|
|
263
|
-
# We first need to escape any : as part of the completion itself.
|
|
264
|
-
comp=\${comp//:/\\:}
|
|
265
|
-
|
|
266
|
-
local tab="$(printf '\\t')"
|
|
267
|
-
comp=\${comp//$tab/:}
|
|
268
|
-
|
|
269
|
-
__${name}_debug "Adding completion: \${comp}"
|
|
270
|
-
completions+=\${comp}
|
|
271
|
-
lastComp=$comp
|
|
272
|
-
fi
|
|
273
|
-
done < <(printf "%s
|
|
274
|
-
" "\${out[@]}")
|
|
275
|
-
|
|
276
|
-
# Add a delimiter after the activeHelp statements, but only if:
|
|
277
|
-
# - there are completions following the activeHelp statements, or
|
|
278
|
-
# - file completion will be performed (so there will be choices after the activeHelp)
|
|
279
|
-
if [ $hasActiveHelp -eq 1 ]; then
|
|
280
|
-
if [ \${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then
|
|
281
|
-
__${name}_debug "Adding activeHelp delimiter"
|
|
282
|
-
compadd -x "--"
|
|
283
|
-
hasActiveHelp=0
|
|
284
|
-
fi
|
|
285
|
-
fi
|
|
286
|
-
|
|
287
|
-
if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
|
|
288
|
-
__${name}_debug "Activating nospace."
|
|
289
|
-
noSpace="-S ''"
|
|
290
|
-
fi
|
|
291
|
-
|
|
292
|
-
if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
|
|
293
|
-
__${name}_debug "Activating keep order."
|
|
294
|
-
keepOrder="-V"
|
|
295
|
-
fi
|
|
296
|
-
|
|
297
|
-
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
|
|
298
|
-
# File extension filtering
|
|
299
|
-
local filteringCmd
|
|
300
|
-
filteringCmd='_files'
|
|
301
|
-
for filter in \${completions[@]}; do
|
|
302
|
-
if [ \${filter[1]} != '*' ]; then
|
|
303
|
-
# zsh requires a glob pattern to do file filtering
|
|
304
|
-
filter="\\*.$filter"
|
|
305
|
-
fi
|
|
306
|
-
filteringCmd+=" -g $filter"
|
|
307
|
-
done
|
|
308
|
-
filteringCmd+=" \${flagPrefix}"
|
|
309
|
-
|
|
310
|
-
__${name}_debug "File filtering command: $filteringCmd"
|
|
311
|
-
_arguments '*:filename:'"$filteringCmd"
|
|
312
|
-
elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
|
|
313
|
-
# File completion for directories only
|
|
314
|
-
local subdir
|
|
315
|
-
subdir="\${completions[1]}"
|
|
316
|
-
if [ -n "$subdir" ]; then
|
|
317
|
-
__${name}_debug "Listing directories in $subdir"
|
|
318
|
-
pushd "\${subdir}" >/dev/null 2>&1
|
|
319
|
-
else
|
|
320
|
-
__${name}_debug "Listing directories in ."
|
|
321
|
-
fi
|
|
322
|
-
|
|
323
|
-
local result
|
|
324
|
-
_arguments '*:dirname:_files -/'" \${flagPrefix}"
|
|
325
|
-
result=$?
|
|
326
|
-
if [ -n "$subdir" ]; then
|
|
327
|
-
popd >/dev/null 2>&1
|
|
328
|
-
fi
|
|
329
|
-
return $result
|
|
330
|
-
else
|
|
331
|
-
__${name}_debug "Calling _describe"
|
|
332
|
-
if eval _describe $keepOrder "completions" completions -Q \${flagPrefix} \${noSpace}; then
|
|
333
|
-
__${name}_debug "_describe found some completions"
|
|
334
|
-
|
|
335
|
-
# Return the success of having called _describe
|
|
336
|
-
return 0
|
|
337
|
-
else
|
|
338
|
-
__${name}_debug "_describe did not find completions."
|
|
339
|
-
__${name}_debug "Checking if we should do file completion."
|
|
340
|
-
if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
|
|
341
|
-
__${name}_debug "deactivating file completion"
|
|
342
|
-
|
|
343
|
-
# Return 0 to indicate completion is finished and prevent zsh from
|
|
344
|
-
# trying other completion algorithms (which could cause hanging).
|
|
345
|
-
# We use NoFileComp directive to explicitly disable file completion.
|
|
346
|
-
return 0
|
|
347
|
-
else
|
|
348
|
-
# Perform file completion
|
|
349
|
-
__${name}_debug "Activating file completion"
|
|
350
|
-
|
|
351
|
-
# We must return the result of this command, so it must be the
|
|
352
|
-
# last command, or else we must store its result to return it.
|
|
353
|
-
_arguments '*:filename:_files'" \${flagPrefix}"
|
|
354
|
-
fi
|
|
355
|
-
fi
|
|
356
|
-
fi
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
# don't run the completion function when being sourced or eval-ed
|
|
360
|
-
if [ "\${funcstack[1]}" = "_${name}" ]; then
|
|
361
|
-
_${name}
|
|
362
|
-
fi
|
|
363
|
-
`;
|
|
364
|
-
}
|
|
365
|
-
function generate2(name, exec) {
|
|
366
|
-
const nameForVar = name.replace(/[-:]/g, "_");
|
|
367
|
-
const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError;
|
|
368
|
-
const ShellCompDirectiveNoSpace = ShellCompDirective.ShellCompDirectiveNoSpace;
|
|
369
|
-
const ShellCompDirectiveNoFileComp = ShellCompDirective.ShellCompDirectiveNoFileComp;
|
|
370
|
-
const ShellCompDirectiveFilterFileExt = ShellCompDirective.ShellCompDirectiveFilterFileExt;
|
|
371
|
-
const ShellCompDirectiveFilterDirs = ShellCompDirective.ShellCompDirectiveFilterDirs;
|
|
372
|
-
const ShellCompDirectiveKeepOrder = ShellCompDirective.ShellCompDirectiveKeepOrder;
|
|
373
|
-
return `# bash completion for ${name}
|
|
374
|
-
|
|
375
|
-
# Define shell completion directives
|
|
376
|
-
readonly ShellCompDirectiveError=${ShellCompDirectiveError}
|
|
377
|
-
readonly ShellCompDirectiveNoSpace=${ShellCompDirectiveNoSpace}
|
|
378
|
-
readonly ShellCompDirectiveNoFileComp=${ShellCompDirectiveNoFileComp}
|
|
379
|
-
readonly ShellCompDirectiveFilterFileExt=${ShellCompDirectiveFilterFileExt}
|
|
380
|
-
readonly ShellCompDirectiveFilterDirs=${ShellCompDirectiveFilterDirs}
|
|
381
|
-
readonly ShellCompDirectiveKeepOrder=${ShellCompDirectiveKeepOrder}
|
|
382
|
-
|
|
383
|
-
# Function to debug completion
|
|
384
|
-
__${nameForVar}_debug() {
|
|
385
|
-
if [[ -n \${BASH_COMP_DEBUG_FILE:-} ]]; then
|
|
386
|
-
echo "$*" >> "\${BASH_COMP_DEBUG_FILE}"
|
|
387
|
-
fi
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
# Function to handle completions
|
|
391
|
-
__${nameForVar}_complete() {
|
|
392
|
-
local cur prev words cword
|
|
393
|
-
_get_comp_words_by_ref -n "=:" cur prev words cword
|
|
394
|
-
|
|
395
|
-
local requestComp out directive
|
|
396
|
-
|
|
397
|
-
# Build the command to get completions
|
|
398
|
-
requestComp="${exec} complete -- \${words[@]:1}"
|
|
399
|
-
|
|
400
|
-
# Add an empty parameter if the last parameter is complete
|
|
401
|
-
if [[ -z "$cur" ]]; then
|
|
402
|
-
requestComp="$requestComp ''"
|
|
403
|
-
fi
|
|
404
|
-
|
|
405
|
-
# Get completions from the program
|
|
406
|
-
out=$(eval "$requestComp" 2>/dev/null)
|
|
407
|
-
|
|
408
|
-
# Extract directive if present
|
|
409
|
-
directive=0
|
|
410
|
-
if [[ "$out" == *:* ]]; then
|
|
411
|
-
directive=\${out##*:}
|
|
412
|
-
out=\${out%:*}
|
|
413
|
-
fi
|
|
414
|
-
|
|
415
|
-
# Process completions based on directive
|
|
416
|
-
if [[ $((directive & $ShellCompDirectiveError)) -ne 0 ]]; then
|
|
417
|
-
# Error, no completion
|
|
418
|
-
return
|
|
419
|
-
fi
|
|
420
|
-
|
|
421
|
-
# Apply directives
|
|
422
|
-
if [[ $((directive & $ShellCompDirectiveNoSpace)) -ne 0 ]]; then
|
|
423
|
-
compopt -o nospace
|
|
424
|
-
fi
|
|
425
|
-
if [[ $((directive & $ShellCompDirectiveKeepOrder)) -ne 0 ]]; then
|
|
426
|
-
compopt -o nosort
|
|
427
|
-
fi
|
|
428
|
-
if [[ $((directive & $ShellCompDirectiveNoFileComp)) -ne 0 ]]; then
|
|
429
|
-
compopt +o default
|
|
430
|
-
fi
|
|
431
|
-
|
|
432
|
-
# Handle file extension filtering
|
|
433
|
-
if [[ $((directive & $ShellCompDirectiveFilterFileExt)) -ne 0 ]]; then
|
|
434
|
-
local filter=""
|
|
435
|
-
for ext in $out; do
|
|
436
|
-
filter="$filter|$ext"
|
|
437
|
-
done
|
|
438
|
-
filter="\\.($filter)"
|
|
439
|
-
compopt -o filenames
|
|
440
|
-
COMPREPLY=( $(compgen -f -X "!$filter" -- "$cur") )
|
|
441
|
-
return
|
|
442
|
-
fi
|
|
443
|
-
|
|
444
|
-
# Handle directory filtering
|
|
445
|
-
if [[ $((directive & $ShellCompDirectiveFilterDirs)) -ne 0 ]]; then
|
|
446
|
-
compopt -o dirnames
|
|
447
|
-
COMPREPLY=( $(compgen -d -- "$cur") )
|
|
448
|
-
return
|
|
449
|
-
fi
|
|
450
|
-
|
|
451
|
-
# Process completions
|
|
452
|
-
local IFS=$'\\n'
|
|
453
|
-
local tab=$(printf '\\t')
|
|
454
|
-
|
|
455
|
-
# Parse completions with descriptions
|
|
456
|
-
local completions=()
|
|
457
|
-
while read -r comp; do
|
|
458
|
-
if [[ "$comp" == *$tab* ]]; then
|
|
459
|
-
# Split completion and description
|
|
460
|
-
local value=\${comp%%$tab*}
|
|
461
|
-
local desc=\${comp#*$tab}
|
|
462
|
-
completions+=("$value")
|
|
463
|
-
else
|
|
464
|
-
completions+=("$comp")
|
|
465
|
-
fi
|
|
466
|
-
done <<< "$out"
|
|
467
|
-
|
|
468
|
-
# Return completions
|
|
469
|
-
COMPREPLY=( $(compgen -W "\${completions[*]}" -- "$cur") )
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
# Register completion function
|
|
473
|
-
complete -F __${nameForVar}_complete ${name}
|
|
474
|
-
`;
|
|
475
|
-
}
|
|
476
|
-
function generate3(name, exec) {
|
|
477
|
-
const nameForVar = name.replace(/[-:]/g, "_");
|
|
478
|
-
const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError;
|
|
479
|
-
const ShellCompDirectiveNoSpace = ShellCompDirective.ShellCompDirectiveNoSpace;
|
|
480
|
-
const ShellCompDirectiveNoFileComp = ShellCompDirective.ShellCompDirectiveNoFileComp;
|
|
481
|
-
const ShellCompDirectiveFilterFileExt = ShellCompDirective.ShellCompDirectiveFilterFileExt;
|
|
482
|
-
const ShellCompDirectiveFilterDirs = ShellCompDirective.ShellCompDirectiveFilterDirs;
|
|
483
|
-
const ShellCompDirectiveKeepOrder = ShellCompDirective.ShellCompDirectiveKeepOrder;
|
|
484
|
-
return `# fish completion for ${name} -*- shell-script -*-
|
|
485
|
-
|
|
486
|
-
function __${nameForVar}_debug
|
|
487
|
-
set -l file "$BASH_COMP_DEBUG_FILE"
|
|
488
|
-
if test -n "$file"
|
|
489
|
-
echo "$argv" >> $file
|
|
490
|
-
end
|
|
491
|
-
end
|
|
492
|
-
|
|
493
|
-
function __${nameForVar}_perform_completion
|
|
494
|
-
__${nameForVar}_debug "Starting __${nameForVar}_perform_completion"
|
|
495
|
-
|
|
496
|
-
# Extract all args except the last one
|
|
497
|
-
set -l args (commandline -opc)
|
|
498
|
-
# Extract the last arg and escape it in case it is a space or wildcard
|
|
499
|
-
set -l lastArg (string escape -- (commandline -ct))
|
|
500
|
-
|
|
501
|
-
__${nameForVar}_debug "args: $args"
|
|
502
|
-
__${nameForVar}_debug "last arg: $lastArg"
|
|
503
|
-
|
|
504
|
-
# Build the completion request command
|
|
505
|
-
set -l requestComp "${exec} complete -- (string join ' ' -- (string escape -- $args[2..-1])) $lastArg"
|
|
506
|
-
|
|
507
|
-
__${nameForVar}_debug "Calling $requestComp"
|
|
508
|
-
set -l results (eval $requestComp 2> /dev/null)
|
|
509
|
-
|
|
510
|
-
# Some programs may output extra empty lines after the directive.
|
|
511
|
-
# Let's ignore them or else it will break completion.
|
|
512
|
-
# Ref: https://github.com/spf13/cobra/issues/1279
|
|
513
|
-
for line in $results[-1..1]
|
|
514
|
-
if test (string trim -- $line) = ""
|
|
515
|
-
# Found an empty line, remove it
|
|
516
|
-
set results $results[1..-2]
|
|
517
|
-
else
|
|
518
|
-
# Found non-empty line, we have our proper output
|
|
519
|
-
break
|
|
520
|
-
end
|
|
521
|
-
end
|
|
522
|
-
|
|
523
|
-
set -l comps $results[1..-2]
|
|
524
|
-
set -l directiveLine $results[-1]
|
|
525
|
-
|
|
526
|
-
# For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>)
|
|
527
|
-
# completions must be prefixed with the flag
|
|
528
|
-
set -l flagPrefix (string match -r -- '-.*=' "$lastArg")
|
|
529
|
-
|
|
530
|
-
__${nameForVar}_debug "Comps: $comps"
|
|
531
|
-
__${nameForVar}_debug "DirectiveLine: $directiveLine"
|
|
532
|
-
__${nameForVar}_debug "flagPrefix: $flagPrefix"
|
|
533
|
-
|
|
534
|
-
for comp in $comps
|
|
535
|
-
printf "%s%s\\n" "$flagPrefix" "$comp"
|
|
536
|
-
end
|
|
537
|
-
|
|
538
|
-
printf "%s\\n" "$directiveLine"
|
|
539
|
-
end
|
|
540
|
-
|
|
541
|
-
# This function limits calls to __${nameForVar}_perform_completion, by caching the result
|
|
542
|
-
function __${nameForVar}_perform_completion_once
|
|
543
|
-
__${nameForVar}_debug "Starting __${nameForVar}_perform_completion_once"
|
|
544
|
-
|
|
545
|
-
if test -n "$__${nameForVar}_perform_completion_once_result"
|
|
546
|
-
__${nameForVar}_debug "Seems like a valid result already exists, skipping __${nameForVar}_perform_completion"
|
|
547
|
-
return 0
|
|
548
|
-
end
|
|
549
|
-
|
|
550
|
-
set --global __${nameForVar}_perform_completion_once_result (__${nameForVar}_perform_completion)
|
|
551
|
-
if test -z "$__${nameForVar}_perform_completion_once_result"
|
|
552
|
-
__${nameForVar}_debug "No completions, probably due to a failure"
|
|
553
|
-
return 1
|
|
554
|
-
end
|
|
555
|
-
|
|
556
|
-
__${nameForVar}_debug "Performed completions and set __${nameForVar}_perform_completion_once_result"
|
|
557
|
-
return 0
|
|
558
|
-
end
|
|
559
|
-
|
|
560
|
-
# This function is used to clear the cached result after completions are run
|
|
561
|
-
function __${nameForVar}_clear_perform_completion_once_result
|
|
562
|
-
__${nameForVar}_debug ""
|
|
563
|
-
__${nameForVar}_debug "========= clearing previously set __${nameForVar}_perform_completion_once_result variable =========="
|
|
564
|
-
set --erase __${nameForVar}_perform_completion_once_result
|
|
565
|
-
__${nameForVar}_debug "Successfully erased the variable __${nameForVar}_perform_completion_once_result"
|
|
566
|
-
end
|
|
567
|
-
|
|
568
|
-
function __${nameForVar}_requires_order_preservation
|
|
569
|
-
__${nameForVar}_debug ""
|
|
570
|
-
__${nameForVar}_debug "========= checking if order preservation is required =========="
|
|
571
|
-
|
|
572
|
-
__${nameForVar}_perform_completion_once
|
|
573
|
-
if test -z "$__${nameForVar}_perform_completion_once_result"
|
|
574
|
-
__${nameForVar}_debug "Error determining if order preservation is required"
|
|
575
|
-
return 1
|
|
576
|
-
end
|
|
577
|
-
|
|
578
|
-
set -l directive (string sub --start 2 $__${nameForVar}_perform_completion_once_result[-1])
|
|
579
|
-
__${nameForVar}_debug "Directive is: $directive"
|
|
580
|
-
|
|
581
|
-
set -l shellCompDirectiveKeepOrder ${ShellCompDirectiveKeepOrder}
|
|
582
|
-
set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) % 2)
|
|
583
|
-
__${nameForVar}_debug "Keeporder is: $keeporder"
|
|
584
|
-
|
|
585
|
-
if test $keeporder -ne 0
|
|
586
|
-
__${nameForVar}_debug "This does require order preservation"
|
|
587
|
-
return 0
|
|
588
|
-
end
|
|
589
|
-
|
|
590
|
-
__${nameForVar}_debug "This doesn't require order preservation"
|
|
591
|
-
return 1
|
|
592
|
-
end
|
|
593
|
-
|
|
594
|
-
# This function does two things:
|
|
595
|
-
# - Obtain the completions and store them in the global __${nameForVar}_comp_results
|
|
596
|
-
# - Return false if file completion should be performed
|
|
597
|
-
function __${nameForVar}_prepare_completions
|
|
598
|
-
__${nameForVar}_debug ""
|
|
599
|
-
__${nameForVar}_debug "========= starting completion logic =========="
|
|
600
|
-
|
|
601
|
-
# Start fresh
|
|
602
|
-
set --erase __${nameForVar}_comp_results
|
|
603
|
-
|
|
604
|
-
__${nameForVar}_perform_completion_once
|
|
605
|
-
__${nameForVar}_debug "Completion results: $__${nameForVar}_perform_completion_once_result"
|
|
606
|
-
|
|
607
|
-
if test -z "$__${nameForVar}_perform_completion_once_result"
|
|
608
|
-
__${nameForVar}_debug "No completion, probably due to a failure"
|
|
609
|
-
# Might as well do file completion, in case it helps
|
|
610
|
-
return 1
|
|
611
|
-
end
|
|
612
|
-
|
|
613
|
-
set -l directive (string sub --start 2 $__${nameForVar}_perform_completion_once_result[-1])
|
|
614
|
-
set --global __${nameForVar}_comp_results $__${nameForVar}_perform_completion_once_result[1..-2]
|
|
615
|
-
|
|
616
|
-
__${nameForVar}_debug "Completions are: $__${nameForVar}_comp_results"
|
|
617
|
-
__${nameForVar}_debug "Directive is: $directive"
|
|
618
|
-
|
|
619
|
-
set -l shellCompDirectiveError ${ShellCompDirectiveError}
|
|
620
|
-
set -l shellCompDirectiveNoSpace ${ShellCompDirectiveNoSpace}
|
|
621
|
-
set -l shellCompDirectiveNoFileComp ${ShellCompDirectiveNoFileComp}
|
|
622
|
-
set -l shellCompDirectiveFilterFileExt ${ShellCompDirectiveFilterFileExt}
|
|
623
|
-
set -l shellCompDirectiveFilterDirs ${ShellCompDirectiveFilterDirs}
|
|
624
|
-
|
|
625
|
-
if test -z "$directive"
|
|
626
|
-
set directive 0
|
|
627
|
-
end
|
|
628
|
-
|
|
629
|
-
set -l compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2)
|
|
630
|
-
if test $compErr -eq 1
|
|
631
|
-
__${nameForVar}_debug "Received error directive: aborting."
|
|
632
|
-
# Might as well do file completion, in case it helps
|
|
633
|
-
return 1
|
|
634
|
-
end
|
|
635
|
-
|
|
636
|
-
set -l filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2)
|
|
637
|
-
set -l dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2)
|
|
638
|
-
if test $filefilter -eq 1; or test $dirfilter -eq 1
|
|
639
|
-
__${nameForVar}_debug "File extension filtering or directory filtering not supported"
|
|
640
|
-
# Do full file completion instead
|
|
641
|
-
return 1
|
|
642
|
-
end
|
|
643
|
-
|
|
644
|
-
set -l nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2)
|
|
645
|
-
set -l nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2)
|
|
646
|
-
|
|
647
|
-
__${nameForVar}_debug "nospace: $nospace, nofiles: $nofiles"
|
|
648
|
-
|
|
649
|
-
# If we want to prevent a space, or if file completion is NOT disabled,
|
|
650
|
-
# we need to count the number of valid completions.
|
|
651
|
-
# To do so, we will filter on prefix as the completions we have received
|
|
652
|
-
# may not already be filtered so as to allow fish to match on different
|
|
653
|
-
# criteria than the prefix.
|
|
654
|
-
if test $nospace -ne 0; or test $nofiles -eq 0
|
|
655
|
-
set -l prefix (commandline -t | string escape --style=regex)
|
|
656
|
-
__${nameForVar}_debug "prefix: $prefix"
|
|
657
|
-
|
|
658
|
-
set -l completions (string match -r -- "^$prefix.*" $__${nameForVar}_comp_results)
|
|
659
|
-
set --global __${nameForVar}_comp_results $completions
|
|
660
|
-
__${nameForVar}_debug "Filtered completions are: $__${nameForVar}_comp_results"
|
|
661
|
-
|
|
662
|
-
# Important not to quote the variable for count to work
|
|
663
|
-
set -l numComps (count $__${nameForVar}_comp_results)
|
|
664
|
-
__${nameForVar}_debug "numComps: $numComps"
|
|
665
|
-
|
|
666
|
-
if test $numComps -eq 1; and test $nospace -ne 0
|
|
667
|
-
# We must first split on \\t to get rid of the descriptions to be
|
|
668
|
-
# able to check what the actual completion will be.
|
|
669
|
-
# We don't need descriptions anyway since there is only a single
|
|
670
|
-
# real completion which the shell will expand immediately.
|
|
671
|
-
set -l split (string split --max 1 "\\t" $__${nameForVar}_comp_results[1])
|
|
672
|
-
|
|
673
|
-
# Fish won't add a space if the completion ends with any
|
|
674
|
-
# of the following characters: @=/:.,
|
|
675
|
-
set -l lastChar (string sub -s -1 -- $split)
|
|
676
|
-
if not string match -r -q "[@=/:.,]" -- "$lastChar"
|
|
677
|
-
# In other cases, to support the "nospace" directive we trick the shell
|
|
678
|
-
# by outputting an extra, longer completion.
|
|
679
|
-
__${nameForVar}_debug "Adding second completion to perform nospace directive"
|
|
680
|
-
set --global __${nameForVar}_comp_results $split[1] $split[1].
|
|
681
|
-
__${nameForVar}_debug "Completions are now: $__${nameForVar}_comp_results"
|
|
682
|
-
end
|
|
683
|
-
end
|
|
684
|
-
|
|
685
|
-
if test $numComps -eq 0; and test $nofiles -eq 0
|
|
686
|
-
# To be consistent with bash and zsh, we only trigger file
|
|
687
|
-
# completion when there are no other completions
|
|
688
|
-
__${nameForVar}_debug "Requesting file completion"
|
|
689
|
-
return 1
|
|
690
|
-
end
|
|
691
|
-
end
|
|
692
|
-
|
|
693
|
-
return 0
|
|
694
|
-
end
|
|
695
|
-
|
|
696
|
-
# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
|
|
697
|
-
# so we can properly delete any completions provided by another script.
|
|
698
|
-
# Only do this if the program can be found, or else fish may print some errors; besides,
|
|
699
|
-
# the existing completions will only be loaded if the program can be found.
|
|
700
|
-
if type -q "${name}"
|
|
701
|
-
# The space after the program name is essential to trigger completion for the program
|
|
702
|
-
# and not completion of the program name itself.
|
|
703
|
-
# Also, we use '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.
|
|
704
|
-
complete --do-complete "${name} " > /dev/null 2>&1
|
|
705
|
-
end
|
|
706
|
-
|
|
707
|
-
# Remove any pre-existing completions for the program since we will be handling all of them.
|
|
708
|
-
complete -c ${name} -e
|
|
709
|
-
|
|
710
|
-
# This will get called after the two calls below and clear the cached result
|
|
711
|
-
complete -c ${name} -n '__${nameForVar}_clear_perform_completion_once_result'
|
|
712
|
-
# The call to __${nameForVar}_prepare_completions will setup __${nameForVar}_comp_results
|
|
713
|
-
# which provides the program's completion choices.
|
|
714
|
-
# If this doesn't require order preservation, we don't use the -k flag
|
|
715
|
-
complete -c ${name} -n 'not __${nameForVar}_requires_order_preservation && __${nameForVar}_prepare_completions' -f -a '$__${nameForVar}_comp_results'
|
|
716
|
-
# Otherwise we use the -k flag
|
|
717
|
-
complete -k -c ${name} -n '__${nameForVar}_requires_order_preservation && __${nameForVar}_prepare_completions' -f -a '$__${nameForVar}_comp_results'
|
|
718
|
-
`;
|
|
719
|
-
}
|
|
720
|
-
function generate4(name, exec) {
|
|
721
|
-
const nameForVar = name.replace(/[-:]/g, "_");
|
|
722
|
-
const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError;
|
|
723
|
-
const ShellCompDirectiveNoSpace = ShellCompDirective.ShellCompDirectiveNoSpace;
|
|
724
|
-
const ShellCompDirectiveNoFileComp = ShellCompDirective.ShellCompDirectiveNoFileComp;
|
|
725
|
-
const ShellCompDirectiveFilterFileExt = ShellCompDirective.ShellCompDirectiveFilterFileExt;
|
|
726
|
-
const ShellCompDirectiveFilterDirs = ShellCompDirective.ShellCompDirectiveFilterDirs;
|
|
727
|
-
const ShellCompDirectiveKeepOrder = ShellCompDirective.ShellCompDirectiveKeepOrder;
|
|
728
|
-
return `# powershell completion for ${name} -*- shell-script -*-
|
|
729
|
-
|
|
730
|
-
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
731
|
-
function __${name}_debug {
|
|
732
|
-
if ($env:BASH_COMP_DEBUG_FILE) {
|
|
733
|
-
"$args" | Out-File -Append -FilePath "$env:BASH_COMP_DEBUG_FILE"
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
filter __${name}_escapeStringWithSpecialChars {
|
|
738
|
-
$_ -replace '\\s|#|@|\\$|;|,|''|\\{|\\}|\\(|\\)|"|\\||<|>|&','\`$&'
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
[scriptblock]$__${nameForVar}CompleterBlock = {
|
|
742
|
-
param(
|
|
743
|
-
$WordToComplete,
|
|
744
|
-
$CommandAst,
|
|
745
|
-
$CursorPosition
|
|
746
|
-
)
|
|
747
|
-
|
|
748
|
-
# Get the current command line and convert into a string
|
|
749
|
-
$Command = $CommandAst.CommandElements
|
|
750
|
-
$Command = "$Command"
|
|
751
|
-
|
|
752
|
-
__${name}_debug ""
|
|
753
|
-
__${name}_debug "========= starting completion logic =========="
|
|
754
|
-
__${name}_debug "WordToComplete: $WordToComplete Command: $Command CursorPosition: $CursorPosition"
|
|
755
|
-
|
|
756
|
-
# The user could have moved the cursor backwards on the command-line.
|
|
757
|
-
# We need to trigger completion from the $CursorPosition location, so we need
|
|
758
|
-
# to truncate the command-line ($Command) up to the $CursorPosition location.
|
|
759
|
-
# Make sure the $Command is longer then the $CursorPosition before we truncate.
|
|
760
|
-
# This happens because the $Command does not include the last space.
|
|
761
|
-
if ($Command.Length -gt $CursorPosition) {
|
|
762
|
-
$Command = $Command.Substring(0, $CursorPosition)
|
|
763
|
-
}
|
|
764
|
-
__${name}_debug "Truncated command: $Command"
|
|
765
|
-
|
|
766
|
-
$ShellCompDirectiveError=${ShellCompDirectiveError}
|
|
767
|
-
$ShellCompDirectiveNoSpace=${ShellCompDirectiveNoSpace}
|
|
768
|
-
$ShellCompDirectiveNoFileComp=${ShellCompDirectiveNoFileComp}
|
|
769
|
-
$ShellCompDirectiveFilterFileExt=${ShellCompDirectiveFilterFileExt}
|
|
770
|
-
$ShellCompDirectiveFilterDirs=${ShellCompDirectiveFilterDirs}
|
|
771
|
-
$ShellCompDirectiveKeepOrder=${ShellCompDirectiveKeepOrder}
|
|
772
|
-
|
|
773
|
-
# Prepare the command to request completions for the program.
|
|
774
|
-
# Split the command at the first space to separate the program and arguments.
|
|
775
|
-
$Program, $Arguments = $Command.Split(" ", 2)
|
|
776
|
-
|
|
777
|
-
$QuotedArgs = ($Arguments -split ' ' | ForEach-Object { "'" + ($_ -replace "'", "''") + "'" }) -join ' '
|
|
778
|
-
__${name}_debug "QuotedArgs: $QuotedArgs"
|
|
779
|
-
|
|
780
|
-
$RequestComp = "& ${exec} complete '--' $QuotedArgs"
|
|
781
|
-
__${name}_debug "RequestComp: $RequestComp"
|
|
782
|
-
|
|
783
|
-
# we cannot use $WordToComplete because it
|
|
784
|
-
# has the wrong values if the cursor was moved
|
|
785
|
-
# so use the last argument
|
|
786
|
-
if ($WordToComplete -ne "" ) {
|
|
787
|
-
$WordToComplete = $Arguments.Split(" ")[-1]
|
|
788
|
-
}
|
|
789
|
-
__${name}_debug "New WordToComplete: $WordToComplete"
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
# Check for flag with equal sign
|
|
793
|
-
$IsEqualFlag = ($WordToComplete -Like "--*=*" )
|
|
794
|
-
if ( $IsEqualFlag ) {
|
|
795
|
-
__${name}_debug "Completing equal sign flag"
|
|
796
|
-
# Remove the flag part
|
|
797
|
-
$Flag, $WordToComplete = $WordToComplete.Split("=", 2)
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
if ( $WordToComplete -eq "" -And ( -Not $IsEqualFlag )) {
|
|
801
|
-
# If the last parameter is complete (there is a space following it)
|
|
802
|
-
# We add an extra empty parameter so we can indicate this to the go method.
|
|
803
|
-
__${name}_debug "Adding extra empty parameter"
|
|
804
|
-
# PowerShell 7.2+ changed the way how the arguments are passed to executables,
|
|
805
|
-
# so for pre-7.2 or when Legacy argument passing is enabled we need to use
|
|
806
|
-
if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or
|
|
807
|
-
($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -or
|
|
808
|
-
(($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -and
|
|
809
|
-
$PSNativeCommandArgumentPassing -eq 'Legacy')) {
|
|
810
|
-
$RequestComp="$RequestComp" + ' \`"\`"'
|
|
811
|
-
} else {
|
|
812
|
-
$RequestComp = "$RequestComp" + ' ""'
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
__${name}_debug "Calling $RequestComp"
|
|
817
|
-
# First disable ActiveHelp which is not supported for Powershell
|
|
818
|
-
$env:ActiveHelp = 0
|
|
819
|
-
|
|
820
|
-
# call the command store the output in $out and redirect stderr and stdout to null
|
|
821
|
-
# $Out is an array contains each line per element
|
|
822
|
-
Invoke-Expression -OutVariable out "$RequestComp" 2>&1 | Out-Null
|
|
823
|
-
|
|
824
|
-
# get directive from last line
|
|
825
|
-
[int]$Directive = $Out[-1].TrimStart(':')
|
|
826
|
-
if ($Directive -eq "") {
|
|
827
|
-
# There is no directive specified
|
|
828
|
-
$Directive = 0
|
|
829
|
-
}
|
|
830
|
-
__${name}_debug "The completion directive is: $Directive"
|
|
831
|
-
|
|
832
|
-
# remove directive (last element) from out
|
|
833
|
-
$Out = $Out | Where-Object { $_ -ne $Out[-1] }
|
|
834
|
-
__${name}_debug "The completions are: $Out"
|
|
835
|
-
|
|
836
|
-
if (($Directive -band $ShellCompDirectiveError) -ne 0 ) {
|
|
837
|
-
# Error code. No completion.
|
|
838
|
-
__${name}_debug "Received error from custom completion go code"
|
|
839
|
-
return
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
$Longest = 0
|
|
843
|
-
[Array]$Values = $Out | ForEach-Object {
|
|
844
|
-
# Split the output in name and description
|
|
845
|
-
$Name, $Description = $_.Split("\`t", 2)
|
|
846
|
-
__${name}_debug "Name: $Name Description: $Description"
|
|
847
|
-
|
|
848
|
-
# Look for the longest completion so that we can format things nicely
|
|
849
|
-
if ($Longest -lt $Name.Length) {
|
|
850
|
-
$Longest = $Name.Length
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
# Set the description to a one space string if there is none set.
|
|
854
|
-
# This is needed because the CompletionResult does not accept an empty string as argument
|
|
855
|
-
if (-Not $Description) {
|
|
856
|
-
$Description = " "
|
|
857
|
-
}
|
|
858
|
-
@{ Name = "$Name"; Description = "$Description" }
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
$Space = " "
|
|
863
|
-
if (($Directive -band $ShellCompDirectiveNoSpace) -ne 0 ) {
|
|
864
|
-
# remove the space here
|
|
865
|
-
__${name}_debug "ShellCompDirectiveNoSpace is called"
|
|
866
|
-
$Space = ""
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
if ((($Directive -band $ShellCompDirectiveFilterFileExt) -ne 0 ) -or
|
|
870
|
-
(($Directive -band $ShellCompDirectiveFilterDirs) -ne 0 )) {
|
|
871
|
-
__${name}_debug "ShellCompDirectiveFilterFileExt ShellCompDirectiveFilterDirs are not supported"
|
|
872
|
-
|
|
873
|
-
# return here to prevent the completion of the extensions
|
|
874
|
-
return
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
$Values = $Values | Where-Object {
|
|
878
|
-
# filter the result
|
|
879
|
-
$_.Name -like "$WordToComplete*"
|
|
880
|
-
|
|
881
|
-
# Join the flag back if we have an equal sign flag
|
|
882
|
-
if ( $IsEqualFlag ) {
|
|
883
|
-
__${name}_debug "Join the equal sign flag back to the completion value"
|
|
884
|
-
$_.Name = $Flag + "=" + $_.Name
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
# we sort the values in ascending order by name if keep order isn't passed
|
|
889
|
-
if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) {
|
|
890
|
-
$Values = $Values | Sort-Object -Property Name
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
|
|
894
|
-
__${name}_debug "ShellCompDirectiveNoFileComp is called"
|
|
895
|
-
|
|
896
|
-
if ($Values.Length -eq 0) {
|
|
897
|
-
# Just print an empty string here so the
|
|
898
|
-
# shell does not start to complete paths.
|
|
899
|
-
# We cannot use CompletionResult here because
|
|
900
|
-
# it does not accept an empty string as argument.
|
|
901
|
-
""
|
|
902
|
-
return
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
# Get the current mode
|
|
907
|
-
$Mode = (Get-PSReadLineKeyHandler | Where-Object { $_.Key -eq "Tab" }).Function
|
|
908
|
-
__${name}_debug "Mode: $Mode"
|
|
909
|
-
|
|
910
|
-
$Values | ForEach-Object {
|
|
911
|
-
|
|
912
|
-
# store temporary because switch will overwrite $_
|
|
913
|
-
$comp = $_
|
|
914
|
-
|
|
915
|
-
# PowerShell supports three different completion modes
|
|
916
|
-
# - TabCompleteNext (default windows style - on each key press the next option is displayed)
|
|
917
|
-
# - Complete (works like bash)
|
|
918
|
-
# - MenuComplete (works like zsh)
|
|
919
|
-
# You set the mode with Set-PSReadLineKeyHandler -Key Tab -Function <mode>
|
|
920
|
-
|
|
921
|
-
# CompletionResult Arguments:
|
|
922
|
-
# 1) CompletionText text to be used as the auto completion result
|
|
923
|
-
# 2) ListItemText text to be displayed in the suggestion list
|
|
924
|
-
# 3) ResultType type of completion result
|
|
925
|
-
# 4) ToolTip text for the tooltip with details about the object
|
|
926
|
-
|
|
927
|
-
switch ($Mode) {
|
|
928
|
-
|
|
929
|
-
# bash like
|
|
930
|
-
"Complete" {
|
|
931
|
-
|
|
932
|
-
if ($Values.Length -eq 1) {
|
|
933
|
-
__${name}_debug "Only one completion left"
|
|
934
|
-
|
|
935
|
-
# insert space after value
|
|
936
|
-
[System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
|
|
937
|
-
|
|
938
|
-
} else {
|
|
939
|
-
# Add the proper number of spaces to align the descriptions
|
|
940
|
-
while($comp.Name.Length -lt $Longest) {
|
|
941
|
-
$comp.Name = $comp.Name + " "
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
# Check for empty description and only add parentheses if needed
|
|
945
|
-
if ($($comp.Description) -eq " " ) {
|
|
946
|
-
$Description = ""
|
|
947
|
-
} else {
|
|
948
|
-
$Description = " ($($comp.Description))"
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
[System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)")
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
# zsh like
|
|
956
|
-
"MenuComplete" {
|
|
957
|
-
# insert space after value
|
|
958
|
-
# MenuComplete will automatically show the ToolTip of
|
|
959
|
-
# the highlighted value at the bottom of the suggestions.
|
|
960
|
-
[System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
# TabCompleteNext and in case we get something unknown
|
|
964
|
-
Default {
|
|
965
|
-
# Like MenuComplete but we don't want to add a space here because
|
|
966
|
-
# the user need to press space anyway to get the completion.
|
|
967
|
-
# Description will not be shown because that's not possible with TabCompleteNext
|
|
968
|
-
[System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
Register-ArgumentCompleter -CommandName '${name}' -ScriptBlock $__${nameForVar}CompleterBlock
|
|
976
|
-
`;
|
|
977
|
-
}
|
|
978
|
-
var ShellCompDirective = {
|
|
979
|
-
ShellCompDirectiveError: 1 << 0,
|
|
980
|
-
ShellCompDirectiveNoSpace: 1 << 1,
|
|
981
|
-
ShellCompDirectiveNoFileComp: 1 << 2,
|
|
982
|
-
ShellCompDirectiveFilterFileExt: 1 << 3,
|
|
983
|
-
ShellCompDirectiveFilterDirs: 1 << 4,
|
|
984
|
-
ShellCompDirectiveKeepOrder: 1 << 5,
|
|
985
|
-
shellCompDirectiveMaxValue: 1 << 6,
|
|
986
|
-
ShellCompDirectiveDefault: 0
|
|
987
|
-
};
|
|
988
|
-
|
|
989
|
-
class Argument {
|
|
990
|
-
name;
|
|
991
|
-
variadic;
|
|
992
|
-
command;
|
|
993
|
-
handler;
|
|
994
|
-
constructor(command, name, handler, variadic = false) {
|
|
995
|
-
this.command = command;
|
|
996
|
-
this.name = name;
|
|
997
|
-
this.handler = handler;
|
|
998
|
-
this.variadic = variadic;
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
class Option {
|
|
1003
|
-
value;
|
|
1004
|
-
description;
|
|
1005
|
-
command;
|
|
1006
|
-
handler;
|
|
1007
|
-
alias;
|
|
1008
|
-
isBoolean;
|
|
1009
|
-
constructor(command, value, description, handler, alias, isBoolean) {
|
|
1010
|
-
this.command = command;
|
|
1011
|
-
this.value = value;
|
|
1012
|
-
this.description = description;
|
|
1013
|
-
this.handler = handler;
|
|
1014
|
-
this.alias = alias;
|
|
1015
|
-
this.isBoolean = isBoolean;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
class Command {
|
|
1020
|
-
value;
|
|
1021
|
-
description;
|
|
1022
|
-
options = new Map;
|
|
1023
|
-
arguments = new Map;
|
|
1024
|
-
parent;
|
|
1025
|
-
constructor(value, description) {
|
|
1026
|
-
this.value = value;
|
|
1027
|
-
this.description = description;
|
|
1028
|
-
}
|
|
1029
|
-
option(value, description, handlerOrAlias, alias) {
|
|
1030
|
-
let handler;
|
|
1031
|
-
let aliasStr;
|
|
1032
|
-
let isBoolean;
|
|
1033
|
-
if (typeof handlerOrAlias === "function") {
|
|
1034
|
-
handler = handlerOrAlias;
|
|
1035
|
-
aliasStr = alias;
|
|
1036
|
-
isBoolean = false;
|
|
1037
|
-
} else if (typeof handlerOrAlias === "string") {
|
|
1038
|
-
handler = undefined;
|
|
1039
|
-
aliasStr = handlerOrAlias;
|
|
1040
|
-
isBoolean = true;
|
|
1041
|
-
} else {
|
|
1042
|
-
handler = undefined;
|
|
1043
|
-
aliasStr = undefined;
|
|
1044
|
-
isBoolean = true;
|
|
1045
|
-
}
|
|
1046
|
-
const option = new Option(this, value, description, handler, aliasStr, isBoolean);
|
|
1047
|
-
this.options.set(value, option);
|
|
1048
|
-
return this;
|
|
1049
|
-
}
|
|
1050
|
-
argument(name, handler, variadic = false) {
|
|
1051
|
-
const arg = new Argument(this, name, handler, variadic);
|
|
1052
|
-
this.arguments.set(name, arg);
|
|
1053
|
-
return this;
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
var SUPPORTED_SHELLS = new Set(["zsh", "bash", "fish", "powershell"]);
|
|
1057
|
-
|
|
1058
|
-
class RootCommand extends Command {
|
|
1059
|
-
commands = new Map;
|
|
1060
|
-
completions = [];
|
|
1061
|
-
directive = ShellCompDirective.ShellCompDirectiveDefault;
|
|
1062
|
-
constructor() {
|
|
1063
|
-
super("", "");
|
|
1064
|
-
}
|
|
1065
|
-
command(value, description) {
|
|
1066
|
-
const c = new Command(value, description);
|
|
1067
|
-
this.commands.set(value, c);
|
|
1068
|
-
return c;
|
|
1069
|
-
}
|
|
1070
|
-
stripOptions(args) {
|
|
1071
|
-
const parts = [];
|
|
1072
|
-
let i = 0;
|
|
1073
|
-
while (i < args.length) {
|
|
1074
|
-
const arg = args[i];
|
|
1075
|
-
if (arg.startsWith("-")) {
|
|
1076
|
-
i++;
|
|
1077
|
-
const hasInlineValue = arg.includes("=");
|
|
1078
|
-
let isBoolean = false;
|
|
1079
|
-
const rootOption = this.findOption(this, arg);
|
|
1080
|
-
if (rootOption) {
|
|
1081
|
-
isBoolean = rootOption.isBoolean ?? false;
|
|
1082
|
-
} else {
|
|
1083
|
-
for (const [, command] of this.commands) {
|
|
1084
|
-
const option = this.findOption(command, arg);
|
|
1085
|
-
if (option) {
|
|
1086
|
-
isBoolean = option.isBoolean ?? false;
|
|
1087
|
-
break;
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
if (!hasInlineValue && !isBoolean && i < args.length && !args[i].startsWith("-")) {
|
|
1092
|
-
i++;
|
|
1093
|
-
}
|
|
1094
|
-
} else {
|
|
1095
|
-
parts.push(arg);
|
|
1096
|
-
i++;
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
return parts;
|
|
1100
|
-
}
|
|
1101
|
-
matchCommand(args) {
|
|
1102
|
-
args = this.stripOptions(args);
|
|
1103
|
-
const parts = [];
|
|
1104
|
-
let remaining = [];
|
|
1105
|
-
let matchedCommand = null;
|
|
1106
|
-
for (let i = 0;i < args.length; i++) {
|
|
1107
|
-
const k = args[i];
|
|
1108
|
-
parts.push(k);
|
|
1109
|
-
const potential = this.commands.get(parts.join(" "));
|
|
1110
|
-
if (potential) {
|
|
1111
|
-
matchedCommand = potential;
|
|
1112
|
-
} else {
|
|
1113
|
-
remaining = args.slice(i, args.length);
|
|
1114
|
-
break;
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
return [matchedCommand || this, remaining];
|
|
1118
|
-
}
|
|
1119
|
-
shouldCompleteFlags(lastPrevArg, toComplete) {
|
|
1120
|
-
if (toComplete.startsWith("-")) {
|
|
1121
|
-
return true;
|
|
1122
|
-
}
|
|
1123
|
-
if (lastPrevArg?.startsWith("-")) {
|
|
1124
|
-
let option = this.findOption(this, lastPrevArg);
|
|
1125
|
-
if (!option) {
|
|
1126
|
-
for (const [, command] of this.commands) {
|
|
1127
|
-
option = this.findOption(command, lastPrevArg);
|
|
1128
|
-
if (option)
|
|
1129
|
-
break;
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
if (option && option.isBoolean) {
|
|
1133
|
-
return false;
|
|
1134
|
-
}
|
|
1135
|
-
return true;
|
|
1136
|
-
}
|
|
1137
|
-
return false;
|
|
1138
|
-
}
|
|
1139
|
-
shouldCompleteCommands(toComplete) {
|
|
1140
|
-
return !toComplete.startsWith("-");
|
|
1141
|
-
}
|
|
1142
|
-
handleFlagCompletion(command, previousArgs, toComplete, lastPrevArg) {
|
|
1143
|
-
let optionName;
|
|
1144
|
-
if (toComplete.includes("=")) {
|
|
1145
|
-
const [flag] = toComplete.split("=");
|
|
1146
|
-
optionName = flag;
|
|
1147
|
-
} else if (lastPrevArg?.startsWith("-")) {
|
|
1148
|
-
const option = this.findOption(command, lastPrevArg);
|
|
1149
|
-
if (option && !option.isBoolean) {
|
|
1150
|
-
optionName = lastPrevArg;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
if (optionName) {
|
|
1154
|
-
const option = this.findOption(command, optionName);
|
|
1155
|
-
if (option?.handler) {
|
|
1156
|
-
const suggestions = [];
|
|
1157
|
-
option.handler.call(option, (value, description) => suggestions.push({ value, description }), command.options);
|
|
1158
|
-
this.completions = suggestions;
|
|
1159
|
-
}
|
|
1160
|
-
return;
|
|
1161
|
-
}
|
|
1162
|
-
if (toComplete.startsWith("-")) {
|
|
1163
|
-
const isShortFlag = toComplete.startsWith("-") && !toComplete.startsWith("--");
|
|
1164
|
-
const cleanToComplete = toComplete.replace(/^-+/, "");
|
|
1165
|
-
for (const [name, option] of command.options) {
|
|
1166
|
-
if (isShortFlag && option.alias && `-${option.alias}`.startsWith(toComplete)) {
|
|
1167
|
-
this.completions.push({
|
|
1168
|
-
value: `-${option.alias}`,
|
|
1169
|
-
description: option.description
|
|
1170
|
-
});
|
|
1171
|
-
} else if (!isShortFlag && name.startsWith(cleanToComplete)) {
|
|
1172
|
-
this.completions.push({
|
|
1173
|
-
value: `--${name}`,
|
|
1174
|
-
description: option.description
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
findOption(command, optionName) {
|
|
1181
|
-
const normalized = this.normalizeOptionToken(optionName);
|
|
1182
|
-
let option = command.options.get(optionName);
|
|
1183
|
-
if (option)
|
|
1184
|
-
return option;
|
|
1185
|
-
option = command.options.get(normalized);
|
|
1186
|
-
if (option)
|
|
1187
|
-
return option;
|
|
1188
|
-
for (const [_name, opt] of command.options) {
|
|
1189
|
-
if (opt.alias === normalized) {
|
|
1190
|
-
return opt;
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
|
-
normalizeOptionToken(optionName) {
|
|
1196
|
-
return optionName.replace(/^-+/, "").split("=")[0] ?? "";
|
|
1197
|
-
}
|
|
1198
|
-
handleCommandCompletion(previousArgs, toComplete) {
|
|
1199
|
-
const commandParts = this.stripOptions(previousArgs);
|
|
1200
|
-
for (const [k, command] of this.commands) {
|
|
1201
|
-
if (k === "")
|
|
1202
|
-
continue;
|
|
1203
|
-
const parts = k.split(" ");
|
|
1204
|
-
const match = parts.slice(0, commandParts.length).every((part, i) => part === commandParts[i]);
|
|
1205
|
-
if (match && parts[commandParts.length]?.startsWith(toComplete)) {
|
|
1206
|
-
this.completions.push({
|
|
1207
|
-
value: parts[commandParts.length],
|
|
1208
|
-
description: command.description
|
|
1209
|
-
});
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
handlePositionalCompletion(command, previousArgs) {
|
|
1214
|
-
const commandParts = command.value.split(" ").length;
|
|
1215
|
-
const currentArgIndex = Math.max(0, previousArgs.length - commandParts);
|
|
1216
|
-
const argumentEntries = Array.from(command.arguments.entries());
|
|
1217
|
-
if (argumentEntries.length > 0) {
|
|
1218
|
-
let targetArgument;
|
|
1219
|
-
if (currentArgIndex < argumentEntries.length) {
|
|
1220
|
-
const [_argName, argument] = argumentEntries[currentArgIndex];
|
|
1221
|
-
targetArgument = argument;
|
|
1222
|
-
} else {
|
|
1223
|
-
const lastArgument = argumentEntries[argumentEntries.length - 1][1];
|
|
1224
|
-
if (lastArgument.variadic) {
|
|
1225
|
-
targetArgument = lastArgument;
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
if (targetArgument && targetArgument.handler && typeof targetArgument.handler === "function") {
|
|
1229
|
-
const suggestions = [];
|
|
1230
|
-
targetArgument.handler.call(targetArgument, (value, description) => suggestions.push({ value, description }), command.options);
|
|
1231
|
-
this.completions.push(...suggestions);
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
complete(toComplete) {
|
|
1236
|
-
this.directive = ShellCompDirective.ShellCompDirectiveNoFileComp;
|
|
1237
|
-
const seen = new Set;
|
|
1238
|
-
this.completions.filter((comp) => {
|
|
1239
|
-
if (seen.has(comp.value))
|
|
1240
|
-
return false;
|
|
1241
|
-
seen.add(comp.value);
|
|
1242
|
-
return true;
|
|
1243
|
-
}).filter((comp) => {
|
|
1244
|
-
if (toComplete.includes("=")) {
|
|
1245
|
-
const [, valueToComplete] = toComplete.split("=");
|
|
1246
|
-
return comp.value.startsWith(valueToComplete ?? "");
|
|
1247
|
-
}
|
|
1248
|
-
return comp.value.startsWith(toComplete);
|
|
1249
|
-
}).forEach((comp) => console.log(`${comp.value} ${comp.description ?? ""}`));
|
|
1250
|
-
console.log(`:${this.directive}`);
|
|
1251
|
-
}
|
|
1252
|
-
parse(args) {
|
|
1253
|
-
this.completions = [];
|
|
1254
|
-
const endsWithSpace = args[args.length - 1] === "";
|
|
1255
|
-
if (endsWithSpace) {
|
|
1256
|
-
args.pop();
|
|
1257
|
-
}
|
|
1258
|
-
let toComplete = args[args.length - 1] || "";
|
|
1259
|
-
const previousArgs = args.slice(0, -1);
|
|
1260
|
-
if (endsWithSpace) {
|
|
1261
|
-
if (toComplete !== "") {
|
|
1262
|
-
previousArgs.push(toComplete);
|
|
1263
|
-
}
|
|
1264
|
-
toComplete = "";
|
|
1265
|
-
}
|
|
1266
|
-
const [matchedCommand] = this.matchCommand(previousArgs);
|
|
1267
|
-
const lastPrevArg = previousArgs[previousArgs.length - 1];
|
|
1268
|
-
if (this.shouldCompleteFlags(lastPrevArg, toComplete)) {
|
|
1269
|
-
this.handleFlagCompletion(matchedCommand, previousArgs, toComplete, lastPrevArg);
|
|
1270
|
-
} else {
|
|
1271
|
-
if (lastPrevArg?.startsWith("-") && toComplete === "" && endsWithSpace) {
|
|
1272
|
-
let option = this.findOption(this, lastPrevArg);
|
|
1273
|
-
if (!option) {
|
|
1274
|
-
for (const [, command] of this.commands) {
|
|
1275
|
-
option = this.findOption(command, lastPrevArg);
|
|
1276
|
-
if (option)
|
|
1277
|
-
break;
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
if (option && option.isBoolean) {
|
|
1281
|
-
this.complete(toComplete);
|
|
1282
|
-
return;
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
if (this.shouldCompleteCommands(toComplete)) {
|
|
1286
|
-
this.handleCommandCompletion(previousArgs, toComplete);
|
|
1287
|
-
}
|
|
1288
|
-
if (matchedCommand && matchedCommand.arguments.size > 0) {
|
|
1289
|
-
this.handlePositionalCompletion(matchedCommand, previousArgs);
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
this.complete(toComplete);
|
|
1293
|
-
}
|
|
1294
|
-
setup(name, executable, shell) {
|
|
1295
|
-
if (!SUPPORTED_SHELLS.has(shell)) {
|
|
1296
|
-
throw new Error(`Unsupported shell: ${shell}`);
|
|
1297
|
-
}
|
|
1298
|
-
switch (shell) {
|
|
1299
|
-
case "zsh": {
|
|
1300
|
-
const script = generate(name, executable);
|
|
1301
|
-
console.log(script);
|
|
1302
|
-
break;
|
|
1303
|
-
}
|
|
1304
|
-
case "bash": {
|
|
1305
|
-
const script = generate2(name, executable);
|
|
1306
|
-
console.log(script);
|
|
1307
|
-
break;
|
|
1308
|
-
}
|
|
1309
|
-
case "fish": {
|
|
1310
|
-
const script = generate3(name, executable);
|
|
1311
|
-
console.log(script);
|
|
1312
|
-
break;
|
|
1313
|
-
}
|
|
1314
|
-
case "powershell": {
|
|
1315
|
-
const script = generate4(name, executable);
|
|
1316
|
-
console.log(script);
|
|
1317
|
-
break;
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
var t = new RootCommand;
|
|
1323
|
-
function dual(arity, body) {
|
|
1324
|
-
if (arity === 2)
|
|
1325
|
-
return (...args) => {
|
|
1326
|
-
if (args.length >= 2)
|
|
1327
|
-
return body(args[0], args[1]);
|
|
1328
|
-
return (self) => body(self, args[0]);
|
|
1329
|
-
};
|
|
1330
|
-
if (arity === 3)
|
|
1331
|
-
return (...args) => {
|
|
1332
|
-
if (args.length >= 3)
|
|
1333
|
-
return body(args[0], args[1], args[2]);
|
|
1334
|
-
return (self) => body(self, args[0], args[1]);
|
|
1335
|
-
};
|
|
1336
|
-
if (arity === 4)
|
|
1337
|
-
return (...args) => {
|
|
1338
|
-
if (args.length >= 4)
|
|
1339
|
-
return body(args[0], args[1], args[2], args[3]);
|
|
1340
|
-
return (self) => body(self, args[0], args[1], args[2]);
|
|
1341
|
-
};
|
|
1342
|
-
return (...args) => {
|
|
1343
|
-
if (args.length >= arity)
|
|
1344
|
-
return body(...args);
|
|
1345
|
-
return (self) => body(self, ...args);
|
|
1346
|
-
};
|
|
1347
|
-
}
|
|
1348
|
-
var serializeCause = (cause) => {
|
|
1349
|
-
if (cause instanceof Error)
|
|
1350
|
-
return {
|
|
1351
|
-
name: cause.name,
|
|
1352
|
-
message: cause.message,
|
|
1353
|
-
stack: cause.stack
|
|
1354
|
-
};
|
|
1355
|
-
return cause;
|
|
1356
|
-
};
|
|
1357
|
-
var isAnyTaggedError = (value) => {
|
|
1358
|
-
return value instanceof Error && "_tag" in value && typeof value._tag === "string";
|
|
1359
|
-
};
|
|
1360
|
-
var TaggedError2 = Object.assign((tag) => () => {
|
|
1361
|
-
|
|
1362
|
-
class Base extends Error {
|
|
1363
|
-
_tag = tag;
|
|
1364
|
-
static is(value) {
|
|
1365
|
-
return value instanceof Base;
|
|
1366
|
-
}
|
|
1367
|
-
constructor(args) {
|
|
1368
|
-
const message = args && "message" in args && typeof args.message === "string" ? args.message : undefined;
|
|
1369
|
-
const cause = args && "cause" in args ? args.cause : undefined;
|
|
1370
|
-
super(message, cause !== undefined ? { cause } : undefined);
|
|
1371
|
-
if (args)
|
|
1372
|
-
Object.assign(this, args);
|
|
1373
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
1374
|
-
this.name = tag;
|
|
1375
|
-
if (cause instanceof Error && cause.stack) {
|
|
1376
|
-
const indented = cause.stack.replace(/\n/g, `
|
|
1377
|
-
`);
|
|
1378
|
-
this.stack = `${this.stack}
|
|
1379
|
-
Caused by: ${indented}`;
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
toJSON() {
|
|
1383
|
-
return {
|
|
1384
|
-
...this,
|
|
1385
|
-
_tag: this._tag,
|
|
1386
|
-
name: this.name,
|
|
1387
|
-
message: this.message,
|
|
1388
|
-
cause: serializeCause(this.cause),
|
|
1389
|
-
stack: this.stack
|
|
1390
|
-
};
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
return Base;
|
|
1394
|
-
}, { is: isAnyTaggedError });
|
|
1395
|
-
var matchError = dual(2, (err$1, handlers) => {
|
|
1396
|
-
const handler = handlers[err$1._tag];
|
|
1397
|
-
return handler(err$1);
|
|
1398
|
-
});
|
|
1399
|
-
var matchErrorPartial = dual(3, (err$1, handlers, fallback) => {
|
|
1400
|
-
const handler = handlers[err$1._tag];
|
|
1401
|
-
if (typeof handler === "function")
|
|
1402
|
-
return handler(err$1);
|
|
1403
|
-
return fallback(err$1);
|
|
1404
|
-
});
|
|
1405
|
-
var UnhandledException = class extends TaggedError2("UnhandledException")() {
|
|
1406
|
-
constructor(args) {
|
|
1407
|
-
const message = args.cause instanceof Error ? `Unhandled exception: ${args.cause.message}` : `Unhandled exception: ${String(args.cause)}`;
|
|
1408
|
-
super({
|
|
1409
|
-
message,
|
|
1410
|
-
cause: args.cause
|
|
1411
|
-
});
|
|
1412
|
-
}
|
|
1413
|
-
};
|
|
1414
|
-
var Panic = class extends TaggedError2("Panic")() {
|
|
1415
|
-
};
|
|
1416
|
-
var ResultDeserializationError = class extends TaggedError2("ResultDeserializationError")() {
|
|
1417
|
-
constructor(args) {
|
|
1418
|
-
super({
|
|
1419
|
-
message: `Failed to deserialize value as Result: expected { status: "ok", value } or { status: "error", error }`,
|
|
1420
|
-
value: args.value
|
|
1421
|
-
});
|
|
1422
|
-
}
|
|
1423
|
-
};
|
|
1424
|
-
var panic = (message, cause) => {
|
|
1425
|
-
throw new Panic({
|
|
1426
|
-
message,
|
|
1427
|
-
cause
|
|
1428
|
-
});
|
|
1429
|
-
};
|
|
1430
|
-
var tryOrPanic = (fn, message) => {
|
|
1431
|
-
try {
|
|
1432
|
-
return fn();
|
|
1433
|
-
} catch (cause) {
|
|
1434
|
-
throw panic(message, cause);
|
|
1435
|
-
}
|
|
1436
|
-
};
|
|
1437
|
-
var tryOrPanicAsync = async (fn, message) => {
|
|
1438
|
-
try {
|
|
1439
|
-
return await fn();
|
|
1440
|
-
} catch (cause) {
|
|
1441
|
-
throw panic(message, cause);
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
var Ok = class Ok2 {
|
|
1445
|
-
status = "ok";
|
|
1446
|
-
constructor(value) {
|
|
1447
|
-
this.value = value;
|
|
1448
|
-
}
|
|
1449
|
-
isOk() {
|
|
1450
|
-
return true;
|
|
1451
|
-
}
|
|
1452
|
-
isErr() {
|
|
1453
|
-
return false;
|
|
1454
|
-
}
|
|
1455
|
-
map(fn) {
|
|
1456
|
-
return tryOrPanic(() => new Ok2(fn(this.value)), "map callback threw");
|
|
1457
|
-
}
|
|
1458
|
-
mapError(_fn) {
|
|
1459
|
-
return this;
|
|
1460
|
-
}
|
|
1461
|
-
andThen(fn) {
|
|
1462
|
-
return tryOrPanic(() => fn(this.value), "andThen callback threw");
|
|
1463
|
-
}
|
|
1464
|
-
andThenAsync(fn) {
|
|
1465
|
-
return tryOrPanicAsync(() => fn(this.value), "andThenAsync callback threw");
|
|
1466
|
-
}
|
|
1467
|
-
match(handlers) {
|
|
1468
|
-
return tryOrPanic(() => handlers.ok(this.value), "match ok handler threw");
|
|
1469
|
-
}
|
|
1470
|
-
unwrap(_message) {
|
|
1471
|
-
return this.value;
|
|
1472
|
-
}
|
|
1473
|
-
unwrapOr(_fallback) {
|
|
1474
|
-
return this.value;
|
|
1475
|
-
}
|
|
1476
|
-
tap(fn) {
|
|
1477
|
-
return tryOrPanic(() => {
|
|
1478
|
-
fn(this.value);
|
|
1479
|
-
return this;
|
|
1480
|
-
}, "tap callback threw");
|
|
1481
|
-
}
|
|
1482
|
-
tapAsync(fn) {
|
|
1483
|
-
return tryOrPanicAsync(async () => {
|
|
1484
|
-
await fn(this.value);
|
|
1485
|
-
return this;
|
|
1486
|
-
}, "tapAsync callback threw");
|
|
1487
|
-
}
|
|
1488
|
-
*[Symbol.iterator]() {
|
|
1489
|
-
return this.value;
|
|
1490
|
-
}
|
|
1491
|
-
};
|
|
1492
|
-
var Err = class Err2 {
|
|
1493
|
-
status = "error";
|
|
1494
|
-
constructor(error) {
|
|
1495
|
-
this.error = error;
|
|
1496
|
-
}
|
|
1497
|
-
isOk() {
|
|
1498
|
-
return false;
|
|
1499
|
-
}
|
|
1500
|
-
isErr() {
|
|
1501
|
-
return true;
|
|
1502
|
-
}
|
|
1503
|
-
map(_fn) {
|
|
1504
|
-
return this;
|
|
1505
|
-
}
|
|
1506
|
-
mapError(fn) {
|
|
1507
|
-
return tryOrPanic(() => new Err2(fn(this.error)), "mapError callback threw");
|
|
1508
|
-
}
|
|
1509
|
-
andThen(_fn) {
|
|
1510
|
-
return this;
|
|
1511
|
-
}
|
|
1512
|
-
andThenAsync(_fn) {
|
|
1513
|
-
return Promise.resolve(this);
|
|
1514
|
-
}
|
|
1515
|
-
match(handlers) {
|
|
1516
|
-
return tryOrPanic(() => handlers.err(this.error), "match err handler threw");
|
|
1517
|
-
}
|
|
1518
|
-
unwrap(message) {
|
|
1519
|
-
return panic(message ?? `Unwrap called on Err: ${String(this.error)}`, this.error);
|
|
1520
|
-
}
|
|
1521
|
-
unwrapOr(fallback) {
|
|
1522
|
-
return fallback;
|
|
1523
|
-
}
|
|
1524
|
-
tap(_fn) {
|
|
1525
|
-
return this;
|
|
1526
|
-
}
|
|
1527
|
-
tapAsync(_fn) {
|
|
1528
|
-
return Promise.resolve(this);
|
|
1529
|
-
}
|
|
1530
|
-
*[Symbol.iterator]() {
|
|
1531
|
-
yield this;
|
|
1532
|
-
return panic("Unreachable: Err yielded in Result.gen but generator continued", this.error);
|
|
1533
|
-
}
|
|
1534
|
-
};
|
|
1535
|
-
function ok(value) {
|
|
1536
|
-
return new Ok(value);
|
|
1537
|
-
}
|
|
1538
|
-
var isOk = (result) => {
|
|
1539
|
-
return result.status === "ok";
|
|
1540
|
-
};
|
|
1541
|
-
var err = (error) => new Err(error);
|
|
1542
|
-
var isError = (result) => {
|
|
1543
|
-
return result.status === "error";
|
|
1544
|
-
};
|
|
1545
|
-
var tryFn = (options, config) => {
|
|
1546
|
-
const execute = () => {
|
|
1547
|
-
if (typeof options === "function")
|
|
1548
|
-
try {
|
|
1549
|
-
return ok(options());
|
|
1550
|
-
} catch (cause) {
|
|
1551
|
-
return err(new UnhandledException({ cause }));
|
|
1552
|
-
}
|
|
1553
|
-
try {
|
|
1554
|
-
return ok(options.try());
|
|
1555
|
-
} catch (originalCause) {
|
|
1556
|
-
try {
|
|
1557
|
-
return err(options.catch(originalCause));
|
|
1558
|
-
} catch (catchHandlerError) {
|
|
1559
|
-
throw panic("Result.try catch handler threw", catchHandlerError);
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
};
|
|
1563
|
-
const times = config?.retry?.times ?? 0;
|
|
1564
|
-
let result = execute();
|
|
1565
|
-
for (let retry = 0;retry < times && result.status === "error"; retry++)
|
|
1566
|
-
result = execute();
|
|
1567
|
-
return result;
|
|
1568
|
-
};
|
|
1569
|
-
var tryPromise = async (options, config) => {
|
|
1570
|
-
const execute = async () => {
|
|
1571
|
-
if (typeof options === "function")
|
|
1572
|
-
try {
|
|
1573
|
-
return ok(await options());
|
|
1574
|
-
} catch (cause) {
|
|
1575
|
-
return err(new UnhandledException({ cause }));
|
|
1576
|
-
}
|
|
1577
|
-
try {
|
|
1578
|
-
return ok(await options.try());
|
|
1579
|
-
} catch (originalCause) {
|
|
1580
|
-
try {
|
|
1581
|
-
return err(await options.catch(originalCause));
|
|
1582
|
-
} catch (catchHandlerError) {
|
|
1583
|
-
throw panic("Result.tryPromise catch handler threw", catchHandlerError);
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
};
|
|
1587
|
-
const retry = config?.retry;
|
|
1588
|
-
if (!retry)
|
|
1589
|
-
return execute();
|
|
1590
|
-
const getDelay = (retryAttempt) => {
|
|
1591
|
-
switch (retry.backoff) {
|
|
1592
|
-
case "constant":
|
|
1593
|
-
return retry.delayMs;
|
|
1594
|
-
case "linear":
|
|
1595
|
-
return retry.delayMs * (retryAttempt + 1);
|
|
1596
|
-
case "exponential":
|
|
1597
|
-
return retry.delayMs * 2 ** retryAttempt;
|
|
1598
|
-
}
|
|
1599
|
-
};
|
|
1600
|
-
const sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
1601
|
-
let result = await execute();
|
|
1602
|
-
const shouldRetryFn = retry.shouldRetry ?? (() => true);
|
|
1603
|
-
for (let attempt = 0;attempt < retry.times; attempt++) {
|
|
1604
|
-
if (result.status !== "error")
|
|
1605
|
-
break;
|
|
1606
|
-
const error = result.error;
|
|
1607
|
-
if (!tryOrPanic(() => shouldRetryFn(error), "shouldRetry predicate threw"))
|
|
1608
|
-
break;
|
|
1609
|
-
await sleep(getDelay(attempt));
|
|
1610
|
-
result = await execute();
|
|
1611
|
-
}
|
|
1612
|
-
return result;
|
|
1613
|
-
};
|
|
1614
|
-
var map = dual(2, (result, fn) => {
|
|
1615
|
-
return result.map(fn);
|
|
1616
|
-
});
|
|
1617
|
-
var mapError = dual(2, (result, fn) => {
|
|
1618
|
-
return result.mapError(fn);
|
|
1619
|
-
});
|
|
1620
|
-
var andThen = dual(2, (result, fn) => {
|
|
1621
|
-
return result.andThen(fn);
|
|
1622
|
-
});
|
|
1623
|
-
var andThenAsync = dual(2, (result, fn) => {
|
|
1624
|
-
return result.andThenAsync(fn);
|
|
1625
|
-
});
|
|
1626
|
-
var match = dual(2, (result, handlers) => {
|
|
1627
|
-
return result.match(handlers);
|
|
1628
|
-
});
|
|
1629
|
-
var tap = dual(2, (result, fn) => {
|
|
1630
|
-
return result.tap(fn);
|
|
1631
|
-
});
|
|
1632
|
-
var tapAsync = dual(2, (result, fn) => {
|
|
1633
|
-
return result.tapAsync(fn);
|
|
1634
|
-
});
|
|
1635
|
-
var unwrap = (result, message) => {
|
|
1636
|
-
return result.unwrap(message);
|
|
1637
|
-
};
|
|
1638
|
-
function assertIsResult(value) {
|
|
1639
|
-
if (value !== null && typeof value === "object" && "status" in value && (value.status === "ok" || value.status === "error"))
|
|
1640
|
-
return;
|
|
1641
|
-
return panic("Result.gen body must return Result.ok() or Result.err(), got: " + (value === null ? "null" : typeof value === "object" ? JSON.stringify(value) : String(value)));
|
|
1642
|
-
}
|
|
1643
|
-
var unwrapOr = dual(2, (result, fallback) => {
|
|
1644
|
-
return result.unwrapOr(fallback);
|
|
1645
|
-
});
|
|
1646
|
-
var gen = (body, thisArg) => {
|
|
1647
|
-
const iterator = body.call(thisArg);
|
|
1648
|
-
if (Symbol.asyncIterator in iterator)
|
|
1649
|
-
return (async () => {
|
|
1650
|
-
const asyncIter = iterator;
|
|
1651
|
-
let state$1;
|
|
1652
|
-
try {
|
|
1653
|
-
state$1 = await asyncIter.next();
|
|
1654
|
-
} catch (cause) {
|
|
1655
|
-
throw panic("generator body threw", cause);
|
|
1656
|
-
}
|
|
1657
|
-
assertIsResult(state$1.value);
|
|
1658
|
-
if (!state$1.done)
|
|
1659
|
-
try {
|
|
1660
|
-
await asyncIter.return?.(undefined);
|
|
1661
|
-
} catch (cause) {
|
|
1662
|
-
throw panic("generator cleanup threw", cause);
|
|
1663
|
-
}
|
|
1664
|
-
return state$1.value;
|
|
1665
|
-
})();
|
|
1666
|
-
const syncIter = iterator;
|
|
1667
|
-
let state;
|
|
1668
|
-
try {
|
|
1669
|
-
state = syncIter.next();
|
|
1670
|
-
} catch (cause) {
|
|
1671
|
-
throw panic("generator body threw", cause);
|
|
1672
|
-
}
|
|
1673
|
-
assertIsResult(state.value);
|
|
1674
|
-
if (!state.done)
|
|
1675
|
-
try {
|
|
1676
|
-
syncIter.return?.(undefined);
|
|
1677
|
-
} catch (cause) {
|
|
1678
|
-
throw panic("generator cleanup threw", cause);
|
|
1679
|
-
}
|
|
1680
|
-
return state.value;
|
|
1681
|
-
};
|
|
1682
|
-
async function* resultAwait(promise) {
|
|
1683
|
-
return yield* await promise;
|
|
1684
|
-
}
|
|
1685
|
-
function isSerializedResult(obj) {
|
|
1686
|
-
return obj !== null && typeof obj === "object" && "status" in obj && (obj.status === "ok" && ("value" in obj) || obj.status === "error" && ("error" in obj));
|
|
1687
|
-
}
|
|
1688
|
-
var serialize = (result) => {
|
|
1689
|
-
return result.status === "ok" ? {
|
|
1690
|
-
status: "ok",
|
|
1691
|
-
value: result.value
|
|
1692
|
-
} : {
|
|
1693
|
-
status: "error",
|
|
1694
|
-
error: result.error
|
|
1695
|
-
};
|
|
1696
|
-
};
|
|
1697
|
-
var deserialize = (value) => {
|
|
1698
|
-
if (isSerializedResult(value))
|
|
1699
|
-
return value.status === "ok" ? new Ok(value.value) : new Err(value.error);
|
|
1700
|
-
return err(new ResultDeserializationError({ value }));
|
|
1701
|
-
};
|
|
1702
|
-
var hydrate = (value) => {
|
|
1703
|
-
return deserialize(value);
|
|
1704
|
-
};
|
|
1705
|
-
var partition = (results) => {
|
|
1706
|
-
const oks = [];
|
|
1707
|
-
const errs = [];
|
|
1708
|
-
for (const r of results)
|
|
1709
|
-
if (r.status === "ok")
|
|
1710
|
-
oks.push(r.value);
|
|
1711
|
-
else
|
|
1712
|
-
errs.push(r.error);
|
|
1713
|
-
return [oks, errs];
|
|
1714
|
-
};
|
|
1715
|
-
var flatten = (result) => {
|
|
1716
|
-
if (result.status === "ok")
|
|
1717
|
-
return result.value;
|
|
1718
|
-
return result;
|
|
1719
|
-
};
|
|
1720
|
-
var Result2 = {
|
|
1721
|
-
ok,
|
|
1722
|
-
isOk,
|
|
1723
|
-
err,
|
|
1724
|
-
isError,
|
|
1725
|
-
try: tryFn,
|
|
1726
|
-
tryPromise,
|
|
1727
|
-
map,
|
|
1728
|
-
mapError,
|
|
1729
|
-
andThen,
|
|
1730
|
-
andThenAsync,
|
|
1731
|
-
match,
|
|
1732
|
-
tap,
|
|
1733
|
-
tapAsync,
|
|
1734
|
-
unwrap,
|
|
1735
|
-
unwrapOr,
|
|
1736
|
-
gen,
|
|
1737
|
-
await: resultAwait,
|
|
1738
|
-
serialize,
|
|
1739
|
-
deserialize,
|
|
1740
|
-
hydrate,
|
|
1741
|
-
partition,
|
|
1742
|
-
flatten
|
|
1743
|
-
};
|
|
1744
|
-
|
|
1745
|
-
class PackageJsonReadError extends TaggedError2("PackageJsonReadError")() {
|
|
1746
|
-
}
|
|
1747
|
-
|
|
1748
|
-
class LoadGeneratedMetadataError extends TaggedError2("LoadGeneratedMetadataError")() {
|
|
1749
|
-
}
|
|
1750
|
-
function stripScope(name) {
|
|
1751
|
-
const idx = name.lastIndexOf("/");
|
|
1752
|
-
return idx >= 0 ? name.slice(idx + 1) : name;
|
|
1753
|
-
}
|
|
1754
|
-
async function resolveCliInfo(options = {}) {
|
|
1755
|
-
if (options.commandName && options.executable) {
|
|
1756
|
-
return { commandName: options.commandName, executable: options.executable };
|
|
1757
|
-
}
|
|
1758
|
-
const packageJsonResult = await readProjectPackageJson();
|
|
1759
|
-
const pkg = Result2.isOk(packageJsonResult) ? packageJsonResult.value : null;
|
|
1760
|
-
const pkgName = typeof pkg?.name === "string" ? pkg.name : undefined;
|
|
1761
|
-
const pkgNameStripped = pkgName ? stripScope(pkgName) : undefined;
|
|
1762
|
-
let inferredCommandName;
|
|
1763
|
-
const bin = pkg?.bin;
|
|
1764
|
-
if (typeof bin === "string") {
|
|
1765
|
-
inferredCommandName = pkgNameStripped;
|
|
1766
|
-
} else if (bin && typeof bin === "object") {
|
|
1767
|
-
const keys = Object.keys(bin);
|
|
1768
|
-
if (pkgNameStripped && keys.includes(pkgNameStripped))
|
|
1769
|
-
inferredCommandName = pkgNameStripped;
|
|
1770
|
-
else
|
|
1771
|
-
inferredCommandName = keys[0];
|
|
1772
|
-
if (inferredCommandName)
|
|
1773
|
-
inferredCommandName = stripScope(inferredCommandName);
|
|
1774
|
-
} else {
|
|
1775
|
-
inferredCommandName = pkgNameStripped;
|
|
1776
|
-
}
|
|
1777
|
-
const commandName = options.commandName ?? inferredCommandName ?? "cli";
|
|
1778
|
-
const executable = options.executable ?? commandName;
|
|
1779
|
-
return { commandName, executable };
|
|
1780
|
-
}
|
|
1781
|
-
async function loadGeneratedMetadata(options = {}) {
|
|
1782
|
-
const generatedPath = options.generatedPath ?? ".bunli/commands.gen.ts";
|
|
1783
|
-
const absolute = resolve(process.cwd(), generatedPath);
|
|
1784
|
-
const url = pathToFileURL(absolute).href;
|
|
1785
|
-
return await Result2.tryPromise({
|
|
1786
|
-
try: async () => {
|
|
1787
|
-
const mod = await import(url);
|
|
1788
|
-
const list = mod.generated?.list?.() ?? [];
|
|
1789
|
-
return { commands: list.map((i) => i.metadata) };
|
|
1790
|
-
},
|
|
1791
|
-
catch: (cause) => new LoadGeneratedMetadataError({
|
|
1792
|
-
generatedPath,
|
|
1793
|
-
message: `Could not load command metadata from ${generatedPath}. Make sure it exists (run "bunli generate").`,
|
|
1794
|
-
cause
|
|
1795
|
-
})
|
|
1796
|
-
});
|
|
1797
|
-
}
|
|
1798
|
-
async function readProjectPackageJson() {
|
|
1799
|
-
return Result2.tryPromise({
|
|
1800
|
-
try: async () => {
|
|
1801
|
-
const pkgPath = resolve(process.cwd(), "package.json");
|
|
1802
|
-
const pkgContent = await readFile(pkgPath, "utf-8");
|
|
1803
|
-
const parsed = JSON.parse(pkgContent);
|
|
1804
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1805
|
-
throw new Error("package.json must be a JSON object");
|
|
1806
|
-
}
|
|
1807
|
-
return parsed;
|
|
1808
|
-
},
|
|
1809
|
-
catch: (cause) => new PackageJsonReadError({
|
|
1810
|
-
message: "Could not read project package.json",
|
|
1811
|
-
cause
|
|
1812
|
-
})
|
|
1813
|
-
});
|
|
1814
|
-
}
|
|
1815
|
-
function canonicalCommandPath(name) {
|
|
1816
|
-
return name.replace(/\s+/g, "/").replace(/\/+/g, "/").replace(/^\/+|\/+$/g, "").trim();
|
|
1817
|
-
}
|
|
1818
|
-
function resolveNestedCommandName(parentPath, rawName) {
|
|
1819
|
-
const child = canonicalCommandPath(rawName);
|
|
1820
|
-
if (!child)
|
|
1821
|
-
return parentPath ?? "";
|
|
1822
|
-
if (!parentPath)
|
|
1823
|
-
return child;
|
|
1824
|
-
if (!child.includes("/")) {
|
|
1825
|
-
return `${parentPath}/${child}`;
|
|
1826
|
-
}
|
|
1827
|
-
if (child === parentPath || child.startsWith(`${parentPath}/`)) {
|
|
1828
|
-
return child;
|
|
1829
|
-
}
|
|
1830
|
-
return child;
|
|
1831
|
-
}
|
|
1832
|
-
function flattenCommandTree(commands) {
|
|
1833
|
-
const flattened = [];
|
|
1834
|
-
const walk = (meta, parentPath) => {
|
|
1835
|
-
const resolvedName = resolveNestedCommandName(parentPath, meta.name);
|
|
1836
|
-
if (!resolvedName)
|
|
1837
|
-
return;
|
|
1838
|
-
flattened.push({
|
|
1839
|
-
...meta,
|
|
1840
|
-
name: resolvedName
|
|
1841
|
-
});
|
|
1842
|
-
for (const nested of meta.commands ?? []) {
|
|
1843
|
-
walk(nested, resolvedName);
|
|
1844
|
-
}
|
|
1845
|
-
};
|
|
1846
|
-
for (const meta of commands) {
|
|
1847
|
-
walk(meta);
|
|
1848
|
-
}
|
|
1849
|
-
return flattened;
|
|
1850
|
-
}
|
|
1851
|
-
function normalizeCommandPath(name) {
|
|
1852
|
-
return name.replace(/\//g, " ").trim();
|
|
1853
|
-
}
|
|
1854
|
-
function isBooleanOption(meta) {
|
|
1855
|
-
const t2 = meta.type.toLowerCase();
|
|
1856
|
-
return t2.includes("boolean") || t2.includes("bool");
|
|
1857
|
-
}
|
|
1858
|
-
function addGlobalFlags(cmd) {
|
|
1859
|
-
for (const [name, flag] of Object.entries(GLOBAL_FLAGS)) {
|
|
1860
|
-
const desc = flag.description ?? "";
|
|
1861
|
-
const short = "short" in flag ? flag.short : undefined;
|
|
1862
|
-
const handler = createGlobalFlagHandler(name);
|
|
1863
|
-
if (handler) {
|
|
1864
|
-
if (short)
|
|
1865
|
-
cmd.option(name, desc, handler, short);
|
|
1866
|
-
else
|
|
1867
|
-
cmd.option(name, desc, handler);
|
|
1868
|
-
continue;
|
|
1869
|
-
}
|
|
1870
|
-
if (short)
|
|
1871
|
-
cmd.option(name, desc, short);
|
|
1872
|
-
else
|
|
1873
|
-
cmd.option(name, desc);
|
|
1874
|
-
}
|
|
1875
|
-
}
|
|
1876
|
-
function createGlobalFlagHandler(name) {
|
|
1877
|
-
const enumValues = name === "format" ? ["json", "yaml", "md", "toon"] : name === "image-mode" ? ["off", "auto", "on"] : undefined;
|
|
1878
|
-
if (!enumValues)
|
|
1879
|
-
return;
|
|
1880
|
-
return (complete) => {
|
|
1881
|
-
for (const value of enumValues)
|
|
1882
|
-
complete(value, "");
|
|
1883
|
-
};
|
|
1884
|
-
}
|
|
1885
|
-
function addOption(cmd, name, meta) {
|
|
1886
|
-
const desc = meta.description ?? "";
|
|
1887
|
-
const short = meta.short;
|
|
1888
|
-
if (isBooleanOption(meta)) {
|
|
1889
|
-
if (short)
|
|
1890
|
-
cmd.option(name, desc, short);
|
|
1891
|
-
else
|
|
1892
|
-
cmd.option(name, desc);
|
|
1893
|
-
return;
|
|
1894
|
-
}
|
|
1895
|
-
const enumValues = meta.enumValues;
|
|
1896
|
-
const literalValue = meta.literalValue;
|
|
1897
|
-
const handler = (complete) => {
|
|
1898
|
-
if (enumValues && enumValues.length > 0) {
|
|
1899
|
-
for (const v of enumValues)
|
|
1900
|
-
complete(String(v), "");
|
|
1901
|
-
return;
|
|
1902
|
-
}
|
|
1903
|
-
if (literalValue !== undefined) {
|
|
1904
|
-
complete(String(literalValue), "");
|
|
1905
|
-
}
|
|
1906
|
-
};
|
|
1907
|
-
if (short)
|
|
1908
|
-
cmd.option(name, desc, handler, short);
|
|
1909
|
-
else
|
|
1910
|
-
cmd.option(name, desc, handler);
|
|
1911
|
-
}
|
|
1912
|
-
function addCommandOptions(cmd, meta) {
|
|
1913
|
-
for (const [name, opt] of Object.entries(meta.options ?? {})) {
|
|
1914
|
-
addOption(cmd, name, opt);
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
function expandAliases(meta, opts) {
|
|
1918
|
-
const primary = normalizeCommandPath(meta.name);
|
|
1919
|
-
if (!opts.includeAliases || !meta.alias)
|
|
1920
|
-
return [primary];
|
|
1921
|
-
const aliases = Array.isArray(meta.alias) ? meta.alias : [meta.alias];
|
|
1922
|
-
const parts = primary.split(" ").filter(Boolean);
|
|
1923
|
-
const parent = parts.slice(0, -1);
|
|
1924
|
-
const expanded = [primary];
|
|
1925
|
-
for (const a of aliases) {
|
|
1926
|
-
const aliasRaw = String(a).trim();
|
|
1927
|
-
if (!aliasRaw)
|
|
1928
|
-
continue;
|
|
1929
|
-
if (aliasRaw.includes("/") || aliasRaw.includes(" ")) {
|
|
1930
|
-
expanded.push(normalizeCommandPath(aliasRaw));
|
|
1931
|
-
continue;
|
|
1932
|
-
}
|
|
1933
|
-
expanded.push([...parent, aliasRaw].join(" ").trim());
|
|
1934
|
-
}
|
|
1935
|
-
return expanded;
|
|
1936
|
-
}
|
|
1937
|
-
function buildRegistry(commands, options = {}) {
|
|
1938
|
-
const opts = {
|
|
1939
|
-
includeAliases: options.includeAliases ?? true,
|
|
1940
|
-
includeGlobalFlags: options.includeGlobalFlags ?? true
|
|
1941
|
-
};
|
|
1942
|
-
const root = new RootCommand;
|
|
1943
|
-
const flattenedCommands = flattenCommandTree(commands);
|
|
1944
|
-
const metaByPath = new Map;
|
|
1945
|
-
const allPaths = new Set;
|
|
1946
|
-
for (const meta of flattenedCommands) {
|
|
1947
|
-
for (const path of expandAliases(meta, opts)) {
|
|
1948
|
-
metaByPath.set(path, meta);
|
|
1949
|
-
const parts = path.split(" ").filter(Boolean);
|
|
1950
|
-
for (let i = 1;i <= parts.length; i += 1) {
|
|
1951
|
-
allPaths.add(parts.slice(0, i).join(" "));
|
|
1952
|
-
}
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
const sortedPaths = Array.from(allPaths).sort((a, b) => {
|
|
1956
|
-
const al = a.split(" ").length;
|
|
1957
|
-
const bl = b.split(" ").length;
|
|
1958
|
-
if (al !== bl)
|
|
1959
|
-
return al - bl;
|
|
1960
|
-
return a.localeCompare(b);
|
|
1961
|
-
});
|
|
1962
|
-
const tabCommands = new Map;
|
|
1963
|
-
for (const path of sortedPaths) {
|
|
1964
|
-
const meta = metaByPath.get(path);
|
|
1965
|
-
const desc = meta?.description ?? "";
|
|
1966
|
-
const cmd = root.command(path, desc);
|
|
1967
|
-
tabCommands.set(path, cmd);
|
|
1968
|
-
if (opts.includeGlobalFlags)
|
|
1969
|
-
addGlobalFlags(cmd);
|
|
1970
|
-
if (meta)
|
|
1971
|
-
addCommandOptions(cmd, meta);
|
|
1972
|
-
}
|
|
1973
|
-
if (opts.includeGlobalFlags)
|
|
1974
|
-
addGlobalFlags(root);
|
|
1975
|
-
return root;
|
|
1976
|
-
}
|
|
1977
|
-
var SHELLS = ["bash", "zsh", "fish", "powershell"];
|
|
1978
|
-
function isShell(value) {
|
|
1979
|
-
return SHELLS.includes(value);
|
|
1980
|
-
}
|
|
1981
|
-
|
|
1982
|
-
class CompletionProtocolError extends TaggedError2("CompletionProtocolError")() {
|
|
1983
|
-
}
|
|
1984
|
-
function completionsCommand(pluginOptions) {
|
|
1985
|
-
return defineCommand({
|
|
1986
|
-
name: "completions",
|
|
1987
|
-
alias: ["complete"],
|
|
1988
|
-
description: "Generate shell completion scripts and handle completion protocol callbacks",
|
|
1989
|
-
handler: async ({ runtime, colors }) => {
|
|
1990
|
-
const argv = runtime.args;
|
|
1991
|
-
const invokedCommand = runtime.command.split(/\s+/).at(-1) ?? "completions";
|
|
1992
|
-
const isProtocolCommand = invokedCommand === "complete";
|
|
1993
|
-
if (!isProtocolCommand) {
|
|
1994
|
-
const first = argv[0];
|
|
1995
|
-
if (argv.length === 1 && typeof first === "string" && isShell(first)) {
|
|
1996
|
-
const shell = first;
|
|
1997
|
-
const { commandName, executable } = await resolveCliInfo(pluginOptions);
|
|
1998
|
-
const root = new RootCommand;
|
|
1999
|
-
root.setup(commandName, executable, shell);
|
|
2000
|
-
return;
|
|
2001
|
-
}
|
|
2002
|
-
console.error(colors.red("Missing or invalid shell name for completions script generation."));
|
|
2003
|
-
console.error(colors.dim("Usage: <cli> completions <bash|zsh|fish|powershell>"));
|
|
2004
|
-
console.error(colors.dim("Protocol callback form: <cli> complete -- <args...>"));
|
|
2005
|
-
return;
|
|
2006
|
-
}
|
|
2007
|
-
const metadataResult = await loadGeneratedMetadata(pluginOptions);
|
|
2008
|
-
if (Result2.isError(metadataResult)) {
|
|
2009
|
-
console.log(":1");
|
|
2010
|
-
if (process.env.BUNLI_DEBUG_COMPLETIONS) {
|
|
2011
|
-
console.error(colors.red(metadataResult.error.message));
|
|
2012
|
-
}
|
|
2013
|
-
return;
|
|
2014
|
-
}
|
|
2015
|
-
const parseResult = Result2.try({
|
|
2016
|
-
try: () => {
|
|
2017
|
-
const root = buildRegistry(metadataResult.value.commands, {
|
|
2018
|
-
includeAliases: pluginOptions.includeAliases,
|
|
2019
|
-
includeGlobalFlags: pluginOptions.includeGlobalFlags
|
|
2020
|
-
});
|
|
2021
|
-
root.parse(argv);
|
|
2022
|
-
},
|
|
2023
|
-
catch: (cause) => new CompletionProtocolError({
|
|
2024
|
-
message: "Completion registry failed to parse protocol arguments.",
|
|
2025
|
-
cause
|
|
2026
|
-
})
|
|
2027
|
-
});
|
|
2028
|
-
if (Result2.isError(parseResult)) {
|
|
2029
|
-
console.log(":1");
|
|
2030
|
-
if (process.env.BUNLI_DEBUG_COMPLETIONS) {
|
|
2031
|
-
console.error(colors.red(parseResult.error.message));
|
|
2032
|
-
}
|
|
2033
|
-
}
|
|
2034
|
-
}
|
|
2035
|
-
});
|
|
2036
|
-
}
|
|
2037
|
-
var completionsPlugin = createPlugin((options = {}) => ({
|
|
2038
|
-
name: "completions",
|
|
2039
|
-
setup(context) {
|
|
2040
|
-
const command = completionsCommand(options);
|
|
2041
|
-
context.registerCommand(command);
|
|
2042
|
-
}
|
|
2043
|
-
}));
|
|
2044
|
-
|
|
2045
|
-
// ../../node_modules/.bun/@bunli+plugin-config@0.4.4+44deef6f8e4a2f18/node_modules/@bunli/plugin-config/src/index.ts
|
|
2046
|
-
import { readFile as readFile2, access } from "fs/promises";
|
|
2047
|
-
import { homedir } from "os";
|
|
2048
|
-
class ConfigFileNotFoundError extends TaggedError("ConfigFileNotFoundError")() {
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
class ConfigFileReadError extends TaggedError("ConfigFileReadError")() {
|
|
2052
|
-
}
|
|
2053
|
-
|
|
2054
|
-
class ConfigFileParseError extends TaggedError("ConfigFileParseError")() {
|
|
2055
|
-
}
|
|
2056
|
-
var configMergerPlugin = createPlugin((options = {}) => {
|
|
2057
|
-
const sources = options.sources || [
|
|
2058
|
-
"~/.config/{{name}}/config.json",
|
|
2059
|
-
".{{name}}rc",
|
|
2060
|
-
".{{name}}rc.json",
|
|
2061
|
-
".config/{{name}}.json"
|
|
2062
|
-
];
|
|
2063
|
-
return {
|
|
2064
|
-
name: "@bunli/plugin-config",
|
|
2065
|
-
version: "1.0.0",
|
|
2066
|
-
async setup(context) {
|
|
2067
|
-
const appName = context.config.name || "bunli";
|
|
2068
|
-
const configs = [];
|
|
2069
|
-
for (const source of sources) {
|
|
2070
|
-
const configPath = source.replace(/^~/, homedir()).replace(/\{\{name\}\}/g, appName);
|
|
2071
|
-
const loadedConfig = await readConfigSource(configPath);
|
|
2072
|
-
if (Result.isError(loadedConfig)) {
|
|
2073
|
-
if (ConfigFileNotFoundError.is(loadedConfig.error)) {
|
|
2074
|
-
context.logger.debug(`Config file not found: ${configPath}`);
|
|
2075
|
-
continue;
|
|
2076
|
-
}
|
|
2077
|
-
if (ConfigFileParseError.is(loadedConfig.error)) {
|
|
2078
|
-
context.logger.warn(`Failed to parse config file ${configPath}: ${loadedConfig.error.message}`);
|
|
2079
|
-
continue;
|
|
2080
|
-
}
|
|
2081
|
-
context.logger.warn(`Failed to load config file ${configPath}: ${loadedConfig.error.message}`);
|
|
2082
|
-
continue;
|
|
2083
|
-
}
|
|
2084
|
-
configs.push(loadedConfig.value);
|
|
2085
|
-
context.logger.debug(`Loaded config from ${configPath}`);
|
|
2086
|
-
if (options.stopOnFirst) {
|
|
2087
|
-
break;
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
if (configs.length > 0) {
|
|
2091
|
-
let merged;
|
|
2092
|
-
if (options.mergeStrategy === "shallow") {
|
|
2093
|
-
merged = Object.assign({}, ...configs);
|
|
2094
|
-
} else {
|
|
2095
|
-
merged = deepMerge(...configs);
|
|
2096
|
-
}
|
|
2097
|
-
context.updateConfig(merged);
|
|
2098
|
-
context.logger.info(`Merged ${configs.length} config file(s)`);
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
};
|
|
2102
|
-
});
|
|
2103
|
-
async function readConfigSource(path) {
|
|
2104
|
-
const existsResult = await Result.tryPromise({
|
|
2105
|
-
try: async () => {
|
|
2106
|
-
await access(path);
|
|
2107
|
-
},
|
|
2108
|
-
catch: (cause) => new ConfigFileNotFoundError({
|
|
2109
|
-
path,
|
|
2110
|
-
message: `Config file not found: ${path}`,
|
|
2111
|
-
cause
|
|
2112
|
-
})
|
|
2113
|
-
});
|
|
2114
|
-
if (Result.isError(existsResult)) {
|
|
2115
|
-
return existsResult;
|
|
2116
|
-
}
|
|
2117
|
-
const readResult = await Result.tryPromise({
|
|
2118
|
-
try: async () => await readFile2(path, "utf-8"),
|
|
2119
|
-
catch: (cause) => new ConfigFileReadError({
|
|
2120
|
-
path,
|
|
2121
|
-
message: `Unable to read config file: ${path}`,
|
|
2122
|
-
cause
|
|
2123
|
-
})
|
|
2124
|
-
});
|
|
2125
|
-
if (Result.isError(readResult)) {
|
|
2126
|
-
return readResult;
|
|
2127
|
-
}
|
|
2128
|
-
return Result.try({
|
|
2129
|
-
try: () => {
|
|
2130
|
-
const parsed = JSON.parse(readResult.value);
|
|
2131
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2132
|
-
throw new Error("Config file must contain a JSON object");
|
|
2133
|
-
}
|
|
2134
|
-
return parsed;
|
|
2135
|
-
},
|
|
2136
|
-
catch: (cause) => new ConfigFileParseError({
|
|
2137
|
-
path,
|
|
2138
|
-
message: `Invalid JSON in config file: ${path}`,
|
|
2139
|
-
cause
|
|
2140
|
-
})
|
|
2141
|
-
});
|
|
2142
|
-
}
|
|
2143
|
-
|
|
2144
|
-
// ../../node_modules/.bun/@bunli+plugin-skills@0.1.0+44deef6f8e4a2f18/node_modules/@bunli/plugin-skills/src/plugin.ts
|
|
2145
|
-
var skillsPlugin = createPlugin((options = {}) => ({
|
|
2146
|
-
name: "skills",
|
|
2147
|
-
setup(context) {
|
|
2148
|
-
const skillsGroup = defineGroup({
|
|
2149
|
-
name: "skills",
|
|
2150
|
-
description: "Manage agent skill files",
|
|
2151
|
-
commands: [
|
|
2152
|
-
defineCommand({
|
|
2153
|
-
name: "sync",
|
|
2154
|
-
description: "Generate and install skill files for detected agents",
|
|
2155
|
-
options: {
|
|
2156
|
-
global: {
|
|
2157
|
-
schema: exports_external.boolean().default(true),
|
|
2158
|
-
description: "Install globally (default) or project-local",
|
|
2159
|
-
argumentKind: "flag"
|
|
2160
|
-
},
|
|
2161
|
-
force: {
|
|
2162
|
-
schema: exports_external.boolean().default(false),
|
|
2163
|
-
short: "f",
|
|
2164
|
-
description: "Force regeneration even if up to date",
|
|
2165
|
-
argumentKind: "flag"
|
|
2166
|
-
}
|
|
2167
|
-
},
|
|
2168
|
-
async handler({ flags, colors, output }) {
|
|
2169
|
-
const typedFlags = flags;
|
|
2170
|
-
const { syncSkills } = await import("./sync-k2k8svyc.js");
|
|
2171
|
-
const { detectAgents, builtinAgents } = await import("./agents-91fpdyyt.js");
|
|
2172
|
-
const allAgents = options.agents ? [...builtinAgents, ...options.agents] : builtinAgents;
|
|
2173
|
-
const detected = detectAgents(allAgents);
|
|
2174
|
-
const commands = context.store.get("_skillsCommands");
|
|
2175
|
-
if (!commands || commands.size === 0) {
|
|
2176
|
-
console.log(colors.yellow("No commands registered. Nothing to sync."));
|
|
2177
|
-
return;
|
|
2178
|
-
}
|
|
2179
|
-
const cliName = context.store.get("_skillsCliName") || "cli";
|
|
2180
|
-
const result = await syncSkills(cliName, commands, {
|
|
2181
|
-
global: typedFlags.global,
|
|
2182
|
-
force: typedFlags.force,
|
|
2183
|
-
description: options.description,
|
|
2184
|
-
agents: detected
|
|
2185
|
-
});
|
|
2186
|
-
if (!result.updated && !typedFlags.force) {
|
|
2187
|
-
console.log(colors.dim("Skills are up to date."));
|
|
2188
|
-
output({ updated: false, agents: detected.map((a) => a.name) });
|
|
2189
|
-
return;
|
|
2190
|
-
}
|
|
2191
|
-
console.log(colors.green(`Synced skills to ${result.paths.length} location(s)`));
|
|
2192
|
-
for (const install of result.agents) {
|
|
2193
|
-
console.log(colors.dim(` ${install.agent}: ${install.mode} \u2192 ${install.path}`));
|
|
2194
|
-
}
|
|
2195
|
-
output({
|
|
2196
|
-
updated: true,
|
|
2197
|
-
paths: result.paths,
|
|
2198
|
-
agents: result.agents.map((a) => ({
|
|
2199
|
-
agent: a.agent,
|
|
2200
|
-
path: a.path,
|
|
2201
|
-
mode: a.mode
|
|
2202
|
-
}))
|
|
2203
|
-
});
|
|
2204
|
-
}
|
|
2205
|
-
}),
|
|
2206
|
-
defineCommand({
|
|
2207
|
-
name: "list",
|
|
2208
|
-
description: "List detected agents on this system",
|
|
2209
|
-
async handler({ colors, output }) {
|
|
2210
|
-
const { detectAgents, builtinAgents } = await import("./agents-91fpdyyt.js");
|
|
2211
|
-
const allAgents = options.agents ? [...builtinAgents, ...options.agents] : builtinAgents;
|
|
2212
|
-
const detected = detectAgents(allAgents);
|
|
2213
|
-
if (detected.length === 0) {
|
|
2214
|
-
console.log(colors.dim("No agents detected."));
|
|
2215
|
-
output({ agents: [] });
|
|
2216
|
-
return;
|
|
2217
|
-
}
|
|
2218
|
-
console.log(`Detected ${detected.length} agent(s):
|
|
2219
|
-
`);
|
|
2220
|
-
for (const agent of detected) {
|
|
2221
|
-
const tag = agent.universal ? colors.dim(" (universal)") : "";
|
|
2222
|
-
console.log(` ${colors.bold(agent.name)}${tag}`);
|
|
2223
|
-
console.log(colors.dim(` ${agent.projectSkillsDir}`));
|
|
2224
|
-
}
|
|
2225
|
-
output({
|
|
2226
|
-
agents: detected.map((a) => ({
|
|
2227
|
-
name: a.name,
|
|
2228
|
-
universal: a.universal,
|
|
2229
|
-
projectSkillsDir: a.projectSkillsDir,
|
|
2230
|
-
globalSkillsDir: a.globalSkillsDir
|
|
2231
|
-
}))
|
|
2232
|
-
});
|
|
2233
|
-
}
|
|
2234
|
-
})
|
|
2235
|
-
]
|
|
2236
|
-
});
|
|
2237
|
-
context.registerCommand(skillsGroup);
|
|
2238
|
-
}
|
|
2239
|
-
}));
|
|
2240
|
-
// bunli.config.ts
|
|
2241
|
-
var bunliConfig = defineConfig({
|
|
2242
|
-
name: package_default.name,
|
|
2243
|
-
version: package_default.version,
|
|
2244
|
-
description: package_default.description,
|
|
2245
|
-
commands: {
|
|
2246
|
-
entry: "./src/cli.ts",
|
|
2247
|
-
directory: "./src/commands",
|
|
2248
|
-
generateReport: true
|
|
2249
|
-
},
|
|
2250
|
-
build: {
|
|
2251
|
-
entry: "./src/cli.ts",
|
|
2252
|
-
outdir: "./dist-bunli",
|
|
2253
|
-
sourcemap: true
|
|
2254
|
-
},
|
|
2255
|
-
test: {
|
|
2256
|
-
pattern: ["tests/*.test.ts"],
|
|
2257
|
-
coverage: false,
|
|
2258
|
-
watch: false
|
|
2259
|
-
},
|
|
2260
|
-
tui: {
|
|
2261
|
-
renderer: {
|
|
2262
|
-
bufferMode: "alternate"
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
});
|
|
2266
|
-
|
|
2267
|
-
// src/command-contract.ts
|
|
2268
|
-
import path from "path";
|
|
2269
|
-
var SHARED_OPTION_PARSER = buildCommandOptionParser(ALL_COMMAND_OPTION_METADATA);
|
|
2270
|
-
var STRING_OPTION_NAMES_BY_GROUP = Object.fromEntries(Object.entries(COMMAND_OPTION_METADATA_BY_GROUP).map(([groupName, metadata]) => [
|
|
2271
|
-
groupName,
|
|
2272
|
-
new Set(collectOptionNamesByType(metadata, "string"))
|
|
2273
|
-
]));
|
|
2274
|
-
var STRING_OPTION_NAMES_BY_COMMAND = Object.fromEntries(WP_TYPIA_RESERVED_TOP_LEVEL_COMMAND_NAMES.map((commandName) => [
|
|
2275
|
-
commandName,
|
|
2276
|
-
new Set(WP_TYPIA_COMMAND_OPTION_GROUP_NAMES_BY_TOP_LEVEL_COMMAND[commandName].flatMap((groupName) => Array.from(STRING_OPTION_NAMES_BY_GROUP[groupName])))
|
|
2277
|
-
]));
|
|
2278
|
-
var GLOBAL_STRING_OPTION_NAMES = new Set(collectOptionNamesByType(GLOBAL_OPTION_METADATA, "string"));
|
|
2279
|
-
var SHORT_OPTION_NAMES_WITH_VALUES = new Set([...SHARED_OPTION_PARSER.shortFlagMap.entries()].filter(([, option]) => option.type === "string").map(([short]) => short));
|
|
2280
|
-
function isReservedTopLevelCommandName(value) {
|
|
2281
|
-
return WP_TYPIA_RESERVED_TOP_LEVEL_COMMAND_NAMES.includes(value);
|
|
2282
|
-
}
|
|
2283
|
-
function assertStringOptionValues(argv) {
|
|
2284
|
-
const firstPositionalIndex = findFirstPositionalIndex(argv, COMMAND_ROUTING_METADATA);
|
|
2285
|
-
if (firstPositionalIndex === -1) {
|
|
2286
|
-
return;
|
|
2287
|
-
}
|
|
2288
|
-
const commandName = argv[firstPositionalIndex];
|
|
2289
|
-
const stringOptionNames = new Set(GLOBAL_STRING_OPTION_NAMES);
|
|
2290
|
-
for (const optionName of STRING_OPTION_NAMES_BY_COMMAND[commandName] ?? []) {
|
|
2291
|
-
stringOptionNames.add(optionName);
|
|
2292
|
-
}
|
|
2293
|
-
for (let index = firstPositionalIndex + 1;index < argv.length; index += 1) {
|
|
2294
|
-
const arg = argv[index];
|
|
2295
|
-
if (arg === "--") {
|
|
2296
|
-
break;
|
|
2297
|
-
}
|
|
2298
|
-
if (arg.length === 2 && arg.startsWith("-")) {
|
|
2299
|
-
if (SHORT_OPTION_NAMES_WITH_VALUES.has(arg.slice(1))) {
|
|
2300
|
-
const next2 = argv[index + 1];
|
|
2301
|
-
if (!next2 || next2.startsWith("-")) {
|
|
2302
|
-
throw createMissingOptionValueError(arg);
|
|
2303
|
-
}
|
|
2304
|
-
index += 1;
|
|
2305
|
-
}
|
|
2306
|
-
continue;
|
|
2307
|
-
}
|
|
2308
|
-
if (!arg.startsWith("--")) {
|
|
2309
|
-
continue;
|
|
2310
|
-
}
|
|
2311
|
-
const [rawName, inlineValue] = arg.slice(2).split("=", 2);
|
|
2312
|
-
if (!stringOptionNames.has(rawName)) {
|
|
2313
|
-
continue;
|
|
2314
|
-
}
|
|
2315
|
-
if (arg.includes("=")) {
|
|
2316
|
-
if (!inlineValue) {
|
|
2317
|
-
throw createMissingOptionValueError(`--${rawName}`);
|
|
2318
|
-
}
|
|
2319
|
-
continue;
|
|
2320
|
-
}
|
|
2321
|
-
const next = argv[index + 1];
|
|
2322
|
-
if (!next || next.startsWith("-")) {
|
|
2323
|
-
throw createMissingOptionValueError(`--${rawName}`);
|
|
2324
|
-
}
|
|
2325
|
-
index += 1;
|
|
2326
|
-
}
|
|
2327
|
-
}
|
|
2328
|
-
function isWindowsDrivePath(value) {
|
|
2329
|
-
return /^[A-Za-z]:([\\/]|$)/.test(value);
|
|
2330
|
-
}
|
|
2331
|
-
function looksLikeStructuredProjectInput(value) {
|
|
2332
|
-
if (value.includes("#")) {
|
|
2333
|
-
return true;
|
|
2334
|
-
}
|
|
2335
|
-
if (!isWindowsDrivePath(value) && /^[A-Za-z][A-Za-z0-9+.-]*:/u.test(value)) {
|
|
2336
|
-
return true;
|
|
2337
|
-
}
|
|
2338
|
-
return value.startsWith("@") && value.includes("/");
|
|
2339
|
-
}
|
|
2340
|
-
function assertPositionalAliasProjectDir(projectDir) {
|
|
2341
|
-
const normalizedProjectDir = path.normalize(projectDir).replace(/[\\/]+$/u, "") || path.normalize(projectDir);
|
|
2342
|
-
if (normalizedProjectDir === "." || normalizedProjectDir === "..") {
|
|
2343
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `The positional alias does not scaffold into \`${projectDir}\`. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` with an explicit child directory instead.`);
|
|
2344
|
-
}
|
|
2345
|
-
if (looksLikeStructuredProjectInput(projectDir)) {
|
|
2346
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `The positional alias only accepts unambiguous local project directories. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` for \`${projectDir}\`.`);
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
function normalizeWpTypiaArgv(argv) {
|
|
2350
|
-
const positionalIndexes = collectPositionalIndexes(argv, COMMAND_ROUTING_METADATA);
|
|
2351
|
-
const firstPositionalIndex = positionalIndexes[0] ?? -1;
|
|
2352
|
-
if (firstPositionalIndex === -1) {
|
|
2353
|
-
return argv;
|
|
2354
|
-
}
|
|
2355
|
-
const firstPositional = argv[firstPositionalIndex];
|
|
2356
|
-
if (!firstPositional) {
|
|
2357
|
-
return argv;
|
|
2358
|
-
}
|
|
2359
|
-
if (firstPositional === "migrations") {
|
|
2360
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, "`wp-typia migrations` was removed in favor of `wp-typia migrate`. Use `wp-typia migrate <subcommand>` instead.");
|
|
2361
|
-
}
|
|
2362
|
-
if (isReservedTopLevelCommandName(firstPositional)) {
|
|
2363
|
-
assertStringOptionValues(argv);
|
|
2364
|
-
return argv;
|
|
2365
|
-
}
|
|
2366
|
-
if (positionalIndexes.length > 1) {
|
|
2367
|
-
const extraPositionals = positionalIndexes.slice(1).map((index) => argv[index]).filter((value) => typeof value === "string" && value.length > 0);
|
|
2368
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `The positional alias only accepts a single project directory. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` for scaffold invocations with additional positional arguments, or check the command spelling if you meant another top-level command. Extra positional arguments: ${extraPositionals.map((value) => `\`${value}\``).join(", ")}.`);
|
|
2369
|
-
}
|
|
2370
|
-
assertPositionalAliasProjectDir(firstPositional);
|
|
2371
|
-
const normalizedArgv = [
|
|
2372
|
-
...argv.slice(0, firstPositionalIndex),
|
|
2373
|
-
"create",
|
|
2374
|
-
...argv.slice(firstPositionalIndex)
|
|
2375
|
-
];
|
|
2376
|
-
assertStringOptionValues(normalizedArgv);
|
|
2377
|
-
return normalizedArgv;
|
|
2378
|
-
}
|
|
2379
|
-
|
|
2380
|
-
// src/config-override.ts
|
|
2381
|
-
var GLOBAL_OPTION_PARSER = buildCommandOptionParser(GLOBAL_OPTION_METADATA);
|
|
2382
|
-
function extractWpTypiaConfigOverride(argv) {
|
|
2383
|
-
const { argv: nextArgv, flags } = extractKnownOptionValuesFromArgv(argv, {
|
|
2384
|
-
optionNames: ["config"],
|
|
2385
|
-
parser: GLOBAL_OPTION_PARSER
|
|
2386
|
-
});
|
|
2387
|
-
return {
|
|
2388
|
-
argv: nextArgv,
|
|
2389
|
-
configOverridePath: typeof flags.config === "string" ? flags.config : undefined
|
|
2390
|
-
};
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2393
|
-
// src/plugins/wp-typia-skills.ts
|
|
2394
|
-
function createWpTypiaSkillsMetadataPlugin(commands) {
|
|
2395
|
-
return {
|
|
2396
|
-
name: "wp-typia-skills-metadata",
|
|
2397
|
-
setup(context) {
|
|
2398
|
-
context.store.set("_skillsCommands", new Map(commands.map((command) => [command.name, command])));
|
|
2399
|
-
context.store.set("_skillsCliName", "wp-typia");
|
|
2400
|
-
}
|
|
2401
|
-
};
|
|
2402
|
-
}
|
|
2403
|
-
|
|
2404
|
-
// src/plugins/wp-typia-user-config.ts
|
|
2405
|
-
var wpTypiaUserConfigPlugin = createPlugin((options = {}) => {
|
|
2406
|
-
let resolvedConfig = {};
|
|
2407
|
-
return {
|
|
2408
|
-
name: "wp-typia-user-config",
|
|
2409
|
-
async setup(context) {
|
|
2410
|
-
resolvedConfig = await loadWpTypiaUserConfig(context.paths.cwd);
|
|
2411
|
-
if (options.overrideSource) {
|
|
2412
|
-
const overrideConfig = await loadWpTypiaUserConfigFromSource(context.paths.cwd, options.overrideSource);
|
|
2413
|
-
resolvedConfig = mergeWpTypiaUserConfig(resolvedConfig, overrideConfig);
|
|
2414
|
-
}
|
|
2415
|
-
},
|
|
2416
|
-
beforeCommand(context) {
|
|
2417
|
-
context.store.wpTypiaUserConfig = resolvedConfig;
|
|
2418
|
-
}
|
|
2419
|
-
};
|
|
2420
|
-
});
|
|
2421
|
-
|
|
2422
|
-
// src/cli.ts
|
|
2423
|
-
function applyStandaloneSupportLayoutEnv() {
|
|
2424
|
-
if (process.env.WP_TYPIA_PROJECT_TOOLS_PACKAGE_ROOT) {
|
|
2425
|
-
return;
|
|
2426
|
-
}
|
|
2427
|
-
const executableDir = path2.dirname(process.execPath);
|
|
2428
|
-
const candidateRoots = [
|
|
2429
|
-
path2.join(executableDir, ".wp-typia", "share", "wp-typia-project-tools"),
|
|
2430
|
-
path2.resolve(executableDir, "..", ".wp-typia", "share", "wp-typia-project-tools")
|
|
2431
|
-
];
|
|
2432
|
-
for (const candidateRoot of candidateRoots) {
|
|
2433
|
-
if (fs.existsSync(path2.join(candidateRoot, "package.json"))) {
|
|
2434
|
-
process.env.WP_TYPIA_PROJECT_TOOLS_PACKAGE_ROOT = candidateRoot;
|
|
2435
|
-
return;
|
|
2436
|
-
}
|
|
2437
|
-
}
|
|
2438
|
-
}
|
|
2439
|
-
function resolveGeneratedMetadataPath(moduleUrl) {
|
|
2440
|
-
const candidates = [
|
|
2441
|
-
new URL("./.bunli/commands.gen.js", moduleUrl),
|
|
2442
|
-
new URL("../lib/.bunli/commands.gen.js", moduleUrl),
|
|
2443
|
-
new URL("../.bunli/commands.gen.ts", moduleUrl)
|
|
2444
|
-
];
|
|
2445
|
-
for (const candidate of candidates) {
|
|
2446
|
-
const candidatePath = fileURLToPath(candidate);
|
|
2447
|
-
if (fs.existsSync(candidatePath)) {
|
|
2448
|
-
return candidatePath;
|
|
2449
|
-
}
|
|
2450
|
-
}
|
|
2451
|
-
return fileURLToPath(new URL("../.bunli/commands.gen.ts", moduleUrl));
|
|
2452
|
-
}
|
|
2453
|
-
async function formatCliError(error) {
|
|
2454
|
-
try {
|
|
2455
|
-
const { formatCliDiagnosticError } = await import("./cli-diagnostics-10drxh34.js");
|
|
2456
|
-
return formatCliDiagnosticError(error);
|
|
2457
|
-
} catch {
|
|
2458
|
-
return error instanceof Error ? error.message : String(error);
|
|
2459
|
-
}
|
|
2460
|
-
}
|
|
2461
|
-
async function createWpTypiaCli(options = {}) {
|
|
2462
|
-
applyStandaloneSupportLayoutEnv();
|
|
2463
|
-
const { wpTypiaCommands } = await import("./command-list-y3g7e9rb.js");
|
|
2464
|
-
const cli = await createCLI({
|
|
2465
|
-
...bunliConfig,
|
|
2466
|
-
description: package_default.description,
|
|
2467
|
-
name: package_default.name,
|
|
2468
|
-
plugins: [
|
|
2469
|
-
configMergerPlugin({
|
|
2470
|
-
mergeStrategy: "deep",
|
|
2471
|
-
sources: [...WP_TYPIA_CONFIG_SOURCES]
|
|
2472
|
-
}),
|
|
2473
|
-
wpTypiaUserConfigPlugin({
|
|
2474
|
-
overrideSource: options.configOverridePath
|
|
2475
|
-
}),
|
|
2476
|
-
aiAgentPlugin({}),
|
|
2477
|
-
createWpTypiaSkillsMetadataPlugin(wpTypiaCommands),
|
|
2478
|
-
skillsPlugin({
|
|
2479
|
-
description: package_default.description
|
|
2480
|
-
}),
|
|
2481
|
-
completionsPlugin({
|
|
2482
|
-
commandName: "wp-typia",
|
|
2483
|
-
executable: "wp-typia",
|
|
2484
|
-
generatedPath: resolveGeneratedMetadataPath(import.meta.url)
|
|
2485
|
-
})
|
|
2486
|
-
],
|
|
2487
|
-
version: package_default.version
|
|
2488
|
-
});
|
|
2489
|
-
for (const command of wpTypiaCommands) {
|
|
2490
|
-
cli.command(command);
|
|
2491
|
-
}
|
|
2492
|
-
return cli;
|
|
2493
|
-
}
|
|
2494
|
-
async function main(argv = process.argv.slice(2)) {
|
|
2495
|
-
const normalizedArgv = normalizeWpTypiaArgv(argv);
|
|
2496
|
-
const { argv: cliArgv, configOverridePath } = extractWpTypiaConfigOverride(normalizedArgv);
|
|
2497
|
-
validateCliOutputFormatArgv(cliArgv);
|
|
2498
|
-
const cli = await createWpTypiaCli({ configOverridePath });
|
|
2499
|
-
await cli.run(normalizeCliOutputFormatArgv(cliArgv));
|
|
2500
|
-
}
|
|
2501
|
-
async function runCliEntrypoint(argv = process.argv.slice(2)) {
|
|
2502
|
-
try {
|
|
2503
|
-
await main(argv);
|
|
2504
|
-
} catch (error) {
|
|
2505
|
-
if (writeStructuredCliDiagnosticError(argv, error)) {
|
|
2506
|
-
return;
|
|
2507
|
-
}
|
|
2508
|
-
console.error(`Error: ${await formatCliError(error)}`);
|
|
2509
|
-
process.exitCode = 1;
|
|
2510
|
-
}
|
|
2511
|
-
}
|
|
2512
|
-
if (import.meta.main) {
|
|
2513
|
-
runCliEntrypoint();
|
|
2514
|
-
}
|
|
2515
|
-
var cli_default = createWpTypiaCli;
|
|
2516
|
-
export {
|
|
2517
|
-
runCliEntrypoint,
|
|
2518
|
-
main,
|
|
2519
|
-
cli_default as default,
|
|
2520
|
-
createWpTypiaCli
|
|
2521
|
-
};
|
|
2522
|
-
|
|
2523
|
-
//# debugId=C2A72BC9D07456AF64756E2164756E21
|