feat(sdk): move catalog-sync under server group (#20282)

## Summary

`catalog-sync` is a server-side admin action — it asks the connected
Twenty server to refresh its marketplace catalog from npm. It doesn't
operate on the local app code (like `build`, `deploy`, `publish`), so
having it sit at the same root level as those commands is a navigability
problem. With 13 commands at the root today, every needless one makes
the help output harder to scan.

This PR moves it under `server`:

```
# New (preferred)
yarn twenty server catalog-sync
yarn twenty server catalog-sync --remote production

# Old (still works, prints deprecation warning)
yarn twenty catalog-sync
```

Also slightly broadens the `server` group description from "Manage a
local Twenty server instance" to "Manage a Twenty server (local instance
and server-side actions)" since `catalog-sync` can target a remote.

## Help output (after)

```
$ yarn twenty --help
Commands:
  ...
  catalog-sync [options]   [Deprecated] Moved under server. Use `yarn twenty server catalog-sync`.
  ...
  server                   Manage a Twenty server (local instance and server-side actions)

$ yarn twenty server --help
Commands:
  start [options]              Start a local Twenty server
  stop [options]               Stop the local Twenty server
  logs [options]               Stream Twenty server logs
  status [options]             Show Twenty server status
  reset [options]              Delete all data and start fresh
  upgrade [options] [version]  Upgrade the twenty-app-dev Docker image
  catalog-sync [options]       Trigger a marketplace catalog sync on the server
```

## Backwards compatibility

The top-level `yarn twenty catalog-sync` still works and runs the same
logic. It prints a yellow warning suggesting the new path, then executes
normally. Plan is to remove it in a future release.

## Test plan
- [x] `npx nx typecheck twenty-sdk` passes
- [x] `npx nx lint twenty-sdk` passes
- [x] `yarn twenty --help` shows the deprecated entry
- [x] `yarn twenty server --help` lists the new subcommand
- [x] `yarn twenty catalog-sync --help` shows the deprecation message in
the description
- [ ] End-to-end: invoking either path triggers a sync against a running
server

## Possible follow-ups

This is one slice of the bigger CLI flattening discussed offline. Other
natural moves: group `build/deploy/publish/install/uninstall/typecheck`
under an `app` group, group `add/exec/logs` under `entity`. Doing those
in their own PRs to keep blast radius small.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Félix Malfait
2026-05-05 15:23:08 +02:00
committed by GitHub
parent 88394c25ef
commit e6125c0e0d
3 changed files with 25 additions and 4 deletions
@@ -115,9 +115,18 @@ export const registerCommands = (program: Command): void => {
program
.command('catalog-sync')
.description('Trigger marketplace catalog sync on the server')
.description(
'[Deprecated] Moved under server. Use `yarn twenty server catalog-sync`.',
)
.option('-r, --remote <name>', 'Sync on a specific remote')
.action(async (options) => {
console.warn(
chalk.yellow(
'`yarn twenty catalog-sync` is deprecated and will be removed in a future release.\n' +
'Use `yarn twenty server catalog-sync` instead.\n',
),
);
await catalogSyncCommand.execute({
remote: options.remote,
});
+13 -1
View File
@@ -14,11 +14,14 @@ import { checkServerHealth } from '@/cli/utilities/server/detect-local-server';
import chalk from 'chalk';
import type { Command } from 'commander';
import { execSync, spawnSync } from 'node:child_process';
import { CatalogSyncCommand } from './catalog-sync';
export const registerServerCommands = (program: Command): void => {
const server = program
.command('server')
.description('Manage a local Twenty server instance');
.description(
'Manage a Twenty server (local instance and server-side actions)',
);
server
.command('start')
@@ -200,4 +203,13 @@ export const registerServerCommands = (program: Command): void => {
}
},
);
server
.command('catalog-sync')
.description('Trigger a marketplace catalog sync on the server')
.option('-r, --remote <name>', 'Sync on a specific remote')
.action(async (options: { remote?: string }) => {
const command = new CatalogSyncCommand();
await command.execute({ remote: options.remote });
});
};