Skip to content

Wire auth and locale to shared.json, AI settings to cli.json#2821

Merged
bcotrim merged 22 commits intostu-1350-decoupled-config-devfrom
stu-1350-decoupled-config-dev-v2
Mar 18, 2026
Merged

Wire auth and locale to shared.json, AI settings to cli.json#2821
bcotrim merged 22 commits intostu-1350-decoupled-config-devfrom
stu-1350-decoupled-config-dev-v2

Conversation

@bcotrim
Copy link
Copy Markdown
Contributor

@bcotrim bcotrim commented Mar 16, 2026

Related issues

How AI was used in this PR

All code was generated via Claude Code (Opus + Haiku). Changes were reviewed and validated by the author through iterative conversation — verifying architecture decisions, confirming read/write boundaries, and running the full test suite at each step.

Proposed Changes

  • Create tools/common/lib/shared-config.ts — new shared config infrastructure at ~/.studio/shared.json for data shared between Desktop and CLI (auth token + locale)
  • Wire Desktop auth reads/writes to shared-config instead of appdata
  • Wire Desktop locale reads/writes to shared-config instead of appdata
  • Wire CLI auth reads/writes to shared-config instead of appdata
  • Move CLI-only AI settings (aiProvider, anthropicApiKey) from appdata to cli.json
  • Move CLI telemetry (lastBumpStats) from appdata to cli.json
  • Remove authToken, locale, AI fields, and lastBumpStats from appdata types and schemas
  • Add 20 tests for shared-config and update all affected test files

After these changes the write boundaries are:

  • Desktopappdata-v1.json (sites, snapshots, preferences) + shared.json (auth, locale)
  • CLIcli.json (sites, AI settings, telemetry) + shared.json (auth) + appdata-v1.json (snapshots only)

Testing Instructions

  • Run npm run typecheck — should pass with no errors
  • Run npm test — all 1292 tests should pass
  • Manual: launch Desktop app, log in via WordPress.com — verify ~/.studio/shared.json contains the auth token
  • Manual: change language in Preferences — verify ~/.studio/shared.json contains the locale
  • Manual: run studio auth login from CLI — verify shared.json is updated
  • Manual: run studio ai and switch provider/enter API key — verify ~/.studio/cli.json contains aiProvider and anthropicApiKey

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

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>
@bcotrim bcotrim self-assigned this Mar 16, 2026
@bcotrim bcotrim marked this pull request as ready for review March 17, 2026 18:24
@bcotrim bcotrim requested review from a team and fredrikekelund March 17, 2026 18:25
Copy link
Copy Markdown
Contributor

@fredrikekelund fredrikekelund left a comment

Choose a reason for hiding this comment

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

Left some comments. Shared config error handling and using _events instead of a shared config file watcher are the big things we need to address, IMO.

Haven't tested yet but will do that now 👍

Comment thread tools/common/lib/shared-config.ts Outdated
Comment on lines +59 to +62
if ( error instanceof z.ZodError || error instanceof SyntaxError ) {
return structuredClone( DEFAULT_SHARED_CONFIG );
}
throw new Error( 'Failed to read shared config file.' );
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.

Same as in apps/cli/lib/cli-config/core.ts, we should look for differing version props here and say something like "A newer version of Studio or the Studio CLI is installed on your system" if the version differs.

Comment thread tools/common/lib/shared-config.ts Outdated
Comment on lines +118 to +120
} catch {
return null;
}
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.

This relates to the error handling I suggested in readSharedConfig. I'm not sure what the best approach is here…

If the user is running an old version of the CLI but have a newer version of Studio installed (that uses a new schema for the shared config file), then we should prompt them to upgrade.

However, we still need both programs to recover from errors well enough to at least report the right thing to the user. This is especially true for Studio, which needs to be able to auto-update as usual.

Comment thread tools/common/lib/shared-config.ts Outdated

const sharedConfigSchema = z
.object( {
version: z.number().default( 1 ),
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.

Let's put the version in a constant and add a comment explaining that any schema update must maintain backwards compatibility. If the change is breaking, the version should be updated and a data migration function should be added.

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.

The important thing to test here, IMO, is how we recover from schema-related errors. We have some of that in the readSharedConfig tests, but I think we can expand on that (along with updating the logic in the actual source code)

Comment thread apps/cli/lib/cli-config/core.ts Outdated
await unlockFileAsync( LOCKFILE_PATH );
}

export async function updateCliConfig(
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.

Suggested change
export async function updateCliConfig(
export async function updateCliConfigWithPartial(

Just a suggestion

Comment thread tools/common/lib/shared-config.ts Outdated
}
}

export async function readAuthToken(): Promise< StoredToken | null > {
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.

Exporting functions that return just parts of the config is clearly great for reducing the amount of test mocks. Nice 👍

Comment thread tools/common/lib/shared-config.ts Outdated
displayName: z.string().default( '' ),
} );

export type StoredToken = z.infer< typeof authTokenSchema >;
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.

Suggested change
export type StoredToken = z.infer< typeof authTokenSchema >;
export type StoredAuthToken = z.infer< typeof authTokenSchema >;

I'd include "auth" in the name somehow

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.

Ouff… I didn't consider the HTTPS certificates. We should put these in ~/.studio, too, IMO. Let's do that in a separate PR, though.

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.

I created STU-1416 to track this

Comment thread apps/cli/lib/certificate-manager.ts Outdated
Comment on lines +71 to +85
function getAppdataDirectory(): string {
if ( process.env.E2E && process.env.E2E_APP_DATA_PATH ) {
return path.join( process.env.E2E_APP_DATA_PATH, 'Studio' );
}

if ( process.platform === 'win32' ) {
if ( ! process.env.APPDATA ) {
throw new LoggerError( __( 'Studio config file path not found.' ) );
}

return path.join( process.env.APPDATA, 'Studio' );
}

return path.join( os.homedir(), 'Library', 'Application Support', 'Studio' );
}
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.

Could we use getAppdataDirectory from apps/cli/lib/server-files.ts here?

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.

Could we use _events for listening to auth changes, too, instead of watching the shared config file?

Copy link
Copy Markdown
Contributor

@fredrikekelund fredrikekelund left a comment

Choose a reason for hiding this comment

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

This works as expected in testing 👍 Error handling for the shared config is really key to get right. I'll still approve now to keep up momentum, since we aren't landing straight to trunk

Comment on lines +83 to +90
if ( ! token ) {
setIsAuthenticated( false );
setClient( undefined );
setWpcomClient( undefined );
setUser( undefined );
return;
}

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.

The auth logout command didn't trigger a change in authentication status in the app for me when I tested it the first time. Probably because the shared config file didn't exist when I started Studio. I guess this would be solved by moving to an _events architecture for auth events instead.

Comment thread apps/cli/ai/providers.ts
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.

Let's update this file to import aiProviderSchema from apps/cli/lib/cli-config/core.ts. We should have a single definition for that

Comment thread apps/cli/ai/providers.ts
Comment on lines +159 to +162
isReady: async () => {
const { anthropicApiKey } = await readCliConfig();
return Boolean( anthropicApiKey );
},
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 need to remember to ping the Architecture team before landing this to trunk, to let them know that they need to manually migrate AI-related props from the appdata file to the CLI config file.

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.

I created STU-1416 to track this

Comment on lines 22 to 25
vi.mock( '@studio/common/lib/shared-config', async ( importOriginal ) => ( {
...( await importOriginal< typeof import('@studio/common/lib/shared-config') >() ),
readAuthToken: vi.fn(),
} ) );
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.

Suggested change
vi.mock( '@studio/common/lib/shared-config', async ( importOriginal ) => ( {
...( await importOriginal< typeof import('@studio/common/lib/shared-config') >() ),
readAuthToken: vi.fn(),
} ) );
vi.mock( import( '@studio/common/lib/shared-config' ), async ( importOriginal ) => ( {
...( await importOriginal() ),
readAuthToken: vi.fn(),
} ) );

Tip: I stumbled upon this recently, that the first argument to vi.mock can be an import() call, which makes Vitest aware of the module types.

Comment thread apps/cli/ai/providers.ts Outdated
export type AiProviderId = keyof typeof AI_PROVIDERS;

export const aiProviderSchema = z.enum( [ 'wpcom', 'anthropic-claude', 'anthropic-api-key' ] );
export { aiProviderSchema };
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.

Do we really need to re-export this definition?

Comment thread tools/common/lib/shared-config.ts Outdated

const sharedConfigSchema = z
.object( {
version: z.number().default( SHARED_CONFIG_VERSION ),
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.

Suggested change
version: z.number().default( SHARED_CONFIG_VERSION ),
version: z.literal( SHARED_CONFIG_VERSION ),

I should have called this out in apps/cli/lib/cli-config/core.ts, too, but this is an important distinction: I think the zod schema parsing should fail unless the version field matches what we expect.

If we don't do this, then the schema parsing might fail for other reasons, but it's not as easy for us to see why it's happening.

We can't just change this line to z.literal instead, we also need a base schema containing just the version field to try with. I'm basically imagining the logic we have in apps/cli/lib/cli-config/core.ts, just with z.literal instead of z.number().default()

@bcotrim bcotrim merged commit 1081ea7 into stu-1350-decoupled-config-dev Mar 18, 2026
5 checks passed
@bcotrim bcotrim deleted the stu-1350-decoupled-config-dev-v2 branch March 18, 2026 21:50
bcotrim added a commit that referenced this pull request Mar 23, 2026
* 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>
fredrikekelund added a commit that referenced this pull request Mar 23, 2026
* 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>
fredrikekelund added a commit that referenced this pull request Mar 24, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants