diff --git a/packages/create-twenty-app/package.json b/packages/create-twenty-app/package.json
index 667aebbf7d..cb85ed2171 100644
--- a/packages/create-twenty-app/package.json
+++ b/packages/create-twenty-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-twenty-app",
- "version": "2.2.0",
+ "version": "2.3.0",
"description": "Command-line interface to create Twenty application",
"main": "dist/cli.cjs",
"bin": "dist/cli.cjs",
diff --git a/packages/twenty-apps/internal/twenty-linear/README.md b/packages/twenty-apps/internal/twenty-linear/README.md
index c44b3e4b13..fd35e9a5d9 100644
--- a/packages/twenty-apps/internal/twenty-linear/README.md
+++ b/packages/twenty-apps/internal/twenty-linear/README.md
@@ -60,9 +60,20 @@ If you're working on this app rather than installing the published version:
```bash
cd packages/twenty-apps/internal/twenty-linear
+
+# For day-to-day development (publish + install + watch in one):
+yarn twenty dev
+
+# Manual publish flow (deploy registers the app, install activates it):
yarn twenty deploy
+yarn twenty install
```
+`twenty dev` is recommended for iteration — it publishes, installs, and
+watches for changes in one command. Use `twenty deploy` + `twenty install`
+when you want to control each step separately (e.g. deploying to a
+production server without auto-installing).
+
This serves as the reference implementation for Twenty's
`defineConnectionProvider({ type: 'oauth' })` flow — useful as a template
when adding OAuth integrations for other providers.
diff --git a/packages/twenty-client-sdk/package.json b/packages/twenty-client-sdk/package.json
index 32ded619a3..3737a02d94 100644
--- a/packages/twenty-client-sdk/package.json
+++ b/packages/twenty-client-sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "twenty-client-sdk",
- "version": "2.2.0",
+ "version": "2.3.0",
"sideEffects": false,
"license": "AGPL-3.0",
"scripts": {
diff --git a/packages/twenty-docs/developers/extend/apps/getting-started.mdx b/packages/twenty-docs/developers/extend/apps/getting-started.mdx
index b9caea8f1a..7b7bc60d49 100644
--- a/packages/twenty-docs/developers/extend/apps/getting-started.mdx
+++ b/packages/twenty-docs/developers/extend/apps/getting-started.mdx
@@ -88,7 +88,7 @@ yarn twenty dev --verbose
```
-Dev mode is only available on Twenty instances running in development (`NODE_ENV=development`). Production instances reject dev sync requests. Use `yarn twenty deploy` to deploy to production servers — see [Publishing Apps](/developers/extend/apps/publishing) for details.
+Dev mode is only available on Twenty instances running in development (`NODE_ENV=development`). Production instances reject dev sync requests. Use `yarn twenty deploy` followed by `yarn twenty install` to publish and install on production servers — `deploy` publishes to the application registry, while `install` installs it on a given workspace. See [Publishing Apps](/developers/extend/apps/publishing) for details.
diff --git a/packages/twenty-sdk/package.json b/packages/twenty-sdk/package.json
index d495d8fe9c..020f7daf1b 100644
--- a/packages/twenty-sdk/package.json
+++ b/packages/twenty-sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "twenty-sdk",
- "version": "2.2.0",
+ "version": "2.3.0",
"sideEffects": false,
"bin": {
"twenty": "dist/cli.cjs"
diff --git a/packages/twenty-sdk/src/cli/commands/app-command.ts b/packages/twenty-sdk/src/cli/commands/app-command.ts
index 8f92cbdf22..1cce1c50de 100644
--- a/packages/twenty-sdk/src/cli/commands/app-command.ts
+++ b/packages/twenty-sdk/src/cli/commands/app-command.ts
@@ -93,7 +93,7 @@ export const registerCommands = (program: Command): void => {
program
.command('deploy [appPath]')
- .description('Build and upload application to a Twenty server')
+ .description("Publish a new version to a Twenty server's registry")
.option('-r, --remote ', 'Deploy to a specific remote')
.action(async (appPath, options) => {
await deployCommand.execute({
diff --git a/packages/twenty-sdk/src/cli/commands/deploy.ts b/packages/twenty-sdk/src/cli/commands/deploy.ts
index b1290ecf6d..89943a0419 100644
--- a/packages/twenty-sdk/src/cli/commands/deploy.ts
+++ b/packages/twenty-sdk/src/cli/commands/deploy.ts
@@ -1,6 +1,10 @@
+import path from 'path';
+
import { appBuild } from '@/cli/operations/build';
import { appDeploy } from '@/cli/operations/deploy';
+import { ConfigService } from '@/cli/utilities/config/config-service';
import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/utilities/config/current-execution-directory';
+import { readJson } from '@/cli/utilities/file/fs-utils';
import { checkSdkVersionCompatibility } from '@/cli/utilities/version/check-sdk-version-compatibility';
import chalk from 'chalk';
@@ -42,6 +46,17 @@ export class DeployCommand {
process.exit(1);
}
- console.log(chalk.green('✓ Deployed successfully'));
+ const packageJson = await readJson<{ name?: string; version?: string }>(
+ path.join(appPath, 'package.json'),
+ ).catch(() => undefined);
+
+ const appName = packageJson?.name ?? result.data.name;
+ const appVersion = packageJson?.version ?? 'unknown';
+ const remoteName = ConfigService.getActiveRemote();
+
+ console.log(
+ chalk.green(`\n✓ Published ${appName} v${appVersion} to ${remoteName}\n`),
+ );
+ console.log(' To install deployed application: `yarn twenty install`');
}
}
diff --git a/packages/twenty-sdk/src/cli/operations/deploy.ts b/packages/twenty-sdk/src/cli/operations/deploy.ts
index 5f4c157e0d..2defd90fce 100644
--- a/packages/twenty-sdk/src/cli/operations/deploy.ts
+++ b/packages/twenty-sdk/src/cli/operations/deploy.ts
@@ -14,6 +14,8 @@ export type AppDeployOptions = {
};
export type AppDeployResult = {
+ id: string;
+ name: string;
universalIdentifier: string;
};
@@ -49,9 +51,7 @@ const innerAppDeploy = async (
return {
success: true,
- data: {
- universalIdentifier: uploadResult.data.universalIdentifier,
- },
+ data: uploadResult.data,
};
};