|
|
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
|
|
disableSilentMode
|
|
|
|
|
// isSilentMode // Not used directly here
|
|
|
|
|
} from '../../../../scripts/modules/utils.js';
|
|
|
|
|
import { getProjectRootFromSession } from '../../tools/utils.js'; // Adjust path if necessary
|
|
|
|
|
import os from 'os'; // Import os module for home directory check
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -16,60 +15,32 @@ import os from 'os'; // Import os module for home directory check
|
|
|
|
|
* @returns {Promise<{success: boolean, data?: any, error?: {code: string, message: string}}>} - Standard result object.
|
|
|
|
|
*/
|
|
|
|
|
export async function initializeProjectDirect(args, log, context = {}) {
|
|
|
|
|
const { session } = context;
|
|
|
|
|
const { session } = context; // Keep session if core logic needs it
|
|
|
|
|
const homeDir = os.homedir();
|
|
|
|
|
let targetDirectory = null;
|
|
|
|
|
|
|
|
|
|
log.info(
|
|
|
|
|
`CONTEXT received in direct function: ${context ? JSON.stringify(Object.keys(context)) : 'MISSING or Falsy'}`
|
|
|
|
|
);
|
|
|
|
|
log.info(
|
|
|
|
|
`SESSION extracted in direct function: ${session ? 'Exists' : 'MISSING or Falsy'}`
|
|
|
|
|
);
|
|
|
|
|
log.info(`Args received in direct function: ${JSON.stringify(args)}`);
|
|
|
|
|
|
|
|
|
|
// --- Determine Target Directory ---
|
|
|
|
|
// 1. Prioritize projectRoot passed directly in args
|
|
|
|
|
// Ensure it's not null, '/', or the home directory
|
|
|
|
|
if (
|
|
|
|
|
args.projectRoot &&
|
|
|
|
|
args.projectRoot !== '/' &&
|
|
|
|
|
args.projectRoot !== homeDir
|
|
|
|
|
) {
|
|
|
|
|
log.info(`Using projectRoot directly from args: ${args.projectRoot}`);
|
|
|
|
|
targetDirectory = args.projectRoot;
|
|
|
|
|
} else {
|
|
|
|
|
// 2. If args.projectRoot is missing or invalid, THEN try session (as a fallback)
|
|
|
|
|
log.warn(
|
|
|
|
|
`args.projectRoot ('${args.projectRoot}') is missing or invalid. Attempting to derive from session.`
|
|
|
|
|
);
|
|
|
|
|
const sessionDerivedPath = getProjectRootFromSession(session, log);
|
|
|
|
|
// Validate the session-derived path as well
|
|
|
|
|
if (
|
|
|
|
|
sessionDerivedPath &&
|
|
|
|
|
sessionDerivedPath !== '/' &&
|
|
|
|
|
sessionDerivedPath !== homeDir
|
|
|
|
|
) {
|
|
|
|
|
log.info(
|
|
|
|
|
`Using project root derived from session: ${sessionDerivedPath}`
|
|
|
|
|
);
|
|
|
|
|
targetDirectory = sessionDerivedPath;
|
|
|
|
|
} else {
|
|
|
|
|
log.error(
|
|
|
|
|
`Could not determine a valid project root. args.projectRoot='${args.projectRoot}', sessionDerivedPath='${sessionDerivedPath}'`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// TRUST the projectRoot passed from the tool layer via args
|
|
|
|
|
// The HOF in the tool layer already normalized and validated it came from a reliable source (args or session)
|
|
|
|
|
const targetDirectory = args.projectRoot;
|
|
|
|
|
|
|
|
|
|
// 3. Validate the final targetDirectory
|
|
|
|
|
if (!targetDirectory) {
|
|
|
|
|
// This error now covers cases where neither args.projectRoot nor session provided a valid path
|
|
|
|
|
// --- Validate the targetDirectory (basic sanity checks) ---
|
|
|
|
|
if (
|
|
|
|
|
!targetDirectory ||
|
|
|
|
|
typeof targetDirectory !== 'string' || // Ensure it's a string
|
|
|
|
|
targetDirectory === '/' ||
|
|
|
|
|
targetDirectory === homeDir
|
|
|
|
|
) {
|
|
|
|
|
log.error(
|
|
|
|
|
`Invalid target directory received from tool layer: '${targetDirectory}'`
|
|
|
|
|
);
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
error: {
|
|
|
|
|
code: 'INVALID_TARGET_DIRECTORY',
|
|
|
|
|
message: `Cannot initialize project: Could not determine a valid target directory. Please ensure a workspace/folder is open or specify projectRoot.`,
|
|
|
|
|
details: `Attempted args.projectRoot: ${args.projectRoot}`
|
|
|
|
|
message: `Cannot initialize project: Invalid target directory '${targetDirectory}' received. Please ensure a valid workspace/folder is open or specified.`,
|
|
|
|
|
details: `Received args.projectRoot: ${args.projectRoot}` // Show what was received
|
|
|
|
|
},
|
|
|
|
|
fromCache: false
|
|
|
|
|
};
|
|
|
|
|
@@ -86,11 +57,12 @@ export async function initializeProjectDirect(args, log, context = {}) {
|
|
|
|
|
log.info(
|
|
|
|
|
`Temporarily changing CWD to ${targetDirectory} for initialization.`
|
|
|
|
|
);
|
|
|
|
|
process.chdir(targetDirectory); // Change CWD to the *validated* targetDirectory
|
|
|
|
|
process.chdir(targetDirectory); // Change CWD to the HOF-provided root
|
|
|
|
|
|
|
|
|
|
enableSilentMode(); // Enable silent mode BEFORE calling the core function
|
|
|
|
|
enableSilentMode();
|
|
|
|
|
try {
|
|
|
|
|
// Always force yes: true when called via MCP to avoid interactive prompts
|
|
|
|
|
// Construct options ONLY from the relevant flags in args
|
|
|
|
|
// The core initializeProject operates in the current CWD, which we just set
|
|
|
|
|
const options = {
|
|
|
|
|
aliases: args.addAliases,
|
|
|
|
|
skipInstall: args.skipInstall,
|
|
|
|
|
@@ -100,12 +72,11 @@ export async function initializeProjectDirect(args, log, context = {}) {
|
|
|
|
|
log.info(`Initializing project with options: ${JSON.stringify(options)}`);
|
|
|
|
|
const result = await initializeProject(options); // Call core logic
|
|
|
|
|
|
|
|
|
|
// Format success result for handleApiResult
|
|
|
|
|
resultData = {
|
|
|
|
|
message: 'Project initialized successfully.',
|
|
|
|
|
next_step:
|
|
|
|
|
'Now that the project is initialized, the next step is to create the tasks by parsing a PRD. This will create the tasks folder and the initial task files (tasks folder will be created when parse-prd is run). The parse-prd tool will require a prd.txt file as input (typically found in the project root directory, scripts/ directory). You can create a prd.txt file by asking the user about their idea, and then using the scripts/example_prd.txt file as a template to genrate a prd.txt file in scripts/. You may skip all of this if the user already has a prd.txt file. You can THEN use the parse-prd tool to create the tasks. So: step 1 after initialization is to create a prd.txt file in scripts/prd.txt or confirm the user already has one. Step 2 is to use the parse-prd tool to create the tasks. Do not bother looking for tasks after initialization, just use the parse-prd tool to create the tasks after creating a prd.txt from which to parse the tasks. You do NOT need to reinitialize the project to parse-prd.',
|
|
|
|
|
...result // Include details returned by initializeProject
|
|
|
|
|
...result
|
|
|
|
|
};
|
|
|
|
|
success = true;
|
|
|
|
|
log.info(
|
|
|
|
|
@@ -120,12 +91,11 @@ export async function initializeProjectDirect(args, log, context = {}) {
|
|
|
|
|
};
|
|
|
|
|
success = false;
|
|
|
|
|
} finally {
|
|
|
|
|
disableSilentMode(); // ALWAYS disable silent mode in finally
|
|
|
|
|
disableSilentMode();
|
|
|
|
|
log.info(`Restoring original CWD: ${originalCwd}`);
|
|
|
|
|
process.chdir(originalCwd); // Change back to original CWD
|
|
|
|
|
process.chdir(originalCwd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return in format expected by handleApiResult
|
|
|
|
|
if (success) {
|
|
|
|
|
return { success: true, data: resultData, fromCache: false };
|
|
|
|
|
} else {
|