-
Notifications
You must be signed in to change notification settings - Fork 8
feat(js-plugins): 🎸 add mcp plugin #131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Farm + React | ||
|
|
||
| This template should help you start developing using React and TypeScript in Farm. | ||
|
|
||
| ## Setup | ||
|
|
||
| Install the dependencies: | ||
|
|
||
| ```bash | ||
| pnpm install | ||
| ``` | ||
|
|
||
| ## Get Started | ||
|
|
||
| Start the dev server: | ||
|
|
||
| ```bash | ||
| pnpm start | ||
| ``` | ||
|
|
||
| Build the app for production: | ||
|
|
||
| ```bash | ||
| pnpm build | ||
| ``` | ||
|
|
||
| Preview the Production build product: | ||
|
|
||
| ```bash | ||
| pnpm preview | ||
| ``` | ||
|
|
||
| Clear persistent cache local files | ||
|
|
||
| ```bash | ||
| pnpm clean | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { defineConfig } from "@farmfe/core"; | ||
| import farmPluginMcp from "@farmfe/plugin-mcp" | ||
|
|
||
| export default defineConfig({ | ||
| compilation: { | ||
| input: { | ||
| index: "./index.html", | ||
| }, | ||
| persistentCache: false, | ||
| progress: false, | ||
| }, | ||
| plugins: [ | ||
| ["@farmfe/plugin-react", { runtime: "automatic" }], | ||
| farmPluginMcp({}) | ||
| ], | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <link rel="icon" type="image/svg+xml" href="/favicon.ico" /> | ||
| <title>Farm + React + TS</title> | ||
| </head> | ||
| <body> | ||
| <div id="root"></div> | ||
| <script src="./src/index.tsx"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| console.log("lib") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| { | ||
| "name": "playground", | ||
| "version": "1.0.0", | ||
| "type": "module", | ||
| "scripts": { | ||
| "dev": "farm start", | ||
| "start": "farm start", | ||
| "build": "farm build", | ||
| "preview": "farm preview", | ||
| "clean": "farm clean" | ||
| }, | ||
| "dependencies": { | ||
| "clsx": "^1.2.1", | ||
| "react": "18", | ||
| "react-dom": "18", | ||
| "@farmfe/plugin-mcp": "workspace:*" | ||
| }, | ||
| "devDependencies": { | ||
| "@farmfe/cli": "^1.0.0", | ||
| "@farmfe/core": "^1.0.22", | ||
| "@farmfe/plugin-react": "^1.0.1", | ||
| "@types/react": "18", | ||
| "core-js": "^3.36.1", | ||
| "@types/react-dom": "18", | ||
| "react-refresh": "^0.14.0" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| :root { | ||
| font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; | ||
| line-height: 1.5; | ||
| font-weight: 400; | ||
|
|
||
| color-scheme: light dark; | ||
| color: rgba(255, 255, 255, 0.87); | ||
| background-color: #242424; | ||
|
|
||
| font-synthesis: none; | ||
| text-rendering: optimizeLegibility; | ||
| -webkit-font-smoothing: antialiased; | ||
| -moz-osx-font-smoothing: grayscale; | ||
| -webkit-text-size-adjust: 100%; | ||
| } | ||
|
|
||
| a { | ||
| font-weight: 500; | ||
| color: #9f1a8f; | ||
| text-decoration: inherit; | ||
| } | ||
| a:hover { | ||
| color: #9f1a8f; | ||
| } | ||
|
|
||
| body { | ||
| margin: 0; | ||
| display: flex; | ||
| place-items: center; | ||
| min-width: 320px; | ||
| min-height: 100vh; | ||
| } | ||
|
|
||
| h1 { | ||
| font-size: 3.2em; | ||
| line-height: 1.1; | ||
| } | ||
|
|
||
| button { | ||
| border-radius: 8px; | ||
| border: 1px solid transparent; | ||
| padding: 0.6em 1.2em; | ||
| font-size: 1em; | ||
| font-weight: 500; | ||
| font-family: inherit; | ||
| background-color: #1a1a1a; | ||
| cursor: pointer; | ||
| transition: border-color 0.25s; | ||
| } | ||
| button:hover { | ||
| border-color: #9f1a8f; | ||
| } | ||
| button:focus, | ||
| button:focus-visible { | ||
| outline: 4px auto -webkit-focus-ring-color; | ||
| } | ||
|
|
||
| @media (prefers-color-scheme: light) { | ||
| :root { | ||
| color: #213547; | ||
| background-color: #ffffff; | ||
| } | ||
| a:hover { | ||
| color: #9F1A8F; | ||
| } | ||
| button { | ||
| background-color: #f9f9f9; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import React from 'react'; | ||
| import { createRoot } from 'react-dom/client'; | ||
| import { Main } from './main'; | ||
| import './index.css' | ||
|
|
||
|
|
||
| const container = document.querySelector('#root'); | ||
| const root = createRoot(container); | ||
|
|
||
| root.render(<Main />); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| #root { | ||
| max-width: 1280px; | ||
| margin: 0 auto; | ||
| padding: 2rem; | ||
| text-align: center; | ||
| } | ||
|
|
||
| .logo { | ||
| height: 6em; | ||
| padding: 1.5em; | ||
| will-change: filter; | ||
| transition: filter 300ms; | ||
| } | ||
| .logo:hover { | ||
| filter: drop-shadow(0 0 2em #9F1A8Faa); | ||
| } | ||
| .logo.react:hover { | ||
| filter: drop-shadow(0 0 2em #61dafbaa); | ||
| } | ||
|
|
||
| @keyframes logo-spin { | ||
| from { | ||
| transform: rotate(0deg); | ||
| } | ||
| to { | ||
| transform: rotate(360deg); | ||
| } | ||
| } | ||
|
|
||
| @media (prefers-reduced-motion: no-preference) { | ||
| a:nth-of-type(2) .logo { | ||
| animation: logo-spin infinite 20s linear; | ||
| } | ||
| } | ||
|
|
||
| .card { | ||
| padding: 2em; | ||
| } | ||
|
|
||
| .read-the-docs { | ||
| color: #888; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,32 @@ | ||||||||||||||||||||||||||
| import React, { useState } from "react"; | ||||||||||||||||||||||||||
| import "./main.css"; | ||||||||||||||||||||||||||
| import reactLogo from "./assets/react.svg"; | ||||||||||||||||||||||||||
| import FarmLogo from "./assets/logo.png"; | ||||||||||||||||||||||||||
| export function Main() { | ||||||||||||||||||||||||||
| const [count, setCount] = useState(0); | ||||||||||||||||||||||||||
| console.log("rendering Main component") | ||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||
| <div> | ||||||||||||||||||||||||||
| <a href="https://farmfe.org/" target="_blank"> | ||||||||||||||||||||||||||
| <img src={FarmLogo} className="logo" alt="Farm logo" /> | ||||||||||||||||||||||||||
| </a> | ||||||||||||||||||||||||||
| <a href="https://react.dev" target="_blank"> | ||||||||||||||||||||||||||
| <img src={reactLogo} className="logo react" alt="React logo" /> | ||||||||||||||||||||||||||
| </a> | ||||||||||||||||||||||||||
|
Comment on lines
+11
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add Links using - <a href="https://farmfe.org/" target="_blank">
+ <a href="https://farmfe.org/" target="_blank" rel="noreferrer">
<img src={FarmLogo} className="logo" alt="Farm logo" />
</a>
- <a href="https://react.dev" target="_blank">
+ <a href="https://react.dev" target="_blank" rel="noreferrer">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (1.9.4)[error] 11-11: Avoid using target="_blank" without rel="noreferrer". Opening external links in new tabs without rel="noreferrer" is a security risk. See the explanation for more details. (lint/a11y/noBlankTarget) [error] 14-14: Avoid using target="_blank" without rel="noreferrer". Opening external links in new tabs without rel="noreferrer" is a security risk. See the explanation for more details. (lint/a11y/noBlankTarget) |
||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||
| <h1>Farm + React</h1> | ||||||||||||||||||||||||||
| <div className="card"> | ||||||||||||||||||||||||||
| <button onClick={() => setCount((count) => count + 1)}> | ||||||||||||||||||||||||||
| count is {count} | ||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||
|
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add explicit The default type of a button is "submit", which could cause unintended form submissions if the button is ever placed inside a form. Best practice is to always specify the button type explicitly. - <button onClick={() => setCount((count) => count + 1)}>
+ <button type="button" onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (1.9.4)[error] 20-20: Provide an explicit type prop for the button element. The default type of a button is submit, which causes the submission of a form when placed inside a (lint/a11y/useButtonType) |
||||||||||||||||||||||||||
| <p> | ||||||||||||||||||||||||||
| Edit <code>src/main.tsx</code> and save to test HMR | ||||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||
| <p className="read-the-docs"> | ||||||||||||||||||||||||||
| Click on the Farm and React logos to learn more | ||||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| declare module '*.svg'; | ||
| declare module '*.png'; | ||
| declare module '*.css'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "target": "ES2020", | ||
| "useDefineForClassFields": true, | ||
| "lib": ["ES2020", "DOM", "DOM.Iterable"], | ||
| "module": "ESNext", | ||
| "skipLibCheck": true, | ||
|
|
||
| /* Bundler mode */ | ||
| "moduleResolution": "bundler", | ||
| "allowImportingTsExtensions": true, | ||
| "resolveJsonModule": true, | ||
| "isolatedModules": true, | ||
| "noEmit": true, | ||
| "jsx": "react-jsx", | ||
|
|
||
| /* Linting */ | ||
| "strict": true, | ||
| "noUnusedLocals": true, | ||
| "noUnusedParameters": true, | ||
| "noFallthroughCasesInSwitch": true | ||
| }, | ||
| "include": ["src"], | ||
| "references": [{ "path": "./tsconfig.node.json" }] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "composite": true, | ||
| "skipLibCheck": true, | ||
| "module": "ESNext", | ||
| "moduleResolution": "bundler", | ||
| "allowSyntheticDefaultImports": true, | ||
| "strict": true | ||
| }, | ||
| "include": ["farm.config.ts"] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add null check for root element
There's no check to ensure the root element exists before creating the React root. This could cause runtime errors if the HTML doesn't contain an element with id 'root'.
📝 Committable suggestion