Skip to content

CLI: Add Sites list command - #1742

Merged
youknowriad merged 10 commits into
trunkfrom
add/list-sites-command
Sep 11, 2025
Merged

CLI: Add Sites list command#1742
youknowriad merged 10 commits into
trunkfrom
add/list-sites-command

Conversation

@youknowriad

Copy link
Copy Markdown
Contributor

Context about this PR pgle0O-QH-p2
See this branch for the full CLI.

Proposed Changes

This PR implements a very simple "list sites" command in the CLI tool. It's the first step towards a more capable and useful CLI tool.

Testing Instructions

  • Build the CLI tool npm run cli:build
  • Run the command node ./dist/cli/main.js sites list

It should list whatever sites you have in your Studio App in the terminal.

Example

Screenshot 2025-09-07 at 12 26 51 AM
@youknowriad
youknowriad requested review from bcotrim and sejas September 6, 2025 22:29
@youknowriad youknowriad self-assigned this Sep 6, 2025
@youknowriad

Copy link
Copy Markdown
Contributor Author

This is the smallest change possible. I'm considering defining a commont/types/sites.ts with the "Site" type and share it between CLI and App.

@bcotrim bcotrim left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for starting the CLI sites work @youknowriad
This is a solid starting point!

I would recommend focusing solely on appdata.sites and excluding newSites from this implementation.

newSites was created as a workaround for the CLI preview command to create sites, since the CLI lacked site management capabilities. Now that we're adding proper site management, we should update the preview command to use it and remove newSites entirely.

Comment thread cli/commands/sites/list.ts
Comment thread cli/index.ts Outdated
registerUpdateCommand( previewYargs );
previewYargs.demandCommand( 1, __( 'You must provide a valid command' ) );
} )
.command( 'sites', __( 'Manage local sites' ), ( sitesYargs ) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should put these commands behind a feature flag for now.

It would be better to ship the complete CLI sites functionality as a full release, with all subcommands (list, add, remove, start, stop), proper documentation, and coordinated marketing. This prevents
users from discovering a partially-implemented feature.

What do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, do we have a precedent of using feature flags to hide CLI features? I know we have feature flags in the app but I'm unsure how these translate to the CLI.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK we haven't used feature flags in the CLI.
For now I would suggest using a env var to conditionally add the sites commands to the CLI in index.ts.
If you want I can take on that issue, and propose a solution on how we can manage feature flags across Studio and CLI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bcotrim Please go ahead I'd love that :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@youknowriad , @bcotrim , I've created a quick PR to add a feature flag using ENABLE_CLI_V2 #1759
Let me know what you think.

@youknowriad

Copy link
Copy Markdown
Contributor Author

newSites was created as a workaround for the CLI preview command to create sites, since the CLI lacked site management capabilities. Now that we're adding proper site management, we should update the preview command to use it and remove newSites entirely.

This is good context for me. In my prototype I actually kind of avoided newSites entirely except for the list command. But I can exclude it from here and maybe ultimately get rid of it once we have the full "create commands" implemented..

@youknowriad
youknowriad force-pushed the add/list-sites-command branch from 6e57a41 to 1a8355d Compare September 10, 2025 13:08
@youknowriad

Copy link
Copy Markdown
Contributor Author

how is this looking?

@sejas sejas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@youknowriad, thanks for pushing the CLI project forward, and splitting the functionality in small PRs.
I tested it by running npm run cli:build and then node ./dist/cli/main.js sites list, and it worked as expected.

I left a suggestion to use the same properties in both formats.
I wonder if we should add more data to the list, like the WordPress version of each site.

For the "running" status, I had the idea of checking if the site is up on the given port, or even building an endpoint at Express.js level that could return if the site is running.

Screenshot 2025-09-10 at 20 02 43

I like how the subcommands are grouped under studio sites main command:

studio-sites-result

I see that Studio CLI adds the --path parameter as a global option. We might consider adding it at the command level instead or just removing it from the sites command, as I don't see it being useful for this command.

Comment thread cli/commands/sites/list.ts Outdated
Comment thread cli/lib/appdata.ts Outdated
@sejas

sejas commented Sep 10, 2025

Copy link
Copy Markdown
Member

how is this looking?

It's looking great! ✨ I’ll be happy to help by submitting new PRs to add functionality.

@sejas

sejas commented Sep 10, 2025

Copy link
Copy Markdown
Member

I see that Studio CLI adds the --path parameter as a global option. We might consider adding it at the command level instead or just removing it from the sites command, as I don't see it being useful for this command.

@youknowriad

Copy link
Copy Markdown
Contributor Author

I wonder if we should add more data to the list, like the WordPress version of each site.

I looked at the type for SiteDetails in the app and I don't see the WP version there?

@youknowriad

Copy link
Copy Markdown
Contributor Author

For the "running" status, I had the idea of checking if the site is up on the given port, or even building an endpoint at Express.js level that could return if the site is running.

Feels like just duplicate work (assuming the flag is persisted properly). We might need this later I give it to you but I prefer to keep things small for now.

@youknowriad

Copy link
Copy Markdown
Contributor Author

I see that Studio CLI adds the --path parameter as a global option. We might consider adding it at the command level instead or just removing it from the sites command, as I don't see it being useful for this command.

Sounds good to me, so add it to all the preview commands right?

sejas commented Sep 11, 2025

Copy link
Copy Markdown
Member

I looked at the type for SiteDetails in the app and I don't see the WP version there?

The WordPress version is not saved in appData and it's read directly from each sites's wp-includes/version.php

studio/src/ipc-handlers.ts

Lines 906 to 923 in 66e76f8

export function getWpVersion( _event: IpcMainInvokeEvent, id: string ) {
const server = SiteServer.get( id );
if ( ! server ) {
return '-';
}
const wordPressPath = server.details.path;
let versionFileContent = '';
try {
versionFileContent = fs.readFileSync(
nodePath.join( wordPressPath, 'wp-includes', 'version.php' ),
'utf8'
);
} catch ( err ) {
return '-';
}
const matches = versionFileContent.match( /\$wp_version\s*=\s*'([0-9a-zA-Z.-]+)'/ );
return matches?.[ 1 ] || '-';
}

@youknowriad

Copy link
Copy Markdown
Contributor Author

The WordPress version is not saved in appData and it's read directly from each sites's wp-includes/version.php

Ok, I guess it's better to add a common library to do that and do it in its own PR. I created a dedicated issue for it STU-788

sejas commented Sep 11, 2025

Copy link
Copy Markdown
Member

Sounds good to me, so add it to all the preview commands right?

Yesterday I created this PR that hides the --path option from the studio sites group of commands: #1758

@wojtekn

wojtekn commented Sep 11, 2025

Copy link
Copy Markdown
Contributor

@youknowriad thanks for the contribution - the list works well for me.

Could we change sites to site to follow the pattern established by WP CLI and adopted by the preview command?

@youknowriad

Copy link
Copy Markdown
Contributor Author

Could we change sites to site to follow the pattern established by WP CLI and adopted by the preview command?

Works for me, but I'm not fully convinced. I think once we have site start/stop, we'll have to reshuffle the command names again. I think we'll have a better idea what works and what doesn't later.

@wojtekn

wojtekn commented Sep 11, 2025

Copy link
Copy Markdown
Contributor

Works for me, but I'm not fully convinced. I think once we have site start/stop, we'll have to reshuffle the command names again. I think we'll have a better idea what works and what doesn't later.

Why would we need to reshuffle it after adding start/stop? I think the singular names would make logical sense and would be consistent with WP CLI.

Studio currently has those:

studio preview create
studio preview list
studio preview delete
studio preview update

Now we would add:

studio site list

And later:

studio site create
studio site delete
studio site update
studio site start
studio site stop

In WP CLI we have:

wp plugin install
wp plugin list
wp plugin update
etc.
@youknowriad

Copy link
Copy Markdown
Contributor Author

For me if you put "start and stop" under "site", you should also put "preview" under "site". But I don't want to get into this discussion right now to be honest, there's no urgency. Let's build what we need and things might clarify later.

@wojtekn

wojtekn commented Sep 11, 2025

Copy link
Copy Markdown
Contributor

I see, thanks @youknowriad .

@sejas sejas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good to me, and now that it's behind a feature flag we can merge this PR. We can always add more fields in the future if necessary.
Currently, the status will be "Stopped" for all sites, but I think it's fine to keep it as a placeholder.
Merging this PR will make it easier to divide the work and add more site commands in different PRs.

Table JSON
Screenshot 2025-09-11 at 12 37 58 Screenshot 2025-09-11 at 12 37 48
Comment thread cli/commands/site/list.ts Outdated
site.name,
site.path,
site.id,
site.running ? __( 'Running' ) : __( 'Stopped' ),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

site.running will be always falsy, as it doesn't exist in AppData, so all sites will appear as Stopped until we implement a mechanism to detect whether a site is running or not.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh really, where can I check exactly what things exists in app data or not? I think for now I'm just going to remove this information.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a "type" that defines what is saved into appData?

@sejas sejas Sep 11, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppData is available in ~/Library/Application Support/Studio/appdata-v1.json and here is an example of one of my sites:

    {
      "id": "e1014e86-ece3-4c1f-a1ac-632d7df5bae7",
      "name": "Antonio Sejas | <yay> | 123",
      "path": "/Users/macbookpro/Studio/my-blog",
      "adminPassword": "NWFake1230d0",
      "port": 8882,
      "phpVersion": "8.0",
      "isWpAutoUpdating": false,
      "customDomain": "antonio-sejas-yay-123.wp.local",
      "enableHttps": false,
      "autoStart": true,
      "themeDetails": {
        "name": "Twenty Twenty-Five/twentytwentyfive-trunk",
        "path": "/var/www/html/wp-content/themes/twentytwentyfive-trunk",
        "slug": "twentytwentyfive-trunk",
        "isBlockTheme": true,
        "supportsWidgets": false,
        "supportsMenus": false
      }
    }

The type that better represent it is StoppedSiteDetails:

interface StoppedSiteDetails {
running: false;
id: string;
name: string;
path: string;
port: number;
phpVersion: string;
isWpAutoUpdating?: boolean;
customDomain?: string;
enableHttps?: boolean;
adminPassword?: string;
tlsKey?: string;
tlsCert?: string;
themeDetails?: {
name: string;
path: string;
slug: string;
isBlockTheme: boolean;
supportsWidgets: boolean;
supportsMenus: boolean;
};
isAddingSite?: boolean;
autoStart?: boolean;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we might need to have that typed properly and shared with both CLI and app at some point to clarify expectations when reading from appData.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was basing my info on the SiteDetails type and I was wrong haha.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, the AppData type should be common for CLI and the App 💯 .

@youknowriad
youknowriad merged commit 1ffbef8 into trunk Sep 11, 2025
12 checks passed
@youknowriad
youknowriad deleted the add/list-sites-command branch September 11, 2025 12:41
@youknowriad

Copy link
Copy Markdown
Contributor Author

Thanks folks, more PRs coming :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

4 participants