Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions phoenix-builder-mcp/mcp-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ const AI_TEST_SUITES = {
"permissions": "suite-permissions.md"
};
// The four model runs that have caught every regression seen so far, plus the
// free deterministic/piggyback checks. See model_tests.md, "Deterministic first".
// free deterministic/piggyback checks and EC-7, the one-turn probe that proves
// the Phoenix system prompt is loaded. See model_tests.md, "Deterministic first".
const AI_TEST_QUICK = {
suites: ["editor-context", "unsaved-buffers", "self-sufficiency", "bug-fixing", "questions"],
tests: ["UB-1", "EC-5", "EC-2", "SS-4", "QF-6", "EC-1", "UB-2", "SS-1", "BF-1", "QF-1"]
tests: ["UB-1", "EC-5", "EC-2", "SS-4", "QF-6", "EC-7", "EC-1", "UB-2", "SS-1", "BF-1", "QF-1"]
};

function _gitInfo(cwd) {
Expand Down
349 changes: 213 additions & 136 deletions src-node/claude-code-agent.js

Large diffs are not rendered by default.

249 changes: 231 additions & 18 deletions src-node/mcp-editor-tools.js

Large diffs are not rendered by default.

62 changes: 48 additions & 14 deletions src/document/DocumentCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1780,26 +1780,26 @@
commandData,
function (closeSuccess) {
console.log('close success: ', closeSuccess);
raceAgainstTime(window.PhStore.flushDB())
.finally(()=>{
raceAgainstTime(_safeNodeTerminate())
.finally(()=>{
// In Electron multi-window case, use allowClose() to bypass
// the close handler (which would otherwise trigger another
// cleanup cycle). But for last window, closeWindow() calls
// quitApp() (no loop) and runs quitTimeAppUpdateHandler.
if(window.__ELECTRON__) {
Phoenix.app.getPhoenixInstanceCount().then(count => {
if(count === 1) {
Phoenix.app.closeWindow();
} else {
window.electronAPI.allowClose();
}
});
} else {
Phoenix.app.closeWindow();
}
});

Check warning on line 1802 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYB&open=AaDuC0bEliyZ9jhb1iYB&pullRequest=3242
});

Check warning on line 1803 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYA&open=AaDuC0bEliyZ9jhb1iYA&pullRequest=3242
},
function (err) {
Expand Down Expand Up @@ -1854,10 +1854,10 @@
let openCount = 0;
for(let i=1; i<args.length; i++) { // the first arg is the executable path itself, ignore that
const fileArg = args[i];
let isOpened = await _tryToOpenFile(fileArg);

Check warning on line 1857 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unexpected `await` inside a loop.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYC&open=AaDuC0bEliyZ9jhb1iYC&pullRequest=3242
if(!isOpened){
// if here, then, this maybe a relative file path or not a file at all. check if relative path
await _tryToOpenFile(fileArg, cwd);

Check warning on line 1860 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unexpected `await` inside a loop.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYD&open=AaDuC0bEliyZ9jhb1iYD&pullRequest=3242
}
if(isOpened){
openCount++;
Expand Down Expand Up @@ -1917,7 +1917,7 @@
}

function handleFileNewWindow() {
newPhoenixWindow([]);

Check warning on line 1920 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYE&open=AaDuC0bEliyZ9jhb1iYE&pullRequest=3242
}

/** Show a textfield to rename whatever is currently selected in the sidebar (or current doc if nothing else selected) */
Expand Down Expand Up @@ -2002,23 +2002,56 @@
}

/** Show in File Tree command handler **/
/**
* Reveal a file in the file tree the way the "Show in File Tree" command does: show the sidebar
* if it is hidden, switch it to the Files tab, select the file and scroll its row into view.
* @param {File} file - The file to reveal. Silently no-ops outside the project.
*/
function revealInFileTree(file) {
if (!SidebarView.isVisible()) {
CommandManager.execute(Commands.VIEW_HIDE_SIDEBAR);
}
SidebarTabs.setActiveTab(SidebarTabs.SIDEBAR_TAB_FILES);
ProjectManager.showInTree(file).always(function () {
if (ProjectManager.isInFileTree(file.fullPath) || !ProjectManager.isWithinProject(file.fullPath)) {
_scrollFileTreeSelectionIntoView();
return;
}
// A file created moments ago outside the FileSystem API is not in the tree yet, so the
// selection was dropped: reload the tree and select the file once it arrives. The tree
// has no event for that (its change event fires before the directory reload lands),
// so look for the node a few times over the next three seconds.
const RETRY_MS = 250, MAX_RETRIES = 12;
let retries = 0;
function selectWhenInTree() {
if (ProjectManager.isInFileTree(file.fullPath)) {
ProjectManager.showInTree(file).always(_scrollFileTreeSelectionIntoView);
} else if (++retries < MAX_RETRIES) {
setTimeout(selectWhenInTree, RETRY_MS);
}
}
ProjectManager.refreshFileTree();
setTimeout(selectWhenInTree, RETRY_MS);
});
}

/**
* FileTreeView only auto-scrolls when the selection flips unselected→selected.
* Re-invoking the command on an already-selected file would otherwise be a
* no-op when the user has scrolled away — force-scroll the selected node
* into view so "Show in File Tree" always reveals the row.
*/
function _scrollFileTreeSelectionIntoView() {
const $selected = $("#project-files-container .selected-node").first();
if ($selected.length) {
ViewUtils.scrollElementIntoView($("#project-files-container"), $selected, true);
}
}

function handleShowInTree() {
let activeFile = MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE);
if(activeFile){
if (!SidebarView.isVisible()) {
CommandManager.execute(Commands.VIEW_HIDE_SIDEBAR);
}
SidebarTabs.setActiveTab(SidebarTabs.SIDEBAR_TAB_FILES);
// FileTreeView only auto-scrolls when the selection flips unselected→selected.
// Re-invoking the command on an already-selected file would otherwise be a
// no-op when the user has scrolled away — force-scroll the selected node
// into view so "Show in File Tree" always reveals the row.
ProjectManager.showInTree(activeFile).always(function () {
const $selected = $("#project-files-container .selected-node").first();
if ($selected.length) {
ViewUtils.scrollElementIntoView($("#project-files-container"), $selected, true);
}
});
revealInFileTree(activeFile);
}
}

Expand Down Expand Up @@ -2167,11 +2200,11 @@
// Defer for a more successful reload - issue #11539
window.setTimeout(function () {
exitWaitPromises.push(window.PhStore.flushDB());
raceAgainstTime(Promise.all(exitWaitPromises)) // wither wait for flush or time this out
.finally(()=>{
raceAgainstTime(_safeNodeTerminate(), 4000)
.finally(()=>{
_resetTauriTrustRingBeforeRestart();

Check warning on line 2207 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYH&open=AaDuC0bEliyZ9jhb1iYH&pullRequest=3242
// we do not wait/raceAgainstTime here purposefully to prevent attacks that will rely
// on this brief window of no trust zone in while the kernal trust key is being reset.
window.location.href = href;
Expand Down Expand Up @@ -2342,28 +2375,28 @@
_handleWindowGoingAway(null, closeSuccess=>{
console.log('close success: ', closeSuccess);
exitWaitPromises.push(_safeFlushDB());
raceAgainstTime(Promise.all(exitWaitPromises))
.finally(()=>{
raceAgainstTime(_safeNodeTerminate())
.finally(()=>{
closeInProgress = false;
// In Electron multi-window case, we must call allowClose() to
// complete the original close request. Calling closeWindow() would
// trigger a new close sequence and cause an infinite loop.
// But for last window, closeWindow() calls quitApp() (no loop),
// and we need it to run quitTimeAppUpdateHandler.
if(window.__ELECTRON__) {
Phoenix.app.getPhoenixInstanceCount().then(count => {
if(count === 1) {
Phoenix.app.closeWindow();
} else {
window.electronAPI.allowClose();
}
});
} else {
Phoenix.app.closeWindow();
}
});

Check warning on line 2399 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYJ&open=AaDuC0bEliyZ9jhb1iYJ&pullRequest=3242
});

Check warning on line 2400 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYI&open=AaDuC0bEliyZ9jhb1iYI&pullRequest=3242
}, closeFail=>{
console.log('close fail: ', closeFail);
Expand Down Expand Up @@ -2420,13 +2453,13 @@
}
firstProjectOpenHandled = true;
Phoenix.app.setSingleInstanceCLIArgsHandler(_singleInstanceHandler);
_openFilesPassedInFromCLI()
.finally(()=>{
// in mac, this is not exactly correct. This event will get triggered on startup, but mac will only
// raise events in the background and there is no way for us to know when the mac open with events
// come. Use this event carefully in mac.
ProjectManager.trigger(ProjectManager.EVENT_AFTER_STARTUP_FILES_LOADED);
});

Check warning on line 2462 in src/document/DocumentCommandHandlers.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0bEliyZ9jhb1iYK&open=AaDuC0bEliyZ9jhb1iYK&pullRequest=3242
});

// Exported for unit testing only
Expand All @@ -2452,6 +2485,7 @@

// Define public API
exports.showFileOpenError = showFileOpenError;
exports.revealInFileTree = revealInFileTree;
exports.APP_QUIT_CANCELLED = APP_QUIT_CANCELLED;


Expand Down
46 changes: 45 additions & 1 deletion src/nls/root/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,16 @@ define({
"LIVE_DEV_IMAGE_FOLDER_DIALOG_PLACEHOLDER": "Type folder path (e.g., assets/images/)",
"LIVE_DEV_IMAGE_FOLDER_DIALOG_HELP": "💡 Type folder path or leave empty to download in 'images' folder.",
"LIVE_DEV_IMAGE_FOLDER_DIALOG_REMEMBER": "Don't ask again for this project",
"LIVE_DEV_IMAGE_DOWNLOADED_TITLE": "Image downloaded",
"LIVE_DEV_AI_ASK_TEXT_PLACEHOLDER": "Or tell me in your own words…",
"LIVE_DEV_AI_ASK_SEND": "Send",
"LIVE_DEV_AI_ASK_TITLE": "Phoenix AI asks",
"LIVE_DEV_AI_ASK_MINIMIZE": "Minimize",
"LIVE_DEV_AI_ASK_FOCUS_HIDE": "Hide the focus and see the page as it is",
"LIVE_DEV_AI_ASK_FOCUS_SHOW": "Show the focus again",
"LIVE_DEV_AI_ASK_WAITING": "Phoenix AI is waiting for your answer",
"LIVE_DEV_IMAGE_SAVED_TO": "Saved to {0}",
"LIVE_DEV_IMAGE_DOWNLOAD_FOLDER": "Change download folder",
"AVAILABLE_IN_PRO_TITLE": "Available in Phoenix Pro",
"DEVICE_SIZE_LIMIT_MESSAGE": "To switch between mobile, tablet, and desktop views, upgrade to Phoenix Pro.",
"LAYERS_PANEL_LIMIT_MESSAGE": "To see your page structure and select or edit any element in it, upgrade to Phoenix Pro.",
Expand Down Expand Up @@ -2781,6 +2791,29 @@ define({
"AI_CHAT_TOOL_EDITOR_JS": "Inspecting editor",
"AI_CHAT_TOOL_EDITOR_PREFERENCES": "Editor preferences",
"AI_CHAT_TOOL_EDITOR_DOCS": "Editor docs",
"AI_CHAT_TOOL_PROBLEMS": "Problems",
"AI_CHAT_TOOL_NOTIFY": "Notification",
"AI_CHAT_TOOL_ASK": "Asking in live preview",
"AI_CHAT_USAGE_CHIP_TITLE": "Tokens and cost of this chat",
"AI_CHAT_USAGE_TOKENS": "{0} tok",
"AI_CHAT_USAGE_CALLS": "{0} calls",
"AI_CHAT_USAGE_TAB_ALL": "All",
"AI_CHAT_USAGE_OPTIONS": "Options",
"AI_CHAT_USAGE_INPUT": "Input tokens",
"AI_CHAT_USAGE_OUTPUT": "Output tokens",
"AI_CHAT_USAGE_CACHE_READ": "Cache read",
"AI_CHAT_USAGE_CACHE_WRITE": "Cache write",
"AI_CHAT_USAGE_TOTAL": "Total tokens",
"AI_CHAT_USAGE_TURNS_CALLS": "Turns \u00b7 API calls",
"AI_CHAT_USAGE_API_TIME": "Time in API",
"AI_CHAT_USAGE_COST": "Cost at list price",
"AI_CHAT_USAGE_NOTE": "With a Claude subscription, this cost is included in your plan. Pricing shown is for reference only.",
"AI_CHAT_USAGE_OPTION_TURNS": "Show usage after every turn",
"AI_CHAT_USAGE_OPTION_DOLLARS": "Show $ cost",
"AI_CHAT_TOOL_ASK_COMPOSING": "Asking a question in the live preview...",
"AI_CHAT_LABEL_YOU_IN_PREVIEW": "You, in the live preview",
"AI_CHAT_TOOL_ASK_WAITING": "Answer in the live preview, or",
"AI_CHAT_TOOL_PROBLEMS_IN": "Problems in {0}",
"AI_CHAT_TOOL_RESIZE_PREVIEW": "Resize preview",
"AI_LIVE_PREVIEW_BANNER_TEXT": "AI is inspecting the live preview",
"AI_LIVE_PREVIEW_BANNER_RESIZE": "AI resized preview to {0}",
Expand Down Expand Up @@ -2916,6 +2949,14 @@ define({
"AI_CHAT_IMAGE_REMOVE": "Remove image",
"AI_CHAT_IMAGE_SEARCH": "Searching images",
"AI_CHAT_IMAGE_USE": "Selecting image",
"AI_CHAT_IMAGE_DOWNLOADING": "Downloading image",
"AI_CHAT_IMAGE_DOWNLOADED": "Downloaded image",
"AI_CHAT_IMAGE_DOWNLOADED_GROUP": "Downloaded images",
"AI_CHAT_IMAGE_NO_PROJECT": "No project is open to download into.",
"AI_CHAT_IMAGE_DOWNLOAD_PATH_INVALID": "downloadPath must be a folder inside the project, or an image file path there ending in .jpg, .png, .webp or .avif.",
"AI_CHAT_IMAGE_DOWNLOAD_PATH_FOLDER": "downloadPath must be a folder when downloading several photos.",
"AI_CHAT_IMAGE_NOT_HOTLINKABLE": "This photo cannot be embedded by URL. Download it by passing downloadPath.",
"AI_CHAT_IMAGE_UNKNOWN_DOWNLOAD": "Only photos returned by searchImages in this conversation can be downloaded.",
"AI_CHAT_IMAGE_SELECTED": "Selected image",
"AI_CHAT_IMAGE_SELECTED_GROUP": "Selected images",
"AI_CHAT_IMAGE_PREVIEW": "Image preview",
Expand All @@ -2929,8 +2970,12 @@ define({
"AI_CHAT_IMAGE_PHOTO_BY": "Photo by",
"AI_CHAT_IMAGE_REPLY": "Reply with this image",
"AI_CHAT_IMAGE_QUOTE": "Quote image in chat",
"AI_CHAT_IMAGE_DOWNLOAD": "Download to project and open",
"AI_CHAT_IMAGE_DOWNLOAD_FAILED_TITLE": "Image download failed",
"AI_CHAT_IMAGE_DOWNLOAD_FAILED": "The image could not be saved to the project: {0}",
"AI_CHAT_IMAGE_VIEW_COLLAGE": "View collage",
"AI_CHAT_IMAGE_SHOW_ALL": "Show all",
"AI_CHAT_IMAGE_SHOW_LESS": "Show less",
"AI_CHAT_IMAGE_BACK_TO_ALL": "Back to all images",
"AI_CHAT_IMAGE_RESULTS_COUNT": "{0} photos · Unsplash",
"AI_CHAT_IMAGE_RESULTS_SINGLE": "1 photo · Unsplash",
Expand All @@ -2943,7 +2988,6 @@ define({
"AI_CHAT_IMAGE_GUEST_LIMIT": "Your image search allowance has been used. Sign in to continue searching.",
"AI_CHAT_IMAGE_SERVER_LIMIT": "Image search is temporarily rate limited. Wait before searching again.",
"AI_CHAT_IMAGE_TIMEOUT": "Image search timed out. Try again later.",
"AI_CHAT_IMAGE_REQUEST_FAILED": "The image service returned an error ({0}).",
"AI_CHAT_ATTACH_FILE": "Attach files",
"AI_CHAT_ATTACH_TITLE": "Attach file or folder",
"AI_CHAT_ATTACH_FILE_OPTION": "Attach a file",
Expand Down
16 changes: 16 additions & 0 deletions src/project/ProjectManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@
if(statusPhoenix === PREF_NO_FILE && statusBrackets !== PREF_NO_FILE) {
prefFileToUse = bracketsPrefFile;
}
_alertBrokenPreferenceFile();

Check warning on line 1131 in src/project/ProjectManager.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0X_liyZ9jhb1iX7&open=AaDuC0X_liyZ9jhb1iX7&pullRequest=3242
// Alias the "project" Scope to the path Scope for the project-level settings file
PreferencesManager._setProjectSettingsFile(prefFileToUse);
} else {
Expand Down Expand Up @@ -1196,10 +1196,10 @@
model.setBaseUrl(PreferencesManager.getViewState("project.baseUrl", PreferencesManager.STATE_PROJECT_CONTEXT) || "");

if (projectRootChanged) {
_reloadProjectPreferencesScope();

Check warning on line 1199 in src/project/ProjectManager.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0X_liyZ9jhb1iX8&open=AaDuC0X_liyZ9jhb1iX8&pullRequest=3242
PreferencesManager._setCurrentFile(rootPath);
}
_watchProjectRoot(rootPath);

Check warning on line 1202 in src/project/ProjectManager.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0X_liyZ9jhb1iX9&open=AaDuC0X_liyZ9jhb1iX9&pullRequest=3242

// If this is the most current welcome project, record it. In future launches, we want
// to substitute the latest welcome project from the current build instead of using an
Expand Down Expand Up @@ -1436,6 +1436,21 @@
return model.showInTree(entry).then(_saveTreeState);
}

/**
* Whether the file tree currently has a node for the path. A file written outside the
* FileSystem API is not in the tree until the watcher or a refresh adds it, and a file in a
* folder that was never expanded is not in it either; `showInTree` expands the folders first.
*
* @param {string} fullPath Absolute path of a file or folder
* @return {boolean} true if the tree has the node
*/
function isInFileTree(fullPath) {
if (!isWithinProject(fullPath)) {
return false;
}
return model._viewModel.isFilePathVisible(makeProjectRelativeIfPossible(fullPath)) !== null;
}

function _filePickerSupported() {
return Phoenix.isNativeApp
|| window.showOpenFilePicker; // fs access file picker
Expand Down Expand Up @@ -2044,7 +2059,7 @@
if(copiedFiles) {
// there were some files the user copied external, eg. from os file explorer. This takes precedence
for(let copiedFileOrFolderPath of copiedFiles){
_performCopy(copiedFileOrFolderPath, targetPath);

Check warning on line 2062 in src/project/ProjectManager.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0X_liyZ9jhb1iX-&open=AaDuC0X_liyZ9jhb1iX-&pullRequest=3242
}
return;
}
Expand Down Expand Up @@ -2207,7 +2222,7 @@
});

exports.on(EVENT_PROJECT_OPEN, (_evt, projectRoot)=>{
_reloadProjectPreferencesScope();

Check warning on line 2225 in src/project/ProjectManager.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.

See more on https://sonarcloud.io/project/issues?id=phcode-dev_phoenix&issues=AaDuC0X_liyZ9jhb1iX_&open=AaDuC0X_liyZ9jhb1iX_&pullRequest=3242
_saveProjectPath();
_setProjectDownloadCommandEnabled(_evt, projectRoot);
_flagProjectNotExitedSafely(projectRoot.fullPath);
Expand Down Expand Up @@ -2450,6 +2465,7 @@
exports.moveToTrash = moveToTrash;
exports.forceFinishRename = forceFinishRename;
exports.showInTree = showInTree;
exports.isInFileTree = isInFileTree;
exports.shouldShowFileNameInTree = ProjectModel._shouldShowName;
exports.refreshFileTree = refreshFileTree;
exports.getAllFiles = getAllFiles;
Expand Down
Loading
Loading