Apply decoupled config strategy to preview sites#2807
Apply decoupled config strategy to preview sites#2807bcotrim merged 15 commits intostu-1350-decoupled-config-devfrom
Conversation
- CLI stores/reads preview site data from cli.json instead of appdata - Studio reads preview sites via CLI commands (preview list --format json) - Added preview set command for updating snapshot settings (--name) - Added --name option to preview create command - Moved refreshSnapshots to store initialization with test guard - Fixed snapshot-slice test mock setup to avoid module-load timing issues
|
Looks like we should change the base branch here, @bcotrim |
65b0dd8 to
c2c0fde
Compare
c2c0fde to
c758246
Compare
… up daemon-client (STU-1350)
fredrikekelund
left a comment
There was a problem hiding this comment.
This looks good to me overall 👍 There's a question of whether we really need the app to interface with the CLI for every preview site operation, but I'm fine with landing this PR first and keeping that discussion going separately.
I haven't tested the changes yet, but I figured I'd share my feedback first. Will finalize my review once I've tested.
| event: SITE_EVENTS, | ||
| data: { siteId: string } | ||
| ): Promise< void > { | ||
| export async function emitCliEvent( payload: CliEventPayload ): Promise< void > { |
tools/common/lib/cli-events.ts
Outdated
| export type SiteEvent = z.infer< typeof siteEventSchema >; | ||
|
|
||
| export const snapshotEventSchema = z.object( { | ||
| event: z.nativeEnum( SNAPSHOT_EVENTS ), |
There was a problem hiding this comment.
| event: z.nativeEnum( SNAPSHOT_EVENTS ), | |
| event: z.enum( SNAPSHOT_EVENTS ), |
nativeEnum is deprecated in zod v4
tools/common/lib/cli-events.ts
Outdated
| } ); | ||
|
|
||
| export const snapshotSocketEventSchema = z.object( { | ||
| event: z.nativeEnum( SNAPSHOT_EVENTS ), |
There was a problem hiding this comment.
| event: z.nativeEnum( SNAPSHOT_EVENTS ), | |
| event: z.enum( SNAPSHOT_EVENTS ), |
nativeEnum is deprecated in zod v4
| } ); | ||
| } | ||
|
|
||
| window.ipcListener.subscribe( 'snapshot-changed', ( event, snapshotEvent: SnapshotEvent ) => { |
There was a problem hiding this comment.
| window.ipcListener.subscribe( 'snapshot-changed', ( event, snapshotEvent: SnapshotEvent ) => { | |
| window.ipcListener.subscribe( 'snapshot-changed', ( event, snapshotEvent ) => { |
The type is already defined in apps/studio/src/ipc-utils.ts
There was a problem hiding this comment.
I still expect the CLI and the app to use a shared config file that they can both read from and write to. I don't think we can get away from that. The language setting and the auth data are two good examples of things that the app shouldn't or couldn't use the CLI to write to the shared config.
With that in mind, I'd argue it's a bit overkill to introduce a CLI command just to update the name of a preview site. It's possible that CLI-only users would also want this ability, it just seems much less important in the CLI than it does in the UI.
I'm not necessarily arguing we need to walk back this change – if it works, then it works. Still, I think there are better arguments for why we need the site set command (it lets us consolidate HTTPS certificate logic in the CLI, it allows us to use only the CLI to talk to the process manager daemon, etc). In this case, we're basically just wrapping a file write operation in another process.
There was a problem hiding this comment.
I was also wondering that during development.
What pushed me to make the decision to add name to edit and create preview is the fact that we show that information in the CLI. It seems strange to me to show a name to our users if we don't allow them to set or edit that name.
apps/cli/lib/cli-config/index.ts
Outdated
There was a problem hiding this comment.
The performance drawbacks of "barrel files" like this don't come into play much in this context, but I would still argue that we shouldn't use them. I see no good reason for it apart from the vanity of shorter import paths.
Other than that: good idea to split up the config file functions into separate files.
| export async function fetchSnapshots(): Promise< Snapshot[] > { | ||
| try { | ||
| return await new Promise< Snapshot[] >( ( resolve, reject ) => { | ||
| const [ emitter ] = executeCliCommand( [ 'preview', 'list', '--format', 'json' ], { | ||
| output: 'capture', | ||
| } ); | ||
|
|
||
| emitter.on( 'data', ( { data } ) => { | ||
| const parsed = snapshotListKeyValueSchema.safeParse( data ); | ||
| if ( parsed.success ) { | ||
| resolve( parsed.data.value ); | ||
| } | ||
| } ); | ||
|
|
||
| emitter.on( 'success', () => resolve( [] ) ); | ||
| emitter.on( 'failure', ( { error } ) => reject( error ) ); | ||
| emitter.on( 'error', ( { error } ) => reject( error ) ); | ||
| } ); | ||
| } catch ( error ) { | ||
| console.error( 'Failed to fetch snapshots from CLI:', error ); | ||
| return []; | ||
| } | ||
| } |
There was a problem hiding this comment.
Similar to what I mentioned in apps/cli/commands/preview/set.ts, it seems like we're adding overhead here without super clear gains. We still need a zod schema to parse the data we receive, so why not just read directly from the shared config file?
We don't necessarily need to walk back this change (it's better to move ahead faster), but I would like to at least raise the question. It goes back to what we discussed in our huddle, @bcotrim, but if the end goal truly is to never have the app read from the shared config file, then I might need some more convincing 😄
There was a problem hiding this comment.
I think the value is making Studio dependent only on the CLI, without knowing about the implementation details.
The same reasoning could be applied to operations, if Studio reads and writes from the config file, why not share the code to run the operations and remove the CLI overhead?
| // Re-fetch snapshots from CLI after any successful operation | ||
| void refreshSnapshots(); |
There was a problem hiding this comment.
Do we really need this? 🤔 Seems like we wouldn't need such a fine-grained event system if we always just refetch the preview site list anyway.
| const existing = state.snapshot.snapshots.find( ( s ) => s.url === snapshot.url ); | ||
| if ( ! existing ) { | ||
| store.dispatch( | ||
| snapshotSlice.actions.setSnapshots( { |
There was a problem hiding this comment.
| snapshotSlice.actions.setSnapshots( { | |
| snapshotSlice.actions.addSnapshot( { |
Optional, but I think we might as well add an explicit addSnapshot action.
| store.dispatch( | ||
| wpcomApi.util.updateQueryData( 'getSnapshotUsage', undefined, ( data ) => { | ||
| // There's a risk that more sites are deleted locally than the count returned by the | ||
| // API, because expired sites are preserved locally. Therefore, we need to ensure | ||
| // the count is non-negative. | ||
| data.siteCount = Math.max( 0, data.siteCount + countDiff ); | ||
| } ) | ||
| ); | ||
|
|
||
| // Wait for changes to take effect on the back-end before invalidating the query | ||
| setTimeout( () => { | ||
| store.dispatch( wpcomApi.util.invalidateTags( [ 'SnapshotUsage' ] ) ); | ||
| }, 8000 ); |
There was a problem hiding this comment.
I think it's worth putting this logic in a reusable function. Also, I wouldn't delete the comments.
| const { atomicSiteId, snapshot } = action.payload; | ||
| const state = store.getState(); | ||
| const existing = state.snapshot.snapshots.find( ( s ) => s.atomicSiteId === atomicSiteId ); | ||
| if ( existing?.url && snapshot.name !== undefined && snapshot.name !== existing.name ) { | ||
| await getIpcApi().setSnapshot( existing.url, { name: snapshot.name } ); | ||
| } |
There was a problem hiding this comment.
This logic doesn't work as intended, because existing.name is already updated by the time this action runs.
…le usage count helper, fix listener state bug
fredrikekelund
left a comment
There was a problem hiding this comment.
Testing works as expected with the latest changes 👍
* Read site data from CLI instead of appdata (#2701) * STU-1350: Read site data from CLI instead of appdata Studio now reads site data via `site list --format json` at startup and maintains state through CLI events subscriber. Removes direct appdata reads for site details, simplifies SiteServer create/start flows, and removes waitForSiteEvent synchronization. * Fix lint: indentation in index.test.ts * Fix typecheck: narrow SiteDetails union before accessing url * Remove dead url branch in SiteServer.create — events subscriber handles it * Address PR review feedback: shared schemas, keyValuePair output, simplify start/delete * Move CLI site data to dedicated config file (#2731) * STU-1350: Read site data from CLI instead of appdata Studio now reads site data via `site list --format json` at startup and maintains state through CLI events subscriber. Removes direct appdata reads for site details, simplifies SiteServer create/start flows, and removes waitForSiteEvent synchronization. * Fix lint: indentation in index.test.ts * STU-1350: Move CLI site data to dedicated cli.json config file Split site data from appdata-v1.json into a new CLI-owned config at ~/.studio/cli.json. Studio now reads sites exclusively via `studio site list` and _events. The CLI is the source of truth for site configuration. Auth tokens, snapshots, locale remain in appdata. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Fix delete test after trunk merge: use saveCliConfig instead of saveAppdata * Extend require-lock-before-save eslint rule to support cli-config lock/save pairs * Use shared lockfile constants and extract DEFAULT_CLI_CONFIG * Fix typecheck: narrow SiteDetails union before accessing url * Remove dead url branch in SiteServer.create — events subscriber handles it * Fix lint: remove extra blank line in cli-config.ts * triggert ci * Update e2e tests to read site data from cli.json * Address PR review feedback for cli-config - Use structuredClone for DEFAULT_CLI_CONFIG deep copy - Rename daemon-paths.ts to paths.ts, extract STUDIO_CLI_HOME - Split config schema for version mismatch detection - Improve readCliConfig error handling with version check - Rename removeSite to removeSiteFromConfig - Revert UPDATED event handler to warn for unknown sites * Fix AI files to import site functions from cli-config instead of appdata --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> * Fix AI tools test mocks to use cli-config instead of appdata * Apply decoupled config strategy to preview sites (#2807) * Apply decoupled config strategy to preview sites (STU-1350) - CLI stores/reads preview site data from cli.json instead of appdata - Studio reads preview sites via CLI commands (preview list --format json) - Added preview set command for updating snapshot settings (--name) - Added --name option to preview create command - Moved refreshSnapshots to store initialization with test guard - Fixed snapshot-slice test mock setup to avoid module-load timing issues * Emit snapshot events to Studio via _events for realtime updates * Move snapshot name generation from cli-config to preview create command * Split cli-config.ts into folder structure (core, sites, snapshots) * Rename site-events to cli-events and enrich snapshot events with inline data (STU-1350) * Fix snapshot update infinite loop and preview set error handling * Unify CLI event emitter, share event schemas in cli-events, and clean up daemon-client (STU-1350) * trigger ci * Fix import order lint errors in core.ts and site-server.ts * Address PR review: add stdout json output, addSnapshot action, reusable usage count helper, fix listener state bug * Remove barrel file, replace z.nativeEnum with z.enum, update imports to direct paths * Fix import order in cli-events.ts and remove unused test imports * Wire auth and locale to shared.json, AI settings to cli.json (#2821) * Wire auth and locale to shared.json, AI settings to cli.json Move auth token reads/writes from appdata to shared-config for Desktop+CLI. Move locale reads/writes to shared-config (Desktop saves, CLI reads). Move aiProvider and anthropicApiKey from shared-config to cli-config (CLI-only). Remove auth and locale fields from appdata schema and types since they're now in separate files. Update all imports and tests accordingly. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Move CLI telemetry stats from appdata to cli-config * Fix import order lint errors * Remove CLI appdata dependency and move infrastructure paths to ~/.studio * Revert server-files and certificate paths to appdata directory * Watch shared config for auth changes from CLI * Align shared config watcher with user-data watcher pattern * trigger ci * Address PR review feedback: events-based auth, rename types, deduplicate schemas * Fix prettier formatting in auth test * Fix shared-config mock in tests to export authTokenSchema * Use z.literal for config version validation, remove unused re-export, update test mocks * Extract authTokenSchema to avoid Node.js imports in renderer bundle * trigger ci * Fix daemon test to use os.tmpdir() for Windows compatibility * Make CLI event emission best-effort in auth commands * Throw on shared config version mismatch instead of silently returning defaults * Add line break before version mismatch error message * Handle version mismatch errors through standard Logger flow in auth commands * Show only display name in AI chat status bar --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> * Migrate appdata to ~/.studio/appdata.json with versioned migrations (#2836) * Migrate appdata to ~/.studio/appdata.json with extensible migration framework * Move appdata migration from CLI to Studio Desktop * Rewrite appdata migration to split into shared.json, cli.json, and appdata.json * trigger ci * Ensure .studio directory exists before lockfile and fix import order * Fix readFile mock type to return Buffer instead of string * Refactor appdata to store only Desktop-specific state with sites as Record<id, AppdataSiteData> * Address PR feedback: rename to app.json and siteMetadata, use zod parsing in migration * Fix prettier formatting in user-data test * Fix e2e migration by respecting E2E_APP_DATA_PATH in getOldAppdataPath * new migration interface * studio migrations * studio migrations * cli migrations * Rename appdata references, centralize config paths and lockfile constants * Isolate e2e config directory to fix test failures * Move site metadata cleanup to SiteServer, fix typecheck and test failures * Add APP_CONFIG_LOCKFILE_NAME constant and fix test failures * Fix lint errors: update AI imports from appdata to cli-config * trigger ci * Exclude AI config fields from app.json and enforce shared config locking * Move getSiteByFolder outside try/finally to prevent unlock without lock * Wrap saveSharedConfig test calls with lock/unlock to satisfy lint rule --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
* Read site data from CLI instead of appdata (#2701) * STU-1350: Read site data from CLI instead of appdata Studio now reads site data via `site list --format json` at startup and maintains state through CLI events subscriber. Removes direct appdata reads for site details, simplifies SiteServer create/start flows, and removes waitForSiteEvent synchronization. * Fix lint: indentation in index.test.ts * Fix typecheck: narrow SiteDetails union before accessing url * Remove dead url branch in SiteServer.create — events subscriber handles it * Address PR review feedback: shared schemas, keyValuePair output, simplify start/delete * Move CLI site data to dedicated config file (#2731) * STU-1350: Read site data from CLI instead of appdata Studio now reads site data via `site list --format json` at startup and maintains state through CLI events subscriber. Removes direct appdata reads for site details, simplifies SiteServer create/start flows, and removes waitForSiteEvent synchronization. * Fix lint: indentation in index.test.ts * STU-1350: Move CLI site data to dedicated cli.json config file Split site data from appdata-v1.json into a new CLI-owned config at ~/.studio/cli.json. Studio now reads sites exclusively via `studio site list` and _events. The CLI is the source of truth for site configuration. Auth tokens, snapshots, locale remain in appdata. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Fix delete test after trunk merge: use saveCliConfig instead of saveAppdata * Extend require-lock-before-save eslint rule to support cli-config lock/save pairs * Use shared lockfile constants and extract DEFAULT_CLI_CONFIG * Fix typecheck: narrow SiteDetails union before accessing url * Remove dead url branch in SiteServer.create — events subscriber handles it * Fix lint: remove extra blank line in cli-config.ts * triggert ci * Update e2e tests to read site data from cli.json * Address PR review feedback for cli-config - Use structuredClone for DEFAULT_CLI_CONFIG deep copy - Rename daemon-paths.ts to paths.ts, extract STUDIO_CLI_HOME - Split config schema for version mismatch detection - Improve readCliConfig error handling with version check - Rename removeSite to removeSiteFromConfig - Revert UPDATED event handler to warn for unknown sites * Fix AI files to import site functions from cli-config instead of appdata --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> * Fix AI tools test mocks to use cli-config instead of appdata * Apply decoupled config strategy to preview sites (#2807) * Apply decoupled config strategy to preview sites (STU-1350) - CLI stores/reads preview site data from cli.json instead of appdata - Studio reads preview sites via CLI commands (preview list --format json) - Added preview set command for updating snapshot settings (--name) - Added --name option to preview create command - Moved refreshSnapshots to store initialization with test guard - Fixed snapshot-slice test mock setup to avoid module-load timing issues * Emit snapshot events to Studio via _events for realtime updates * Move snapshot name generation from cli-config to preview create command * Split cli-config.ts into folder structure (core, sites, snapshots) * Rename site-events to cli-events and enrich snapshot events with inline data (STU-1350) * Fix snapshot update infinite loop and preview set error handling * Unify CLI event emitter, share event schemas in cli-events, and clean up daemon-client (STU-1350) * trigger ci * Fix import order lint errors in core.ts and site-server.ts * Address PR review: add stdout json output, addSnapshot action, reusable usage count helper, fix listener state bug * Remove barrel file, replace z.nativeEnum with z.enum, update imports to direct paths * Fix import order in cli-events.ts and remove unused test imports * Migrate appdata to ~/.studio/appdata.json with extensible migration framework * Move appdata migration from CLI to Studio Desktop * Wire auth and locale to shared.json, AI settings to cli.json (#2821) * Wire auth and locale to shared.json, AI settings to cli.json Move auth token reads/writes from appdata to shared-config for Desktop+CLI. Move locale reads/writes to shared-config (Desktop saves, CLI reads). Move aiProvider and anthropicApiKey from shared-config to cli-config (CLI-only). Remove auth and locale fields from appdata schema and types since they're now in separate files. Update all imports and tests accordingly. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Move CLI telemetry stats from appdata to cli-config * Fix import order lint errors * Remove CLI appdata dependency and move infrastructure paths to ~/.studio * Revert server-files and certificate paths to appdata directory * Watch shared config for auth changes from CLI * Align shared config watcher with user-data watcher pattern * trigger ci * Address PR review feedback: events-based auth, rename types, deduplicate schemas * Fix prettier formatting in auth test * Fix shared-config mock in tests to export authTokenSchema * Use z.literal for config version validation, remove unused re-export, update test mocks * Extract authTokenSchema to avoid Node.js imports in renderer bundle * trigger ci * Fix daemon test to use os.tmpdir() for Windows compatibility * Make CLI event emission best-effort in auth commands * Throw on shared config version mismatch instead of silently returning defaults * Add line break before version mismatch error message * Handle version mismatch errors through standard Logger flow in auth commands * Show only display name in AI chat status bar --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> * Rewrite appdata migration to split into shared.json, cli.json, and appdata.json * trigger ci * Ensure .studio directory exists before lockfile and fix import order * Fix readFile mock type to return Buffer instead of string * Refactor appdata to store only Desktop-specific state with sites as Record<id, AppdataSiteData> * Address PR feedback: rename to app.json and siteMetadata, use zod parsing in migration * Fix prettier formatting in user-data test * Fix e2e migration by respecting E2E_APP_DATA_PATH in getOldAppdataPath * new migration interface * studio migrations * studio migrations * cli migrations * Rename appdata references, centralize config paths and lockfile constants * Isolate e2e config directory to fix test failures * Move site metadata cleanup to SiteServer, fix typecheck and test failures * HTTPS certificate migration * Rename file * Add APP_CONFIG_LOCKFILE_NAME constant and fix test failures * Fix merge conflict --------- Co-authored-by: Bernardo Cotrim <bmmcotrim@gmail.com> Co-authored-by: bcotrim <bernardo.cotrim@a8c.com> Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
* Read site data from CLI instead of appdata (#2701) * STU-1350: Read site data from CLI instead of appdata Studio now reads site data via `site list --format json` at startup and maintains state through CLI events subscriber. Removes direct appdata reads for site details, simplifies SiteServer create/start flows, and removes waitForSiteEvent synchronization. * Fix lint: indentation in index.test.ts * Fix typecheck: narrow SiteDetails union before accessing url * Remove dead url branch in SiteServer.create — events subscriber handles it * Address PR review feedback: shared schemas, keyValuePair output, simplify start/delete * Move CLI site data to dedicated config file (#2731) * STU-1350: Read site data from CLI instead of appdata Studio now reads site data via `site list --format json` at startup and maintains state through CLI events subscriber. Removes direct appdata reads for site details, simplifies SiteServer create/start flows, and removes waitForSiteEvent synchronization. * Fix lint: indentation in index.test.ts * STU-1350: Move CLI site data to dedicated cli.json config file Split site data from appdata-v1.json into a new CLI-owned config at ~/.studio/cli.json. Studio now reads sites exclusively via `studio site list` and _events. The CLI is the source of truth for site configuration. Auth tokens, snapshots, locale remain in appdata. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Fix delete test after trunk merge: use saveCliConfig instead of saveAppdata * Extend require-lock-before-save eslint rule to support cli-config lock/save pairs * Use shared lockfile constants and extract DEFAULT_CLI_CONFIG * Fix typecheck: narrow SiteDetails union before accessing url * Remove dead url branch in SiteServer.create — events subscriber handles it * Fix lint: remove extra blank line in cli-config.ts * triggert ci * Update e2e tests to read site data from cli.json * Address PR review feedback for cli-config - Use structuredClone for DEFAULT_CLI_CONFIG deep copy - Rename daemon-paths.ts to paths.ts, extract STUDIO_CLI_HOME - Split config schema for version mismatch detection - Improve readCliConfig error handling with version check - Rename removeSite to removeSiteFromConfig - Revert UPDATED event handler to warn for unknown sites * Fix AI files to import site functions from cli-config instead of appdata --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> * Fix AI tools test mocks to use cli-config instead of appdata * Apply decoupled config strategy to preview sites (#2807) * Apply decoupled config strategy to preview sites (STU-1350) - CLI stores/reads preview site data from cli.json instead of appdata - Studio reads preview sites via CLI commands (preview list --format json) - Added preview set command for updating snapshot settings (--name) - Added --name option to preview create command - Moved refreshSnapshots to store initialization with test guard - Fixed snapshot-slice test mock setup to avoid module-load timing issues * Emit snapshot events to Studio via _events for realtime updates * Move snapshot name generation from cli-config to preview create command * Split cli-config.ts into folder structure (core, sites, snapshots) * Rename site-events to cli-events and enrich snapshot events with inline data (STU-1350) * Fix snapshot update infinite loop and preview set error handling * Unify CLI event emitter, share event schemas in cli-events, and clean up daemon-client (STU-1350) * trigger ci * Fix import order lint errors in core.ts and site-server.ts * Address PR review: add stdout json output, addSnapshot action, reusable usage count helper, fix listener state bug * Remove barrel file, replace z.nativeEnum with z.enum, update imports to direct paths * Fix import order in cli-events.ts and remove unused test imports * Migrate appdata to ~/.studio/appdata.json with extensible migration framework * Move appdata migration from CLI to Studio Desktop * Wire auth and locale to shared.json, AI settings to cli.json (#2821) * Wire auth and locale to shared.json, AI settings to cli.json Move auth token reads/writes from appdata to shared-config for Desktop+CLI. Move locale reads/writes to shared-config (Desktop saves, CLI reads). Move aiProvider and anthropicApiKey from shared-config to cli-config (CLI-only). Remove auth and locale fields from appdata schema and types since they're now in separate files. Update all imports and tests accordingly. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Move CLI telemetry stats from appdata to cli-config * Fix import order lint errors * Remove CLI appdata dependency and move infrastructure paths to ~/.studio * Revert server-files and certificate paths to appdata directory * Watch shared config for auth changes from CLI * Align shared config watcher with user-data watcher pattern * trigger ci * Address PR review feedback: events-based auth, rename types, deduplicate schemas * Fix prettier formatting in auth test * Fix shared-config mock in tests to export authTokenSchema * Use z.literal for config version validation, remove unused re-export, update test mocks * Extract authTokenSchema to avoid Node.js imports in renderer bundle * trigger ci * Fix daemon test to use os.tmpdir() for Windows compatibility * Make CLI event emission best-effort in auth commands * Throw on shared config version mismatch instead of silently returning defaults * Add line break before version mismatch error message * Handle version mismatch errors through standard Logger flow in auth commands * Show only display name in AI chat status bar --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> * Rewrite appdata migration to split into shared.json, cli.json, and appdata.json * trigger ci * Ensure .studio directory exists before lockfile and fix import order * Fix readFile mock type to return Buffer instead of string * Refactor appdata to store only Desktop-specific state with sites as Record<id, AppdataSiteData> * Address PR feedback: rename to app.json and siteMetadata, use zod parsing in migration * Fix prettier formatting in user-data test * Fix e2e migration by respecting E2E_APP_DATA_PATH in getOldAppdataPath * new migration interface * studio migrations * studio migrations * cli migrations * Rename appdata references, centralize config paths and lockfile constants * Isolate e2e config directory to fix test failures * Move site metadata cleanup to SiteServer, fix typecheck and test failures * HTTPS certificate migration * Rename file * Initial server-files migration implementation In this implementation, Studio copies the entire server-files directory to a well-known location. This, by itself, is not enough to make the CLI standalone. We need to actually distribute the wp-files files with the CLI. * Add APP_CONFIG_LOCKFILE_NAME constant and fix test failures * Actually move server-files to CLI management * Fix test * Fix merge conflict * Exclude wp-files from app bundle * Load sites from `SiteServer.getAll()` * Various fixes * Fix lint * Fix * Improved `updateServerFiles` error handling * Remove fs-extra * Abstract GitHub release fetching * Include wp-files in package.json files * Fix errors * Remove outdated wp-now migration * Fix tests * Fix issues identified by agentic review * Setup server-files in middleware * Address issues raised by AI review * Fix more review issues * Set up and update in parallel * Remove unused code * Remove unused import --------- Co-authored-by: Bernardo Cotrim <bmmcotrim@gmail.com> Co-authored-by: bcotrim <bernardo.cotrim@a8c.com> Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Related issues
How AI was used in this PR
TBD
Proposed Changes
Extends the decoupled config strategy (implemented for sites in PR #2701) to preview sites:
~/.studio/cli.jsoninstead of appdata-v1.jsoncli-config.ts: Centralized config management with Zod schema validation and file locking for safe concurrent writespreview list --format jsonto fetch snapshots from the CLI configpreview setcommand: Allows updating snapshot settings (e.g.,preview set <hostname> --name "New Name"). Follows the same pattern assite setpreview createnow supports--name: Optionally name a preview site at creation timerefreshSnapshots()to store setup (avoiding module-load timing issues in tests)This maintains consistency with the decoupled strategy: CLI is the source of truth for data, Studio accesses it via CLI commands.
Testing Instructions
npm run cli:build && npm teststudio preview create /path/to/site --name "My Preview"studio preview list --format json(shows all snapshots)studio preview set <hostname> --name "New Name"~/.studio/cli.jsoncontains the snapshots (not appdata)Pre-merge Checklist