poe-code 3.0.178 → 3.0.179
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/dist/index.js +6 -2
- package/dist/index.js.map +2 -2
- package/package.json +6 -2
- package/packages/cmdkit/dist/cli.compile-check.d.ts +1 -0
- package/packages/cmdkit/dist/cli.compile-check.js +26 -0
- package/packages/cmdkit/dist/cli.d.ts +12 -0
- package/packages/cmdkit/dist/cli.js +2306 -0
- package/packages/cmdkit/dist/cli.js.map +7 -0
- package/packages/cmdkit/dist/index.compile-check.d.ts +1 -0
- package/packages/cmdkit/dist/index.compile-check.js +50 -0
- package/packages/cmdkit/dist/index.d.ts +164 -0
- package/packages/cmdkit/dist/index.js +518 -0
- package/packages/cmdkit/dist/index.js.map +7 -0
- package/packages/cmdkit/dist/mcp.compile-check.d.ts +1 -0
- package/packages/cmdkit/dist/mcp.compile-check.js +26 -0
- package/packages/cmdkit/dist/mcp.d.ts +16 -0
- package/packages/cmdkit/dist/mcp.js +1153 -0
- package/packages/cmdkit/dist/mcp.js.map +7 -0
- package/packages/cmdkit/dist/renderer.d.ts +5 -0
- package/packages/cmdkit/dist/renderer.js +164 -0
- package/packages/cmdkit/dist/renderer.js.map +7 -0
- package/packages/cmdkit/dist/sdk.compile-check.d.ts +1 -0
- package/packages/cmdkit/dist/sdk.compile-check.js +79 -0
- package/packages/cmdkit/dist/sdk.d.ts +63 -0
- package/packages/cmdkit/dist/sdk.js +314 -0
- package/packages/cmdkit/dist/sdk.js.map +7 -0
- package/packages/cmdkit-schema/dist/index.compile-check.d.ts +1 -0
- package/packages/cmdkit-schema/dist/index.compile-check.js +11 -0
- package/packages/cmdkit-schema/dist/index.d.ts +81 -0
- package/packages/cmdkit-schema/dist/index.js +130 -0
- package/packages/design-system/dist/acp/components.d.ts +11 -0
- package/packages/design-system/dist/acp/components.js +121 -0
- package/packages/design-system/dist/acp/index.d.ts +3 -0
- package/packages/design-system/dist/acp/index.js +2 -0
- package/packages/design-system/dist/acp/writer.d.ts +13 -0
- package/packages/design-system/dist/acp/writer.js +21 -0
- package/packages/design-system/dist/components/command-errors.d.ts +16 -0
- package/packages/design-system/dist/components/command-errors.js +22 -0
- package/packages/design-system/dist/components/help-formatter.d.ts +20 -0
- package/packages/design-system/dist/components/help-formatter.js +27 -0
- package/packages/design-system/dist/components/index.d.ts +10 -0
- package/packages/design-system/dist/components/index.js +7 -0
- package/packages/design-system/dist/components/logger.d.ts +11 -0
- package/packages/design-system/dist/components/logger.js +60 -0
- package/packages/design-system/dist/components/symbols.d.ts +12 -0
- package/packages/design-system/dist/components/symbols.js +71 -0
- package/packages/design-system/dist/components/table.d.ts +13 -0
- package/packages/design-system/dist/components/table.js +74 -0
- package/packages/design-system/dist/components/text.d.ts +14 -0
- package/packages/design-system/dist/components/text.js +104 -0
- package/packages/design-system/dist/dashboard/ansi.d.ts +18 -0
- package/packages/design-system/dist/dashboard/ansi.js +298 -0
- package/packages/design-system/dist/dashboard/buffer.d.ts +25 -0
- package/packages/design-system/dist/dashboard/buffer.js +189 -0
- package/packages/design-system/dist/dashboard/components/border.d.ts +9 -0
- package/packages/design-system/dist/dashboard/components/border.js +123 -0
- package/packages/design-system/dist/dashboard/components/footer.d.ts +8 -0
- package/packages/design-system/dist/dashboard/components/footer.js +58 -0
- package/packages/design-system/dist/dashboard/components/output-pane.d.ts +21 -0
- package/packages/design-system/dist/dashboard/components/output-pane.js +323 -0
- package/packages/design-system/dist/dashboard/components/stats-pane.d.ts +7 -0
- package/packages/design-system/dist/dashboard/components/stats-pane.js +120 -0
- package/packages/design-system/dist/dashboard/dashboard.d.ts +20 -0
- package/packages/design-system/dist/dashboard/dashboard.js +187 -0
- package/packages/design-system/dist/dashboard/demo.d.ts +13 -0
- package/packages/design-system/dist/dashboard/demo.js +145 -0
- package/packages/design-system/dist/dashboard/index.d.ts +7 -0
- package/packages/design-system/dist/dashboard/index.js +3 -0
- package/packages/design-system/dist/dashboard/keymap.d.ts +3 -0
- package/packages/design-system/dist/dashboard/keymap.js +114 -0
- package/packages/design-system/dist/dashboard/layout.d.ts +25 -0
- package/packages/design-system/dist/dashboard/layout.js +79 -0
- package/packages/design-system/dist/dashboard/snapshot.d.ts +10 -0
- package/packages/design-system/dist/dashboard/snapshot.js +72 -0
- package/packages/design-system/dist/dashboard/store.d.ts +9 -0
- package/packages/design-system/dist/dashboard/store.js +107 -0
- package/packages/design-system/dist/dashboard/terminal.d.ts +35 -0
- package/packages/design-system/dist/dashboard/terminal.js +215 -0
- package/packages/design-system/dist/dashboard/types.d.ts +45 -0
- package/packages/design-system/dist/dashboard/types.js +1 -0
- package/packages/design-system/dist/index.d.ts +33 -0
- package/packages/design-system/dist/index.js +31 -0
- package/packages/design-system/dist/internal/output-format.d.ts +6 -0
- package/packages/design-system/dist/internal/output-format.js +22 -0
- package/packages/design-system/dist/internal/strip-ansi.d.ts +1 -0
- package/packages/design-system/dist/internal/strip-ansi.js +3 -0
- package/packages/design-system/dist/internal/theme-detect.d.ts +11 -0
- package/packages/design-system/dist/internal/theme-detect.js +49 -0
- package/packages/design-system/dist/prompts/index.d.ts +66 -0
- package/packages/design-system/dist/prompts/index.js +132 -0
- package/packages/design-system/dist/prompts/primitives/cancel.d.ts +2 -0
- package/packages/design-system/dist/prompts/primitives/cancel.js +9 -0
- package/packages/design-system/dist/prompts/primitives/intro.d.ts +1 -0
- package/packages/design-system/dist/prompts/primitives/intro.js +15 -0
- package/packages/design-system/dist/prompts/primitives/log.d.ts +18 -0
- package/packages/design-system/dist/prompts/primitives/log.js +101 -0
- package/packages/design-system/dist/prompts/primitives/note.d.ts +1 -0
- package/packages/design-system/dist/prompts/primitives/note.js +39 -0
- package/packages/design-system/dist/prompts/primitives/outro.d.ts +1 -0
- package/packages/design-system/dist/prompts/primitives/outro.js +16 -0
- package/packages/design-system/dist/prompts/primitives/spinner.d.ts +6 -0
- package/packages/design-system/dist/prompts/primitives/spinner.js +74 -0
- package/packages/design-system/dist/prompts/theme.d.ts +11 -0
- package/packages/design-system/dist/prompts/theme.js +12 -0
- package/packages/design-system/dist/static/index.d.ts +4 -0
- package/packages/design-system/dist/static/index.js +2 -0
- package/packages/design-system/dist/static/menu.d.ts +11 -0
- package/packages/design-system/dist/static/menu.js +36 -0
- package/packages/design-system/dist/static/spinner.d.ts +14 -0
- package/packages/design-system/dist/static/spinner.js +46 -0
- package/packages/design-system/dist/terminal-markdown/ast.d.ts +84 -0
- package/packages/design-system/dist/terminal-markdown/ast.js +1 -0
- package/packages/design-system/dist/terminal-markdown/demo-content.d.ts +2 -0
- package/packages/design-system/dist/terminal-markdown/demo-content.js +139 -0
- package/packages/design-system/dist/terminal-markdown/index.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/index.js +8 -0
- package/packages/design-system/dist/terminal-markdown/parser/block.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/parser/block.js +1205 -0
- package/packages/design-system/dist/terminal-markdown/parser/frontmatter.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/parser/frontmatter.js +395 -0
- package/packages/design-system/dist/terminal-markdown/parser/inline.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/parser/inline.js +1087 -0
- package/packages/design-system/dist/terminal-markdown/parser.d.ts +5 -0
- package/packages/design-system/dist/terminal-markdown/parser.js +13 -0
- package/packages/design-system/dist/terminal-markdown/renderer.d.ts +6 -0
- package/packages/design-system/dist/terminal-markdown/renderer.js +572 -0
- package/packages/design-system/dist/terminal-markdown/testing/theme-render-fixture.d.ts +1 -0
- package/packages/design-system/dist/terminal-markdown/testing/theme-render-fixture.js +27 -0
- package/packages/design-system/dist/tokens/colors.d.ts +35 -0
- package/packages/design-system/dist/tokens/colors.js +34 -0
- package/packages/design-system/dist/tokens/index.d.ts +4 -0
- package/packages/design-system/dist/tokens/index.js +4 -0
- package/packages/design-system/dist/tokens/spacing.d.ts +6 -0
- package/packages/design-system/dist/tokens/spacing.js +6 -0
- package/packages/design-system/dist/tokens/typography.d.ts +7 -0
- package/packages/design-system/dist/tokens/typography.js +8 -0
- package/packages/design-system/dist/tokens/widths.d.ts +5 -0
- package/packages/design-system/dist/tokens/widths.js +5 -0
- package/packages/tiny-stdio-mcp-server/dist/content/audio.d.ts +14 -0
- package/packages/tiny-stdio-mcp-server/dist/content/audio.js +76 -0
- package/packages/tiny-stdio-mcp-server/dist/content/convert.d.ts +16 -0
- package/packages/tiny-stdio-mcp-server/dist/content/convert.js +42 -0
- package/packages/tiny-stdio-mcp-server/dist/content/file-type.d.ts +11 -0
- package/packages/tiny-stdio-mcp-server/dist/content/file-type.js +93 -0
- package/packages/tiny-stdio-mcp-server/dist/content/file.d.ts +26 -0
- package/packages/tiny-stdio-mcp-server/dist/content/file.js +94 -0
- package/packages/tiny-stdio-mcp-server/dist/content/image.d.ts +14 -0
- package/packages/tiny-stdio-mcp-server/dist/content/image.js +64 -0
- package/packages/tiny-stdio-mcp-server/dist/content/index.d.ts +5 -0
- package/packages/tiny-stdio-mcp-server/dist/content/index.js +8 -0
- package/packages/tiny-stdio-mcp-server/dist/content/mime.d.ts +1 -0
- package/packages/tiny-stdio-mcp-server/dist/content/mime.js +1 -0
- package/packages/tiny-stdio-mcp-server/dist/index.d.ts +9 -0
- package/packages/tiny-stdio-mcp-server/dist/index.js +7 -0
- package/packages/tiny-stdio-mcp-server/dist/jsonrpc.d.ts +14 -0
- package/packages/tiny-stdio-mcp-server/dist/jsonrpc.js +99 -0
- package/packages/tiny-stdio-mcp-server/dist/schema.d.ts +19 -0
- package/packages/tiny-stdio-mcp-server/dist/schema.js +18 -0
- package/packages/tiny-stdio-mcp-server/dist/server.d.ts +13 -0
- package/packages/tiny-stdio-mcp-server/dist/server.js +226 -0
- package/packages/tiny-stdio-mcp-server/dist/testing.d.ts +7 -0
- package/packages/tiny-stdio-mcp-server/dist/testing.js +20 -0
- package/packages/tiny-stdio-mcp-server/dist/types.d.ts +119 -0
- package/packages/tiny-stdio-mcp-server/dist/types.js +16 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
export const brand = "#a200ff";
|
|
3
|
+
export const dark = {
|
|
4
|
+
header: (text) => chalk.magentaBright.bold(text),
|
|
5
|
+
divider: (text) => chalk.dim(text),
|
|
6
|
+
prompt: (text) => chalk.cyan(text),
|
|
7
|
+
number: (text) => chalk.cyanBright(text),
|
|
8
|
+
intro: (text) => chalk.bgMagenta.white(` Poe - ${text} `),
|
|
9
|
+
resolvedSymbol: chalk.magenta("◇"),
|
|
10
|
+
errorSymbol: chalk.red("■"),
|
|
11
|
+
accent: (text) => chalk.cyan(text),
|
|
12
|
+
muted: (text) => chalk.dim(text),
|
|
13
|
+
success: (text) => chalk.green(text),
|
|
14
|
+
warning: (text) => chalk.yellow(text),
|
|
15
|
+
error: (text) => chalk.red(text),
|
|
16
|
+
info: (text) => chalk.magenta(text),
|
|
17
|
+
badge: (text) => chalk.bgYellow.black(` ${text} `)
|
|
18
|
+
};
|
|
19
|
+
export const light = {
|
|
20
|
+
header: (text) => chalk.hex("#a200ff").bold(text),
|
|
21
|
+
divider: (text) => chalk.hex("#666666")(text),
|
|
22
|
+
prompt: (text) => chalk.hex("#006699").bold(text),
|
|
23
|
+
number: (text) => chalk.hex("#0077cc").bold(text),
|
|
24
|
+
intro: (text) => chalk.bgHex("#a200ff").white(` Poe - ${text} `),
|
|
25
|
+
resolvedSymbol: chalk.hex("#a200ff")("◇"),
|
|
26
|
+
errorSymbol: chalk.hex("#cc0000")("■"),
|
|
27
|
+
accent: (text) => chalk.hex("#006699").bold(text),
|
|
28
|
+
muted: (text) => chalk.hex("#666666")(text),
|
|
29
|
+
success: (text) => chalk.hex("#008800")(text),
|
|
30
|
+
warning: (text) => chalk.hex("#cc6600")(text),
|
|
31
|
+
error: (text) => chalk.hex("#cc0000")(text),
|
|
32
|
+
info: (text) => chalk.hex("#a200ff")(text),
|
|
33
|
+
badge: (text) => chalk.bgHex("#cc6600").white(` ${text} `)
|
|
34
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const typography: {
|
|
2
|
+
readonly bold: (text: string) => string;
|
|
3
|
+
readonly dim: (text: string) => string;
|
|
4
|
+
readonly italic: (text: string) => string;
|
|
5
|
+
readonly underline: (text: string) => string;
|
|
6
|
+
readonly strikethrough: (text: string) => string;
|
|
7
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
export const typography = {
|
|
3
|
+
bold: (text) => chalk.bold(text),
|
|
4
|
+
dim: (text) => chalk.dim(text),
|
|
5
|
+
italic: (text) => chalk.italic(text),
|
|
6
|
+
underline: (text) => chalk.underline(text),
|
|
7
|
+
strikethrough: (text) => chalk.strikethrough(text)
|
|
8
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface AudioContent {
|
|
2
|
+
type: "audio";
|
|
3
|
+
data: string;
|
|
4
|
+
mimeType: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class Audio {
|
|
7
|
+
private readonly base64Data;
|
|
8
|
+
private readonly mimeType;
|
|
9
|
+
private constructor();
|
|
10
|
+
static fromUrl(url: string): Promise<Audio>;
|
|
11
|
+
static fromBytes(data: Uint8Array, format?: string): Audio;
|
|
12
|
+
static fromBase64(base64: string, mimeType: string): Audio;
|
|
13
|
+
toContentBlock(): AudioContent;
|
|
14
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { fileTypeFromBuffer } from "./mime.js";
|
|
2
|
+
const SUPPORTED_AUDIO_MIMES = new Set([
|
|
3
|
+
"audio/mpeg",
|
|
4
|
+
"audio/wav",
|
|
5
|
+
"audio/ogg",
|
|
6
|
+
"audio/mp4",
|
|
7
|
+
]);
|
|
8
|
+
const AUDIO_FORMAT_MAP = {
|
|
9
|
+
mp3: "audio/mpeg",
|
|
10
|
+
wav: "audio/wav",
|
|
11
|
+
ogg: "audio/ogg",
|
|
12
|
+
m4a: "audio/mp4",
|
|
13
|
+
mpeg: "audio/mpeg",
|
|
14
|
+
};
|
|
15
|
+
export class Audio {
|
|
16
|
+
base64Data;
|
|
17
|
+
mimeType;
|
|
18
|
+
constructor(base64Data, mimeType) {
|
|
19
|
+
this.base64Data = base64Data;
|
|
20
|
+
this.mimeType = mimeType;
|
|
21
|
+
}
|
|
22
|
+
static async fromUrl(url) {
|
|
23
|
+
const response = await fetch(url);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`Failed to fetch audio from ${url}: ${response.status} ${response.statusText}`);
|
|
26
|
+
}
|
|
27
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
28
|
+
const data = new Uint8Array(arrayBuffer);
|
|
29
|
+
const detected = fileTypeFromBuffer(data);
|
|
30
|
+
let mimeType;
|
|
31
|
+
if (detected && SUPPORTED_AUDIO_MIMES.has(detected.mime)) {
|
|
32
|
+
mimeType = detected.mime;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const contentType = response.headers.get("content-type")?.split(";")[0];
|
|
36
|
+
if (contentType && SUPPORTED_AUDIO_MIMES.has(contentType)) {
|
|
37
|
+
mimeType = contentType;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new Error(`Unable to detect audio MIME type from ${url}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const base64 = Buffer.from(data).toString("base64");
|
|
44
|
+
return new Audio(base64, mimeType);
|
|
45
|
+
}
|
|
46
|
+
static fromBytes(data, format) {
|
|
47
|
+
let mimeType;
|
|
48
|
+
if (format) {
|
|
49
|
+
if (format.includes("/")) {
|
|
50
|
+
mimeType = format;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
mimeType = AUDIO_FORMAT_MAP[format.toLowerCase()] || `audio/${format}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const detected = fileTypeFromBuffer(data);
|
|
58
|
+
if (!detected || !SUPPORTED_AUDIO_MIMES.has(detected.mime)) {
|
|
59
|
+
throw new Error("Unable to detect audio MIME type from bytes");
|
|
60
|
+
}
|
|
61
|
+
mimeType = detected.mime;
|
|
62
|
+
}
|
|
63
|
+
const base64 = Buffer.from(data).toString("base64");
|
|
64
|
+
return new Audio(base64, mimeType);
|
|
65
|
+
}
|
|
66
|
+
static fromBase64(base64, mimeType) {
|
|
67
|
+
return new Audio(base64, mimeType);
|
|
68
|
+
}
|
|
69
|
+
toContentBlock() {
|
|
70
|
+
return {
|
|
71
|
+
type: "audio",
|
|
72
|
+
data: this.base64Data,
|
|
73
|
+
mimeType: this.mimeType,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Image, type ImageContent } from "./image.js";
|
|
2
|
+
import { Audio, type AudioContent } from "./audio.js";
|
|
3
|
+
import { File, type EmbeddedResource } from "./file.js";
|
|
4
|
+
export interface TextContent {
|
|
5
|
+
type: "text";
|
|
6
|
+
text: string;
|
|
7
|
+
}
|
|
8
|
+
export type ContentBlock = TextContent | ImageContent | AudioContent | EmbeddedResource;
|
|
9
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
10
|
+
export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
|
|
11
|
+
export type JsonObject = {
|
|
12
|
+
[key: string]: JsonValue;
|
|
13
|
+
};
|
|
14
|
+
export type ToolReturn = undefined | JsonPrimitive | JsonObject | Image | Audio | File | ContentBlock | Array<undefined | JsonPrimitive | JsonObject | Image | Audio | File | ContentBlock>;
|
|
15
|
+
export declare function toContentBlocks(result: ToolReturn): ContentBlock[];
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Image } from "./image.js";
|
|
2
|
+
import { Audio } from "./audio.js";
|
|
3
|
+
import { File } from "./file.js";
|
|
4
|
+
function convertSingleValue(value) {
|
|
5
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
6
|
+
return { type: "text", text: String(value) };
|
|
7
|
+
}
|
|
8
|
+
if (value === null) {
|
|
9
|
+
return { type: "text", text: "null" };
|
|
10
|
+
}
|
|
11
|
+
if (value instanceof Image) {
|
|
12
|
+
return value.toContentBlock();
|
|
13
|
+
}
|
|
14
|
+
if (value instanceof Audio) {
|
|
15
|
+
return value.toContentBlock();
|
|
16
|
+
}
|
|
17
|
+
if (value instanceof File) {
|
|
18
|
+
return value.toContentBlock();
|
|
19
|
+
}
|
|
20
|
+
if (isContentBlock(value)) {
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
return { type: "text", text: JSON.stringify(value) };
|
|
24
|
+
}
|
|
25
|
+
export function toContentBlocks(result) {
|
|
26
|
+
if (result === undefined) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
if (Array.isArray(result)) {
|
|
30
|
+
return result.flatMap((item) => toContentBlocks(item));
|
|
31
|
+
}
|
|
32
|
+
return [convertSingleValue(result)];
|
|
33
|
+
}
|
|
34
|
+
function isContentBlock(value) {
|
|
35
|
+
if (!("type" in value) || typeof value.type !== "string") {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return (value.type === "text" ||
|
|
39
|
+
value.type === "image" ||
|
|
40
|
+
value.type === "audio" ||
|
|
41
|
+
value.type === "resource");
|
|
42
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal magic bytes detection for common media types.
|
|
3
|
+
* This can be replaced with `file-type` package (https://npm.im/file-type)
|
|
4
|
+
* if more comprehensive detection is needed. The API is designed to be
|
|
5
|
+
* compatible: fileTypeFromBuffer(data) returns { mime: string, ext: string } | undefined
|
|
6
|
+
*/
|
|
7
|
+
export interface FileTypeResult {
|
|
8
|
+
mime: string;
|
|
9
|
+
ext: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function fileTypeFromBuffer(data: Uint8Array): FileTypeResult | undefined;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal magic bytes detection for common media types.
|
|
3
|
+
* This can be replaced with `file-type` package (https://npm.im/file-type)
|
|
4
|
+
* if more comprehensive detection is needed. The API is designed to be
|
|
5
|
+
* compatible: fileTypeFromBuffer(data) returns { mime: string, ext: string } | undefined
|
|
6
|
+
*/
|
|
7
|
+
export function fileTypeFromBuffer(data) {
|
|
8
|
+
if (data.length < 12) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
// PNG: 89 50 4E 47 0D 0A 1A 0A
|
|
12
|
+
if (data[0] === 0x89 &&
|
|
13
|
+
data[1] === 0x50 &&
|
|
14
|
+
data[2] === 0x4e &&
|
|
15
|
+
data[3] === 0x47 &&
|
|
16
|
+
data[4] === 0x0d &&
|
|
17
|
+
data[5] === 0x0a &&
|
|
18
|
+
data[6] === 0x1a &&
|
|
19
|
+
data[7] === 0x0a) {
|
|
20
|
+
return { mime: "image/png", ext: "png" };
|
|
21
|
+
}
|
|
22
|
+
// JPEG: FF D8 FF
|
|
23
|
+
if (data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff) {
|
|
24
|
+
return { mime: "image/jpeg", ext: "jpg" };
|
|
25
|
+
}
|
|
26
|
+
// GIF: 47 49 46 38 (GIF8)
|
|
27
|
+
if (data[0] === 0x47 &&
|
|
28
|
+
data[1] === 0x49 &&
|
|
29
|
+
data[2] === 0x46 &&
|
|
30
|
+
data[3] === 0x38) {
|
|
31
|
+
return { mime: "image/gif", ext: "gif" };
|
|
32
|
+
}
|
|
33
|
+
// WEBP: 52 49 46 46 ... 57 45 42 50 (RIFF...WEBP)
|
|
34
|
+
if (data[0] === 0x52 &&
|
|
35
|
+
data[1] === 0x49 &&
|
|
36
|
+
data[2] === 0x46 &&
|
|
37
|
+
data[3] === 0x46 &&
|
|
38
|
+
data[8] === 0x57 &&
|
|
39
|
+
data[9] === 0x45 &&
|
|
40
|
+
data[10] === 0x42 &&
|
|
41
|
+
data[11] === 0x50) {
|
|
42
|
+
return { mime: "image/webp", ext: "webp" };
|
|
43
|
+
}
|
|
44
|
+
// MP3: FF FB or FF FA (MPEG audio) or 49 44 33 (ID3 tag)
|
|
45
|
+
if ((data[0] === 0xff && (data[1] === 0xfb || data[1] === 0xfa)) ||
|
|
46
|
+
(data[0] === 0x49 && data[1] === 0x44 && data[2] === 0x33)) {
|
|
47
|
+
return { mime: "audio/mpeg", ext: "mp3" };
|
|
48
|
+
}
|
|
49
|
+
// WAV: 52 49 46 46 ... 57 41 56 45 (RIFF...WAVE)
|
|
50
|
+
if (data[0] === 0x52 &&
|
|
51
|
+
data[1] === 0x49 &&
|
|
52
|
+
data[2] === 0x46 &&
|
|
53
|
+
data[3] === 0x46 &&
|
|
54
|
+
data[8] === 0x57 &&
|
|
55
|
+
data[9] === 0x41 &&
|
|
56
|
+
data[10] === 0x56 &&
|
|
57
|
+
data[11] === 0x45) {
|
|
58
|
+
return { mime: "audio/wav", ext: "wav" };
|
|
59
|
+
}
|
|
60
|
+
// OGG: 4F 67 67 53 (OggS)
|
|
61
|
+
if (data[0] === 0x4f &&
|
|
62
|
+
data[1] === 0x67 &&
|
|
63
|
+
data[2] === 0x67 &&
|
|
64
|
+
data[3] === 0x53) {
|
|
65
|
+
return { mime: "audio/ogg", ext: "ogg" };
|
|
66
|
+
}
|
|
67
|
+
// M4A: MP4 container with audio - check for M4A brand at offset 8
|
|
68
|
+
// ftyp followed by M4A brand
|
|
69
|
+
if (data[4] === 0x66 &&
|
|
70
|
+
data[5] === 0x74 &&
|
|
71
|
+
data[6] === 0x79 &&
|
|
72
|
+
data[7] === 0x70 &&
|
|
73
|
+
data[8] === 0x4d &&
|
|
74
|
+
data[9] === 0x34 &&
|
|
75
|
+
data[10] === 0x41) {
|
|
76
|
+
return { mime: "audio/mp4", ext: "m4a" };
|
|
77
|
+
}
|
|
78
|
+
// MP4: ... 66 74 79 70 (ftyp box, offset 4)
|
|
79
|
+
if (data[4] === 0x66 &&
|
|
80
|
+
data[5] === 0x74 &&
|
|
81
|
+
data[6] === 0x79 &&
|
|
82
|
+
data[7] === 0x70) {
|
|
83
|
+
return { mime: "video/mp4", ext: "mp4" };
|
|
84
|
+
}
|
|
85
|
+
// WEBM: 1A 45 DF A3 (EBML header)
|
|
86
|
+
if (data[0] === 0x1a &&
|
|
87
|
+
data[1] === 0x45 &&
|
|
88
|
+
data[2] === 0xdf &&
|
|
89
|
+
data[3] === 0xa3) {
|
|
90
|
+
return { mime: "video/webm", ext: "webm" };
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface TextResourceContents {
|
|
2
|
+
uri: string;
|
|
3
|
+
mimeType: string;
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
export interface BlobResourceContents {
|
|
7
|
+
uri: string;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
blob: string;
|
|
10
|
+
}
|
|
11
|
+
export interface EmbeddedResource {
|
|
12
|
+
type: "resource";
|
|
13
|
+
resource: TextResourceContents | BlobResourceContents;
|
|
14
|
+
}
|
|
15
|
+
export declare class File {
|
|
16
|
+
private readonly data;
|
|
17
|
+
private readonly mimeType;
|
|
18
|
+
private readonly isText;
|
|
19
|
+
private readonly name?;
|
|
20
|
+
private constructor();
|
|
21
|
+
static fromUrl(url: string): Promise<File>;
|
|
22
|
+
static fromBytes(data: Uint8Array, mimeType: string): File;
|
|
23
|
+
static fromText(text: string, mimeType?: string): File;
|
|
24
|
+
static fromBase64(base64: string, mimeType: string): File;
|
|
25
|
+
toContentBlock(): EmbeddedResource;
|
|
26
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { fileTypeFromBuffer } from "./mime.js";
|
|
2
|
+
function isTextMimeType(mimeType) {
|
|
3
|
+
return (mimeType.startsWith("text/") ||
|
|
4
|
+
mimeType === "application/json" ||
|
|
5
|
+
mimeType === "application/xml" ||
|
|
6
|
+
mimeType === "application/javascript" ||
|
|
7
|
+
mimeType === "application/typescript");
|
|
8
|
+
}
|
|
9
|
+
export class File {
|
|
10
|
+
data;
|
|
11
|
+
mimeType;
|
|
12
|
+
isText;
|
|
13
|
+
name;
|
|
14
|
+
constructor(data, mimeType, isText, name) {
|
|
15
|
+
this.data = data;
|
|
16
|
+
this.mimeType = mimeType;
|
|
17
|
+
this.isText = isText;
|
|
18
|
+
this.name = name;
|
|
19
|
+
}
|
|
20
|
+
static async fromUrl(url) {
|
|
21
|
+
const response = await fetch(url);
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`Failed to fetch file from ${url}: ${response.status} ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
26
|
+
const data = new Uint8Array(arrayBuffer);
|
|
27
|
+
const detected = fileTypeFromBuffer(data);
|
|
28
|
+
let mimeType;
|
|
29
|
+
if (detected) {
|
|
30
|
+
mimeType = detected.mime;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const contentType = response.headers.get("content-type")?.split(";")[0];
|
|
34
|
+
if (contentType) {
|
|
35
|
+
mimeType = contentType;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
throw new Error(`Unable to detect MIME type from ${url}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const isText = isTextMimeType(mimeType);
|
|
42
|
+
const name = url.split("/").pop() || "file";
|
|
43
|
+
return new File(data, mimeType, isText, name);
|
|
44
|
+
}
|
|
45
|
+
static fromBytes(data, mimeType) {
|
|
46
|
+
const isText = isTextMimeType(mimeType);
|
|
47
|
+
return new File(data, mimeType, isText);
|
|
48
|
+
}
|
|
49
|
+
static fromText(text, mimeType = "text/plain") {
|
|
50
|
+
return new File(text, mimeType, true);
|
|
51
|
+
}
|
|
52
|
+
static fromBase64(base64, mimeType) {
|
|
53
|
+
const data = Buffer.from(base64, "base64");
|
|
54
|
+
const isText = isTextMimeType(mimeType);
|
|
55
|
+
return new File(new Uint8Array(data), mimeType, isText);
|
|
56
|
+
}
|
|
57
|
+
toContentBlock() {
|
|
58
|
+
const uri = this.name ? `file:///${this.name}` : "file:///data";
|
|
59
|
+
if (this.isText) {
|
|
60
|
+
let text;
|
|
61
|
+
if (typeof this.data === "string") {
|
|
62
|
+
text = this.data;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
text = new TextDecoder("utf-8").decode(this.data);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
type: "resource",
|
|
69
|
+
resource: {
|
|
70
|
+
uri,
|
|
71
|
+
mimeType: this.mimeType,
|
|
72
|
+
text,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
let blob;
|
|
78
|
+
if (typeof this.data === "string") {
|
|
79
|
+
blob = Buffer.from(this.data).toString("base64");
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
blob = Buffer.from(this.data).toString("base64");
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
type: "resource",
|
|
86
|
+
resource: {
|
|
87
|
+
uri,
|
|
88
|
+
mimeType: this.mimeType,
|
|
89
|
+
blob,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ImageContent {
|
|
2
|
+
type: "image";
|
|
3
|
+
data: string;
|
|
4
|
+
mimeType: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class Image {
|
|
7
|
+
private readonly base64Data;
|
|
8
|
+
private readonly mimeType;
|
|
9
|
+
private constructor();
|
|
10
|
+
static fromUrl(url: string): Promise<Image>;
|
|
11
|
+
static fromBytes(data: Uint8Array, format?: string): Image;
|
|
12
|
+
static fromBase64(base64: string, mimeType: string): Image;
|
|
13
|
+
toContentBlock(): ImageContent;
|
|
14
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { fileTypeFromBuffer } from "./mime.js";
|
|
2
|
+
const SUPPORTED_IMAGE_MIMES = new Set([
|
|
3
|
+
"image/png",
|
|
4
|
+
"image/jpeg",
|
|
5
|
+
"image/gif",
|
|
6
|
+
"image/webp",
|
|
7
|
+
]);
|
|
8
|
+
export class Image {
|
|
9
|
+
base64Data;
|
|
10
|
+
mimeType;
|
|
11
|
+
constructor(base64Data, mimeType) {
|
|
12
|
+
this.base64Data = base64Data;
|
|
13
|
+
this.mimeType = mimeType;
|
|
14
|
+
}
|
|
15
|
+
static async fromUrl(url) {
|
|
16
|
+
const response = await fetch(url);
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new Error(`Failed to fetch image from ${url}: ${response.status} ${response.statusText}`);
|
|
19
|
+
}
|
|
20
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
21
|
+
const data = new Uint8Array(arrayBuffer);
|
|
22
|
+
const detected = fileTypeFromBuffer(data);
|
|
23
|
+
let mimeType;
|
|
24
|
+
if (detected && SUPPORTED_IMAGE_MIMES.has(detected.mime)) {
|
|
25
|
+
mimeType = detected.mime;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const contentType = response.headers.get("content-type")?.split(";")[0];
|
|
29
|
+
if (contentType && SUPPORTED_IMAGE_MIMES.has(contentType)) {
|
|
30
|
+
mimeType = contentType;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
throw new Error(`Unable to detect image MIME type from ${url}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const base64 = Buffer.from(data).toString("base64");
|
|
37
|
+
return new Image(base64, mimeType);
|
|
38
|
+
}
|
|
39
|
+
static fromBytes(data, format) {
|
|
40
|
+
let mimeType;
|
|
41
|
+
if (format) {
|
|
42
|
+
mimeType = format.includes("/") ? format : `image/${format}`;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const detected = fileTypeFromBuffer(data);
|
|
46
|
+
if (!detected || !SUPPORTED_IMAGE_MIMES.has(detected.mime)) {
|
|
47
|
+
throw new Error("Unable to detect image MIME type from bytes");
|
|
48
|
+
}
|
|
49
|
+
mimeType = detected.mime;
|
|
50
|
+
}
|
|
51
|
+
const base64 = Buffer.from(data).toString("base64");
|
|
52
|
+
return new Image(base64, mimeType);
|
|
53
|
+
}
|
|
54
|
+
static fromBase64(base64, mimeType) {
|
|
55
|
+
return new Image(base64, mimeType);
|
|
56
|
+
}
|
|
57
|
+
toContentBlock() {
|
|
58
|
+
return {
|
|
59
|
+
type: "image",
|
|
60
|
+
data: this.base64Data,
|
|
61
|
+
mimeType: this.mimeType,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { fileTypeFromBuffer, type FileTypeResult } from "./mime.js";
|
|
2
|
+
export { Image, type ImageContent } from "./image.js";
|
|
3
|
+
export { Audio, type AudioContent } from "./audio.js";
|
|
4
|
+
export { File, type EmbeddedResource, type TextResourceContents, type BlobResourceContents, } from "./file.js";
|
|
5
|
+
export { toContentBlocks, type ContentBlock, type TextContent, type ToolReturn, } from "./convert.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// MIME detection
|
|
2
|
+
export { fileTypeFromBuffer } from "./mime.js";
|
|
3
|
+
// Content helpers
|
|
4
|
+
export { Image } from "./image.js";
|
|
5
|
+
export { Audio } from "./audio.js";
|
|
6
|
+
export { File, } from "./file.js";
|
|
7
|
+
// Conversion utility
|
|
8
|
+
export { toContentBlocks, } from "./convert.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { fileTypeFromBuffer, type FileTypeResult } from "./file-type.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { fileTypeFromBuffer } from "./file-type.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { createServer } from "./server.js";
|
|
2
|
+
export type { Server } from "./server.js";
|
|
3
|
+
export { defineSchema } from "./schema.js";
|
|
4
|
+
export type { TypedSchema } from "./schema.js";
|
|
5
|
+
export { Image, Audio, File, toContentBlocks, fileTypeFromBuffer, } from "./content/index.js";
|
|
6
|
+
export type { ImageContent, AudioContent, EmbeddedResource, TextResourceContents, BlobResourceContents, ContentBlock, TextContent, FileTypeResult, } from "./content/index.js";
|
|
7
|
+
export type { ToolReturn } from "./content/index.js";
|
|
8
|
+
export type { ServerOptions, ToolHandler, ToolDefinition, Tool, CallToolResult, HandleResult, ContentItem, JSONSchema, JSONSchemaProperty, Transport, SDKTransport, JSONRPCRequest, JSONRPCResponse, JSONRPCError, JSONRPCMessage, JSONRPCNotification, InitializeResult, } from "./types.js";
|
|
9
|
+
export { JSON_RPC_ERROR_CODES, ToolError } from "./types.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Server
|
|
2
|
+
export { createServer } from "./server.js";
|
|
3
|
+
// Schema
|
|
4
|
+
export { defineSchema } from "./schema.js";
|
|
5
|
+
// Content helpers
|
|
6
|
+
export { Image, Audio, File, toContentBlocks, fileTypeFromBuffer, } from "./content/index.js";
|
|
7
|
+
export { JSON_RPC_ERROR_CODES, ToolError } from "./types.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { JSONRPCRequest, JSONRPCError, JSONRPCNotification } from "./types.js";
|
|
2
|
+
export interface ParseResult {
|
|
3
|
+
success: true;
|
|
4
|
+
request: JSONRPCRequest | JSONRPCNotification;
|
|
5
|
+
isNotification: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ParseError {
|
|
8
|
+
success: false;
|
|
9
|
+
error: JSONRPCError;
|
|
10
|
+
id: string | number | null;
|
|
11
|
+
}
|
|
12
|
+
export declare function parseMessage(line: string): ParseResult | ParseError;
|
|
13
|
+
export declare function formatSuccessResponse(id: string | number | null, result: unknown): string;
|
|
14
|
+
export declare function formatErrorResponse(id: string | number | null, error: JSONRPCError): string;
|