feat: kan mcp server (#485)
* feat: kan mcp server initial attempt * fix: card was missing options and added default fallbacks * fix: label creating with better information for colors and presets
This commit is contained in:
129
README.md
129
README.md
@@ -171,7 +171,7 @@ pnpm dev
|
||||
## Environment Variables 🔐
|
||||
|
||||
| Variable | Description | Required | Example |
|
||||
| ----------------------------------------- | --------------------------------------------------------- | ------------------------------------- | ----------------------------------------------------------- |
|
||||
| ----------------------------------------- | --------------------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------- |
|
||||
| `POSTGRES_URL` | PostgreSQL connection URL | To use external database | `postgres://user:pass@localhost:5432/db` |
|
||||
| `REDIS_URL` | Redis connection URL | For rate limiting (optional) | `redis://localhost:6379` or `redis://redis:6379` (Docker) |
|
||||
| `EMAIL_FROM` | Sender email address | For Email | `"Kan <hello@mail.kan.bn>"` |
|
||||
@@ -217,6 +217,133 @@ pnpm dev
|
||||
|
||||
See `.env.example` for a complete list of supported environment variables.
|
||||
|
||||
## MCP Server (AI Control) 🤖
|
||||
|
||||
Kan ships with a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that lets any MCP-compatible AI client — GitHub Copilot, Claude Desktop, Cursor, Codex, and others — read and control your Kan instance using natural language.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 18+
|
||||
- A running Kan instance (self-hosted or cloud)
|
||||
- A Kan API key (Settings → API Keys → Create key)
|
||||
|
||||
### Installation
|
||||
|
||||
You do **not** need to clone this repository. The recommended way is to use `npx`, which runs the server on-demand and always uses the latest version — no global install required:
|
||||
|
||||
```bash
|
||||
npx -y @kan/mcp
|
||||
```
|
||||
|
||||
Alternatively, install it globally:
|
||||
|
||||
```bash
|
||||
npm install -g @kan/mcp
|
||||
kan-mcp
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
The server is configured via two environment variables:
|
||||
|
||||
| Variable | Description | Example |
|
||||
| --------------- | ----------------------------------- | ------------------------------ |
|
||||
| `KAN_BASE_URL` | Base URL of your Kan instance | `https://your-kan.example.com` |
|
||||
| `KAN_API_TOKEN` | API key from your Kan user settings | `kan_xxxxxxxxxxxx` |
|
||||
|
||||
#### GitHub Copilot (VS Code)
|
||||
|
||||
Add the following to your VS Code `mcp.json` (open it via **MCP: Open User MCP Configuration** from the Command Palette):
|
||||
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"kan": {
|
||||
"type": "stdio",
|
||||
"command": "npx",
|
||||
"args": ["-y", "@kan/mcp"],
|
||||
"env": {
|
||||
"KAN_BASE_URL": "https://your-kan-instance.com",
|
||||
"KAN_API_TOKEN": "kan_your_api_key_here"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then use Copilot in **Agent mode** to interact with Kan.
|
||||
|
||||
#### Claude Desktop
|
||||
|
||||
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kan": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@kan/mcp"],
|
||||
"env": {
|
||||
"KAN_BASE_URL": "https://your-kan-instance.com",
|
||||
"KAN_API_TOKEN": "kan_your_api_key_here"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Cursor / Codex / other clients
|
||||
|
||||
Use the same `command` + `args` + `env` pattern above — all MCP stdio clients follow the same format.
|
||||
|
||||
### Example prompts
|
||||
|
||||
Once connected, you can ask your AI assistant things like:
|
||||
|
||||
**Browsing**
|
||||
|
||||
- _"List all my workspaces"_
|
||||
- _"Show me all boards in the Marketing workspace"_
|
||||
- _"What cards are in the Backlog list of the Q3 Planning board?"_
|
||||
- _"Get the full details of card X including comments and checklists"_
|
||||
|
||||
**Managing cards**
|
||||
|
||||
- _"Create a card called 'Fix login bug' in the To Do list of the Dev board"_
|
||||
- _"Move the 'API redesign' card to the In Progress list"_
|
||||
- _"Set a due date of next Friday on the 'Write docs' card"_
|
||||
- _"Add a comment to the 'Deploy to prod' card saying the deployment is blocked"_
|
||||
- _"Duplicate the 'Sprint template' card into the new Sprint 4 list"_
|
||||
- _"Mark the 'Setup CI' checklist item as complete"_
|
||||
|
||||
**Organisation**
|
||||
|
||||
- _"Add the 'urgent' label to all cards assigned to me in the Backend board"_
|
||||
- _"Create a 'Release checklist' checklist on the v2.0 card with items: smoke test, update changelog, tag release"_
|
||||
- _"What tasks are assigned to @alice in the Mechanics Rework board?"_
|
||||
|
||||
**Workspace management**
|
||||
|
||||
- _"Create a new workspace called 'Client Projects'"_
|
||||
- _"Invite bob@example.com to the Marketing workspace as a member"_
|
||||
- _"Create a new board called 'Sprint 5' in the Dev workspace with lists: Backlog, In Progress, Done"_
|
||||
- _"Search for anything related to 'authentication' across the Dev workspace"_
|
||||
|
||||
### Available tools
|
||||
|
||||
The MCP server exposes 46 tools across 7 resource types:
|
||||
|
||||
| Resource | Tools |
|
||||
| ----------------- | ------------------------------------------------------------------- |
|
||||
| Workspaces | list, find by name, get, create, update, delete, search, check slug |
|
||||
| Boards | list, find by name, get, get by slug, create, update, delete |
|
||||
| Lists | create, update, delete |
|
||||
| Cards | create, get, update, delete, duplicate, get activities |
|
||||
| Card interactions | add/update/delete comment, toggle label, toggle member |
|
||||
| Checklists | create, update, delete, create item, update item, delete item |
|
||||
| Labels | get, create, update, delete |
|
||||
| Members | invite, remove, update role, manage invite links |
|
||||
|
||||
## Contributing 🤝
|
||||
|
||||
We welcome contributions! Please read our [contribution guidelines](CONTRIBUTING.md) before submitting a pull request.
|
||||
|
||||
29
packages/mcp/package.json
Normal file
29
packages/mcp/package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "@kan/mcp",
|
||||
"version": "0.1.0",
|
||||
"description": "MCP server for Kan — control workspaces, boards, lists, and cards via AI",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"kan-mcp": "./dist/index.js"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --noEmit false --declaration false --emitDeclarationOnly false --outDir dist",
|
||||
"clean": "git clean -xdf .cache .turbo dist node_modules",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.11.0",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@kan/tsconfig": "workspace:*",
|
||||
"typescript": "catalog:"
|
||||
}
|
||||
}
|
||||
64
packages/mcp/src/client.ts
Normal file
64
packages/mcp/src/client.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
export interface KanConfig {
|
||||
baseUrl: string;
|
||||
apiToken: string;
|
||||
}
|
||||
|
||||
function getConfig(): KanConfig {
|
||||
const baseUrl = process.env["KAN_BASE_URL"];
|
||||
const apiToken = process.env["KAN_API_TOKEN"];
|
||||
|
||||
if (!baseUrl) {
|
||||
throw new Error("KAN_BASE_URL environment variable is required");
|
||||
}
|
||||
if (!apiToken) {
|
||||
throw new Error("KAN_API_TOKEN environment variable is required");
|
||||
}
|
||||
|
||||
return {
|
||||
baseUrl: baseUrl.replace(/\/$/, ""),
|
||||
apiToken,
|
||||
};
|
||||
}
|
||||
|
||||
export class KanApiError extends Error {
|
||||
constructor(
|
||||
public readonly status: number,
|
||||
public readonly statusText: string,
|
||||
public readonly body: unknown,
|
||||
) {
|
||||
super(`Kan API error ${status} ${statusText}: ${JSON.stringify(body)}`);
|
||||
this.name = "KanApiError";
|
||||
}
|
||||
}
|
||||
|
||||
export async function kanRequest<T>(
|
||||
method: string,
|
||||
path: string,
|
||||
body?: unknown,
|
||||
): Promise<T> {
|
||||
const config = getConfig();
|
||||
const url = `${config.baseUrl}/api/v1${path}`;
|
||||
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${config.apiToken}`,
|
||||
},
|
||||
body: body !== undefined ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
|
||||
let data: unknown;
|
||||
const contentType = res.headers.get("content-type") ?? "";
|
||||
if (contentType.includes("application/json")) {
|
||||
data = await res.json();
|
||||
} else {
|
||||
data = await res.text();
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
throw new KanApiError(res.status, res.statusText, data);
|
||||
}
|
||||
|
||||
return data as T;
|
||||
}
|
||||
27
packages/mcp/src/index.ts
Normal file
27
packages/mcp/src/index.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env node
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
|
||||
import { registerWorkspaceTools } from "./tools/workspace.js";
|
||||
import { registerBoardTools } from "./tools/board.js";
|
||||
import { registerListTools } from "./tools/list.js";
|
||||
import { registerCardTools } from "./tools/card.js";
|
||||
import { registerChecklistTools } from "./tools/checklist.js";
|
||||
import { registerLabelTools } from "./tools/label.js";
|
||||
import { registerMemberTools } from "./tools/member.js";
|
||||
|
||||
const server = new McpServer({
|
||||
name: "kan",
|
||||
version: "0.1.0",
|
||||
});
|
||||
|
||||
registerWorkspaceTools(server);
|
||||
registerBoardTools(server);
|
||||
registerListTools(server);
|
||||
registerCardTools(server);
|
||||
registerChecklistTools(server);
|
||||
registerLabelTools(server);
|
||||
registerMemberTools(server);
|
||||
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
144
packages/mcp/src/tools/board.ts
Normal file
144
packages/mcp/src/tools/board.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
import { kanRequest } from "../client.js";
|
||||
|
||||
export function registerBoardTools(server: McpServer): void {
|
||||
server.tool(
|
||||
"list_boards",
|
||||
"List all boards in a workspace. Requires the workspace publicId — use find_workspace_by_name first if you only know the workspace name.",
|
||||
{ workspacePublicId: z.string().min(12).describe("The workspace's 12-character public ID (not the name). Get it from list_workspaces or find_workspace_by_name first.") },
|
||||
async ({ workspacePublicId }) => {
|
||||
const data = await kanRequest("GET", `/workspaces/${workspacePublicId}/boards`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"find_board_by_name",
|
||||
"Find a board by workspace name and board name (both case-insensitive). Resolves workspace name → publicId, then board name → publicId automatically. Use this when you only know names.",
|
||||
{
|
||||
workspaceName: z.string().describe("The workspace name (e.g. 'UC Roleplay')"),
|
||||
boardName: z.string().describe("The board name (e.g. 'Mechanics Rework')"),
|
||||
},
|
||||
async ({ workspaceName, boardName }) => {
|
||||
const workspaces = await kanRequest<{ publicId: string; name: string }[]>("GET", "/workspaces");
|
||||
const workspace = workspaces.find(
|
||||
(w) => w.name.toLowerCase() === workspaceName.toLowerCase(),
|
||||
);
|
||||
if (!workspace) {
|
||||
const names = workspaces.map((w) => w.name).join(", ");
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `No workspace found with name "${workspaceName}". Available: ${names}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
const boards = await kanRequest<{ publicId: string; name: string }[]>(
|
||||
"GET",
|
||||
`/workspaces/${workspace.publicId}/boards`,
|
||||
);
|
||||
const board = boards.find(
|
||||
(b) => b.name.toLowerCase() === boardName.toLowerCase(),
|
||||
);
|
||||
if (!board) {
|
||||
const names = boards.map((b) => b.name).join(", ");
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `No board found with name "${boardName}" in workspace "${workspaceName}". Available boards: ${names}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
return { content: [{ type: "text", text: JSON.stringify(board, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"get_board",
|
||||
"Get a board by its public ID, including its lists and cards",
|
||||
{
|
||||
boardPublicId: z.string().describe("The board's public ID"),
|
||||
labelPublicId: z.string().optional().describe("Filter cards by label public ID"),
|
||||
memberPublicId: z.string().optional().describe("Filter cards by member public ID"),
|
||||
},
|
||||
async ({ boardPublicId, labelPublicId, memberPublicId }) => {
|
||||
const params = new URLSearchParams();
|
||||
if (labelPublicId) params.set("labelPublicId", labelPublicId);
|
||||
if (memberPublicId) params.set("memberPublicId", memberPublicId);
|
||||
const qs = params.toString() ? `?${params}` : "";
|
||||
const data = await kanRequest("GET", `/boards/${boardPublicId}${qs}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"get_board_by_slug",
|
||||
"Get a board by workspace slug and board slug",
|
||||
{
|
||||
workspaceSlug: z.string().describe("The workspace slug"),
|
||||
boardSlug: z.string().describe("The board slug"),
|
||||
},
|
||||
async ({ workspaceSlug, boardSlug }) => {
|
||||
const data = await kanRequest("GET", `/workspaces/${workspaceSlug}/boards/${boardSlug}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"create_board",
|
||||
"Create a new board in a workspace",
|
||||
{
|
||||
workspacePublicId: z.string().describe("The workspace's public ID"),
|
||||
name: z.string().describe("Board name"),
|
||||
slug: z.string().optional().describe("URL-friendly slug (auto-generated if omitted)"),
|
||||
visibility: z
|
||||
.enum(["public", "private"])
|
||||
.optional()
|
||||
.describe("Board visibility (default: private)"),
|
||||
},
|
||||
async ({ workspacePublicId, name, slug, visibility }) => {
|
||||
const data = await kanRequest("POST", `/workspaces/${workspacePublicId}/boards`, {
|
||||
name,
|
||||
slug,
|
||||
visibility,
|
||||
});
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_board",
|
||||
"Update a board's name, slug, visibility, or favorite status",
|
||||
{
|
||||
boardPublicId: z.string().describe("The board's public ID"),
|
||||
name: z.string().optional().describe("New board name"),
|
||||
slug: z.string().optional().describe("New board slug"),
|
||||
visibility: z.enum(["public", "private"]).optional().describe("New visibility"),
|
||||
isFavorite: z.boolean().optional().describe("Whether the board is favorited"),
|
||||
},
|
||||
async ({ boardPublicId, name, slug, visibility, isFavorite }) => {
|
||||
const data = await kanRequest("PUT", `/boards/${boardPublicId}`, {
|
||||
name,
|
||||
slug,
|
||||
visibility,
|
||||
isFavorite,
|
||||
});
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"delete_board",
|
||||
"Delete a board (soft delete)",
|
||||
{ boardPublicId: z.string().describe("The board's public ID") },
|
||||
async ({ boardPublicId }) => {
|
||||
const data = await kanRequest("DELETE", `/boards/${boardPublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
}
|
||||
192
packages/mcp/src/tools/card.ts
Normal file
192
packages/mcp/src/tools/card.ts
Normal file
@@ -0,0 +1,192 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
import { kanRequest } from "../client.js";
|
||||
|
||||
export function registerCardTools(server: McpServer): void {
|
||||
server.tool(
|
||||
"create_card",
|
||||
"Create a new card in a list",
|
||||
{
|
||||
listPublicId: z.string().describe("The list's public ID"),
|
||||
title: z.string().describe("Card title"),
|
||||
description: z.string().optional().describe("Card description (markdown supported)"),
|
||||
dueDate: z.string().optional().describe("Due date in ISO 8601 format"),
|
||||
labelPublicIds: z
|
||||
.array(z.string())
|
||||
.optional()
|
||||
.describe("Public IDs of labels to attach"),
|
||||
memberPublicIds: z
|
||||
.array(z.string())
|
||||
.optional()
|
||||
.describe("Public IDs of workspace members to assign"),
|
||||
position: z
|
||||
.enum(["start", "end"])
|
||||
.optional()
|
||||
.describe("Where to insert the card in the list (default: end)"),
|
||||
},
|
||||
async ({ listPublicId, title, description, dueDate, labelPublicIds, memberPublicIds, position }) => {
|
||||
const data = await kanRequest("POST", "/cards", {
|
||||
listPublicId,
|
||||
title,
|
||||
description,
|
||||
dueDate,
|
||||
labelPublicIds: labelPublicIds ?? [],
|
||||
memberPublicIds: memberPublicIds ?? [],
|
||||
position: position ?? "end",
|
||||
});
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"get_card",
|
||||
"Get full details of a card including comments, checklists, labels and members",
|
||||
{ cardPublicId: z.string().describe("The card's public ID") },
|
||||
async ({ cardPublicId }) => {
|
||||
const data = await kanRequest("GET", `/cards/${cardPublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_card",
|
||||
"Update a card's title, description, due date, or move it to another list",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID"),
|
||||
title: z.string().optional().describe("New card title"),
|
||||
description: z.string().optional().describe("New description"),
|
||||
dueDate: z.string().nullable().optional().describe("Due date in ISO 8601, or null to clear"),
|
||||
listPublicId: z.string().optional().describe("Move card to this list (public ID)"),
|
||||
},
|
||||
async ({ cardPublicId, title, description, dueDate, listPublicId }) => {
|
||||
const data = await kanRequest("PUT", `/cards/${cardPublicId}`, {
|
||||
title,
|
||||
description,
|
||||
dueDate,
|
||||
listPublicId,
|
||||
});
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"delete_card",
|
||||
"Delete a card (soft delete)",
|
||||
{ cardPublicId: z.string().describe("The card's public ID") },
|
||||
async ({ cardPublicId }) => {
|
||||
const data = await kanRequest("DELETE", `/cards/${cardPublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"duplicate_card",
|
||||
"Duplicate a card to the same or a different list",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID to duplicate"),
|
||||
targetListPublicId: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Target list public ID (defaults to same list)"),
|
||||
},
|
||||
async ({ cardPublicId, targetListPublicId }) => {
|
||||
const data = await kanRequest("POST", `/cards/${cardPublicId}/duplicate`, {
|
||||
targetListPublicId,
|
||||
});
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"get_card_activities",
|
||||
"Get the activity history of a card",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID"),
|
||||
cursor: z.string().optional().describe("Pagination cursor from a previous response"),
|
||||
},
|
||||
async ({ cardPublicId, cursor }) => {
|
||||
const params = cursor ? `?cursor=${encodeURIComponent(cursor)}` : "";
|
||||
const data = await kanRequest("GET", `/cards/${cardPublicId}/activities${params}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"add_card_comment",
|
||||
"Add a comment to a card",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID"),
|
||||
content: z.string().describe("Comment text"),
|
||||
},
|
||||
async ({ cardPublicId, content }) => {
|
||||
const data = await kanRequest("POST", `/cards/${cardPublicId}/comments`, { content });
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_card_comment",
|
||||
"Update the text of an existing comment",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID"),
|
||||
commentPublicId: z.string().describe("The comment's public ID"),
|
||||
content: z.string().describe("New comment text"),
|
||||
},
|
||||
async ({ cardPublicId, commentPublicId, content }) => {
|
||||
const data = await kanRequest(
|
||||
"PUT",
|
||||
`/cards/${cardPublicId}/comments/${commentPublicId}`,
|
||||
{ content },
|
||||
);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"delete_card_comment",
|
||||
"Delete a comment from a card",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID"),
|
||||
commentPublicId: z.string().describe("The comment's public ID"),
|
||||
},
|
||||
async ({ cardPublicId, commentPublicId }) => {
|
||||
const data = await kanRequest(
|
||||
"DELETE",
|
||||
`/cards/${cardPublicId}/comments/${commentPublicId}`,
|
||||
);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"toggle_card_label",
|
||||
"Add or remove a label on a card (toggles if already present)",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID"),
|
||||
labelPublicId: z.string().describe("The label's public ID"),
|
||||
},
|
||||
async ({ cardPublicId, labelPublicId }) => {
|
||||
const data = await kanRequest(
|
||||
"PUT",
|
||||
`/cards/${cardPublicId}/labels/${labelPublicId}`,
|
||||
);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"toggle_card_member",
|
||||
"Add or remove a member assignment on a card (toggles if already assigned)",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID"),
|
||||
workspaceMemberPublicId: z.string().describe("The workspace member's public ID"),
|
||||
},
|
||||
async ({ cardPublicId, workspaceMemberPublicId }) => {
|
||||
const data = await kanRequest(
|
||||
"PUT",
|
||||
`/cards/${cardPublicId}/members/${workspaceMemberPublicId}`,
|
||||
);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
}
|
||||
83
packages/mcp/src/tools/checklist.ts
Normal file
83
packages/mcp/src/tools/checklist.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
import { kanRequest } from "../client.js";
|
||||
|
||||
export function registerChecklistTools(server: McpServer): void {
|
||||
server.tool(
|
||||
"create_checklist",
|
||||
"Add a checklist to a card",
|
||||
{
|
||||
cardPublicId: z.string().describe("The card's public ID"),
|
||||
name: z.string().describe("Checklist name"),
|
||||
},
|
||||
async ({ cardPublicId, name }) => {
|
||||
const data = await kanRequest("POST", `/cards/${cardPublicId}/checklists`, { name });
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_checklist",
|
||||
"Rename a checklist",
|
||||
{
|
||||
checklistPublicId: z.string().describe("The checklist's public ID"),
|
||||
name: z.string().describe("New checklist name"),
|
||||
},
|
||||
async ({ checklistPublicId, name }) => {
|
||||
const data = await kanRequest("PUT", `/checklists/${checklistPublicId}`, { name });
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"delete_checklist",
|
||||
"Delete a checklist and all its items",
|
||||
{ checklistPublicId: z.string().describe("The checklist's public ID") },
|
||||
async ({ checklistPublicId }) => {
|
||||
const data = await kanRequest("DELETE", `/checklists/${checklistPublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"create_checklist_item",
|
||||
"Add an item to a checklist",
|
||||
{
|
||||
checklistPublicId: z.string().describe("The checklist's public ID"),
|
||||
title: z.string().describe("Item title"),
|
||||
},
|
||||
async ({ checklistPublicId, title }) => {
|
||||
const data = await kanRequest("POST", `/checklists/${checklistPublicId}/items`, { title });
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_checklist_item",
|
||||
"Update a checklist item's title, completion status, or position",
|
||||
{
|
||||
checklistItemPublicId: z.string().describe("The checklist item's public ID"),
|
||||
title: z.string().optional().describe("New item title"),
|
||||
isCompleted: z.boolean().optional().describe("Mark item as completed or not"),
|
||||
index: z.number().int().optional().describe("New position index"),
|
||||
},
|
||||
async ({ checklistItemPublicId, title, isCompleted, index }) => {
|
||||
const data = await kanRequest("PATCH", `/checklists/items/${checklistItemPublicId}`, {
|
||||
title,
|
||||
isCompleted,
|
||||
index,
|
||||
});
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"delete_checklist_item",
|
||||
"Delete a checklist item",
|
||||
{ checklistItemPublicId: z.string().describe("The checklist item's public ID") },
|
||||
async ({ checklistItemPublicId }) => {
|
||||
const data = await kanRequest("DELETE", `/checklists/items/${checklistItemPublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
}
|
||||
101
packages/mcp/src/tools/label.ts
Normal file
101
packages/mcp/src/tools/label.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
import { kanRequest } from "../client.js";
|
||||
|
||||
// Preset colour palette supported by the Kan UI.
|
||||
// Mirrors packages/shared/src/constants/colours.ts. Keep in sync.
|
||||
const COLOUR_PRESETS = {
|
||||
Teal: "#0d9488",
|
||||
Green: "#65a30d",
|
||||
Blue: "#0284c7",
|
||||
Purple: "#4f46e5",
|
||||
Yellow: "#ca8a04",
|
||||
Orange: "#ea580c",
|
||||
Red: "#dc2626",
|
||||
Pink: "#db2777",
|
||||
} as const;
|
||||
|
||||
const colourNames = Object.keys(COLOUR_PRESETS) as [
|
||||
keyof typeof COLOUR_PRESETS,
|
||||
...(keyof typeof COLOUR_PRESETS)[],
|
||||
];
|
||||
const colourNameSchema = z.enum(colourNames);
|
||||
const presetDescription = `One of the preset colour names: ${colourNames.join(", ")}`;
|
||||
|
||||
function resolveColourCode(
|
||||
colour: keyof typeof COLOUR_PRESETS | undefined,
|
||||
colourCode: string | undefined,
|
||||
): string | undefined {
|
||||
if (colourCode) return colourCode;
|
||||
if (colour) return COLOUR_PRESETS[colour];
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function registerLabelTools(server: McpServer): void {
|
||||
server.tool(
|
||||
"get_label",
|
||||
"Get a label by its public ID",
|
||||
{ labelPublicId: z.string().describe("The label's public ID") },
|
||||
async ({ labelPublicId }) => {
|
||||
const data = await kanRequest("GET", `/labels/${labelPublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"create_label",
|
||||
`Create a label for a board. Pick a colour by preset name (${colourNames.join(", ")}) or pass an explicit 7-char hex via colourCode. Defaults to Teal.`,
|
||||
{
|
||||
boardPublicId: z.string().describe("The board's public ID"),
|
||||
name: z.string().describe("Label name"),
|
||||
colour: colourNameSchema.optional().describe(presetDescription),
|
||||
colourCode: z
|
||||
.string()
|
||||
.regex(/^#[0-9a-fA-F]{6}$/)
|
||||
.optional()
|
||||
.describe("Explicit 7-char hex colour (e.g. #0d9488). Overrides `colour` if both are set."),
|
||||
},
|
||||
async ({ boardPublicId, name, colour, colourCode }) => {
|
||||
const resolved = resolveColourCode(colour, colourCode) ?? COLOUR_PRESETS.Teal;
|
||||
const data = await kanRequest("POST", "/labels", {
|
||||
boardPublicId,
|
||||
name,
|
||||
colourCode: resolved,
|
||||
});
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_label",
|
||||
"Update a label's name or colour. Pick a colour by preset name or pass an explicit 7-char hex.",
|
||||
{
|
||||
labelPublicId: z.string().describe("The label's public ID"),
|
||||
name: z.string().optional().describe("New label name"),
|
||||
colour: colourNameSchema.optional().describe(presetDescription),
|
||||
colourCode: z
|
||||
.string()
|
||||
.regex(/^#[0-9a-fA-F]{6}$/)
|
||||
.optional()
|
||||
.describe("Explicit 7-char hex colour. Overrides `colour` if both are set."),
|
||||
},
|
||||
async ({ labelPublicId, name, colour, colourCode }) => {
|
||||
const resolved = resolveColourCode(colour, colourCode);
|
||||
const body: Record<string, unknown> = {};
|
||||
if (name !== undefined) body.name = name;
|
||||
if (resolved !== undefined) body.colourCode = resolved;
|
||||
const data = await kanRequest("PUT", `/labels/${labelPublicId}`, body);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"delete_label",
|
||||
"Delete a label",
|
||||
{ labelPublicId: z.string().describe("The label's public ID") },
|
||||
async ({ labelPublicId }) => {
|
||||
const data = await kanRequest("DELETE", `/labels/${labelPublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
}
|
||||
42
packages/mcp/src/tools/list.ts
Normal file
42
packages/mcp/src/tools/list.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
import { kanRequest } from "../client.js";
|
||||
|
||||
export function registerListTools(server: McpServer): void {
|
||||
server.tool(
|
||||
"create_list",
|
||||
"Create a new list inside a board",
|
||||
{
|
||||
boardPublicId: z.string().describe("The board's public ID"),
|
||||
name: z.string().describe("List name"),
|
||||
},
|
||||
async ({ boardPublicId, name }) => {
|
||||
const data = await kanRequest("POST", "/lists", { boardPublicId, name });
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_list",
|
||||
"Update a list's name or position",
|
||||
{
|
||||
listPublicId: z.string().describe("The list's public ID"),
|
||||
name: z.string().optional().describe("New list name"),
|
||||
index: z.number().int().optional().describe("New position index"),
|
||||
},
|
||||
async ({ listPublicId, name, index }) => {
|
||||
const data = await kanRequest("PUT", `/lists/${listPublicId}`, { name, index });
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"delete_list",
|
||||
"Delete a list and all its cards",
|
||||
{ listPublicId: z.string().describe("The list's public ID") },
|
||||
async ({ listPublicId }) => {
|
||||
const data = await kanRequest("DELETE", `/lists/${listPublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
}
|
||||
90
packages/mcp/src/tools/member.ts
Normal file
90
packages/mcp/src/tools/member.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
import { kanRequest } from "../client.js";
|
||||
|
||||
export function registerMemberTools(server: McpServer): void {
|
||||
server.tool(
|
||||
"invite_member",
|
||||
"Invite a user to a workspace by email",
|
||||
{
|
||||
workspacePublicId: z.string().describe("The workspace's public ID"),
|
||||
email: z.string().email().describe("Email address to invite"),
|
||||
role: z
|
||||
.enum(["admin", "member", "guest"])
|
||||
.optional()
|
||||
.describe("Role to assign (default: member)"),
|
||||
},
|
||||
async ({ workspacePublicId, email, role }) => {
|
||||
const data = await kanRequest(
|
||||
"POST",
|
||||
`/workspaces/${workspacePublicId}/members/invite`,
|
||||
{ email, role },
|
||||
);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"remove_member",
|
||||
"Remove a member from a workspace",
|
||||
{
|
||||
workspacePublicId: z.string().describe("The workspace's public ID"),
|
||||
memberPublicId: z.string().describe("The workspace member's public ID"),
|
||||
},
|
||||
async ({ workspacePublicId, memberPublicId }) => {
|
||||
const data = await kanRequest(
|
||||
"DELETE",
|
||||
`/workspaces/${workspacePublicId}/members/${memberPublicId}`,
|
||||
);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_member_role",
|
||||
"Change the role of a workspace member",
|
||||
{
|
||||
workspacePublicId: z.string().describe("The workspace's public ID"),
|
||||
memberPublicId: z.string().describe("The workspace member's public ID"),
|
||||
role: z.enum(["admin", "member", "guest"]).describe("New role"),
|
||||
},
|
||||
async ({ workspacePublicId, memberPublicId, role }) => {
|
||||
const data = await kanRequest(
|
||||
"PUT",
|
||||
`/workspaces/${workspacePublicId}/members/${memberPublicId}/role`,
|
||||
{ role },
|
||||
);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"get_workspace_invite_link",
|
||||
"Get the active invite link for a workspace",
|
||||
{ workspacePublicId: z.string().describe("The workspace's public ID") },
|
||||
async ({ workspacePublicId }) => {
|
||||
const data = await kanRequest("GET", `/workspaces/${workspacePublicId}/invite`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"create_workspace_invite_link",
|
||||
"Create a new invite link for a workspace (7-day expiry)",
|
||||
{ workspacePublicId: z.string().describe("The workspace's public ID") },
|
||||
async ({ workspacePublicId }) => {
|
||||
const data = await kanRequest("POST", `/workspaces/${workspacePublicId}/invites`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"deactivate_workspace_invite_links",
|
||||
"Deactivate all active invite links for a workspace",
|
||||
{ workspacePublicId: z.string().describe("The workspace's public ID") },
|
||||
async ({ workspacePublicId }) => {
|
||||
const data = await kanRequest("DELETE", `/workspaces/${workspacePublicId}/invites`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
}
|
||||
121
packages/mcp/src/tools/workspace.ts
Normal file
121
packages/mcp/src/tools/workspace.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
import { kanRequest } from "../client.js";
|
||||
|
||||
export function registerWorkspaceTools(server: McpServer): void {
|
||||
server.tool(
|
||||
"list_workspaces",
|
||||
"List all workspaces the authenticated user belongs to. Call this first to resolve a workspace name to its publicId before calling any other workspace-scoped tool.",
|
||||
{},
|
||||
async () => {
|
||||
const data = await kanRequest("GET", "/workspaces");
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"find_workspace_by_name",
|
||||
"Find a workspace by its name (case-insensitive). Returns the matching workspace including its publicId. Use this whenever you only know the workspace name and need its publicId.",
|
||||
{ name: z.string().describe("Workspace name to search for") },
|
||||
async ({ name }) => {
|
||||
const workspaces = await kanRequest<{ publicId: string; name: string }[]>("GET", "/workspaces");
|
||||
const match = workspaces.find(
|
||||
(w) => w.name.toLowerCase() === name.toLowerCase(),
|
||||
);
|
||||
if (!match) {
|
||||
const names = workspaces.map((w) => w.name).join(", ");
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `No workspace found with name "${name}". Available workspaces: ${names}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
return { content: [{ type: "text", text: JSON.stringify(match, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"get_workspace",
|
||||
"Get a workspace by its public ID, including its members",
|
||||
{ workspacePublicId: z.string().describe("The workspace's public ID") },
|
||||
async ({ workspacePublicId }) => {
|
||||
const data = await kanRequest("GET", `/workspaces/${workspacePublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"get_workspace_by_slug",
|
||||
"Get a workspace by its slug, including its boards",
|
||||
{ workspaceSlug: z.string().describe("The workspace slug") },
|
||||
async ({ workspaceSlug }) => {
|
||||
const data = await kanRequest("GET", `/workspaces/${workspaceSlug}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"create_workspace",
|
||||
"Create a new workspace",
|
||||
{
|
||||
name: z.string().describe("Workspace name"),
|
||||
slug: z.string().optional().describe("URL-friendly slug (auto-generated if omitted)"),
|
||||
},
|
||||
async ({ name, slug }) => {
|
||||
const data = await kanRequest("POST", "/workspaces", { name, slug });
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"update_workspace",
|
||||
"Update a workspace's name or slug",
|
||||
{
|
||||
workspacePublicId: z.string().describe("The workspace's public ID"),
|
||||
name: z.string().optional().describe("New workspace name"),
|
||||
slug: z.string().optional().describe("New workspace slug"),
|
||||
},
|
||||
async ({ workspacePublicId, name, slug }) => {
|
||||
const data = await kanRequest("PUT", `/workspaces/${workspacePublicId}`, { name, slug });
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"delete_workspace",
|
||||
"Permanently delete a workspace",
|
||||
{ workspacePublicId: z.string().describe("The workspace's public ID") },
|
||||
async ({ workspacePublicId }) => {
|
||||
const data = await kanRequest("DELETE", `/workspaces/${workspacePublicId}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"search_workspace",
|
||||
"Search for boards and cards by title within a workspace",
|
||||
{
|
||||
workspacePublicId: z.string().describe("The workspace's public ID"),
|
||||
query: z.string().describe("Search query string"),
|
||||
},
|
||||
async ({ workspacePublicId, query }) => {
|
||||
const params = new URLSearchParams({ query });
|
||||
const data = await kanRequest("GET", `/workspaces/${workspacePublicId}/search?${params}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"check_workspace_slug_availability",
|
||||
"Check whether a workspace slug is available",
|
||||
{ slug: z.string().describe("Slug to check") },
|
||||
async ({ slug }) => {
|
||||
const params = new URLSearchParams({ slug });
|
||||
const data = await kanRequest("GET", `/workspaces/check-slug-availability?${params}`);
|
||||
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
||||
},
|
||||
);
|
||||
}
|
||||
14
packages/mcp/tsconfig.json
Normal file
14
packages/mcp/tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "@kan/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"noEmit": false,
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"target": "ES2022",
|
||||
"declaration": false,
|
||||
"tsBuildInfoFile": ".cache/tsbuildinfo.json"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
407
pnpm-lock.yaml
generated
407
pnpm-lock.yaml
generated
@@ -533,6 +533,22 @@ importers:
|
||||
specifier: 'catalog:'
|
||||
version: 5.9.2
|
||||
|
||||
packages/mcp:
|
||||
dependencies:
|
||||
'@modelcontextprotocol/sdk':
|
||||
specifier: ^1.11.0
|
||||
version: 1.29.0(zod@3.25.76)
|
||||
zod:
|
||||
specifier: 'catalog:'
|
||||
version: 3.25.76
|
||||
devDependencies:
|
||||
'@kan/tsconfig':
|
||||
specifier: workspace:*
|
||||
version: link:../../tooling/typescript
|
||||
typescript:
|
||||
specifier: 'catalog:'
|
||||
version: 5.9.2
|
||||
|
||||
packages/shared:
|
||||
dependencies:
|
||||
'@aws-sdk/client-s3':
|
||||
@@ -2347,6 +2363,12 @@ packages:
|
||||
react: ^18 || ^19 || ^19.0.0-rc
|
||||
react-dom: ^18 || ^19 || ^19.0.0-rc
|
||||
|
||||
'@hono/node-server@1.19.14':
|
||||
resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==}
|
||||
engines: {node: '>=18.14.1'}
|
||||
peerDependencies:
|
||||
hono: ^4
|
||||
|
||||
'@hookform/resolvers@3.10.0':
|
||||
resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==}
|
||||
peerDependencies:
|
||||
@@ -2841,6 +2863,16 @@ packages:
|
||||
'@mintlify/models': 0.0.25
|
||||
openapi-types: 12.x
|
||||
|
||||
'@modelcontextprotocol/sdk@1.29.0':
|
||||
resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@cfworker/json-schema': ^4.1.1
|
||||
zod: ^3.25 || ^4.0
|
||||
peerDependenciesMeta:
|
||||
'@cfworker/json-schema':
|
||||
optional: true
|
||||
|
||||
'@next/env@15.5.9':
|
||||
resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==}
|
||||
|
||||
@@ -4349,6 +4381,10 @@ packages:
|
||||
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
accepts@2.0.0:
|
||||
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
acorn-import-phases@1.0.4:
|
||||
resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
@@ -4636,6 +4672,10 @@ packages:
|
||||
bl@5.1.0:
|
||||
resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==}
|
||||
|
||||
body-parser@2.2.2:
|
||||
resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
boolbase@1.0.0:
|
||||
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
|
||||
|
||||
@@ -4920,12 +4960,24 @@ packages:
|
||||
constant-case@2.0.0:
|
||||
resolution: {integrity: sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==}
|
||||
|
||||
content-disposition@1.1.0:
|
||||
resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
content-type@1.0.5:
|
||||
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
convert-source-map@2.0.0:
|
||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||
|
||||
cookie-es@1.2.2:
|
||||
resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
|
||||
|
||||
cookie-signature@1.2.2:
|
||||
resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
|
||||
engines: {node: '>=6.6.0'}
|
||||
|
||||
cookie@0.7.2:
|
||||
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -5306,6 +5358,9 @@ packages:
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
ee-first@1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
|
||||
electron-to-chromium@1.5.211:
|
||||
resolution: {integrity: sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==}
|
||||
|
||||
@@ -5324,6 +5379,10 @@ packages:
|
||||
emoji-regex@9.2.2:
|
||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
|
||||
encodeurl@2.0.0:
|
||||
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
end-of-stream@1.4.5:
|
||||
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
|
||||
|
||||
@@ -5564,10 +5623,22 @@ packages:
|
||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
etag@1.8.1:
|
||||
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
events@3.3.0:
|
||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
||||
engines: {node: '>=0.8.x'}
|
||||
|
||||
eventsource-parser@3.0.8:
|
||||
resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
eventsource@3.0.7:
|
||||
resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
execa@5.1.1:
|
||||
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -5576,6 +5647,16 @@ packages:
|
||||
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
express-rate-limit@8.4.1:
|
||||
resolution: {integrity: sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcliS8La5EPRN3p9wzItqBwJrfNw==}
|
||||
engines: {node: '>= 16'}
|
||||
peerDependencies:
|
||||
express: '>= 4.11'
|
||||
|
||||
express@5.2.1:
|
||||
resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
exsolve@1.0.8:
|
||||
resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
|
||||
|
||||
@@ -5653,6 +5734,10 @@ packages:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
finalhandler@2.1.1:
|
||||
resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
|
||||
engines: {node: '>= 18.0.0'}
|
||||
|
||||
find-up@5.0.0:
|
||||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -5689,6 +5774,10 @@ packages:
|
||||
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
||||
engines: {node: '>=0.4.x'}
|
||||
|
||||
forwarded@0.2.0:
|
||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
framer-motion@12.26.2:
|
||||
resolution: {integrity: sha512-lflOQEdjquUi9sCg5Y1LrsZDlsjrHw7m0T9Yedvnk7Bnhqfkc89/Uha10J3CFhkL+TCZVCRw9eUGyM/lyYhXQA==}
|
||||
peerDependencies:
|
||||
@@ -5703,6 +5792,10 @@ packages:
|
||||
react-dom:
|
||||
optional: true
|
||||
|
||||
fresh@2.0.0:
|
||||
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
fs-extra@10.1.0:
|
||||
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -5786,25 +5879,29 @@ packages:
|
||||
glob@10.3.10:
|
||||
resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
hasBin: true
|
||||
|
||||
glob@10.4.5:
|
||||
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
hasBin: true
|
||||
|
||||
glob@11.0.3:
|
||||
resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==}
|
||||
engines: {node: 20 || >=22}
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
hasBin: true
|
||||
|
||||
glob@11.1.0:
|
||||
resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==}
|
||||
engines: {node: 20 || >=22}
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
hasBin: true
|
||||
|
||||
glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
|
||||
globals@14.0.0:
|
||||
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
|
||||
@@ -5890,6 +5987,10 @@ packages:
|
||||
hoist-non-react-statics@3.3.2:
|
||||
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
|
||||
|
||||
hono@4.12.16:
|
||||
resolution: {integrity: sha512-jN0ZewiNAWSe5khM3EyCmBb250+b40wWbwNILNfEvq84VREWwOIkuUsFONk/3i3nqkz7Oe1PcpM2mwQEK2L9Kg==}
|
||||
engines: {node: '>=16.9.0'}
|
||||
|
||||
html-to-text@9.0.5:
|
||||
resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -5904,6 +6005,10 @@ packages:
|
||||
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
http-errors@2.0.1:
|
||||
resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
http-proxy-agent@7.0.2:
|
||||
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -5924,6 +6029,10 @@ packages:
|
||||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
iconv-lite@0.7.2:
|
||||
resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
ieee754@1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
|
||||
@@ -5992,6 +6101,14 @@ packages:
|
||||
resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
ip-address@10.1.0:
|
||||
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
ipaddr.js@1.9.1:
|
||||
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
iron-webcrypto@1.2.1:
|
||||
resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
|
||||
|
||||
@@ -6132,6 +6249,9 @@ packages:
|
||||
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-promise@4.0.0:
|
||||
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
|
||||
|
||||
is-regex@1.2.1:
|
||||
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -6576,9 +6696,17 @@ packages:
|
||||
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
media-typer@1.1.0:
|
||||
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
memoize-one@5.2.1:
|
||||
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
|
||||
|
||||
merge-descriptors@2.0.0:
|
||||
resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
merge-stream@2.0.0:
|
||||
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
|
||||
|
||||
@@ -6870,6 +6998,10 @@ packages:
|
||||
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
negotiator@1.0.0:
|
||||
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
neo-async@2.6.2:
|
||||
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
|
||||
|
||||
@@ -7025,6 +7157,10 @@ packages:
|
||||
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
on-finished@2.4.1:
|
||||
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
|
||||
@@ -7117,6 +7253,10 @@ packages:
|
||||
parseley@0.12.1:
|
||||
resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==}
|
||||
|
||||
parseurl@1.3.3:
|
||||
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
pascal-case@2.0.1:
|
||||
resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==}
|
||||
|
||||
@@ -7150,6 +7290,9 @@ packages:
|
||||
resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
path-to-regexp@8.4.2:
|
||||
resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==}
|
||||
|
||||
path-type@4.0.0:
|
||||
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -7237,6 +7380,10 @@ packages:
|
||||
resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
pkce-challenge@5.0.1:
|
||||
resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
|
||||
pkg-types@2.3.0:
|
||||
resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
|
||||
|
||||
@@ -7475,6 +7622,10 @@ packages:
|
||||
prosemirror-view@1.40.1:
|
||||
resolution: {integrity: sha512-pbwUjt3G7TlsQQHDiYSupWBhJswpLVB09xXm1YiJPdkjkh9Pe7Y51XdLh5VWIZmROLY8UpUpG03lkdhm9lzIBA==}
|
||||
|
||||
proxy-addr@2.0.7:
|
||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
proxy-agent@6.5.0:
|
||||
resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -7502,6 +7653,10 @@ packages:
|
||||
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
qs@6.15.1:
|
||||
resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
@@ -7517,6 +7672,10 @@ packages:
|
||||
randombytes@2.1.0:
|
||||
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||
|
||||
range-parser@1.2.1:
|
||||
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
rate-limiter-flexible@9.0.1:
|
||||
resolution: {integrity: sha512-sO+QdoGPCxroi4VkO2FIVjfUGuexhRkBc9ROHqu5eVEEz+oPHzQqvCc25ajFfMUBosbNGb6qpNa8xmxH9YNZsg==}
|
||||
|
||||
@@ -7524,6 +7683,10 @@ packages:
|
||||
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
raw-body@3.0.2:
|
||||
resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
rc@1.2.8:
|
||||
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
|
||||
hasBin: true
|
||||
@@ -7760,6 +7923,10 @@ packages:
|
||||
rou3@0.7.11:
|
||||
resolution: {integrity: sha512-ELguG3ENDw5NKNmWHO3OGEjcgdxkCNvnMR22gKHEgRXuwiriap5RIYdummOaOiqUNcC5yU5txGCHWNm7KlHuAA==}
|
||||
|
||||
router@2.2.0:
|
||||
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
run-async@2.4.1:
|
||||
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
@@ -7843,12 +8010,20 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
send@1.2.1:
|
||||
resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
sentence-case@2.1.1:
|
||||
resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==}
|
||||
|
||||
serialize-javascript@6.0.2:
|
||||
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
|
||||
|
||||
serve-static@2.2.1:
|
||||
resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
set-cookie-parser@2.7.2:
|
||||
resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
|
||||
|
||||
@@ -7992,6 +8167,10 @@ packages:
|
||||
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
statuses@2.0.2:
|
||||
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
std-env@3.10.0:
|
||||
resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
|
||||
|
||||
@@ -8380,6 +8559,10 @@ packages:
|
||||
resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
type-is@2.0.1:
|
||||
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
typed-array-buffer@1.0.3:
|
||||
resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -8815,6 +8998,11 @@ packages:
|
||||
peerDependencies:
|
||||
zod: ^3.24.1
|
||||
|
||||
zod-to-json-schema@3.25.2:
|
||||
resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==}
|
||||
peerDependencies:
|
||||
zod: ^3.25.28 || ^4
|
||||
|
||||
zod@3.25.76:
|
||||
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
|
||||
|
||||
@@ -10678,6 +10866,10 @@ snapshots:
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
||||
|
||||
'@hono/node-server@1.19.14(hono@4.12.16)':
|
||||
dependencies:
|
||||
hono: 4.12.16
|
||||
|
||||
'@hookform/resolvers@3.10.0(react-hook-form@7.62.0(react@18.3.1))':
|
||||
dependencies:
|
||||
react-hook-form: 7.62.0(react@18.3.1)
|
||||
@@ -11192,6 +11384,28 @@ snapshots:
|
||||
zod: 3.25.76
|
||||
zod-to-json-schema: 3.24.6(zod@3.25.76)
|
||||
|
||||
'@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@hono/node-server': 1.19.14(hono@4.12.16)
|
||||
ajv: 8.17.1
|
||||
ajv-formats: 3.0.1(ajv@8.17.1)
|
||||
content-type: 1.0.5
|
||||
cors: 2.8.5
|
||||
cross-spawn: 7.0.6
|
||||
eventsource: 3.0.7
|
||||
eventsource-parser: 3.0.8
|
||||
express: 5.2.1
|
||||
express-rate-limit: 8.4.1(express@5.2.1)
|
||||
hono: 4.12.16
|
||||
jose: 6.1.3
|
||||
json-schema-typed: 8.0.2
|
||||
pkce-challenge: 5.0.1
|
||||
raw-body: 3.0.2
|
||||
zod: 3.25.76
|
||||
zod-to-json-schema: 3.25.2(zod@3.25.76)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@next/env@15.5.9': {}
|
||||
|
||||
'@next/env@16.0.8':
|
||||
@@ -12929,6 +13143,11 @@ snapshots:
|
||||
mime-types: 2.1.35
|
||||
negotiator: 0.6.3
|
||||
|
||||
accepts@2.0.0:
|
||||
dependencies:
|
||||
mime-types: 3.0.2
|
||||
negotiator: 1.0.0
|
||||
|
||||
acorn-import-phases@1.0.4(acorn@8.15.0):
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
@@ -13209,6 +13428,20 @@ snapshots:
|
||||
inherits: 2.0.4
|
||||
readable-stream: 3.6.2
|
||||
|
||||
body-parser@2.2.2:
|
||||
dependencies:
|
||||
bytes: 3.1.2
|
||||
content-type: 1.0.5
|
||||
debug: 4.4.3
|
||||
http-errors: 2.0.0
|
||||
iconv-lite: 0.7.2
|
||||
on-finished: 2.4.1
|
||||
qs: 6.15.1
|
||||
raw-body: 3.0.2
|
||||
type-is: 2.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
boolbase@1.0.0: {}
|
||||
|
||||
bowser@2.12.1: {}
|
||||
@@ -13514,10 +13747,16 @@ snapshots:
|
||||
snake-case: 2.1.0
|
||||
upper-case: 1.1.3
|
||||
|
||||
content-disposition@1.1.0: {}
|
||||
|
||||
content-type@1.0.5: {}
|
||||
|
||||
convert-source-map@2.0.0: {}
|
||||
|
||||
cookie-es@1.2.2: {}
|
||||
|
||||
cookie-signature@1.2.2: {}
|
||||
|
||||
cookie@0.7.2: {}
|
||||
|
||||
copy-anything@3.0.5:
|
||||
@@ -13801,6 +14040,8 @@ snapshots:
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
ee-first@1.1.1: {}
|
||||
|
||||
electron-to-chromium@1.5.211: {}
|
||||
|
||||
electron-to-chromium@1.5.240: {}
|
||||
@@ -13813,6 +14054,8 @@ snapshots:
|
||||
|
||||
emoji-regex@9.2.2: {}
|
||||
|
||||
encodeurl@2.0.0: {}
|
||||
|
||||
end-of-stream@1.4.5:
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
@@ -14345,8 +14588,16 @@ snapshots:
|
||||
|
||||
esutils@2.0.3: {}
|
||||
|
||||
etag@1.8.1: {}
|
||||
|
||||
events@3.3.0: {}
|
||||
|
||||
eventsource-parser@3.0.8: {}
|
||||
|
||||
eventsource@3.0.7:
|
||||
dependencies:
|
||||
eventsource-parser: 3.0.8
|
||||
|
||||
execa@5.1.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
@@ -14361,6 +14612,44 @@ snapshots:
|
||||
|
||||
expect-type@1.3.0: {}
|
||||
|
||||
express-rate-limit@8.4.1(express@5.2.1):
|
||||
dependencies:
|
||||
express: 5.2.1
|
||||
ip-address: 10.1.0
|
||||
|
||||
express@5.2.1:
|
||||
dependencies:
|
||||
accepts: 2.0.0
|
||||
body-parser: 2.2.2
|
||||
content-disposition: 1.1.0
|
||||
content-type: 1.0.5
|
||||
cookie: 0.7.2
|
||||
cookie-signature: 1.2.2
|
||||
debug: 4.4.3
|
||||
depd: 2.0.0
|
||||
encodeurl: 2.0.0
|
||||
escape-html: 1.0.3
|
||||
etag: 1.8.1
|
||||
finalhandler: 2.1.1
|
||||
fresh: 2.0.0
|
||||
http-errors: 2.0.0
|
||||
merge-descriptors: 2.0.0
|
||||
mime-types: 3.0.2
|
||||
on-finished: 2.4.1
|
||||
once: 1.4.0
|
||||
parseurl: 1.3.3
|
||||
proxy-addr: 2.0.7
|
||||
qs: 6.14.0
|
||||
range-parser: 1.2.1
|
||||
router: 2.2.0
|
||||
send: 1.2.1
|
||||
serve-static: 2.2.1
|
||||
statuses: 2.0.1
|
||||
type-is: 2.0.1
|
||||
vary: 1.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
exsolve@1.0.8: {}
|
||||
|
||||
extend-shallow@2.0.1:
|
||||
@@ -14433,6 +14722,17 @@ snapshots:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
||||
finalhandler@2.1.1:
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
encodeurl: 2.0.0
|
||||
escape-html: 1.0.3
|
||||
on-finished: 2.4.1
|
||||
parseurl: 1.3.3
|
||||
statuses: 2.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
find-up@5.0.0:
|
||||
dependencies:
|
||||
locate-path: 6.0.0
|
||||
@@ -14466,6 +14766,8 @@ snapshots:
|
||||
|
||||
format@0.2.2: {}
|
||||
|
||||
forwarded@0.2.0: {}
|
||||
|
||||
framer-motion@12.26.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
motion-dom: 12.26.2
|
||||
@@ -14475,6 +14777,8 @@ snapshots:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
fresh@2.0.0: {}
|
||||
|
||||
fs-extra@10.1.0:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
@@ -14725,6 +15029,8 @@ snapshots:
|
||||
dependencies:
|
||||
react-is: 16.13.1
|
||||
|
||||
hono@4.12.16: {}
|
||||
|
||||
html-to-text@9.0.5:
|
||||
dependencies:
|
||||
'@selderee/plugin-htmlparser2': 0.11.0
|
||||
@@ -14750,6 +15056,14 @@ snapshots:
|
||||
statuses: 2.0.1
|
||||
toidentifier: 1.0.1
|
||||
|
||||
http-errors@2.0.1:
|
||||
dependencies:
|
||||
depd: 2.0.0
|
||||
inherits: 2.0.4
|
||||
setprototypeof: 1.2.0
|
||||
statuses: 2.0.2
|
||||
toidentifier: 1.0.1
|
||||
|
||||
http-proxy-agent@7.0.2:
|
||||
dependencies:
|
||||
agent-base: 7.1.4
|
||||
@@ -14774,6 +15088,10 @@ snapshots:
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
|
||||
iconv-lite@0.7.2:
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
|
||||
ieee754@1.2.1: {}
|
||||
|
||||
ignore@5.3.2: {}
|
||||
@@ -14877,6 +15195,10 @@ snapshots:
|
||||
|
||||
ip-address@10.0.1: {}
|
||||
|
||||
ip-address@10.1.0: {}
|
||||
|
||||
ipaddr.js@1.9.1: {}
|
||||
|
||||
iron-webcrypto@1.2.1: {}
|
||||
|
||||
is-absolute-url@4.0.1: {}
|
||||
@@ -14996,6 +15318,8 @@ snapshots:
|
||||
|
||||
is-plain-object@5.0.0: {}
|
||||
|
||||
is-promise@4.0.0: {}
|
||||
|
||||
is-regex@1.2.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
@@ -15553,8 +15877,12 @@ snapshots:
|
||||
|
||||
media-typer@0.3.0: {}
|
||||
|
||||
media-typer@1.1.0: {}
|
||||
|
||||
memoize-one@5.2.1: {}
|
||||
|
||||
merge-descriptors@2.0.0: {}
|
||||
|
||||
merge-stream@2.0.0: {}
|
||||
|
||||
merge2@1.4.1: {}
|
||||
@@ -16058,6 +16386,8 @@ snapshots:
|
||||
|
||||
negotiator@0.6.3: {}
|
||||
|
||||
negotiator@1.0.0: {}
|
||||
|
||||
neo-async@2.6.2: {}
|
||||
|
||||
netmask@2.0.2: {}
|
||||
@@ -16224,6 +16554,10 @@ snapshots:
|
||||
|
||||
on-exit-leak-free@2.1.2: {}
|
||||
|
||||
on-finished@2.4.1:
|
||||
dependencies:
|
||||
ee-first: 1.1.1
|
||||
|
||||
once@1.4.0:
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
@@ -16376,6 +16710,8 @@ snapshots:
|
||||
leac: 0.6.0
|
||||
peberminta: 0.9.0
|
||||
|
||||
parseurl@1.3.3: {}
|
||||
|
||||
pascal-case@2.0.1:
|
||||
dependencies:
|
||||
camel-case: 3.0.0
|
||||
@@ -16408,6 +16744,8 @@ snapshots:
|
||||
lru-cache: 11.2.4
|
||||
minipass: 7.1.2
|
||||
|
||||
path-to-regexp@8.4.2: {}
|
||||
|
||||
path-type@4.0.0: {}
|
||||
|
||||
pathe@2.0.3: {}
|
||||
@@ -16503,6 +16841,8 @@ snapshots:
|
||||
|
||||
pirates@4.0.7: {}
|
||||
|
||||
pkce-challenge@5.0.1: {}
|
||||
|
||||
pkg-types@2.3.0:
|
||||
dependencies:
|
||||
confbox: 0.2.2
|
||||
@@ -16726,6 +17066,11 @@ snapshots:
|
||||
prosemirror-state: 1.4.3
|
||||
prosemirror-transform: 1.10.4
|
||||
|
||||
proxy-addr@2.0.7:
|
||||
dependencies:
|
||||
forwarded: 0.2.0
|
||||
ipaddr.js: 1.9.1
|
||||
|
||||
proxy-agent@6.5.0:
|
||||
dependencies:
|
||||
agent-base: 7.1.4
|
||||
@@ -16758,6 +17103,10 @@ snapshots:
|
||||
dependencies:
|
||||
side-channel: 1.1.0
|
||||
|
||||
qs@6.15.1:
|
||||
dependencies:
|
||||
side-channel: 1.1.0
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
quick-format-unescaped@4.0.4: {}
|
||||
@@ -16770,6 +17119,8 @@ snapshots:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
range-parser@1.2.1: {}
|
||||
|
||||
rate-limiter-flexible@9.0.1: {}
|
||||
|
||||
raw-body@2.5.2:
|
||||
@@ -16779,6 +17130,13 @@ snapshots:
|
||||
iconv-lite: 0.4.24
|
||||
unpipe: 1.0.0
|
||||
|
||||
raw-body@3.0.2:
|
||||
dependencies:
|
||||
bytes: 3.1.2
|
||||
http-errors: 2.0.1
|
||||
iconv-lite: 0.7.2
|
||||
unpipe: 1.0.0
|
||||
|
||||
rc@1.2.8:
|
||||
dependencies:
|
||||
deep-extend: 0.6.0
|
||||
@@ -17129,6 +17487,16 @@ snapshots:
|
||||
|
||||
rou3@0.7.11: {}
|
||||
|
||||
router@2.2.0:
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
depd: 2.0.0
|
||||
is-promise: 4.0.0
|
||||
parseurl: 1.3.3
|
||||
path-to-regexp: 8.4.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
run-async@2.4.1: {}
|
||||
|
||||
run-async@3.0.0: {}
|
||||
@@ -17206,6 +17574,22 @@ snapshots:
|
||||
|
||||
semver@7.7.3: {}
|
||||
|
||||
send@1.2.1:
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
encodeurl: 2.0.0
|
||||
escape-html: 1.0.3
|
||||
etag: 1.8.1
|
||||
fresh: 2.0.0
|
||||
http-errors: 2.0.1
|
||||
mime-types: 3.0.2
|
||||
ms: 2.1.3
|
||||
on-finished: 2.4.1
|
||||
range-parser: 1.2.1
|
||||
statuses: 2.0.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
sentence-case@2.1.1:
|
||||
dependencies:
|
||||
no-case: 2.3.2
|
||||
@@ -17215,6 +17599,15 @@ snapshots:
|
||||
dependencies:
|
||||
randombytes: 2.1.0
|
||||
|
||||
serve-static@2.2.1:
|
||||
dependencies:
|
||||
encodeurl: 2.0.0
|
||||
escape-html: 1.0.3
|
||||
parseurl: 1.3.3
|
||||
send: 1.2.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
set-cookie-parser@2.7.2: {}
|
||||
|
||||
set-function-length@1.2.2:
|
||||
@@ -17436,6 +17829,8 @@ snapshots:
|
||||
|
||||
statuses@2.0.1: {}
|
||||
|
||||
statuses@2.0.2: {}
|
||||
|
||||
std-env@3.10.0: {}
|
||||
|
||||
stdin-discarder@0.1.0:
|
||||
@@ -17901,6 +18296,12 @@ snapshots:
|
||||
media-typer: 0.3.0
|
||||
mime-types: 2.1.35
|
||||
|
||||
type-is@2.0.1:
|
||||
dependencies:
|
||||
content-type: 1.0.5
|
||||
media-typer: 1.1.0
|
||||
mime-types: 3.0.2
|
||||
|
||||
typed-array-buffer@1.0.3:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
@@ -18478,6 +18879,10 @@ snapshots:
|
||||
dependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
zod-to-json-schema@3.25.2(zod@3.25.76):
|
||||
dependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
zod@3.25.76: {}
|
||||
|
||||
zod@4.1.13: {}
|
||||
|
||||
43
turbo.json
43
turbo.json
@@ -3,28 +3,49 @@
|
||||
"ui": "tui",
|
||||
"tasks": {
|
||||
"topo": {
|
||||
"dependsOn": ["^topo"]
|
||||
"dependsOn": [
|
||||
"^topo"
|
||||
]
|
||||
},
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [".cache/tsbuildinfo.json", "dist/**"]
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
".cache/tsbuildinfo.json",
|
||||
"dist/**"
|
||||
]
|
||||
},
|
||||
"dev": {
|
||||
"dependsOn": ["^dev"],
|
||||
"dependsOn": [
|
||||
"^dev"
|
||||
],
|
||||
"cache": false,
|
||||
"persistent": false
|
||||
},
|
||||
"format": {
|
||||
"outputs": [".cache/.prettiercache"],
|
||||
"outputs": [
|
||||
".cache/.prettiercache"
|
||||
],
|
||||
"outputLogs": "new-only"
|
||||
},
|
||||
"lint": {
|
||||
"dependsOn": ["^topo", "^build"],
|
||||
"outputs": [".cache/.eslintcache"]
|
||||
"dependsOn": [
|
||||
"^topo",
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
".cache/.eslintcache"
|
||||
]
|
||||
},
|
||||
"typecheck": {
|
||||
"dependsOn": ["^topo", "^build"],
|
||||
"outputs": [".cache/tsbuildinfo.json"]
|
||||
"dependsOn": [
|
||||
"^topo",
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
".cache/tsbuildinfo.json"
|
||||
]
|
||||
},
|
||||
"clean": {
|
||||
"cache": false
|
||||
@@ -132,7 +153,9 @@
|
||||
"REDIS_URL",
|
||||
"LOG_LEVEL",
|
||||
"AXIOM_TOKEN",
|
||||
"AXIOM_DATASET"
|
||||
"AXIOM_DATASET",
|
||||
"KAN_BASE_URL",
|
||||
"KAN_API_TOKEN"
|
||||
],
|
||||
"globalPassThroughEnv": [
|
||||
"NODE_ENV",
|
||||
|
||||
Reference in New Issue
Block a user