toolcraft 0.0.38 → 0.0.40

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.
Files changed (61) hide show
  1. package/README.md +41 -4
  2. package/dist/cli.js +40 -9
  3. package/dist/http-errors.d.ts +57 -0
  4. package/dist/http-errors.js +72 -0
  5. package/dist/index.d.ts +10 -0
  6. package/dist/index.js +15 -0
  7. package/dist/mcp-proxy.js +16 -1
  8. package/dist/mcp.js +224 -12
  9. package/node_modules/@poe-code/frontmatter/README.md +35 -0
  10. package/node_modules/@poe-code/frontmatter/dist/fences.d.ts +8 -0
  11. package/node_modules/@poe-code/frontmatter/dist/fences.js +72 -0
  12. package/node_modules/@poe-code/frontmatter/dist/index.d.ts +3 -0
  13. package/node_modules/@poe-code/frontmatter/dist/index.js +3 -0
  14. package/node_modules/@poe-code/frontmatter/dist/parse.d.ts +20 -0
  15. package/node_modules/@poe-code/frontmatter/dist/parse.js +137 -0
  16. package/node_modules/@poe-code/frontmatter/dist/stringify.d.ts +1 -0
  17. package/node_modules/@poe-code/frontmatter/dist/stringify.js +35 -0
  18. package/node_modules/@poe-code/frontmatter/package.json +25 -0
  19. package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.d.ts +1 -0
  20. package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.js +25 -1
  21. package/node_modules/tiny-mcp-client/README.md +7 -0
  22. package/node_modules/tiny-mcp-client/dist/internal.d.ts +2 -0
  23. package/node_modules/tiny-mcp-client/dist/internal.js +3 -0
  24. package/node_modules/tiny-mcp-client/dist/mcp-tool-types.compile-check.js +10 -0
  25. package/node_modules/tiny-mcp-client/src/http-oauth.test.ts +2 -8
  26. package/node_modules/tiny-mcp-client/src/internal.ts +6 -0
  27. package/node_modules/tiny-mcp-client/src/mcp-tool-types.compile-check.ts +10 -0
  28. package/node_modules/toolcraft-design/README.md +12 -0
  29. package/node_modules/toolcraft-design/dist/prompts/index.d.ts +39 -14
  30. package/node_modules/toolcraft-design/dist/prompts/index.js +10 -6
  31. package/node_modules/toolcraft-design/dist/prompts/interactive/cancel-symbol.d.ts +2 -0
  32. package/node_modules/toolcraft-design/dist/prompts/interactive/cancel-symbol.js +4 -0
  33. package/node_modules/toolcraft-design/dist/prompts/interactive/confirm.d.ts +9 -0
  34. package/node_modules/toolcraft-design/dist/prompts/interactive/confirm.js +47 -0
  35. package/node_modules/toolcraft-design/dist/prompts/interactive/core.d.ts +55 -0
  36. package/node_modules/toolcraft-design/dist/prompts/interactive/core.js +274 -0
  37. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.d.ts +20 -0
  38. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.js +53 -0
  39. package/node_modules/toolcraft-design/dist/prompts/interactive/index.d.ts +6 -0
  40. package/node_modules/toolcraft-design/dist/prompts/interactive/index.js +6 -0
  41. package/node_modules/toolcraft-design/dist/prompts/interactive/keys.d.ts +2 -0
  42. package/node_modules/toolcraft-design/dist/prompts/interactive/keys.js +28 -0
  43. package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.d.ts +13 -0
  44. package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.js +131 -0
  45. package/node_modules/toolcraft-design/dist/prompts/interactive/pagination.d.ts +10 -0
  46. package/node_modules/toolcraft-design/dist/prompts/interactive/pagination.js +52 -0
  47. package/node_modules/toolcraft-design/dist/prompts/interactive/password.d.ts +10 -0
  48. package/node_modules/toolcraft-design/dist/prompts/interactive/password.js +55 -0
  49. package/node_modules/toolcraft-design/dist/prompts/interactive/select.d.ts +18 -0
  50. package/node_modules/toolcraft-design/dist/prompts/interactive/select.js +89 -0
  51. package/node_modules/toolcraft-design/dist/prompts/interactive/test-helpers.d.ts +21 -0
  52. package/node_modules/toolcraft-design/dist/prompts/interactive/test-helpers.js +32 -0
  53. package/node_modules/toolcraft-design/dist/prompts/interactive/text.d.ts +12 -0
  54. package/node_modules/toolcraft-design/dist/prompts/interactive/text.js +60 -0
  55. package/node_modules/toolcraft-design/dist/prompts/interactive/wrap.d.ts +4 -0
  56. package/node_modules/toolcraft-design/dist/prompts/interactive/wrap.js +18 -0
  57. package/node_modules/toolcraft-design/dist/prompts/primitives/cancel.d.ts +1 -1
  58. package/node_modules/toolcraft-design/dist/prompts/primitives/cancel.js +1 -1
  59. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/frontmatter.js +20 -453
  60. package/node_modules/toolcraft-design/package.json +6 -3
  61. package/package.json +9 -6
@@ -0,0 +1,18 @@
1
+ import { CANCEL } from "./cancel-symbol.js";
2
+ export interface SelectOption<Value> {
3
+ value: Value;
4
+ label: string;
5
+ hint?: string;
6
+ disabled?: boolean;
7
+ }
8
+ export interface SelectOptions<Value> {
9
+ message: string;
10
+ options: Array<SelectOption<Value>>;
11
+ initialValue?: Value;
12
+ maxItems?: number;
13
+ signal?: AbortSignal;
14
+ input?: NodeJS.ReadableStream;
15
+ output?: NodeJS.WritableStream;
16
+ }
17
+ export declare function findNonDisabled<Value>(start: number, direction: 1 | -1, options: Array<SelectOption<Value>>): number;
18
+ export declare function selectPrompt<Value>(opts: SelectOptions<Value>): Promise<Value | typeof CANCEL>;
@@ -0,0 +1,89 @@
1
+ import { color } from "../../components/color.js";
2
+ import { GLYPHS, symbol } from "./glyphs.js";
3
+ import { Prompt } from "./core.js";
4
+ import { limitOptions } from "./pagination.js";
5
+ class SelectPrompt extends Prompt {
6
+ options;
7
+ constructor(opts) {
8
+ if (opts.options.length === 0) {
9
+ throw new Error("Select prompt requires at least one option.");
10
+ }
11
+ if (opts.options.every((option) => option.disabled)) {
12
+ throw new Error("Select prompt requires at least one enabled option.");
13
+ }
14
+ const initialIndex = Math.max(opts.options.findIndex((option) => option.value === opts.initialValue), 0);
15
+ const cursor = findNonDisabled(initialIndex, 1, opts.options);
16
+ super({
17
+ ...opts,
18
+ initialValue: opts.options[cursor]?.value,
19
+ render: (prompt) => renderSelectPrompt(prompt, opts)
20
+ }, false);
21
+ this.options = opts.options;
22
+ this._cursor = cursor;
23
+ this.setValue(this.options[this._cursor]?.value);
24
+ this.on("cursor", (action) => {
25
+ if (action === "up" || action === "left") {
26
+ this._cursor = findNonDisabled(this._cursor - 1, -1, this.options);
27
+ }
28
+ else if (action === "down" || action === "right") {
29
+ this._cursor = findNonDisabled(this._cursor + 1, 1, this.options);
30
+ }
31
+ this.setValue(this.options[this._cursor]?.value);
32
+ });
33
+ }
34
+ get visibleOptions() {
35
+ return this.options;
36
+ }
37
+ promptNonTty() {
38
+ if (process.env.POE_NO_PROMPT === "1") {
39
+ return Promise.resolve(this.value);
40
+ }
41
+ return super.promptNonTty();
42
+ }
43
+ }
44
+ export function findNonDisabled(start, direction, options) {
45
+ if (options.every((option) => option.disabled)) {
46
+ return start;
47
+ }
48
+ let index = start;
49
+ for (let checked = 0; checked < options.length; checked += 1) {
50
+ index = (index + options.length) % options.length;
51
+ if (!options[index]?.disabled) {
52
+ return index;
53
+ }
54
+ index += direction;
55
+ }
56
+ return start;
57
+ }
58
+ function renderOption(option, active, submitted, cancelled) {
59
+ const hint = option.hint ? color.dim(` (${option.hint})`) : "";
60
+ if (submitted)
61
+ return color.dim(option.label);
62
+ if (cancelled)
63
+ return color.dim.strikethrough(option.label);
64
+ if (option.disabled)
65
+ return `${color.gray(GLYPHS.radioInactive)} ${color.gray.strikethrough(option.label)}${hint}`;
66
+ if (active)
67
+ return `${color.green(GLYPHS.radioActive)} ${option.label}${hint}`;
68
+ return `${color.dim(GLYPHS.radioInactive)} ${color.dim(option.label)}${hint}`;
69
+ }
70
+ function renderSelectPrompt(prompt, opts) {
71
+ if (prompt.state === "submit" || prompt.state === "cancel") {
72
+ const option = prompt.visibleOptions[prompt.cursor];
73
+ const rendered = option ? renderOption(option, false, prompt.state === "submit", prompt.state === "cancel") : "";
74
+ const end = prompt.state === "submit" ? color.green(GLYPHS.barEnd) : color.red(GLYPHS.barEnd);
75
+ return `${color.gray(GLYPHS.barStart)} ${symbol(prompt.state)} ${opts.message}\n${color.gray(GLYPHS.bar)} ${rendered}\n${end}`;
76
+ }
77
+ const lines = limitOptions({
78
+ cursor: prompt.cursor,
79
+ options: prompt.visibleOptions,
80
+ output: opts.output ?? process.stdout,
81
+ maxItems: opts.maxItems,
82
+ columnPadding: 3,
83
+ style: (option, active) => renderOption(option, active, false, false)
84
+ }).map((line) => `${color.cyan(GLYPHS.bar)} ${line}`);
85
+ return `${color.gray(GLYPHS.barStart)} ${symbol(prompt.state)} ${opts.message}\n${lines.join("\n")}\n${color.cyan(GLYPHS.barEnd)}`;
86
+ }
87
+ export function selectPrompt(opts) {
88
+ return new SelectPrompt(opts).prompt();
89
+ }
@@ -0,0 +1,21 @@
1
+ import { PassThrough, Writable } from "node:stream";
2
+ export interface PromptHarness {
3
+ input: PassThrough & {
4
+ isTTY?: boolean;
5
+ setRawMode?: (enabled: boolean) => void;
6
+ };
7
+ output: Writable & {
8
+ columns?: number;
9
+ rows?: number;
10
+ isTTY?: boolean;
11
+ frames: string[];
12
+ };
13
+ rawModes: boolean[];
14
+ getOutput: () => string;
15
+ }
16
+ export declare function createPromptHarness(options?: {
17
+ tty?: boolean;
18
+ columns?: number;
19
+ rows?: number;
20
+ }): PromptHarness;
21
+ export declare function tick(): Promise<void>;
@@ -0,0 +1,32 @@
1
+ import { PassThrough, Writable } from "node:stream";
2
+ export function createPromptHarness(options = {}) {
3
+ const chunks = [];
4
+ const frames = [];
5
+ const rawModes = [];
6
+ const input = new PassThrough();
7
+ const output = new Writable({
8
+ write(chunk, _encoding, callback) {
9
+ const value = String(chunk);
10
+ chunks.push(value);
11
+ frames.push(value);
12
+ callback();
13
+ }
14
+ });
15
+ input.isTTY = options.tty ?? true;
16
+ input.setRawMode = (enabled) => {
17
+ rawModes.push(enabled);
18
+ };
19
+ output.isTTY = options.tty ?? true;
20
+ output.columns = options.columns ?? 80;
21
+ output.rows = options.rows ?? 20;
22
+ output.frames = frames;
23
+ return {
24
+ input,
25
+ output,
26
+ rawModes,
27
+ getOutput: () => chunks.join("")
28
+ };
29
+ }
30
+ export async function tick() {
31
+ await new Promise((resolve) => setImmediate(resolve));
32
+ }
@@ -0,0 +1,12 @@
1
+ import { CANCEL } from "./cancel-symbol.js";
2
+ export interface TextOptions {
3
+ message: string;
4
+ placeholder?: string;
5
+ defaultValue?: string;
6
+ initialValue?: string;
7
+ validate?: (value: string) => string | Error | undefined;
8
+ signal?: AbortSignal;
9
+ input?: NodeJS.ReadableStream;
10
+ output?: NodeJS.WritableStream;
11
+ }
12
+ export declare function textPrompt(opts: TextOptions): Promise<string | typeof CANCEL>;
@@ -0,0 +1,60 @@
1
+ import { color } from "../../components/color.js";
2
+ import { GLYPHS, symbol, symbolBar } from "./glyphs.js";
3
+ import { Prompt } from "./core.js";
4
+ class TextPrompt extends Prompt {
5
+ constructor(opts) {
6
+ const initialUserInput = opts.initialValue ?? "";
7
+ super({
8
+ ...opts,
9
+ initialValue: initialUserInput,
10
+ initialUserInput,
11
+ render: (prompt) => renderTextPrompt(prompt, opts),
12
+ validate: opts.validate
13
+ });
14
+ this.on("userInput", (value) => this.setValue(value));
15
+ this.on("finalize", () => {
16
+ if (this.state === "submit") {
17
+ this.setValue(this.value || opts.defaultValue || "");
18
+ }
19
+ });
20
+ }
21
+ get userInputWithCursor() {
22
+ if (this.state === "submit") {
23
+ return this.userInput;
24
+ }
25
+ const before = this.userInput.slice(0, this.cursor);
26
+ const current = this.userInput[this.cursor];
27
+ const after = this.userInput.slice(this.cursor + 1);
28
+ if (current) {
29
+ return `${before}${color.inverse(current)}${after}`;
30
+ }
31
+ return `${before}${color.inverse("█")}`;
32
+ }
33
+ promptNonTty() {
34
+ return this.readNonTtyLine();
35
+ }
36
+ }
37
+ function renderHeader(prompt, message) {
38
+ return `${color.gray(GLYPHS.barStart)} ${symbol(prompt.state)} ${message}`;
39
+ }
40
+ function renderTextPrompt(prompt, opts) {
41
+ const value = prompt.value ?? "";
42
+ if (prompt.state === "submit") {
43
+ return `${renderHeader(prompt, opts.message)}\n${color.gray(GLYPHS.bar)} ${color.dim(value)}\n${color.green(GLYPHS.barEnd)}`;
44
+ }
45
+ if (prompt.state === "cancel") {
46
+ return `${renderHeader(prompt, opts.message)}\n${color.gray(GLYPHS.bar)} ${color.dim.strikethrough(value)}\n${color.red(GLYPHS.barEnd)}`;
47
+ }
48
+ const input = prompt.userInput.length > 0
49
+ ? prompt.userInputWithCursor
50
+ : opts.placeholder
51
+ ? `${color.inverse(opts.placeholder[0] ?? " ")}${color.dim(opts.placeholder.slice(1))}`
52
+ : color.inverse("_");
53
+ if (prompt.state === "error") {
54
+ return `${renderHeader(prompt, opts.message)}\n${symbolBar(prompt.state)} ${input}\n${color.yellow(GLYPHS.barEnd)} ${color.yellow(prompt.error)}`;
55
+ }
56
+ return `${renderHeader(prompt, opts.message)}\n${symbolBar(prompt.state)} ${input}\n${color.cyan(GLYPHS.barEnd)}`;
57
+ }
58
+ export function textPrompt(opts) {
59
+ return new TextPrompt(opts).prompt();
60
+ }
@@ -0,0 +1,4 @@
1
+ export declare function getColumns(output: NodeJS.WritableStream): number;
2
+ export declare function getRows(output: NodeJS.WritableStream): number;
3
+ export declare function wrapTextWithPrefix(output: NodeJS.WritableStream, text: string, prefix: string, startPrefix?: string): string;
4
+ export declare function wrapFrame(output: NodeJS.WritableStream, frame: string): string;
@@ -0,0 +1,18 @@
1
+ import { wrapAnsi } from "fast-wrap-ansi";
2
+ import stringWidth from "fast-string-width";
3
+ export function getColumns(output) {
4
+ return Math.max(1, output.columns ?? 80);
5
+ }
6
+ export function getRows(output) {
7
+ return Math.max(1, output.rows ?? 20);
8
+ }
9
+ export function wrapTextWithPrefix(output, text, prefix, startPrefix = prefix) {
10
+ const width = Math.max(1, getColumns(output) - stringWidth(prefix));
11
+ return wrapAnsi(text, width, { hard: true, trim: false })
12
+ .split("\n")
13
+ .map((line, index) => `${index === 0 ? startPrefix : prefix}${line}`)
14
+ .join("\n");
15
+ }
16
+ export function wrapFrame(output, frame) {
17
+ return wrapAnsi(frame, getColumns(output), { hard: true, trim: false });
18
+ }
@@ -1,2 +1,2 @@
1
- export { isCancel } from "@clack/prompts";
1
+ export { isCancel } from "../interactive/cancel-symbol.js";
2
2
  export declare function cancel(msg?: string): void;
@@ -1,5 +1,5 @@
1
1
  import { color } from "../../components/color.js";
2
- export { isCancel } from "@clack/prompts";
2
+ export { isCancel } from "../interactive/cancel-symbol.js";
3
3
  import { resolveOutputFormat } from "../../internal/output-format.js";
4
4
  export function cancel(msg = "") {
5
5
  if (resolveOutputFormat() !== "terminal") {