toolcraft-openapi 0.0.1
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 +64 -0
- package/dist/api-command.d.ts +7 -0
- package/dist/api-command.js +4 -0
- package/dist/auth/bearer-token-auth.d.ts +8 -0
- package/dist/auth/bearer-token-auth.js +216 -0
- package/dist/auth/types.d.ts +9 -0
- package/dist/auth/types.js +1 -0
- package/dist/bin/generate.d.ts +40 -0
- package/dist/bin/generate.js +248 -0
- package/dist/define-client.d.ts +20 -0
- package/dist/define-client.js +148 -0
- package/dist/generate.d.ts +210 -0
- package/dist/generate.js +1131 -0
- package/dist/group-by-noun.d.ts +6 -0
- package/dist/group-by-noun.js +17 -0
- package/dist/http.d.ts +26 -0
- package/dist/http.js +123 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +6 -0
- package/dist/interpreter.d.ts +6 -0
- package/dist/interpreter.js +289 -0
- package/dist/lock.d.ts +14 -0
- package/dist/lock.js +48 -0
- package/dist/naming.d.ts +24 -0
- package/dist/naming.js +218 -0
- package/dist/request-shape.d.ts +15 -0
- package/dist/request-shape.js +5 -0
- package/dist/runtime.d.ts +13 -0
- package/dist/runtime.js +94 -0
- package/dist/spec-source.d.ts +11 -0
- package/dist/spec-source.js +63 -0
- package/node_modules/@poe-code/design-system/dist/acp/components.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/acp/components.js +121 -0
- package/node_modules/@poe-code/design-system/dist/acp/index.d.ts +3 -0
- package/node_modules/@poe-code/design-system/dist/acp/index.js +2 -0
- package/node_modules/@poe-code/design-system/dist/acp/writer.d.ts +13 -0
- package/node_modules/@poe-code/design-system/dist/acp/writer.js +21 -0
- package/node_modules/@poe-code/design-system/dist/components/command-errors.d.ts +16 -0
- package/node_modules/@poe-code/design-system/dist/components/command-errors.js +22 -0
- package/node_modules/@poe-code/design-system/dist/components/help-formatter.d.ts +20 -0
- package/node_modules/@poe-code/design-system/dist/components/help-formatter.js +27 -0
- package/node_modules/@poe-code/design-system/dist/components/index.d.ts +10 -0
- package/node_modules/@poe-code/design-system/dist/components/index.js +7 -0
- package/node_modules/@poe-code/design-system/dist/components/logger.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/components/logger.js +60 -0
- package/node_modules/@poe-code/design-system/dist/components/symbols.d.ts +12 -0
- package/node_modules/@poe-code/design-system/dist/components/symbols.js +71 -0
- package/node_modules/@poe-code/design-system/dist/components/table.d.ts +13 -0
- package/node_modules/@poe-code/design-system/dist/components/table.js +74 -0
- package/node_modules/@poe-code/design-system/dist/components/text.d.ts +14 -0
- package/node_modules/@poe-code/design-system/dist/components/text.js +104 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/ansi.d.ts +18 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/ansi.js +298 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/buffer.d.ts +25 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/buffer.js +189 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/border.d.ts +9 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/border.js +123 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/footer.d.ts +8 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/footer.js +57 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/output-pane.d.ts +12 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/output-pane.js +254 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/stats-pane.d.ts +7 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/components/stats-pane.js +121 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/dashboard.d.ts +20 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/dashboard.js +167 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/demo.d.ts +13 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/demo.js +145 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/index.d.ts +8 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/index.js +4 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/keymap.d.ts +3 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/keymap.js +99 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/layout.d.ts +25 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/layout.js +79 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/should-use-dashboard.d.ts +10 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/should-use-dashboard.js +7 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/snapshot.d.ts +10 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/snapshot.js +68 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/store.d.ts +8 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/store.js +51 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/terminal.d.ts +37 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/terminal.js +233 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/types.d.ts +36 -0
- package/node_modules/@poe-code/design-system/dist/dashboard/types.js +1 -0
- package/node_modules/@poe-code/design-system/dist/index.d.ts +33 -0
- package/node_modules/@poe-code/design-system/dist/index.js +31 -0
- package/node_modules/@poe-code/design-system/dist/internal/output-format.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/internal/output-format.js +22 -0
- package/node_modules/@poe-code/design-system/dist/internal/strip-ansi.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/internal/strip-ansi.js +3 -0
- package/node_modules/@poe-code/design-system/dist/internal/theme-detect.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/internal/theme-detect.js +49 -0
- package/node_modules/@poe-code/design-system/dist/prompts/index.d.ts +66 -0
- package/node_modules/@poe-code/design-system/dist/prompts/index.js +132 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/cancel.d.ts +2 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/cancel.js +9 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.js +15 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.d.ts +18 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.js +101 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.js +39 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/outro.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/outro.js +16 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/spinner.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/spinner.js +74 -0
- package/node_modules/@poe-code/design-system/dist/prompts/theme.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/prompts/theme.js +12 -0
- package/node_modules/@poe-code/design-system/dist/static/index.d.ts +4 -0
- package/node_modules/@poe-code/design-system/dist/static/index.js +2 -0
- package/node_modules/@poe-code/design-system/dist/static/menu.d.ts +11 -0
- package/node_modules/@poe-code/design-system/dist/static/menu.js +36 -0
- package/node_modules/@poe-code/design-system/dist/static/spinner.d.ts +14 -0
- package/node_modules/@poe-code/design-system/dist/static/spinner.js +46 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/ast.d.ts +92 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/ast.js +1 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/demo-content.d.ts +2 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/demo-content.js +139 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/index.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/index.js +8 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/block.d.ts +7 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/block.js +1495 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/frontmatter.d.ts +8 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/frontmatter.js +412 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/inline.d.ts +10 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/inline.js +1166 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser.d.ts +5 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser.js +42 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/renderer.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/renderer.js +572 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/testing/theme-render-fixture.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/terminal-markdown/testing/theme-render-fixture.js +27 -0
- package/node_modules/@poe-code/design-system/dist/tokens/colors.d.ts +35 -0
- package/node_modules/@poe-code/design-system/dist/tokens/colors.js +34 -0
- package/node_modules/@poe-code/design-system/dist/tokens/index.d.ts +4 -0
- package/node_modules/@poe-code/design-system/dist/tokens/index.js +4 -0
- package/node_modules/@poe-code/design-system/dist/tokens/spacing.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/tokens/spacing.js +6 -0
- package/node_modules/@poe-code/design-system/dist/tokens/typography.d.ts +7 -0
- package/node_modules/@poe-code/design-system/dist/tokens/typography.js +8 -0
- package/node_modules/@poe-code/design-system/dist/tokens/widths.d.ts +5 -0
- package/node_modules/@poe-code/design-system/dist/tokens/widths.js +5 -0
- package/node_modules/@poe-code/design-system/package.json +25 -0
- package/node_modules/auth-store/README.md +47 -0
- package/node_modules/auth-store/dist/create-secret-store.d.ts +2 -0
- package/node_modules/auth-store/dist/create-secret-store.js +35 -0
- package/node_modules/auth-store/dist/encrypted-file-store.d.ts +39 -0
- package/node_modules/auth-store/dist/encrypted-file-store.js +156 -0
- package/node_modules/auth-store/dist/index.d.ts +7 -0
- package/node_modules/auth-store/dist/index.js +4 -0
- package/node_modules/auth-store/dist/keychain-store.d.ts +22 -0
- package/node_modules/auth-store/dist/keychain-store.js +111 -0
- package/node_modules/auth-store/dist/provider-store.d.ts +10 -0
- package/node_modules/auth-store/dist/provider-store.js +28 -0
- package/node_modules/auth-store/dist/types.d.ts +20 -0
- package/node_modules/auth-store/dist/types.js +1 -0
- package/node_modules/auth-store/package.json +25 -0
- package/package.json +48 -0
package/dist/naming.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { UserError } from "agent-kit";
|
|
2
|
+
export const METHOD_DEFAULTS = {
|
|
3
|
+
delete: {
|
|
4
|
+
collection: "delete",
|
|
5
|
+
resource: "delete",
|
|
6
|
+
confirm: true
|
|
7
|
+
},
|
|
8
|
+
get: {
|
|
9
|
+
collection: "list",
|
|
10
|
+
resource: "view",
|
|
11
|
+
genericVerbs: ["get", "list", "view"],
|
|
12
|
+
preferOperationIdWhenPathTailIsGeneric: true
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
export function deriveNoun(operation, path, operationId) {
|
|
16
|
+
const noun = operation.tags?.[0];
|
|
17
|
+
if (typeof noun !== "string" || noun.length === 0) {
|
|
18
|
+
const fallbackNoun = deriveNounFromPath(path);
|
|
19
|
+
if (fallbackNoun === undefined) {
|
|
20
|
+
throw new UserError(`Operation ${JSON.stringify(operationId)} must define tags[0] or a static resource segment in the path to derive a command noun.`);
|
|
21
|
+
}
|
|
22
|
+
return fallbackNoun;
|
|
23
|
+
}
|
|
24
|
+
return toKebabCase(noun);
|
|
25
|
+
}
|
|
26
|
+
export function deriveVerb(method, path, operation, operationId, noun) {
|
|
27
|
+
const segments = splitPathSegments(path);
|
|
28
|
+
const defaults = METHOD_DEFAULTS[method];
|
|
29
|
+
if (defaults !== undefined) {
|
|
30
|
+
const lastSegment = segments.at(-1);
|
|
31
|
+
if (isPathTemplateSegment(lastSegment)) {
|
|
32
|
+
return defaults.resource;
|
|
33
|
+
}
|
|
34
|
+
if (defaults.preferOperationIdWhenPathTailIsGeneric === true) {
|
|
35
|
+
const derived = deriveVerbFromOperationId(method, operation.operationId, noun, defaults);
|
|
36
|
+
const pathTail = lastSegment === undefined ? undefined : toKebabCase(lastSegment);
|
|
37
|
+
if (derived !== undefined) {
|
|
38
|
+
if (pathTail === undefined || derived !== pathTail) {
|
|
39
|
+
return derived;
|
|
40
|
+
}
|
|
41
|
+
if (!operationIdStartsWithCollectionVerb(method, operation.operationId, noun, defaults)) {
|
|
42
|
+
return pathTail;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return defaults.collection;
|
|
47
|
+
}
|
|
48
|
+
const derived = deriveVerbFromOperationId(method, operation.operationId, noun);
|
|
49
|
+
if (derived !== undefined) {
|
|
50
|
+
return derived;
|
|
51
|
+
}
|
|
52
|
+
throw new UserError(`Operation ${JSON.stringify(operationId)} is missing an operationId, so agent-kit-openapi cannot derive a stable command verb.`);
|
|
53
|
+
}
|
|
54
|
+
export function normalizeParamName(name) {
|
|
55
|
+
return toCamelCase(name);
|
|
56
|
+
}
|
|
57
|
+
export function toPascalCase(value) {
|
|
58
|
+
const camel = toCamelCase(value);
|
|
59
|
+
return camel.length === 0 ? camel : `${camel[0]?.toUpperCase() ?? ""}${camel.slice(1)}`;
|
|
60
|
+
}
|
|
61
|
+
export function toCamelCase(value) {
|
|
62
|
+
return splitWords(value)
|
|
63
|
+
.map((word, index) => (index === 0 ? word : `${word[0]?.toUpperCase() ?? ""}${word.slice(1)}`))
|
|
64
|
+
.join("");
|
|
65
|
+
}
|
|
66
|
+
export function toKebabCase(value) {
|
|
67
|
+
return splitWords(value).join("-");
|
|
68
|
+
}
|
|
69
|
+
export function toCliFlag(value) {
|
|
70
|
+
return toKebabCase(value);
|
|
71
|
+
}
|
|
72
|
+
export function splitWords(value) {
|
|
73
|
+
const normalized = value
|
|
74
|
+
.replaceAll("-", " ")
|
|
75
|
+
.replaceAll("_", " ")
|
|
76
|
+
.replaceAll(".", " ")
|
|
77
|
+
.replaceAll("/", " ");
|
|
78
|
+
return normalized
|
|
79
|
+
.split(" ")
|
|
80
|
+
.flatMap(splitCamelCaseWord)
|
|
81
|
+
.filter((word) => word.length > 0)
|
|
82
|
+
.map((word) => word.toLowerCase());
|
|
83
|
+
}
|
|
84
|
+
export function toMcpPrefix(name) {
|
|
85
|
+
return name.replaceAll("-", "_");
|
|
86
|
+
}
|
|
87
|
+
export function isIdentifierName(value) {
|
|
88
|
+
return /^[$A-Z_a-z][$\w]*$/u.test(value);
|
|
89
|
+
}
|
|
90
|
+
function splitPathSegments(path) {
|
|
91
|
+
return path.split("/").filter((segment) => segment.length > 0);
|
|
92
|
+
}
|
|
93
|
+
function deriveNounFromPath(path) {
|
|
94
|
+
return splitPathSegments(path)
|
|
95
|
+
.find((segment) => !isPathTemplateSegment(segment) && segment !== "api" && !isVersionWord(segment))
|
|
96
|
+
?.split("/")
|
|
97
|
+
.map((segment) => toKebabCase(segment))
|
|
98
|
+
.find((segment) => segment.length > 0);
|
|
99
|
+
}
|
|
100
|
+
function isPathTemplateSegment(segment) {
|
|
101
|
+
return segment !== undefined && segment.startsWith("{") && segment.endsWith("}");
|
|
102
|
+
}
|
|
103
|
+
function deriveVerbFromOperationId(method, operationId, noun, defaults) {
|
|
104
|
+
const words = normalizeOperationIdWords(method, operationId, noun);
|
|
105
|
+
if (words === undefined) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const verbWords = stripLeadingGenericVerb(words, defaults?.genericVerbs);
|
|
109
|
+
return verbWords.length === 0 ? undefined : verbWords.join("-");
|
|
110
|
+
}
|
|
111
|
+
function operationIdStartsWithCollectionVerb(method, operationId, noun, defaults) {
|
|
112
|
+
const words = normalizeOperationIdWords(method, operationId, noun);
|
|
113
|
+
return words?.[0] === defaults.collection;
|
|
114
|
+
}
|
|
115
|
+
function normalizeOperationIdWords(method, operationId, noun) {
|
|
116
|
+
if (operationId === undefined) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
const nounWords = splitWords(noun);
|
|
120
|
+
return dedupeAdjacentWords(trimTrailingNounUnlessItConsumesAll(trimTrailingMethod(trimLeadingWords(splitWords(operationId).filter((word) => !isVersionWord(word)), nounWords), method), nounWords));
|
|
121
|
+
}
|
|
122
|
+
function stripLeadingGenericVerb(words, genericVerbs) {
|
|
123
|
+
if (genericVerbs === undefined || words.length <= 1 || !genericVerbs.includes(words[0] ?? "")) {
|
|
124
|
+
return words;
|
|
125
|
+
}
|
|
126
|
+
let start = 1;
|
|
127
|
+
while (start < words.length - 1 && words[start] === words[0]) {
|
|
128
|
+
start += 1;
|
|
129
|
+
}
|
|
130
|
+
return words.slice(start);
|
|
131
|
+
}
|
|
132
|
+
function trimTrailingNounUnlessItConsumesAll(words, nounWords) {
|
|
133
|
+
const withoutTrailingNoun = trimTrailingWords(words, nounWords);
|
|
134
|
+
return withoutTrailingNoun.length === 0 ? words : withoutTrailingNoun;
|
|
135
|
+
}
|
|
136
|
+
function trimLeadingWords(words, prefix) {
|
|
137
|
+
if (prefix.length === 0 || prefix.length > words.length) {
|
|
138
|
+
return words;
|
|
139
|
+
}
|
|
140
|
+
for (let index = 0; index < prefix.length; index += 1) {
|
|
141
|
+
if (words[index] !== prefix[index]) {
|
|
142
|
+
return words;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return words.slice(prefix.length);
|
|
146
|
+
}
|
|
147
|
+
function trimTrailingWords(words, suffix) {
|
|
148
|
+
if (suffix.length === 0 || suffix.length >= words.length) {
|
|
149
|
+
return words;
|
|
150
|
+
}
|
|
151
|
+
const start = words.length - suffix.length;
|
|
152
|
+
for (let index = 0; index < suffix.length; index += 1) {
|
|
153
|
+
if (words[start + index] !== suffix[index]) {
|
|
154
|
+
return words;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return words.slice(0, start);
|
|
158
|
+
}
|
|
159
|
+
function trimTrailingMethod(words, method) {
|
|
160
|
+
return words.at(-1) === method ? words.slice(0, -1) : words;
|
|
161
|
+
}
|
|
162
|
+
function dedupeAdjacentWords(words) {
|
|
163
|
+
if (words.length === 0) {
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
const deduped = [words[0] ?? ""];
|
|
167
|
+
for (let index = 1; index < words.length; index += 1) {
|
|
168
|
+
const word = words[index] ?? "";
|
|
169
|
+
if (word !== deduped.at(-1)) {
|
|
170
|
+
deduped.push(word);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return deduped;
|
|
174
|
+
}
|
|
175
|
+
function isVersionWord(word) {
|
|
176
|
+
if (!word.startsWith("v") || word.length < 2) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
for (const character of word.slice(1)) {
|
|
180
|
+
if (character < "0" || character > "9") {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
function splitCamelCaseWord(value) {
|
|
187
|
+
if (value.length === 0) {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
const words = [value[0] ?? ""];
|
|
191
|
+
for (let index = 1; index < value.length; index += 1) {
|
|
192
|
+
const character = value[index] ?? "";
|
|
193
|
+
const previous = value[index - 1] ?? "";
|
|
194
|
+
const next = value[index + 1];
|
|
195
|
+
if (shouldStartNewWord(previous, character, next)) {
|
|
196
|
+
words.push(character);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const currentWord = words.at(-1) ?? "";
|
|
200
|
+
words[words.length - 1] = `${currentWord}${character}`;
|
|
201
|
+
}
|
|
202
|
+
return words;
|
|
203
|
+
}
|
|
204
|
+
function shouldStartNewWord(previous, character, next) {
|
|
205
|
+
if (!isUppercaseLetter(character)) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
if (isLowercaseLetter(previous)) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
return isUppercaseLetter(previous) && next !== undefined && isLowercaseLetter(next);
|
|
212
|
+
}
|
|
213
|
+
function isLowercaseLetter(character) {
|
|
214
|
+
return character >= "a" && character <= "z";
|
|
215
|
+
}
|
|
216
|
+
function isUppercaseLetter(character) {
|
|
217
|
+
return character >= "A" && character <= "Z";
|
|
218
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const REQUEST_PARAM_SECTIONS: readonly [{
|
|
2
|
+
readonly location: "path";
|
|
3
|
+
readonly key: "pathParams";
|
|
4
|
+
readonly omittable: false;
|
|
5
|
+
}, {
|
|
6
|
+
readonly location: "query";
|
|
7
|
+
readonly key: "query";
|
|
8
|
+
readonly omittable: false;
|
|
9
|
+
}, {
|
|
10
|
+
readonly location: "body";
|
|
11
|
+
readonly key: "body";
|
|
12
|
+
readonly omittable: true;
|
|
13
|
+
}];
|
|
14
|
+
export type RequestParamSection = (typeof REQUEST_PARAM_SECTIONS)[number];
|
|
15
|
+
export type RequestSectionKey = RequestParamSection["key"];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CommandNode } from "agent-kit";
|
|
2
|
+
import { type DefineClientOptions, type DefinedClient, type OpenApiClientServices } from "./define-client.js";
|
|
3
|
+
import { type OpenApiDocument } from "./generate.js";
|
|
4
|
+
import { type OpenApiSourceFileSystem } from "./spec-source.js";
|
|
5
|
+
export type OpenApiDocumentSource = OpenApiDocument | string | URL;
|
|
6
|
+
export interface CommandsFromSpecOptions {
|
|
7
|
+
cwd?: string;
|
|
8
|
+
fetch?: typeof globalThis.fetch;
|
|
9
|
+
fs?: OpenApiSourceFileSystem;
|
|
10
|
+
}
|
|
11
|
+
export type DefineClientFromSpecOptions<TServices extends object = Record<string, never>> = Omit<DefineClientOptions<TServices>, "commands"> & CommandsFromSpecOptions;
|
|
12
|
+
export declare function commandsFromSpec(source: OpenApiDocumentSource, options?: CommandsFromSpecOptions): Promise<CommandNode<OpenApiClientServices>[]>;
|
|
13
|
+
export declare function defineClientFromSpec<TServices extends object = Record<string, never>>(spec: OpenApiDocumentSource, options: DefineClientFromSpecOptions<TServices>): Promise<DefinedClient<TServices>>;
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { defineCommand, defineGroup, S } from "agent-kit";
|
|
3
|
+
import { defineClient } from "./define-client.js";
|
|
4
|
+
import { collectSchemaOptionEntries, collectGeneratedCommands } from "./generate.js";
|
|
5
|
+
import { groupByNoun } from "./group-by-noun.js";
|
|
6
|
+
import { requestJson } from "./http.js";
|
|
7
|
+
import { buildRequestShape, executePreflightBlocks } from "./interpreter.js";
|
|
8
|
+
import { parseOpenApiDocument, readOpenApiSourceText } from "./spec-source.js";
|
|
9
|
+
const RUNTIME_COMMAND_SCOPE = ["cli", "mcp", "sdk"];
|
|
10
|
+
export async function commandsFromSpec(source, options = {}) {
|
|
11
|
+
const document = await resolveDocument(source, options);
|
|
12
|
+
return createRuntimeGroups(collectGeneratedCommands(document));
|
|
13
|
+
}
|
|
14
|
+
export async function defineClientFromSpec(spec, options) {
|
|
15
|
+
const { cwd, fetch, fs: specFs, ...clientOptions } = options;
|
|
16
|
+
const commands = (await commandsFromSpec(spec, {
|
|
17
|
+
cwd,
|
|
18
|
+
fetch,
|
|
19
|
+
fs: specFs
|
|
20
|
+
}));
|
|
21
|
+
return defineClient({ ...clientOptions, commands });
|
|
22
|
+
}
|
|
23
|
+
async function resolveDocument(source, options) {
|
|
24
|
+
if (typeof source !== "string" && !(source instanceof URL)) {
|
|
25
|
+
return source;
|
|
26
|
+
}
|
|
27
|
+
const sourceText = await readOpenApiSourceText(source, {
|
|
28
|
+
cwd: options.cwd ?? process.cwd(),
|
|
29
|
+
fetch: options.fetch ?? globalThis.fetch,
|
|
30
|
+
fs: options.fs ?? fs
|
|
31
|
+
});
|
|
32
|
+
return parseOpenApiDocument(sourceText, source);
|
|
33
|
+
}
|
|
34
|
+
function createRuntimeGroups(commands) {
|
|
35
|
+
return groupByNoun(commands).map(({ noun, commands: nounCommands }) => defineGroup({
|
|
36
|
+
name: noun,
|
|
37
|
+
children: nounCommands.map((command) => createRuntimeCommand(command))
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
function createRuntimeCommand(command) {
|
|
41
|
+
const paramsSchema = S.Object(Object.fromEntries(command.params.map((param) => [param.paramName, createRuntimeParamSchema(param)])), command.paramsSchemaOptions);
|
|
42
|
+
return defineCommand({
|
|
43
|
+
name: command.verb,
|
|
44
|
+
...(command.description === undefined ? {} : { description: command.description }),
|
|
45
|
+
scope: RUNTIME_COMMAND_SCOPE,
|
|
46
|
+
...(command.confirm ? { confirm: true } : {}),
|
|
47
|
+
params: paramsSchema,
|
|
48
|
+
handler: createRuntimeHandler(command)
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function createRuntimeHandler(command) {
|
|
52
|
+
return async ({ params, baseUrl, tokenSource, fetch }) => {
|
|
53
|
+
const resolvedValues = executePreflightBlocks(command.preflightBlocks, params);
|
|
54
|
+
const requestShape = buildRequestShape(command.requestFields, command.sectionRenders, command.optionalSections, params, resolvedValues);
|
|
55
|
+
return requestJson({
|
|
56
|
+
baseUrl,
|
|
57
|
+
path: command.path,
|
|
58
|
+
method: command.method,
|
|
59
|
+
auth: command.auth,
|
|
60
|
+
tokenSource,
|
|
61
|
+
fetch,
|
|
62
|
+
dryRun: params.dryRun,
|
|
63
|
+
verbose: params.verbose,
|
|
64
|
+
...requestShape
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function createRuntimeParamSchema(param) {
|
|
69
|
+
const definition = createRuntimeDefinition(param.definition, param.description, param.shortFlag, param.scope);
|
|
70
|
+
return param.optional ? S.Optional(definition) : definition;
|
|
71
|
+
}
|
|
72
|
+
function createRuntimeDefinition(definition, description, shortFlag, scope) {
|
|
73
|
+
const options = createRuntimeSchemaOptions(definition, description, shortFlag, scope);
|
|
74
|
+
return RUNTIME_DEFINITION_BUILDERS[definition.kind](definition, options);
|
|
75
|
+
}
|
|
76
|
+
const RUNTIME_DEFINITION_BUILDERS = {
|
|
77
|
+
array: (definition, options) => {
|
|
78
|
+
const itemDefinition = createRuntimeDefinition(definition.itemDefinition, undefined, undefined, undefined);
|
|
79
|
+
return options === undefined ? S.Array(itemDefinition) : S.Array(itemDefinition, options);
|
|
80
|
+
},
|
|
81
|
+
boolean: (_definition, options) => options === undefined ? S.Boolean() : S.Boolean(options),
|
|
82
|
+
enum: (definition, options) => options === undefined ? S.Enum(definition.enumValues) : S.Enum(definition.enumValues, options),
|
|
83
|
+
number: (_definition, options) => options === undefined ? S.Number() : S.Number(options),
|
|
84
|
+
string: (_definition, options) => options === undefined ? S.String() : S.String(options)
|
|
85
|
+
};
|
|
86
|
+
function createRuntimeSchemaOptions(definition, description, shortFlag, scope) {
|
|
87
|
+
const options = Object.fromEntries(collectSchemaOptionEntries({
|
|
88
|
+
definition,
|
|
89
|
+
description,
|
|
90
|
+
shortFlag,
|
|
91
|
+
scope
|
|
92
|
+
}).map(({ key, value }) => [key, Array.isArray(value) ? [...value] : value]));
|
|
93
|
+
return Object.keys(options).length === 0 ? undefined : options;
|
|
94
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { OpenApiDocument } from "./generate.js";
|
|
2
|
+
export interface OpenApiSourceFileSystem {
|
|
3
|
+
readFile(filePath: string, encoding: BufferEncoding): Promise<string>;
|
|
4
|
+
}
|
|
5
|
+
export interface OpenApiSourceServices {
|
|
6
|
+
cwd: string;
|
|
7
|
+
fetch: typeof globalThis.fetch;
|
|
8
|
+
fs: OpenApiSourceFileSystem;
|
|
9
|
+
}
|
|
10
|
+
export declare function readOpenApiSourceText(input: string | URL, services: OpenApiSourceServices): Promise<string>;
|
|
11
|
+
export declare function parseOpenApiDocument(sourceText: string, input: string | URL): OpenApiDocument;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
import { UserError } from "agent-kit";
|
|
5
|
+
export async function readOpenApiSourceText(input, services) {
|
|
6
|
+
const inputUrl = input instanceof URL ? input : tryParseUrl(input);
|
|
7
|
+
const sourceLabel = formatSourceLabel(input);
|
|
8
|
+
try {
|
|
9
|
+
if (typeof input === "string" && inputUrl === null) {
|
|
10
|
+
return await services.fs.readFile(path.resolve(services.cwd, input), "utf8");
|
|
11
|
+
}
|
|
12
|
+
if (inputUrl === null) {
|
|
13
|
+
throw new UserError(`Unsupported OpenAPI input ${JSON.stringify(sourceLabel)}.`);
|
|
14
|
+
}
|
|
15
|
+
if (inputUrl.protocol === "file:") {
|
|
16
|
+
return await services.fs.readFile(fileURLToPath(inputUrl), "utf8");
|
|
17
|
+
}
|
|
18
|
+
if (inputUrl.protocol !== "http:" && inputUrl.protocol !== "https:") {
|
|
19
|
+
throw new UserError(`Unsupported OpenAPI input URL protocol ${JSON.stringify(inputUrl.protocol)}.`);
|
|
20
|
+
}
|
|
21
|
+
const response = await services.fetch(inputUrl.toString());
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new UserError(`Failed to fetch ${JSON.stringify(inputUrl.toString())}: ${response.status} ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
return await response.text();
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error instanceof UserError) {
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
throw new UserError(`Failed to read OpenAPI document ${JSON.stringify(sourceLabel)}: ${getErrorMessage(error)}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function parseOpenApiDocument(sourceText, input) {
|
|
35
|
+
let parsed;
|
|
36
|
+
try {
|
|
37
|
+
parsed = parseYaml(sourceText);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
throw new UserError(`Failed to parse OpenAPI document ${JSON.stringify(formatSourceLabel(input))}: ${getErrorMessage(error)}`);
|
|
41
|
+
}
|
|
42
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
43
|
+
throw new UserError(`OpenAPI document ${JSON.stringify(formatSourceLabel(input))} must parse to an object.`);
|
|
44
|
+
}
|
|
45
|
+
return parsed;
|
|
46
|
+
}
|
|
47
|
+
function tryParseUrl(value) {
|
|
48
|
+
try {
|
|
49
|
+
return new URL(value);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function formatSourceLabel(source) {
|
|
56
|
+
return source instanceof URL ? source.toString() : source;
|
|
57
|
+
}
|
|
58
|
+
function getErrorMessage(error) {
|
|
59
|
+
if (error instanceof Error) {
|
|
60
|
+
return error.message;
|
|
61
|
+
}
|
|
62
|
+
return String(error);
|
|
63
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function renderAgentMessage(text: string): void;
|
|
2
|
+
export declare function renderToolStart(kind: string, title: string): void;
|
|
3
|
+
export declare function renderToolComplete(kind: string): void;
|
|
4
|
+
export declare function renderReasoning(text: string): void;
|
|
5
|
+
export declare function renderUsage(tokens: {
|
|
6
|
+
input: number;
|
|
7
|
+
output: number;
|
|
8
|
+
cached?: number;
|
|
9
|
+
costUsd?: number;
|
|
10
|
+
}): void;
|
|
11
|
+
export declare function renderError(message: string): void;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { resolveOutputFormat } from "../internal/output-format.js";
|
|
3
|
+
import { renderMarkdown } from "../terminal-markdown/index.js";
|
|
4
|
+
import { getAcpWriter } from "./writer.js";
|
|
5
|
+
function truncate(text, maxLength) {
|
|
6
|
+
if (text.length <= maxLength)
|
|
7
|
+
return text;
|
|
8
|
+
if (maxLength <= 3)
|
|
9
|
+
return text.slice(0, maxLength);
|
|
10
|
+
return `${text.slice(0, maxLength - 3)}...`;
|
|
11
|
+
}
|
|
12
|
+
const KIND_COLORS = {
|
|
13
|
+
exec: (text) => chalk.yellow(text),
|
|
14
|
+
edit: (text) => chalk.magenta(text),
|
|
15
|
+
read: (text) => chalk.cyan(text),
|
|
16
|
+
search: (text) => chalk.blue(text),
|
|
17
|
+
think: (text) => chalk.dim(text),
|
|
18
|
+
other: (text) => chalk.dim(text)
|
|
19
|
+
};
|
|
20
|
+
function colorForKind(kind) {
|
|
21
|
+
return KIND_COLORS[kind] ?? ((text) => chalk.dim(text));
|
|
22
|
+
}
|
|
23
|
+
function writeLine(line) {
|
|
24
|
+
getAcpWriter()(line);
|
|
25
|
+
}
|
|
26
|
+
const AGENT_PREFIX = `${chalk.green.bold("✓")} agent: `;
|
|
27
|
+
function formatCost(costUsd) {
|
|
28
|
+
return new Intl.NumberFormat("en-US", {
|
|
29
|
+
style: "currency",
|
|
30
|
+
currency: "USD",
|
|
31
|
+
minimumFractionDigits: 2,
|
|
32
|
+
maximumFractionDigits: 6
|
|
33
|
+
}).format(costUsd);
|
|
34
|
+
}
|
|
35
|
+
export function renderAgentMessage(text) {
|
|
36
|
+
const format = resolveOutputFormat();
|
|
37
|
+
if (format === "markdown") {
|
|
38
|
+
writeLine(`- **agent:** ${text}`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (format === "json") {
|
|
42
|
+
writeLine(JSON.stringify({ event: "agent_message", text }));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const rendered = renderMarkdown(text).trimEnd();
|
|
46
|
+
writeLine(`${AGENT_PREFIX}${rendered}`);
|
|
47
|
+
}
|
|
48
|
+
export function renderToolStart(kind, title) {
|
|
49
|
+
const format = resolveOutputFormat();
|
|
50
|
+
if (format === "markdown") {
|
|
51
|
+
writeLine(`- *→ ${kind}: ${title}*`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (format === "json") {
|
|
55
|
+
writeLine(JSON.stringify({ event: "tool_start", kind, title }));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const color = colorForKind(kind);
|
|
59
|
+
writeLine(color(` → ${kind}: ${title}`));
|
|
60
|
+
}
|
|
61
|
+
export function renderToolComplete(kind) {
|
|
62
|
+
const format = resolveOutputFormat();
|
|
63
|
+
if (format === "markdown") {
|
|
64
|
+
writeLine(`- *✓ ${kind}*`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (format === "json") {
|
|
68
|
+
writeLine(JSON.stringify({ event: "tool_complete", kind }));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const color = colorForKind(kind);
|
|
72
|
+
writeLine(color(` ✓ ${kind}`));
|
|
73
|
+
}
|
|
74
|
+
export function renderReasoning(text) {
|
|
75
|
+
const format = resolveOutputFormat();
|
|
76
|
+
if (format === "markdown") {
|
|
77
|
+
writeLine(`- *thinking:* ${truncate(text, 80)}`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (format === "json") {
|
|
81
|
+
writeLine(JSON.stringify({ event: "reasoning", text }));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
writeLine(chalk.dim(` ✓ ${truncate(text, 80)}`));
|
|
85
|
+
}
|
|
86
|
+
export function renderUsage(tokens) {
|
|
87
|
+
const format = resolveOutputFormat();
|
|
88
|
+
const cached = typeof tokens.cached === "number" && tokens.cached > 0 ? ` (${tokens.cached} cached)` : "";
|
|
89
|
+
let cost = "";
|
|
90
|
+
if (typeof tokens.costUsd === "number") {
|
|
91
|
+
cost = ` (${formatCost(tokens.costUsd)})`;
|
|
92
|
+
}
|
|
93
|
+
if (format === "markdown") {
|
|
94
|
+
writeLine(`- **tokens:** ${tokens.input} in → ${tokens.output} out${cost}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (format === "json") {
|
|
98
|
+
writeLine(JSON.stringify({
|
|
99
|
+
event: "usage",
|
|
100
|
+
inputTokens: tokens.input,
|
|
101
|
+
outputTokens: tokens.output,
|
|
102
|
+
cachedTokens: tokens.cached ?? 0,
|
|
103
|
+
costUsd: tokens.costUsd ?? 0
|
|
104
|
+
}));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
writeLine("");
|
|
108
|
+
writeLine(chalk.green(`✓ tokens: ${tokens.input} in${cached} → ${tokens.output} out${cost}`));
|
|
109
|
+
}
|
|
110
|
+
export function renderError(message) {
|
|
111
|
+
const format = resolveOutputFormat();
|
|
112
|
+
if (format === "markdown") {
|
|
113
|
+
writeLine(`- **error:** ${message}`);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (format === "json") {
|
|
117
|
+
writeLine(JSON.stringify({ event: "error", message }));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
writeLine(chalk.red(`✗ ${message}`));
|
|
121
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type AcpLineWriter = (line: string) => void;
|
|
2
|
+
/**
|
|
3
|
+
* Return the writer active in the current async context, or the default
|
|
4
|
+
* stdout writer if none is bound.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getAcpWriter(): AcpLineWriter;
|
|
7
|
+
/**
|
|
8
|
+
* Run `fn` with `writer` bound as the active ACP line writer. All calls to
|
|
9
|
+
* `renderAgentMessage`, `renderToolStart`, `renderAcpEvent`, etc. made inside
|
|
10
|
+
* `fn` (or async work awaited from `fn`) will go through `writer` instead of
|
|
11
|
+
* writing to `process.stdout`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function withAcpWriter<T>(writer: AcpLineWriter, fn: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
const storage = new AsyncLocalStorage();
|
|
3
|
+
const defaultWriter = (line) => {
|
|
4
|
+
process.stdout.write(`${line}\n`);
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Return the writer active in the current async context, or the default
|
|
8
|
+
* stdout writer if none is bound.
|
|
9
|
+
*/
|
|
10
|
+
export function getAcpWriter() {
|
|
11
|
+
return storage.getStore() ?? defaultWriter;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Run `fn` with `writer` bound as the active ACP line writer. All calls to
|
|
15
|
+
* `renderAgentMessage`, `renderToolStart`, `renderAcpEvent`, etc. made inside
|
|
16
|
+
* `fn` (or async work awaited from `fn`) will go through `writer` instead of
|
|
17
|
+
* writing to `process.stdout`.
|
|
18
|
+
*/
|
|
19
|
+
export function withAcpWriter(writer, fn) {
|
|
20
|
+
return storage.run(writer, fn);
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare function formatCommandNotFound(input: {
|
|
2
|
+
unknownCommand: string;
|
|
3
|
+
helpCommand: string;
|
|
4
|
+
}): {
|
|
5
|
+
label: string;
|
|
6
|
+
hint: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function formatCommandNotFoundPanel(input: {
|
|
9
|
+
unknownCommand: string;
|
|
10
|
+
helpCommand: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
}): {
|
|
13
|
+
title: string;
|
|
14
|
+
label: string;
|
|
15
|
+
footer: string;
|
|
16
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { typography } from "../tokens/typography.js";
|
|
2
|
+
import { text } from "./text.js";
|
|
3
|
+
export function formatCommandNotFound(input) {
|
|
4
|
+
const unknown = input.unknownCommand.length > 0
|
|
5
|
+
? input.unknownCommand
|
|
6
|
+
: "<command>";
|
|
7
|
+
return {
|
|
8
|
+
label: `${typography.bold("Unknown command:")} ${text.command(unknown)}`,
|
|
9
|
+
hint: `${text.muted("Run")} ${text.usageCommand(input.helpCommand)} ${text.muted("for available commands.")}`
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function formatCommandNotFoundPanel(input) {
|
|
13
|
+
const message = formatCommandNotFound({
|
|
14
|
+
unknownCommand: input.unknownCommand,
|
|
15
|
+
helpCommand: input.helpCommand
|
|
16
|
+
});
|
|
17
|
+
return {
|
|
18
|
+
title: input.title ?? "command not found",
|
|
19
|
+
label: message.label,
|
|
20
|
+
footer: message.hint
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface CommandInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
}
|
|
5
|
+
export interface OptionInfo {
|
|
6
|
+
flags: string;
|
|
7
|
+
description: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function formatCommand(name: string, description: string): string;
|
|
10
|
+
export declare function formatUsage(command: string, args?: string): string;
|
|
11
|
+
export declare function formatOption(flags: string, description: string): string;
|
|
12
|
+
export declare function formatCommandList(commands: CommandInfo[]): string;
|
|
13
|
+
export declare function formatOptionList(options: OptionInfo[]): string;
|
|
14
|
+
export declare const helpFormatter: {
|
|
15
|
+
readonly formatCommand: typeof formatCommand;
|
|
16
|
+
readonly formatUsage: typeof formatUsage;
|
|
17
|
+
readonly formatOption: typeof formatOption;
|
|
18
|
+
readonly formatCommandList: typeof formatCommandList;
|
|
19
|
+
readonly formatOptionList: typeof formatOptionList;
|
|
20
|
+
};
|