@avakit/mcp 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ server.registerTool(
|
|
|
41
41
|
"scaffold_app",
|
|
42
42
|
{
|
|
43
43
|
title: "Scaffold an Avalanche dapp",
|
|
44
|
-
description: "Create a new Avalanche dapp from a template (minimal, nft-mint, token-gated-app, erc20-token, icm-messenger, eerc-token). Wraps create-avalanche-app. Returns the created files and next steps.",
|
|
44
|
+
description: "Create a new Avalanche dapp from a template (minimal, nft-mint, token-gated-app, erc20-token, icm-messenger, eerc-token, l1-launch, token-bridge). Wraps create-avalanche-app. Returns the created files and next steps.",
|
|
45
45
|
inputSchema: {
|
|
46
46
|
name: z.string().describe("Project directory name, e.g. my-avax-app"),
|
|
47
47
|
template: z.enum([
|
|
@@ -50,7 +50,9 @@ server.registerTool(
|
|
|
50
50
|
"token-gated-app",
|
|
51
51
|
"erc20-token",
|
|
52
52
|
"icm-messenger",
|
|
53
|
-
"eerc-token"
|
|
53
|
+
"eerc-token",
|
|
54
|
+
"l1-launch",
|
|
55
|
+
"token-bridge"
|
|
54
56
|
]).default("minimal"),
|
|
55
57
|
chain: z.enum(["fuji", "c-chain"]).default("fuji"),
|
|
56
58
|
wallet: z.enum(["web3auth", "injected"]).default("web3auth"),
|
|
@@ -183,7 +185,7 @@ AvaKit is an open-source, AI-native Avalanche developer toolkit.
|
|
|
183
185
|
|
|
184
186
|
## Scaffolding
|
|
185
187
|
- \`scaffold_app\` (this MCP) or \`npm create avalanche-app@latest\`
|
|
186
|
-
- Templates: minimal, nft-mint, token-gated-app, erc20-token, icm-messenger, eerc-token
|
|
188
|
+
- Templates: minimal, nft-mint, token-gated-app, erc20-token, icm-messenger, eerc-token, l1-launch, token-bridge
|
|
187
189
|
- Each app ships shadcn/ui (black & white + dark/light), social-login wallet, and CLAUDE.md/llms.txt/.cursor rules.
|
|
188
190
|
|
|
189
191
|
## @avakit/react
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @avakit/mcp — AvaKit MCP server (stdio).\n *\n * Exposes Avalanche *actions* (not just docs) to AI coding agents:\n * • scaffold_app — create a dapp from a template (wraps create-avalanche-app)\n * • list_templates — available templates\n * • read_chain — balance / tx receipt / contract view\n * • deploy_contract — deploy compiled bytecode (testnet-first, mainnet needs confirm)\n * • get_context — AvaKit + Avalanche coding context\n *\n * See docs/09-spec-mcp.md. Guardrails: private keys only ever come from the\n * AVAKIT_DEPLOYER_KEY env var, are never logged, and mainnet deploys require\n * explicit confirmation.\n */\n\nimport { existsSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n type AvaChain,\n cChain,\n fuji,\n getBalance,\n getPublicClient,\n getTransactionReceipt,\n readContract,\n toViemChain,\n} from \"@avakit/core\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { listTemplates, scaffoldApp } from \"create-avalanche-app/api\";\nimport { type Abi, type Address, createWalletClient, type Hex, http } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { z } from \"zod\";\n\nfunction chainFrom(id: string | undefined): AvaChain {\n return id === \"c-chain\" ? cChain : fuji;\n}\n\nfunction toJson(value: unknown): string {\n return JSON.stringify(value, (_key, val) => (typeof val === \"bigint\" ? val.toString() : val), 2);\n}\n\nfunction text(body: string, isError = false) {\n return { content: [{ type: \"text\" as const, text: body }], isError };\n}\n\nconst server = new McpServer({ name: \"avakit-mcp\", version: \"0.1.0\" });\n\nserver.registerTool(\n \"list_templates\",\n {\n title: \"List templates\",\n description: \"List the Avalanche dapp templates available to scaffold_app.\",\n inputSchema: {},\n },\n async () => text(toJson(listTemplates())),\n);\n\nserver.registerTool(\n \"scaffold_app\",\n {\n title: \"Scaffold an Avalanche dapp\",\n description:\n \"Create a new Avalanche dapp from a template (minimal, nft-mint, token-gated-app, erc20-token, icm-messenger, eerc-token). Wraps create-avalanche-app. Returns the created files and next steps.\",\n inputSchema: {\n name: z.string().describe(\"Project directory name, e.g. my-avax-app\"),\n template: z\n .enum([\n \"minimal\",\n \"nft-mint\",\n \"token-gated-app\",\n \"erc20-token\",\n \"icm-messenger\",\n \"eerc-token\",\n ])\n .default(\"minimal\"),\n chain: z.enum([\"fuji\", \"c-chain\"]).default(\"fuji\"),\n wallet: z.enum([\"web3auth\", \"injected\"]).default(\"web3auth\"),\n directory: z.string().optional().describe(\"Parent directory (default: cwd)\"),\n local: z.boolean().optional().describe(\"Link @avakit/* via workspace (repo dev only)\"),\n },\n },\n async ({ name, template, chain, wallet, directory, local }) => {\n const parent = directory ? path.resolve(directory) : process.cwd();\n const targetDir = path.resolve(parent, name);\n if (existsSync(targetDir) && readdirSync(targetDir).length > 0) {\n return text(`Directory \"${targetDir}\" already exists and is not empty.`, true);\n }\n const { files } = await scaffoldApp({\n projectName: name,\n targetDir,\n template,\n chain,\n wallet,\n local,\n });\n const nextSteps = [\n `cd ${name}`,\n \"pnpm install\",\n ...(wallet === \"web3auth\" ? [\"cp .env.example .env.local # add Web3Auth client ID\"] : []),\n \"pnpm dev\",\n ];\n return text(toJson({ path: targetDir, filesCreated: files.length, files, nextSteps }));\n },\n);\n\nserver.registerTool(\n \"read_chain\",\n {\n title: \"Read Avalanche chain data\",\n description:\n \"Read a native AVAX balance, a transaction receipt, or a contract view/pure function over RPC.\",\n inputSchema: {\n action: z.enum([\"balance\", \"txReceipt\", \"contractRead\"]),\n chain: z.enum([\"fuji\", \"c-chain\"]).default(\"fuji\"),\n address: z.string().optional().describe(\"Address for balance / contractRead\"),\n hash: z.string().optional().describe(\"Tx hash for txReceipt\"),\n abi: z.array(z.any()).optional().describe(\"Contract ABI for contractRead\"),\n functionName: z.string().optional().describe(\"View function for contractRead\"),\n args: z.array(z.any()).optional(),\n },\n },\n async ({ action, chain, address, hash, abi, functionName, args }) => {\n const c = chainFrom(chain);\n try {\n if (action === \"balance\") {\n if (!address) return text(\"balance requires 'address'.\", true);\n const wei = await getBalance(address as Address, c);\n return text(toJson({ address, chain: c.name, wei, avax: (Number(wei) / 1e18).toString() }));\n }\n if (action === \"txReceipt\") {\n if (!hash) return text(\"txReceipt requires 'hash'.\", true);\n return text(toJson(await getTransactionReceipt(hash as Hex, c)));\n }\n if (!address || !abi || !functionName) {\n return text(\"contractRead requires 'address', 'abi', and 'functionName'.\", true);\n }\n const result = await readContract(c, {\n address: address as Address,\n abi: abi as Abi,\n functionName: functionName as never,\n args,\n });\n return text(toJson(result));\n } catch (e) {\n return text(`read_chain failed: ${e instanceof Error ? e.message : String(e)}`, true);\n }\n },\n);\n\nserver.registerTool(\n \"deploy_contract\",\n {\n title: \"Deploy a contract\",\n description:\n \"Deploy compiled bytecode to Avalanche using a deployer key from the AVAKIT_DEPLOYER_KEY env var. Fuji testnet by default; mainnet (c-chain) requires confirm:true.\",\n inputSchema: {\n abi: z.array(z.any()),\n bytecode: z.string().describe(\"Creation bytecode (0x-prefixed)\"),\n args: z.array(z.any()).optional(),\n chain: z.enum([\"fuji\", \"c-chain\"]).default(\"fuji\"),\n confirm: z.boolean().optional().describe(\"Required to deploy to mainnet\"),\n },\n },\n async ({ abi, bytecode, args, chain, confirm }) => {\n const c = chainFrom(chain);\n if (!c.testnet && !confirm) {\n return text(`Refusing to deploy to ${c.name} (mainnet) without confirm:true.`, true);\n }\n const key = process.env.AVAKIT_DEPLOYER_KEY;\n if (!key) {\n return text(\n \"No deployer key found. Set AVAKIT_DEPLOYER_KEY to a 0x private key (use a throwaway testnet key — never a key holding real funds).\",\n true,\n );\n }\n try {\n const account = privateKeyToAccount(key as Hex);\n const viemChain = toViemChain(c);\n const wallet = createWalletClient({ account, chain: viemChain, transport: http(c.rpcUrl) });\n const publicClient = getPublicClient(c);\n const bc = bytecode.startsWith(\"0x\") ? (bytecode as Hex) : (`0x${bytecode}` as Hex);\n const txHash = await wallet.deployContract({\n abi: abi as Abi,\n bytecode: bc,\n args,\n account,\n chain: viemChain,\n } as never);\n const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });\n if (!receipt.contractAddress) {\n return text(\"Deployment did not return a contract address.\", true);\n }\n return text(\n toJson({\n address: receipt.contractAddress,\n txHash,\n explorerUrl: `${c.explorerUrl}/address/${receipt.contractAddress}`,\n }),\n );\n } catch (e) {\n return text(`deploy failed: ${e instanceof Error ? e.message : String(e)}`, true);\n }\n },\n);\n\nconst AVAKIT_CONTEXT = `# AvaKit context\n\nAvaKit is an open-source, AI-native Avalanche developer toolkit.\n\n## Scaffolding\n- \\`scaffold_app\\` (this MCP) or \\`npm create avalanche-app@latest\\`\n- Templates: minimal, nft-mint, token-gated-app, erc20-token, icm-messenger, eerc-token\n- Each app ships shadcn/ui (black & white + dark/light), social-login wallet, and CLAUDE.md/llms.txt/.cursor rules.\n\n## @avakit/react\n- \\`<AvaKitProvider chains={[...]} adapters={[...]}>\\`, \\`<ConnectAvalanche />\\`\n- Hooks: useAvaAccount, useAvaChain, useBalance, useContract, useAvaDeploy, useAvaKit\n\n## @avakit/core\n- Chains: fuji, cChain, defineChain (from @avakit/core/chains)\n- Adapters: injectedAdapter(), web3authAdapter({ clientId }) (from @avakit/core/web3auth)\n- getPublicClient, getWalletClient, ensureChain, deployContract, getBalance, readContract\n\n## Conventions\n- UI: shadcn/ui only. Black & white until brand colors are added; dark/light from day one.\n- Chains: Fuji testnet by default; mainnet is explicit opt-in.\n- Secrets: never in code. Web3Auth client ID (free) in NEXT_PUBLIC_WEB3AUTH_CLIENT_ID.\n\n## Docs\n- Avalanche Builder Hub: https://build.avax.network/llms.txt\n- Web3Auth dashboard: https://dashboard.web3auth.io\n- Fuji faucet: https://core.app/tools/testnet-faucet`;\n\nserver.registerTool(\n \"get_context\",\n {\n title: \"Get AvaKit context\",\n description:\n \"Return AvaKit + Avalanche context for coding: the API surface, conventions, and doc links.\",\n inputSchema: { topic: z.string().optional().describe(\"Optional focus topic\") },\n },\n async ({ topic }) =>\n text(topic ? `${AVAKIT_CONTEXT}\\n\\n(Requested focus: ${topic})` : AVAKIT_CONTEXT),\n);\n\nasync function main(): Promise<void> {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n process.stderr.write(\"avakit-mcp running on stdio\\n\");\n}\n\nmain().catch((error: unknown) => {\n process.stderr.write(`avakit-mcp fatal: ${String(error)}\\n`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @avakit/mcp — AvaKit MCP server (stdio).\n *\n * Exposes Avalanche *actions* (not just docs) to AI coding agents:\n * • scaffold_app — create a dapp from a template (wraps create-avalanche-app)\n * • list_templates — available templates\n * • read_chain — balance / tx receipt / contract view\n * • deploy_contract — deploy compiled bytecode (testnet-first, mainnet needs confirm)\n * • get_context — AvaKit + Avalanche coding context\n *\n * See docs/09-spec-mcp.md. Guardrails: private keys only ever come from the\n * AVAKIT_DEPLOYER_KEY env var, are never logged, and mainnet deploys require\n * explicit confirmation.\n */\n\nimport { existsSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n type AvaChain,\n cChain,\n fuji,\n getBalance,\n getPublicClient,\n getTransactionReceipt,\n readContract,\n toViemChain,\n} from \"@avakit/core\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { listTemplates, scaffoldApp } from \"create-avalanche-app/api\";\nimport { type Abi, type Address, createWalletClient, type Hex, http } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { z } from \"zod\";\n\nfunction chainFrom(id: string | undefined): AvaChain {\n return id === \"c-chain\" ? cChain : fuji;\n}\n\nfunction toJson(value: unknown): string {\n return JSON.stringify(value, (_key, val) => (typeof val === \"bigint\" ? val.toString() : val), 2);\n}\n\nfunction text(body: string, isError = false) {\n return { content: [{ type: \"text\" as const, text: body }], isError };\n}\n\nconst server = new McpServer({ name: \"avakit-mcp\", version: \"0.1.0\" });\n\nserver.registerTool(\n \"list_templates\",\n {\n title: \"List templates\",\n description: \"List the Avalanche dapp templates available to scaffold_app.\",\n inputSchema: {},\n },\n async () => text(toJson(listTemplates())),\n);\n\nserver.registerTool(\n \"scaffold_app\",\n {\n title: \"Scaffold an Avalanche dapp\",\n description:\n \"Create a new Avalanche dapp from a template (minimal, nft-mint, token-gated-app, erc20-token, icm-messenger, eerc-token, l1-launch, token-bridge). Wraps create-avalanche-app. Returns the created files and next steps.\",\n inputSchema: {\n name: z.string().describe(\"Project directory name, e.g. my-avax-app\"),\n template: z\n .enum([\n \"minimal\",\n \"nft-mint\",\n \"token-gated-app\",\n \"erc20-token\",\n \"icm-messenger\",\n \"eerc-token\",\n \"l1-launch\",\n \"token-bridge\",\n ])\n .default(\"minimal\"),\n chain: z.enum([\"fuji\", \"c-chain\"]).default(\"fuji\"),\n wallet: z.enum([\"web3auth\", \"injected\"]).default(\"web3auth\"),\n directory: z.string().optional().describe(\"Parent directory (default: cwd)\"),\n local: z.boolean().optional().describe(\"Link @avakit/* via workspace (repo dev only)\"),\n },\n },\n async ({ name, template, chain, wallet, directory, local }) => {\n const parent = directory ? path.resolve(directory) : process.cwd();\n const targetDir = path.resolve(parent, name);\n if (existsSync(targetDir) && readdirSync(targetDir).length > 0) {\n return text(`Directory \"${targetDir}\" already exists and is not empty.`, true);\n }\n const { files } = await scaffoldApp({\n projectName: name,\n targetDir,\n template,\n chain,\n wallet,\n local,\n });\n const nextSteps = [\n `cd ${name}`,\n \"pnpm install\",\n ...(wallet === \"web3auth\" ? [\"cp .env.example .env.local # add Web3Auth client ID\"] : []),\n \"pnpm dev\",\n ];\n return text(toJson({ path: targetDir, filesCreated: files.length, files, nextSteps }));\n },\n);\n\nserver.registerTool(\n \"read_chain\",\n {\n title: \"Read Avalanche chain data\",\n description:\n \"Read a native AVAX balance, a transaction receipt, or a contract view/pure function over RPC.\",\n inputSchema: {\n action: z.enum([\"balance\", \"txReceipt\", \"contractRead\"]),\n chain: z.enum([\"fuji\", \"c-chain\"]).default(\"fuji\"),\n address: z.string().optional().describe(\"Address for balance / contractRead\"),\n hash: z.string().optional().describe(\"Tx hash for txReceipt\"),\n abi: z.array(z.any()).optional().describe(\"Contract ABI for contractRead\"),\n functionName: z.string().optional().describe(\"View function for contractRead\"),\n args: z.array(z.any()).optional(),\n },\n },\n async ({ action, chain, address, hash, abi, functionName, args }) => {\n const c = chainFrom(chain);\n try {\n if (action === \"balance\") {\n if (!address) return text(\"balance requires 'address'.\", true);\n const wei = await getBalance(address as Address, c);\n return text(toJson({ address, chain: c.name, wei, avax: (Number(wei) / 1e18).toString() }));\n }\n if (action === \"txReceipt\") {\n if (!hash) return text(\"txReceipt requires 'hash'.\", true);\n return text(toJson(await getTransactionReceipt(hash as Hex, c)));\n }\n if (!address || !abi || !functionName) {\n return text(\"contractRead requires 'address', 'abi', and 'functionName'.\", true);\n }\n const result = await readContract(c, {\n address: address as Address,\n abi: abi as Abi,\n functionName: functionName as never,\n args,\n });\n return text(toJson(result));\n } catch (e) {\n return text(`read_chain failed: ${e instanceof Error ? e.message : String(e)}`, true);\n }\n },\n);\n\nserver.registerTool(\n \"deploy_contract\",\n {\n title: \"Deploy a contract\",\n description:\n \"Deploy compiled bytecode to Avalanche using a deployer key from the AVAKIT_DEPLOYER_KEY env var. Fuji testnet by default; mainnet (c-chain) requires confirm:true.\",\n inputSchema: {\n abi: z.array(z.any()),\n bytecode: z.string().describe(\"Creation bytecode (0x-prefixed)\"),\n args: z.array(z.any()).optional(),\n chain: z.enum([\"fuji\", \"c-chain\"]).default(\"fuji\"),\n confirm: z.boolean().optional().describe(\"Required to deploy to mainnet\"),\n },\n },\n async ({ abi, bytecode, args, chain, confirm }) => {\n const c = chainFrom(chain);\n if (!c.testnet && !confirm) {\n return text(`Refusing to deploy to ${c.name} (mainnet) without confirm:true.`, true);\n }\n const key = process.env.AVAKIT_DEPLOYER_KEY;\n if (!key) {\n return text(\n \"No deployer key found. Set AVAKIT_DEPLOYER_KEY to a 0x private key (use a throwaway testnet key — never a key holding real funds).\",\n true,\n );\n }\n try {\n const account = privateKeyToAccount(key as Hex);\n const viemChain = toViemChain(c);\n const wallet = createWalletClient({ account, chain: viemChain, transport: http(c.rpcUrl) });\n const publicClient = getPublicClient(c);\n const bc = bytecode.startsWith(\"0x\") ? (bytecode as Hex) : (`0x${bytecode}` as Hex);\n const txHash = await wallet.deployContract({\n abi: abi as Abi,\n bytecode: bc,\n args,\n account,\n chain: viemChain,\n } as never);\n const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });\n if (!receipt.contractAddress) {\n return text(\"Deployment did not return a contract address.\", true);\n }\n return text(\n toJson({\n address: receipt.contractAddress,\n txHash,\n explorerUrl: `${c.explorerUrl}/address/${receipt.contractAddress}`,\n }),\n );\n } catch (e) {\n return text(`deploy failed: ${e instanceof Error ? e.message : String(e)}`, true);\n }\n },\n);\n\nconst AVAKIT_CONTEXT = `# AvaKit context\n\nAvaKit is an open-source, AI-native Avalanche developer toolkit.\n\n## Scaffolding\n- \\`scaffold_app\\` (this MCP) or \\`npm create avalanche-app@latest\\`\n- Templates: minimal, nft-mint, token-gated-app, erc20-token, icm-messenger, eerc-token, l1-launch, token-bridge\n- Each app ships shadcn/ui (black & white + dark/light), social-login wallet, and CLAUDE.md/llms.txt/.cursor rules.\n\n## @avakit/react\n- \\`<AvaKitProvider chains={[...]} adapters={[...]}>\\`, \\`<ConnectAvalanche />\\`\n- Hooks: useAvaAccount, useAvaChain, useBalance, useContract, useAvaDeploy, useAvaKit\n\n## @avakit/core\n- Chains: fuji, cChain, defineChain (from @avakit/core/chains)\n- Adapters: injectedAdapter(), web3authAdapter({ clientId }) (from @avakit/core/web3auth)\n- getPublicClient, getWalletClient, ensureChain, deployContract, getBalance, readContract\n\n## Conventions\n- UI: shadcn/ui only. Black & white until brand colors are added; dark/light from day one.\n- Chains: Fuji testnet by default; mainnet is explicit opt-in.\n- Secrets: never in code. Web3Auth client ID (free) in NEXT_PUBLIC_WEB3AUTH_CLIENT_ID.\n\n## Docs\n- Avalanche Builder Hub: https://build.avax.network/llms.txt\n- Web3Auth dashboard: https://dashboard.web3auth.io\n- Fuji faucet: https://core.app/tools/testnet-faucet`;\n\nserver.registerTool(\n \"get_context\",\n {\n title: \"Get AvaKit context\",\n description:\n \"Return AvaKit + Avalanche context for coding: the API surface, conventions, and doc links.\",\n inputSchema: { topic: z.string().optional().describe(\"Optional focus topic\") },\n },\n async ({ topic }) =>\n text(topic ? `${AVAKIT_CONTEXT}\\n\\n(Requested focus: ${topic})` : AVAKIT_CONTEXT),\n);\n\nasync function main(): Promise<void> {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n process.stderr.write(\"avakit-mcp running on stdio\\n\");\n}\n\nmain().catch((error: unknown) => {\n process.stderr.write(`avakit-mcp fatal: ${String(error)}\\n`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avakit/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "AvaKit MCP server — scaffold, deploy, and read Avalanche from Claude Code / Cursor.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
18
18
|
"viem": "2.54.1",
|
|
19
19
|
"zod": "4.4.3",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
20
|
+
"@avakit/core": "0.1.2",
|
|
21
|
+
"create-avalanche-app": "0.1.6"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "26.0.1",
|