-
Notifications
You must be signed in to change notification settings - Fork 196
@W-19624822 feat: eliminate the extra parameters exposed through create_page tool #3359
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: develop
Are you sure you want to change the base?
Changes from 9 commits
b78c74e
d2edfad
0496568
a1f78f6
39444b8
99c06d6
ef10577
6a71a6d
967fbbf
da37b42
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 |
---|---|---|
|
@@ -14,7 +14,8 @@ import { | |
isLocalSharedUIComponent, | ||
isBaseComponent, | ||
isSharedUIBaseComponent, | ||
generateComponentImportStatement | ||
generateComponentImportStatement, | ||
detectWorkspacePaths | ||
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. @wei-liu-sf yes - it is an internal util function |
||
} from '../utils' | ||
import {z} from 'zod' | ||
|
||
|
@@ -25,11 +26,6 @@ const systemPromptForCreatePage = `You are a smart assistant that can use tools | |
- What is the name of the new page to create? \ | ||
- List the components to include on the page, separated by commas. Component names should be in PascalCase (e.g., Image, ProductView) \ | ||
- What is the URL route for this page? (e.g., /new-home, /my-products) \ | ||
- What is the absolute path to your node_modules directory? \ | ||
- What is the absolute path to your components directory? \ | ||
- What is the absolute path to your pages directory? \ | ||
- What is the absolute path to your routes.jsx file? \ | ||
- Is ccExtensibility.overridesDir set in your package.json? (true/false) \ | ||
Collect answers to these questions, then call the tool with the collected information as input parameters.` | ||
|
||
const systemPromptForProductHook = `User has added the ProductView component to the new page. Please ask user: \ | ||
|
@@ -83,42 +79,36 @@ class CreateNewPageTool { | |
), | ||
route: z | ||
.string() | ||
.describe('The URL route for this page (e.g., /new-home, /my-product-view)'), | ||
nodeModulesPath: z.string().describe('The absolute path to the node_modules directory'), | ||
componentsPath: z.string().describe('The absolute path to the components directory'), | ||
pagesPath: z.string().describe('The absolute path to the pages directory'), | ||
routesPath: z.string().describe('The absolute path to the routes.jsx file'), | ||
hasOverridesDir: z | ||
.boolean() | ||
.describe('Whether ccExtensibility.overridesDir is set in package.json') | ||
.describe('The URL route for this page (e.g., /new-home, /my-product-view)') | ||
} | ||
this.unfoundComponents = [] | ||
|
||
this.handler = async (args) => { | ||
logMCPMessage(`------- Calling CreateNewPageTool handler`) | ||
if ( | ||
!args || | ||
!args.pageName || | ||
!args.componentList || | ||
!args.route || | ||
!args.nodeModulesPath || | ||
!args.componentsPath || | ||
!args.pagesPath || | ||
!args.routesPath || | ||
args.hasOverridesDir === undefined | ||
) { | ||
if (!args || !args.pageName || !args.componentList || !args.route) { | ||
return { | ||
role: 'system', | ||
content: [{type: 'text', text: systemPromptForCreatePage}] | ||
} | ||
} | ||
return this.createPage(args.pageName, args.componentList, args.route, { | ||
nodeModulesPath: args.nodeModulesPath, | ||
componentsPath: args.componentsPath, | ||
pagesPath: args.pagesPath, | ||
routesPath: args.routesPath, | ||
hasOverridesDir: args.hasOverridesDir | ||
}) | ||
|
||
try { | ||
const absolutePaths = await detectWorkspacePaths() | ||
logMCPMessage(`Detected workspace paths: ${JSON.stringify(absolutePaths)}`) | ||
|
||
return this.createPage(args.pageName, args.componentList, args.route, absolutePaths) | ||
} catch (error) { | ||
logMCPMessage(`Error detecting workspace paths: ${error.message}`) | ||
return { | ||
role: 'developer', | ||
content: [ | ||
{ | ||
type: 'text', | ||
text: `Error detecting workspace configuration: ${error.message}` | ||
} | ||
] | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -186,6 +186,58 @@ export async function logMCPMessage(message) { | |
} | ||
} | ||
|
||
/** | ||
* Detects workspace paths based on current working directory | ||
* @returns {Object} containing detected absolute paths & configuration | ||
*/ | ||
export async function detectWorkspacePaths() { | ||
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. Can we use cwd first? Most likely it will work. 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. Try to figure out project directory from: 1. cwd, 2. from env 3. prompt user 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. got it, thx |
||
// Use PWA_STOREFRONT_APP_PATH (always provided by MCP configuration) | ||
const appPath = process.env.PWA_STOREFRONT_APP_PATH | ||
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. How to make sure that this will always be set 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. |
||
|
||
if (!appPath) { | ||
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. @snilakandan13 the error is thrown in case when the env variable is not set. However if not set, the server starts successfully, but the tool call fails. As discussed maybe we should not let the server start at all if this is not set. |
||
throw new Error( | ||
'PWA_STOREFRONT_APP_PATH environment variable is not set. Please check your MCP configuration.' | ||
) | ||
} | ||
|
||
// Verify the provided app path exists | ||
try { | ||
await fsPromises.access(appPath) | ||
} catch (error) { | ||
throw new Error(`PWA_STOREFRONT_APP_PATH does not exist: ${appPath}`) | ||
} | ||
|
||
// Build paths relative to the provided app directory | ||
const pagesPath = path.join(appPath, 'pages') | ||
const componentsPath = path.join(appPath, 'components') | ||
const routesPath = path.join(appPath, 'routes.jsx') | ||
|
||
// Node modules is typically one level up from the app directory | ||
const nodeModulesPath = path.join(appPath, '..', 'node_modules') | ||
|
||
// Check if overrides directory exists (for ccExtensibility.overridesDir) | ||
const hasOverridesDir = fs.existsSync(path.join(appPath, '..', 'overrides')) | ||
|
||
// Verify essential directories exist | ||
if (!fs.existsSync(pagesPath)) { | ||
throw new Error(`Pages directory not found at: ${pagesPath}`) | ||
} | ||
if (!fs.existsSync(componentsPath)) { | ||
throw new Error(`Components directory not found at: ${componentsPath}`) | ||
} | ||
if (!fs.existsSync(routesPath)) { | ||
throw new Error(`Routes file not found at: ${routesPath}`) | ||
} | ||
|
||
return { | ||
pagesPath, | ||
componentsPath, | ||
routesPath, | ||
nodeModulesPath, | ||
hasOverridesDir | ||
} | ||
} | ||
|
||
/** | ||
* Returns the import statement for a component | ||
* @param {string} componentName - The name of the component to import. | ||
|
Uh oh!
There was an error while loading. Please reload this page.