i18n - docs translations (#19226)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
committed by
GitHub
parent
16e3e38b79
commit
ae202a1b59
File diff suppressed because it is too large
Load Diff
@@ -4,73 +4,142 @@ description: أنشئ أول تطبيق Twenty خلال دقائق.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
التطبيقات حاليًا في مرحلة الاختبار الألفا. الميزة تعمل لكنها لا تزال قيد التطور.
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
تتيح لك التطبيقات توسيع Twenty باستخدام كائنات وحقول ووظائف منطقية ومهارات ذكاء اصطناعي ومكونات واجهة مستخدم مخصصة — جميعها تُدار ككود.
|
||||
|
||||
**ما الذي يمكنك بناؤه:**
|
||||
|
||||
* كائنات مخصّصة، وحقول، وطرق عرض، وعناصر تنقّل لتشكيل نموذج بياناتك
|
||||
* دوال منطقية يتم تشغيلها عبر مسارات HTTP، وجداول cron، أو أحداث قاعدة البيانات
|
||||
* مكوّنات واجهة أمامية تُعرَض مباشرة داخل واجهة مستخدم Twenty
|
||||
* مهارات توسّع قدرات وكلاء الذكاء الاصطناعي في Twenty
|
||||
* انشر تطبيقاً عبر مساحات عمل متعددة
|
||||
|
||||
## المتطلبات الأساسية
|
||||
|
||||
* Node.js 24+
|
||||
* Yarn 4
|
||||
* Docker (أو مثيل Twenty محلي قيد التشغيل)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## البدء
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
أنشئ تطبيقًا جديدًا باستخدام المُهيئ الرسمي، ثم قم بالمصادقة وابدأ التطوير:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
> استخدم الخيار `--minimal` لتهيئة تثبيت مصغّر
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
من هنا يمكنك:
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
راجع أيضًا: صفحات مرجع CLI لـ [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) و[twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
## هيكل المشروع (مُنشأ بالقالب)
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
عند تشغيل `npx create-twenty-app@latest my-twenty-app`، يقوم المُهيئ بما يلي:
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
* ينسخ تطبيقًا أساسيًا مصغّرًا إلى `my-twenty-app/`
|
||||
* يضيف اعتمادًا محليًا `twenty-sdk` وتهيئة Yarn 4
|
||||
* ينشئ ملفات ضبط ونصوصًا مرتبطة بـ `twenty` CLI
|
||||
* يُنشئ الملفات الأساسية (تهيئة التطبيق، دور الدالة الافتراضي، دالتا ما قبل التثبيت وما بعد التثبيت) بالإضافة إلى ملفات أمثلة استنادًا إلى وضع الإنشاء.
|
||||
<Warning>
|
||||
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](/l/ar/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
يبدو التطبيق المُنشأ حديثًا باستخدام الوضع الافتراضي `--exhaustive` كما يلي:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Head over to [Building Apps](/l/ar/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -83,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
مع `--minimal`، سيتم إنشاء الملفات الأساسية فقط (`application-config.ts`، `roles/default-role.ts`، `logic-functions/pre-install.ts`، و`logic-functions/post-install.ts`).
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
بشكل عام:
|
||||
### Key files
|
||||
|
||||
* **package.json**: يصرّح باسم التطبيق والإصدار والمحرّكات (Node 24+، Yarn 4)، ويضيف `twenty-sdk` بالإضافة إلى نص برمجي `twenty` يفوِّض إلى `twenty` CLI المحلي. شغِّل `yarn twenty help` لعرض جميع الأوامر المتاحة.
|
||||
* **.gitignore**: يتجاهل العناصر الشائعة مثل `node_modules` و`.yarn` و`.twenty/` و`dist/` و`build/` ومجلدات التغطية وملفات السجلات وملفات `.env*`.
|
||||
* **yarn.lock**، **.yarnrc.yml**، **.yarn/**: تقوم بقفل وتكوين حزمة أدوات Yarn 4 المستخدمة في المشروع.
|
||||
* **.nvmrc**: يثبّت إصدار Node.js المتوقع للمشروع.
|
||||
* **.oxlintrc.json** و **tsconfig.json**: يقدّمان إعدادات الفحص والتهيئة لـ TypeScript لمصادر TypeScript في تطبيقك.
|
||||
* **README.md**: ملف README قصير في جذر التطبيق يتضمن تعليمات أساسية.
|
||||
* **public/**: مجلد لتخزين الأصول العامة (صور، خطوط، ملفات ثابتة) التي سيتم تقديمها مع تطبيقك. الملفات الموضوعة هنا تُرفع أثناء المزامنة وتكون متاحة أثناء وقت التشغيل.
|
||||
* **src/**: المكان الرئيسي حيث تعرّف تطبيقك ككود
|
||||
| File / Folder | الغرض |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | مهارات توسّع قدرات وكلاء الذكاء الاصطناعي في Twenty. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### اكتشاف الكيانات
|
||||
## Managing remotes
|
||||
|
||||
يكتشف SDK الكيانات عبر تحليل ملفات TypeScript الخاصة بك بحثًا عن استدعاءات **`export default define<Entity>({...})`**. يحتوي كل نوع كيان على دالة مساعدة مقابلة يتم تصديرها من `twenty-sdk`:
|
||||
|
||||
| دالة مساعدة | نوع الكيان |
|
||||
| -------------------------------- | ---------------------------------------------- |
|
||||
| `defineObject` | تعريفات كائنات مخصصة |
|
||||
| `defineLogicFunction` | تعريفات الوظائف المنطقية |
|
||||
| `definePreInstallLogicFunction` | دالة منطقية لما قبل التثبيت (تعمل قبل التثبيت) |
|
||||
| `definePostInstallLogicFunction` | دالة منطقية لما بعد التثبيت (تعمل بعد التثبيت) |
|
||||
| `defineFrontComponent` | تعريفات المكونات الواجهية |
|
||||
| `defineRole` | تعريفات الأدوار |
|
||||
| `defineField` | امتدادات الحقول للكائنات الموجودة |
|
||||
| `defineView` | تعريفات العروض المحفوظة |
|
||||
| `defineNavigationMenuItem` | تعريفات عناصر قائمة التنقل |
|
||||
| `defineSkill` | تعريفات مهارات وكلاء الذكاء الاصطناعي |
|
||||
|
||||
<Note>
|
||||
**تسمية الملفات مرنة.** يعتمد اكتشاف الكيانات على بنية الشجرة المجردة (AST) — إذ يقوم SDK بفحص ملفات المصدر لديك بحثًا عن النمط `export default define<Entity>({...})`. يمكنك تنظيم ملفاتك ومجلداتك كيفما تشاء. التجميع حسب نوع الكيان (مثلًا، `logic-functions/` و`roles/`) هو مجرد عرف لتنظيم الشيفرة، وليس مطلبًا إلزاميًا.
|
||||
</Note>
|
||||
|
||||
مثال على كيان تم اكتشافه:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
ستضيف الأوامر اللاحقة مزيدًا من الملفات والمجلدات:
|
||||
|
||||
* `yarn twenty dev` سيولّد تلقائياً `CoreApiClient` مضبوط الأنواع (لبيانات مساحة العمل عبر `/graphql`) داخل `node_modules/twenty-client-sdk/`. `MetadataApiClient` (لتهيئة مساحة العمل ورفع الملفات عبر `/metadata`) يأتي مُبنًى مسبقاً ومتاحاً على الفور. استوردْهما من `twenty-client-sdk/core` و`twenty-client-sdk/metadata` على الترتيب.
|
||||
* `yarn twenty add` سيضيف ملفات تعريف الكيانات ضمن `src/` لكائناتك المخصّصة، والوظائف، ومكوّنات الواجهة الأمامية، والأدوار، والمهارات، وغير ذلك.
|
||||
|
||||
## المصادقة
|
||||
|
||||
في المرة الأولى التي تشغّل فيها `yarn twenty auth:login`، سيُطلب منك إدخال:
|
||||
|
||||
* عنوان URL لواجهة برمجة التطبيقات (الافتراضي http://localhost:3000 أو ملف تعريف مساحة العمل الحالية لديك)
|
||||
* مفتاح واجهة برمجة التطبيقات
|
||||
|
||||
تُخزَّن بيانات اعتمادك لكل مستخدم في `~/.twenty/config.json`. يمكنك الاحتفاظ بملفات تعريف متعددة والتبديل بينها.
|
||||
|
||||
### إدارة مساحات العمل
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
بمجرد أن تقوم بالتبديل بين مساحات العمل باستخدام `yarn twenty auth:switch`، ستستخدم جميع الأوامر اللاحقة تلك المساحة افتراضيًا. لا يزال بإمكانك تجاوزه مؤقتًا باستخدام `--workspace <name>`.
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### بدء الخادم
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| أمر | الوصف |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## إعداد يدوي (بدون المهيئ)
|
||||
|
||||
بينما نوصي باستخدام `create-twenty-app` للحصول على أفضل تجربة للبدء، يمكنك أيضًا إعداد مشروع يدويًا. لا تثبّت CLI عالميًا. بدل ذلك، أضف `twenty-sdk` كاعتماد محلي واربط سكربتًا واحدًا في ملف package.json لديك:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
ثم أضف سكربتًا باسم `twenty`:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -210,25 +393,19 @@ yarn add -D twenty-sdk
|
||||
}
|
||||
```
|
||||
|
||||
الآن يمكنك تشغيل جميع الأوامر عبر `yarn twenty <command>`، مثلًا: `yarn twenty dev`، `yarn twenty help`، إلخ.
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## كيفية استخدام مثيل محلي من Twenty
|
||||
|
||||
إذا كنت تقوم بتشغيل مثيل محلي من Twenty بالفعل (على سبيل المثال عبر `npx nx start twenty-server`)، فيمكنك الاتصال به بدلًا من استخدام Docker:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## استكشاف الأخطاء وإصلاحها
|
||||
|
||||
* أخطاء المصادقة: شغّل `yarn twenty auth:login` وتأكد من أن مفتاح واجهة برمجة التطبيقات لديك يمتلك الأذونات المطلوبة.
|
||||
* يتعذّر الاتصال بالخادم: تحقق من عنوان URL لواجهة برمجة التطبيقات وأن خادم Twenty قابل للوصول.
|
||||
* الأنواع أو العميل مفقود/قديم: أعد تشغيل `yarn twenty dev` — فهو يولِّد العميل مضبوط الأنواع تلقائيًا.
|
||||
* وضع التطوير لا يزامن: تأكد من أن `yarn twenty dev` قيد التشغيل وأن التغييرات غير متجاهلة في بيئتك.
|
||||
If you run into issues:
|
||||
|
||||
قناة المساعدة على Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,34 +4,76 @@ description: وزّع تطبيق Twenty الخاص بك على سوق Twenty أ
|
||||
---
|
||||
|
||||
<Warning>
|
||||
التطبيقات حاليًا في مرحلة الاختبار الألفا. الميزة تعمل لكنها لا تزال قيد التطور.
|
||||
التطبيقات حاليًا في مرحلة الألفا. الميزة تعمل لكنها لا تزال قيد التطور.
|
||||
</Warning>
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
بمجرد أن يكون تطبيقك [مبنيًا ومختبرًا محليًا](/l/ar/developers/extend/apps/building)، لديك مساران لتوزيعه:
|
||||
|
||||
* **النشر على npm** — أدرج تطبيقك في سوق Twenty ليتسنى لأي مساحة عمل اكتشافه وتثبيته.
|
||||
* **نشر أرشيف tar** — ارفع تطبيقك مباشرةً إلى خادم Twenty محدد للاستخدام الداخلي أو الخاص.
|
||||
* **النشر على npm** — أدرج تطبيقك في سوق Twenty ليتسنى لأي مساحة عمل اكتشافه وتثبيته.
|
||||
|
||||
كلا المسارين يبدآن من نفس خطوة **build**.
|
||||
|
||||
## بناء تطبيقك
|
||||
|
||||
يقوم الأمر `build` بتجميع مصادر TypeScript الخاصة بك، وتحويل دوال المنطق ومكوّنات الواجهة الأمامية، وإنشاء ملف `manifest.json` يصف محتويات تطبيقك:
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
يتم حفظ المخرجات في `.twenty/output/`. يحتوي هذا الدليل على كل ما يلزم للتوزيع: الكود المُجمَّع، والأصول، وملف manifest، ونسخة من `package.json` الخاص بك.
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
لإنشاء حزمة tarball بصيغة `.tgz` أيضًا (تُستخدم داخليًا بواسطة أمر النشر، أو للتوزيع اليدوي):
|
||||
## النشر إلى خادم (tarball)
|
||||
|
||||
بالنسبة للتطبيقات التي لا تريد إتاحتها للعامة — مثل الأدوات المملوكة، أو عمليات التكامل الخاصة بالمؤسسات فقط، أو الإصدارات التجريبية — يمكنك نشر tarball مباشرةً إلى خادم Twenty.
|
||||
|
||||
### المتطلبات الأساسية
|
||||
|
||||
قبل النشر، تحتاج إلى remote مُعدّ يشير إلى خادم الهدف. تُخزّن remotes عنوان URL للخادم وبيانات اعتماد المصادقة محليًا في `~/.twenty/config.json`.
|
||||
|
||||
أضِف remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build --tarball
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### النشر
|
||||
|
||||
بناء تطبيقك ورفعه إلى الخادم في خطوة واحدة:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### مشاركة تطبيق منشور
|
||||
|
||||
تطبيقات tarball لا تُدرَج في السوق العامة، لذا لن تكتشفها مساحات العمل الأخرى على الخادم نفسه عبر الاستعراض. لمشاركة تطبيق منشور:
|
||||
|
||||
1. اذهب إلى **الإعدادات > التطبيقات > التسجيلات** وافتح تطبيقك
|
||||
2. في علامة التبويب **التوزيع**، انقر **نسخ رابط المشاركة**
|
||||
3. شارك هذا الرابط مع المستخدمين في مساحات عمل أخرى — سيأخذهم مباشرةً إلى صفحة تثبيت التطبيق
|
||||
|
||||
يستخدم رابط المشاركة عنوان URL الأساسي للخادم (من دون أي نطاق فرعي لمساحة عمل)، لذا يعمل مع أي مساحة عمل على الخادم.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### إدارة الإصدارات
|
||||
|
||||
لطرح تحديث:
|
||||
|
||||
1. ارفع قيمة الحقل `version` في ملف `package.json`
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. سترى مساحات العمل التي ثبّتت التطبيق الترقية متاحة في إعداداتها
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## النشر على npm
|
||||
|
||||
يُتيح النشر على npm إمكانية العثور على تطبيقك في سوق Twenty. يمكن لأي مساحة عمل في Twenty استعراض تطبيقات السوق وتثبيتها وترقيتها مباشرةً من واجهة المستخدم.
|
||||
@@ -39,41 +81,42 @@ yarn twenty build --tarball
|
||||
### المتطلبات
|
||||
|
||||
* حساب على [npm](https://www.npmjs.com)
|
||||
* الكلمة المفتاحية `twenty-app` **يجب** أن تُدرج في مصفوفة `keywords` في `package.json` الخاص بك
|
||||
|
||||
### إضافة الكلمة المفتاحية المطلوبة
|
||||
|
||||
يعثر سوق Twenty على التطبيقات من خلال البحث في سجل npm عن الحزم التي تحتوي على الكلمة المفتاحية `twenty-app`. أضِفها إلى `package.json` الخاص بك:
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"],
|
||||
...
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
يبحث السوق عن `keywords:twenty-app` في سجل npm. من دون هذه الكلمة المفتاحية، لن تظهر حزمتك في السوق حتى وإن كانت تحمل بادئة الاسم `twenty-app-`.
|
||||
</Note>
|
||||
### بيانات التعريف لسوق التطبيقات
|
||||
|
||||
### الخطوات
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
1. **بناء تطبيقك:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
2. **النشر على npm:**
|
||||
See the [defineApplication accordion](/l/ar/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
هذا يُشغِّل `npm publish` من دليل `.twenty/output/`.
|
||||
|
||||
للنشر تحت dist-tag معيّن (مثلًا: `beta` أو `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
@@ -82,25 +125,17 @@ yarn twenty publish --tag beta
|
||||
|
||||
### كيف تعمل آلية الاكتشاف في السوق
|
||||
|
||||
يقوم خادم Twenty بمزامنة كتالوج السوق من سجل npm **كل ساعة**:
|
||||
يقوم خادم Twenty بمزامنة كتالوج السوق من سجل npm **كل ساعة**.
|
||||
|
||||
1. يبحث عن جميع حزم npm التي تحتوي على الكلمة المفتاحية `keywords:twenty-app`
|
||||
2. ولكل حزمة، يجلب ملف `manifest.json` من شبكة CDN الخاصة بـ npm
|
||||
3. يتم استخراج بيانات التعريف الخاصة بالتطبيق (الاسم، الوصف، المؤلف، الشعار، لقطات الشاشة، الفئة) من ملف manifest وعرضها في السوق
|
||||
|
||||
بعد النشر، قد يستغرق ظهور تطبيقك في السوق ما يصل إلى ساعة واحدة. لتشغيل المزامنة فورًا بدلًا من انتظار التشغيل التالي كل ساعة:
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
لاستهداف remote معيّن:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync -r production
|
||||
```
|
||||
|
||||
تأتي بيانات التعريف المعروضة في السوق من استدعائك لـ `defineApplication()` في الشيفرة المصدرية لتطبيقك — حقول مثل `displayName` و`description` و`author` و`category` و`logoUrl` و`screenshots` و`aboutDescription` و`websiteUrl` و`termsUrl`.
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
إذا لم يحدد تطبيقك `aboutDescription` في `defineApplication()`، فسيستخدم السوق تلقائيًا ملف `README.md` الخاص بحزمتك من npm كمحتوى لصفحة حول. هذا يعني أنه يمكنك الاحتفاظ بملف README واحد لكل من npm وسوق Twenty. إذا كنت تريد وصفًا مختلفًا في السوق، فقم بتعيين `aboutDescription` بشكل صريح.
|
||||
@@ -108,7 +143,7 @@ yarn twenty catalog-sync -r production
|
||||
|
||||
### النشر عبر CI
|
||||
|
||||
يتضمن المشروع المُولَّد سير عمل GitHub Actions يقوم بالنشر عند كل إصدار:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -133,121 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
بالنسبة لأنظمة CI الأخرى (GitLab CI، وCircleCI، إلخ)، تنطبق الأوامر الثلاثة نفسها: `yarn install`، ثم `yarn twenty build`، ثم `npm publish` من `.twenty/output`.
|
||||
|
||||
<Tip>
|
||||
<Note>
|
||||
**npm provenance** اختياري ولكنه موصى به. يضيف النشر باستخدام `--provenance` شارة ثقة إلى إدراجك على npm، مما يتيح للمستخدمين التحقق من أن الحزمة تم بناؤها من التزام محدد ضمن خط أنابيب CI عام. راجع [وثائق npm provenance](https://docs.npmjs.com/generating-provenance-statements) للحصول على تعليمات الإعداد.
|
||||
</Tip>
|
||||
|
||||
## النشر إلى خادم (tarball)
|
||||
|
||||
بالنسبة للتطبيقات التي لا تريد إتاحتها للعامة — مثل الأدوات المملوكة، أو عمليات التكامل الخاصة بالمؤسسات فقط، أو الإصدارات التجريبية — يمكنك نشر tarball مباشرةً إلى خادم Twenty.
|
||||
|
||||
### المتطلبات الأساسية
|
||||
|
||||
قبل النشر، تحتاج إلى remote مُعدّ يشير إلى خادم الهدف. تُخزّن remotes عنوان URL للخادم وبيانات اعتماد المصادقة محليًا في `~/.twenty/config.json`.
|
||||
|
||||
أضِف remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
لخادم تطوير محلي:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --local --as local
|
||||
```
|
||||
|
||||
يمكنك أيضًا إجراء المصادقة باستخدام مفتاح API للبيئات غير التفاعلية:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
|
||||
```
|
||||
|
||||
إدارة remotes الخاصة بك:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote list # List all configured remotes
|
||||
yarn twenty remote switch prod # Set the default remote
|
||||
yarn twenty remote status # Show active remote and auth status
|
||||
yarn twenty remote remove old # Remove a remote
|
||||
```
|
||||
|
||||
### النشر
|
||||
|
||||
بناء تطبيقك ورفعه إلى الخادم في خطوة واحدة:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
```
|
||||
|
||||
يُنشئ هذا التطبيق باستخدام `--tarball`، ثم يرفع ملف tarball إلى الـ remote الافتراضي عبر رفع متعدد الأجزاء لـ GraphQL.
|
||||
|
||||
لنشره إلى remote معيّن:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy -r production
|
||||
```
|
||||
|
||||
### مشاركة تطبيق منشور
|
||||
|
||||
تطبيقات tarball لا تُدرَج في السوق العامة، لذا لن تكتشفها مساحات العمل الأخرى على الخادم نفسه عبر الاستعراض. لمشاركة تطبيق منشور:
|
||||
|
||||
1. اذهب إلى **الإعدادات > التطبيقات > التسجيلات** وافتح تطبيقك
|
||||
2. في علامة التبويب **التوزيع**، انقر **نسخ رابط المشاركة**
|
||||
3. شارك هذا الرابط مع المستخدمين في مساحات عمل أخرى — سيأخذهم مباشرةً إلى صفحة تثبيت التطبيق
|
||||
|
||||
يستخدم رابط المشاركة عنوان URL الأساسي للخادم (من دون أي نطاق فرعي لمساحة عمل)، لذا يعمل مع أي مساحة عمل على الخادم.
|
||||
|
||||
### إدارة الإصدارات
|
||||
|
||||
لطرح تحديث:
|
||||
|
||||
1. ارفع قيمة الحقل `version` في ملف `package.json`
|
||||
2. شغّل `yarn twenty deploy` (أو `yarn twenty deploy -r production`)
|
||||
3. سترى مساحات العمل التي ثبّتت التطبيق الترقية متاحة في إعداداتها
|
||||
</Note>
|
||||
|
||||
## تثبيت التطبيقات
|
||||
|
||||
بعد نشر التطبيق (npm) أو نشره إلى الخادم (tarball)، تقوم مساحات العمل بتثبيته عبر واجهة المستخدم:
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
أو من صفحة **الإعدادات > التطبيقات** في واجهة Twenty، حيث يمكن استعراض التطبيقات من السوق ومن النشر عبر tarball وتثبيتها.
|
||||
|
||||
## فئات توزيع التطبيقات
|
||||
|
||||
تُنظِّم Twenty التطبيقات في ثلاث فئات استنادًا إلى طريقة توزيعها:
|
||||
|
||||
| الفئة | كيف يعمل | مرئي في سوق Twenty؟ |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------- |
|
||||
| **التطوير** | تطبيقات وضع التطوير المحلي التي تعمل عبر `yarn twenty dev`. تُستخدم للبناء والاختبار. | لا |
|
||||
| **منشور (npm)** | تطبيقات منشورة على npm تحتوي على الكلمة المفتاحية `twenty-app`. مدرجة في سوق Twenty لتتمكن أي مساحة عمل من تثبيتها. | نعم |
|
||||
| **داخلي (tarball)** | تطبيقات منشورة عبر tarball إلى خادم محدد. متاحة فقط لمساحات العمل على ذلك الخادم عبر رابط مشاركة. | لا |
|
||||
|
||||
<Tip>
|
||||
ابدأ في وضع **التطوير** أثناء بناء تطبيقك. عندما يصبح جاهزًا، اختر **منشور** (npm) للتوزيع الواسع أو **داخلي** (tarball) للنشر الخاص.
|
||||
</Tip>
|
||||
|
||||
## مرجع CLI
|
||||
|
||||
| أمر | الوصف | الأعلام الرئيسية |
|
||||
| --------------------------- | ------------------------------------ | ----------------------------------------------------- |
|
||||
| `yarn twenty build` | تجميع التطبيق وإنشاء manifest | `--tarball` — يقوم أيضًا بإنشاء حزمة `.tgz` |
|
||||
| `yarn twenty publish` | بناء التطبيق ونشره إلى npm | `--tag <tag>` — وسم توزيع npm (مثلًا: `beta`، `next`) |
|
||||
| `yarn twenty deploy` | بناء ورفع tarball إلى خادم | `-r, --remote <name>` — الـ remote المستهدف |
|
||||
| `yarn twenty catalog-sync` | تشغيل مزامنة كتالوج السوق على الخادم | `-r, --remote <name>` — الـ remote المستهدف |
|
||||
| `yarn twenty install` | تثبيت تطبيق منشور على مساحة عمل | `-r, --remote <name>` — الـ remote المستهدف |
|
||||
| `yarn twenty dev` | مراقبة ومزامنة التغييرات المحلية | يستخدم الـ remote الافتراضي |
|
||||
| `yarn twenty remote add` | إضافة اتصال بخادم | `--url`, `--token`, `--as`, `--local`, `--port` |
|
||||
| `yarn twenty remote list` | عرض الـ remotes المُكوَّنة | — |
|
||||
| `yarn twenty remote switch` | تعيين الـ remote الافتراضي | — |
|
||||
| `yarn twenty remote status` | عرض حالة الاتصال | — |
|
||||
| `yarn twenty remote remove` | إزالة remote | — |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,73 +4,142 @@ description: Vytvořte svou první aplikaci Twenty během několika minut.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Aplikace jsou aktuálně v alfa testování. Tato funkce je funkční, ale stále se vyvíjí.
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
Aplikace vám umožňují rozšířit Twenty o vlastní objekty, pole, logické funkce, AI schopnosti a komponenty uživatelského rozhraní — vše je spravováno jako kód.
|
||||
|
||||
**Co můžete vytvořit:**
|
||||
|
||||
* Vlastní objekty, pole, zobrazení a položky navigace pro utváření vašeho datového modelu
|
||||
* Logické funkce spouštěné trasami HTTP, plánovačem cron nebo událostmi databáze
|
||||
* Frontendové komponenty, které se vykreslují přímo uvnitř uživatelského rozhraní Twenty
|
||||
* Dovednosti, které rozšiřují možnosti AI agentů Twenty
|
||||
* Nasazení aplikace napříč více pracovními prostory
|
||||
|
||||
## Předpoklady
|
||||
|
||||
* Node.js 24+
|
||||
* Yarn 4
|
||||
* Docker (nebo běžící lokální instance Twenty)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## Začínáme
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
Vytvořte novou aplikaci pomocí oficiálního scaffolderu, poté se ověřte a začněte vyvíjet:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
> Použijte volbu `--minimal` k vygenerování minimální instalace
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
Odtud můžete:
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
Viz také: referenční stránky CLI pro [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) a [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
## Struktura projektu (vytvořená scaffolderem)
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
Když spustíte `npx create-twenty-app@latest my-twenty-app`, scaffolder:
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
* Zkopíruje minimální základní aplikaci do `my-twenty-app/`
|
||||
* Přidá lokální závislost `twenty-sdk` a konfiguraci pro Yarn 4
|
||||
* Vytvoří konfigurační soubory a skripty napojené na `twenty` CLI
|
||||
* Vygeneruje základní soubory (konfigurace aplikace, výchozí role funkcí, předinstalační a postinstalační funkce) a k nim ukázkové soubory podle zvoleného režimu generování kostry
|
||||
<Warning>
|
||||
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](/l/cs/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
Čerstvě vygenerovaná aplikace s výchozím režimem `--exhaustive` vypadá takto:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Head over to [Building Apps](/l/cs/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -83,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
S volbou `--minimal` se vytvoří pouze základní soubory (`application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` a `logic-functions/post-install.ts`).
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
V kostce:
|
||||
### Key files
|
||||
|
||||
* **package.json**: Deklaruje název aplikace, verzi, engines (Node 24+, Yarn 4) a přidává `twenty-sdk` plus skript `twenty`, který deleguje na lokální `twenty` CLI. Spusťte `yarn twenty help` pro výpis všech dostupných příkazů.
|
||||
* **.gitignore**: Ignoruje běžné artefakty jako `node_modules`, `.yarn`, `.twenty/`, `dist/`, `build/`, složky s coverage, soubory s logy a soubory `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Zamykají a konfigurují nástrojový řetězec Yarn 4 používaný projektem.
|
||||
* **.nvmrc**: Fixuje verzi Node.js požadovanou projektem.
|
||||
* **.oxlintrc.json** a **tsconfig.json**: Poskytují lintování a konfiguraci TypeScriptu pro zdrojové soubory vaší aplikace v TypeScriptu.
|
||||
* **README.md**: Krátké README v kořeni aplikace se základními pokyny.
|
||||
* **public/**: Složka pro ukládání veřejných prostředků (obrázky, písma, statické soubory), které bude vaše aplikace poskytovat. Soubory umístěné zde se během synchronizace nahrají a jsou za běhu dostupné.
|
||||
* **src/**: Hlavní místo, kde definujete svou aplikaci jako kód
|
||||
| File / Folder | Účel |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | Dovednosti, které rozšiřují možnosti AI agentů Twenty. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### Detekce entit
|
||||
## Managing remotes
|
||||
|
||||
SDK detekuje entity analýzou vašich souborů TypeScript a hledá volání **`export default define<Entity>({...})`**. Každý typ entity má odpovídající pomocnou funkci exportovanou z `twenty-sdk`:
|
||||
|
||||
| Pomocná funkce | Typ entity |
|
||||
| -------------------------------- | --------------------------------------------------------- |
|
||||
| `defineObject` | Definice vlastních objektů |
|
||||
| `defineLogicFunction` | Definice logických funkcí |
|
||||
| `definePreInstallLogicFunction` | Předinstalační logická funkce (spouští se před instalací) |
|
||||
| `definePostInstallLogicFunction` | Postinstalační logická funkce (spouští se po instalaci) |
|
||||
| `defineFrontComponent` | Definice frontendových komponent |
|
||||
| `defineRole` | Definice rolí |
|
||||
| `defineField` | Rozšíření polí u existujících objektů |
|
||||
| `defineView` | Definice uložených zobrazení |
|
||||
| `defineNavigationMenuItem` | Definice položek navigační nabídky |
|
||||
| `defineSkill` | Definice dovedností agenta AI |
|
||||
|
||||
<Note>
|
||||
**Pojmenování souborů je flexibilní.** Detekce entit je založená na AST — SDK prochází vaše zdrojové soubory a hledá vzor `export default define<Entity>({...})`. Soubory a složky můžete organizovat, jak chcete. Seskupování podle typu entity (např. `logic-functions/`, `roles/`) je pouze konvence pro organizaci kódu, nikoli požadavek.
|
||||
</Note>
|
||||
|
||||
Příklad detekované entity:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
Pozdější příkazy přidají další soubory a složky:
|
||||
|
||||
* `yarn twenty dev` automaticky vygeneruje typovaný `CoreApiClient` (pro data pracovního prostoru přes `/graphql`) do `node_modules/twenty-client-sdk/`. `MetadataApiClient` (pro konfiguraci pracovního prostoru a nahrávání souborů přes `/metadata`) je dodáván předpřipravený a je okamžitě k dispozici. Importujte je z `twenty-client-sdk/core` a `twenty-client-sdk/metadata` v uvedeném pořadí.
|
||||
* `yarn twenty add` přidá soubory s definicemi entit do `src/` pro vaše vlastní objekty, funkce, frontové komponenty, role, dovednosti a další.
|
||||
|
||||
## Ověření
|
||||
|
||||
Při prvním spuštění `yarn twenty auth:login` budete vyzváni k zadání:
|
||||
|
||||
* URL API (výchozí je http://localhost:3000 nebo váš aktuální profil pracovního prostoru)
|
||||
* Klíč API
|
||||
|
||||
Vaše přihlašovací údaje se ukládají pro jednotlivé uživatele do `~/.twenty/config.json`. Můžete spravovat více profilů a přepínat mezi nimi.
|
||||
|
||||
### Správa pracovních prostorů
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Jakmile přepnete pracovní prostor pomocí `yarn twenty auth:switch`, všechny následující příkazy budou tento pracovní prostor používat jako výchozí. Můžete jej stále dočasně přepsat pomocí `--workspace <name>`.
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### Spuštění serveru
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| Příkaz | Popis |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## Ruční nastavení (bez scaffolderu)
|
||||
|
||||
Ačkoli pro nejlepší začátky doporučujeme použít `create-twenty-app`, projekt můžete nastavit i ručně. Neinstalujte CLI globálně. Místo toho přidejte `twenty-sdk` jako lokální závislost a přidejte jeden skript do souboru package.json:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
Poté přidejte skript `twenty`:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -210,25 +393,19 @@ Poté přidejte skript `twenty`:
|
||||
}
|
||||
```
|
||||
|
||||
Nyní můžete spouštět všechny příkazy přes `yarn twenty <command>`, např. `yarn twenty dev`, `yarn twenty help` atd.
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## Jak používat lokální instanci Twenty
|
||||
|
||||
Pokud již lokálně provozujete instanci Twenty (např. pomocí `npx nx start twenty-server`), můžete se k ní připojit namísto použití Dockeru:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## Řešení potíží
|
||||
|
||||
* Chyby ověření: spusťte `yarn twenty auth:login` a ujistěte se, že váš klíč API má požadovaná oprávnění.
|
||||
* Nelze se připojit k serveru: ověřte URL API a že je server Twenty dosažitelný.
|
||||
* Typy nebo klient chybí nebo jsou zastaralé: restartujte `yarn twenty dev` — automaticky generuje typovaného klienta.
|
||||
* Režim vývoje se nesynchronizuje: ujistěte se, že běží `yarn twenty dev` a že vaše prostředí změny neignoruje.
|
||||
If you run into issues:
|
||||
|
||||
Kanál podpory na Discordu: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,34 +4,76 @@ description: Distribuujte svou aplikaci Twenty do Marketplace nebo ji nasaďte i
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Aplikace jsou aktuálně v alfa testování. Tato funkce je funkční, ale stále se vyvíjí.
|
||||
Aplikace jsou aktuálně v alfa fázi. Funkce funguje, ale stále se vyvíjí.
|
||||
</Warning>
|
||||
|
||||
## Přehled
|
||||
|
||||
Jakmile je vaše aplikace [sestavena a otestována lokálně](/l/cs/developers/extend/apps/building), máte dvě cesty, jak ji distribuovat:
|
||||
|
||||
* **Publish to npm** — uveďte svou aplikaci v Marketplace Twenty, aby ji mohl kterýkoli pracovní prostor objevit a nainstalovat.
|
||||
* **Nasaďte tarball** — nahrajte svou aplikaci přímo na konkrétní server Twenty pro interní nebo soukromé použití.
|
||||
* **Publish to npm** — uveďte svou aplikaci v Marketplace Twenty, aby ji mohl kterýkoli pracovní prostor objevit a nainstalovat.
|
||||
|
||||
Obě cesty začínají stejným krokem **build**.
|
||||
|
||||
## Sestavení vaší aplikace
|
||||
|
||||
Příkaz `build` zkompiluje vaše zdrojové soubory TypeScriptu, transpiluje logické funkce a frontendové komponenty a vygeneruje soubor `manifest.json`, který popisuje obsah vaší aplikace:
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
Výstup se zapisuje do `.twenty/output/`. Tento adresář obsahuje vše potřebné pro distribuci: zkompilovaný kód, statické soubory, manifest a kopii souboru `package.json`.
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
Chcete-li také vytvořit tarball `.tgz` (používaný interně příkazem deploy nebo pro ruční distribuci):
|
||||
## Nasazení na server (tarball)
|
||||
|
||||
U aplikací, které nechcete zpřístupnit veřejně — proprietární nástroje, integrace pouze pro enterprise nebo experimentální buildy — můžete nasadit tarball přímo na server Twenty.
|
||||
|
||||
### Předpoklady
|
||||
|
||||
Před nasazením potřebujete nakonfigurovaný vzdálený cíl směřující na cílový server. Vzdálené cíle ukládají adresu URL serveru a přihlašovací údaje lokálně v `~/.twenty/config.json`.
|
||||
|
||||
Přidat vzdálený cíl:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build --tarball
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### Nasazení
|
||||
|
||||
Sestavte a nahrajte svou aplikaci na server v jednom kroku:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### Sdílení nasazené aplikace
|
||||
|
||||
Aplikace ve formě tarball nejsou uvedeny ve veřejném tržišti, takže je ostatní pracovní prostory na tomtéž serveru procházením neobjeví. Chcete-li sdílet nasazenou aplikaci:
|
||||
|
||||
1. Přejděte do **Nastavení > Aplikace > Registrace** a otevřete svou aplikaci
|
||||
2. Na kartě **Distribuce** klikněte na **Zkopírovat odkaz ke sdílení**
|
||||
3. Sdílejte tento odkaz s uživateli v jiných pracovních prostorech — zavede je přímo na instalační stránku aplikace
|
||||
|
||||
Odkaz ke sdílení používá základní adresu URL serveru (bez jakékoli subdomény pracovního prostoru), takže funguje pro libovolný pracovní prostor na serveru.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### Správa verzí
|
||||
|
||||
Chcete-li vydat aktualizaci:
|
||||
|
||||
1. Zvyšte hodnotu pole `version` v souboru `package.json`
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. Pracovní prostory, které mají aplikaci nainstalovanou, uvidí dostupnou aktualizaci ve svém nastavení
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## Publikování na npm
|
||||
|
||||
Publikování na npm zajistí, že bude vaše aplikace dohledatelná v Marketplace Twenty. Jakýkoli pracovní prostor Twenty může procházet, instalovat a aktualizovat aplikace z Marketplace přímo z UI.
|
||||
@@ -39,41 +81,42 @@ Publikování na npm zajistí, že bude vaše aplikace dohledatelná v Marketpla
|
||||
### Požadavky
|
||||
|
||||
* Účet na [npm](https://www.npmjs.com)
|
||||
* Klíčové slovo `twenty-app` **musí** být uvedeno v poli `keywords` vašeho `package.json`
|
||||
|
||||
### Přidání požadovaného klíčového slova
|
||||
|
||||
Tržiště Twenty objevuje aplikace hledáním balíčků v registru npm s klíčovým slovem `twenty-app`. Přidejte jej do svého `package.json`:
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"],
|
||||
...
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Tržiště vyhledává v registru npm výraz `keywords:twenty-app`. Bez tohoto klíčového slova se váš balíček v tržišti neobjeví, i když má jmennou předponu `twenty-app-`.
|
||||
</Note>
|
||||
### Metadata tržiště
|
||||
|
||||
### Postup
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
1. **Sestavení vaší aplikace:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
2. **Publikování na npm:**
|
||||
See the [defineApplication accordion](/l/cs/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
Tímto se spustí `npm publish` z adresáře `.twenty/output/`.
|
||||
|
||||
Chcete-li publikovat pod konkrétním dist-tagem (např. `beta` nebo `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
@@ -82,25 +125,17 @@ yarn twenty publish --tag beta
|
||||
|
||||
### Jak funguje objevování v tržišti
|
||||
|
||||
Server Twenty synchronizuje svůj katalog tržiště z registru npm **každou hodinu**:
|
||||
Server Twenty synchronizuje svůj katalog tržiště z registru npm **každou hodinu**.
|
||||
|
||||
1. Vyhledá všechny balíčky na npm s klíčovým slovem `keywords:twenty-app`
|
||||
2. Pro každý balíček stáhne `manifest.json` z CDN npm
|
||||
3. Metadata aplikace (název, popis, autor, logo, snímky obrazovky, kategorie) se získají z manifestu a zobrazí se v tržišti
|
||||
|
||||
Po publikování se vaše aplikace může v tržišti objevit až za jednu hodinu. Chcete-li spustit synchronizaci okamžitě místo čekání na další hodinové spuštění:
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
Chcete-li zacílit na konkrétní vzdálený cíl:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync -r production
|
||||
```
|
||||
|
||||
Metadata zobrazená v tržišti pocházejí z volání `defineApplication()` ve zdrojovém kódu vaší aplikace — z polí jako `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl` a `termsUrl`.
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
Pokud vaše aplikace nedefinuje `aboutDescription` v `defineApplication()`, tržiště automaticky použije soubor `README.md` vašeho balíčku z npm jako obsah stránky O aplikaci. To znamená, že můžete spravovat jediný soubor README jak pro npm, tak pro tržiště Twenty. Pokud chcete v tržišti jiný popis, explicitně nastavte `aboutDescription`.
|
||||
@@ -108,7 +143,7 @@ Pokud vaše aplikace nedefinuje `aboutDescription` v `defineApplication()`, trž
|
||||
|
||||
### Publikování pomocí CI
|
||||
|
||||
Vygenerovaný projekt obsahuje pracovní postup GitHub Actions, který publikuje při každém vydání:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -133,121 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
Pro jiné systémy CI (GitLab CI, CircleCI atd.) platí stejné tři příkazy: `yarn install`, `yarn twenty build` a poté `npm publish` z `.twenty/output`.
|
||||
|
||||
<Tip>
|
||||
<Note>
|
||||
**npm provenance** je volitelné, ale doporučené. Publikování s `--provenance` přidá k vašemu záznamu na npm odznak důvěryhodnosti a umožní uživatelům ověřit, že balíček byl sestaven z konkrétního commitu ve veřejné CI pipeline. Pokyny k nastavení najdete v [dokumentaci k npm provenance](https://docs.npmjs.com/generating-provenance-statements).
|
||||
</Tip>
|
||||
|
||||
## Nasazení na server (tarball)
|
||||
|
||||
U aplikací, které nechcete zpřístupnit veřejně — proprietární nástroje, integrace pouze pro enterprise nebo experimentální buildy — můžete nasadit tarball přímo na server Twenty.
|
||||
|
||||
### Předpoklady
|
||||
|
||||
Před nasazením potřebujete nakonfigurovaný vzdálený cíl směřující na cílový server. Vzdálené cíle ukládají adresu URL serveru a přihlašovací údaje lokálně v `~/.twenty/config.json`.
|
||||
|
||||
Přidat vzdálený cíl:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
Pro lokální vývojový server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --local --as local
|
||||
```
|
||||
|
||||
Pro neinteraktivní prostředí se můžete ověřit také pomocí klíče API:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
|
||||
```
|
||||
|
||||
Spravujte své vzdálené servery:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote list # List all configured remotes
|
||||
yarn twenty remote switch prod # Set the default remote
|
||||
yarn twenty remote status # Show active remote and auth status
|
||||
yarn twenty remote remove old # Remove a remote
|
||||
```
|
||||
|
||||
### Nasazení
|
||||
|
||||
Sestavte a nahrajte svou aplikaci na server v jednom kroku:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
```
|
||||
|
||||
Tímto se aplikace sestaví s `--tarball` a poté se tarball nahraje na výchozí vzdálený server prostřednictvím vícedílného (multipart) nahrávání GraphQL.
|
||||
|
||||
Chcete-li nasadit na konkrétní vzdálený server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy -r production
|
||||
```
|
||||
|
||||
### Sdílení nasazené aplikace
|
||||
|
||||
Aplikace ve formě tarball nejsou uvedeny ve veřejném tržišti, takže je ostatní pracovní prostory na tomtéž serveru procházením neobjeví. Chcete-li sdílet nasazenou aplikaci:
|
||||
|
||||
1. Přejděte do **Nastavení > Aplikace > Registrace** a otevřete svou aplikaci
|
||||
2. Na kartě **Distribuce** klikněte na **Zkopírovat odkaz ke sdílení**
|
||||
3. Sdílejte tento odkaz s uživateli v jiných pracovních prostorech — zavede je přímo na instalační stránku aplikace
|
||||
|
||||
Odkaz ke sdílení používá základní adresu URL serveru (bez jakékoli subdomény pracovního prostoru), takže funguje pro libovolný pracovní prostor na serveru.
|
||||
|
||||
### Správa verzí
|
||||
|
||||
Chcete-li vydat aktualizaci:
|
||||
|
||||
1. Zvyšte hodnotu pole `version` v souboru `package.json`
|
||||
2. Spusťte `yarn twenty deploy` (nebo `yarn twenty deploy -r production`)
|
||||
3. Pracovní prostory, které mají aplikaci nainstalovanou, uvidí dostupnou aktualizaci ve svém nastavení
|
||||
</Note>
|
||||
|
||||
## Instalace aplikací
|
||||
|
||||
Jakmile je aplikace publikována (npm) nebo nasazena (tarball), pracovní prostory ji instalují prostřednictvím uživatelského rozhraní:
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
Nebo ze stránky **Nastavení > Aplikace** v rozhraní Twenty, kde lze procházet a instalovat jak aplikace z tržiště, tak aplikace nasazené jako tarball.
|
||||
|
||||
## Kategorie distribuce aplikací
|
||||
|
||||
Twenty organizuje aplikace do tří kategorií podle způsobu distribuce:
|
||||
|
||||
| Kategorie | Jak to funguje | Viditelné v Marketplace? |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
||||
| **Vývoj** | Aplikace v místním vývojářském režimu spuštěné přes `yarn twenty dev`. Slouží k sestavování a testování. | Ne |
|
||||
| **Publikováno (npm)** | Aplikace publikované na npm s klíčovým slovem `twenty-app`. Uvedeny v Marketplace, aby je mohl kterýkoli pracovní prostor nainstalovat. | Ano |
|
||||
| **Interní (tarball)** | Aplikace nasazené pomocí tarballu na konkrétní server. Dostupné pouze pro pracovní prostory na tomto serveru prostřednictvím odkazu ke sdílení. | Ne |
|
||||
|
||||
<Tip>
|
||||
Začněte v režimu **Development** při sestavování své aplikace. Až bude připravena, zvolte **Published** (npm) pro širokou distribuci nebo **Internal** (tarball) pro soukromé nasazení.
|
||||
</Tip>
|
||||
|
||||
## Reference CLI
|
||||
|
||||
| Příkaz | Popis | Klíčové přepínače |
|
||||
| --------------------------- | ----------------------------------------------------- | --------------------------------------------------- |
|
||||
| `yarn twenty build` | Sestaví aplikaci a vygeneruje manifest | `--tarball` — také vytvoří balíček `.tgz` |
|
||||
| `yarn twenty publish` | Sestaví a publikuje na npm | `--tag <tag>` — npm dist-tag (např. `beta`, `next`) |
|
||||
| `yarn twenty deploy` | Sestaví a nahraje tarball na server | `-r, --remote <name>` — cílový vzdálený repozitář |
|
||||
| `yarn twenty catalog-sync` | Spustí synchronizaci katalogu tržiště na serveru | `-r, --remote <name>` — cílový vzdálený repozitář |
|
||||
| `yarn twenty install` | Nainstaluje nasazenou aplikaci do pracovního prostoru | `-r, --remote <name>` — cílový vzdálený server |
|
||||
| `yarn twenty dev` | Sleduje a synchronizuje lokální změny | Používá výchozí vzdálený server |
|
||||
| `yarn twenty remote add` | Přidá připojení k serveru | `--url`, `--token`, `--as`, `--local`, `--port` |
|
||||
| `yarn twenty remote list` | Vypíše nakonfigurované vzdálené servery | — |
|
||||
| `yarn twenty remote switch` | Nastaví výchozí vzdálený server | — |
|
||||
| `yarn twenty remote status` | Zobrazí stav připojení | — |
|
||||
| `yarn twenty remote remove` | Odebere vzdálený server | — |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,73 +4,142 @@ description: Erstellen Sie in wenigen Minuten Ihre erste Twenty-App.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Apps befinden sich derzeit in der Alpha-Testphase. Die Funktion ist funktionsfähig, entwickelt sich jedoch noch weiter.
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
Apps ermöglichen es Ihnen, Twenty mit benutzerdefinierten Objekten, Feldern, Logikfunktionen, KI-Fähigkeiten und UI-Komponenten zu erweitern — alles als Code verwaltet.
|
||||
|
||||
**Was Sie erstellen können:**
|
||||
|
||||
* Benutzerdefinierte Objekte, Felder, Ansichten und Navigationselemente, um Ihr Datenmodell zu gestalten
|
||||
* Logikfunktionen, die durch HTTP-Routen, Cron-Zeitpläne oder Datenbankereignisse ausgelöst werden
|
||||
* Frontend-Komponenten, die direkt innerhalb der Twenty-UI gerendert werden
|
||||
* Skills, die die KI-Agenten von Twenty erweitern
|
||||
* Eine App in mehreren Workspaces bereitstellen
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
* Node.js 24+
|
||||
* Yarn 4
|
||||
* Docker (oder eine lokal laufende Twenty-Instanz)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## Erste Schritte
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
Erstellen Sie mit dem offiziellen Scaffolder eine neue App, authentifizieren Sie sich und beginnen Sie mit der Entwicklung:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
> Verwenden Sie die Option `--minimal`, um eine minimale Installation zu erstellen
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
Von hier aus können Sie:
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
Siehe auch: die CLI-Referenzseiten für [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) und [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
## Projektstruktur (vom Scaffolder erzeugt)
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
Wenn Sie `npx create-twenty-app@latest my-twenty-app` ausführen, erledigt der Scaffolder Folgendes:
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
* Kopiert eine minimale Basisanwendung nach `my-twenty-app/`
|
||||
* Fügt eine lokale `twenty-sdk`-Abhängigkeit und die Yarn-4-Konfiguration hinzu
|
||||
* Erstellt Konfigurationsdateien und Skripte, die an die `twenty`-CLI angebunden sind
|
||||
* Erzeugt Kerndateien (Anwendungskonfiguration, Standardrolle für Logikfunktionen, Pre-Installations- und Post-Installationsfunktionen) sowie Beispieldateien entsprechend dem Scaffolding-Modus
|
||||
<Warning>
|
||||
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](/l/de/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
Eine frisch erstellte App mit dem Standardmodus `--exhaustive` sieht so aus:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Head over to [Building Apps](/l/de/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -83,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
Mit `--minimal` werden nur die Kerndateien erstellt (`application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` und `logic-functions/post-install.ts`).
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
Auf hoher Ebene:
|
||||
### Key files
|
||||
|
||||
* **package.json**: Deklariert den App-Namen, die Version und die Engines (Node 24+, Yarn 4) und fügt `twenty-sdk` sowie ein `twenty`-Skript hinzu, das an die lokale `twenty`-CLI delegiert. Führen Sie `yarn twenty help` aus, um alle verfügbaren Befehle aufzulisten.
|
||||
* **.gitignore**: Ignoriert übliche Artefakte wie `node_modules`, `.yarn`, `.twenty/`, `dist/`, `build/`, Coverage-Ordner, Logdateien und `.env*`-Dateien.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Fixieren und konfigurieren die vom Projekt verwendete Yarn-4-Toolchain.
|
||||
* **.nvmrc**: Legt die vom Projekt erwartete Node.js-Version fest.
|
||||
* **.oxlintrc.json** und **tsconfig.json**: Stellen Linting und TypeScript-Konfiguration für die TypeScript-Quellen Ihrer App bereit.
|
||||
* **README.md**: Ein kurzes README im App-Root mit grundlegenden Anweisungen.
|
||||
* **public/**: Ein Ordner zum Speichern öffentlicher Assets (Bilder, Schriftarten, statische Dateien), die zusammen mit Ihrer Anwendung bereitgestellt werden. Hier abgelegte Dateien werden während der Synchronisierung hochgeladen und sind zur Laufzeit zugänglich.
|
||||
* **src/**: Der Hauptort, an dem Sie Ihre Anwendung als Code definieren
|
||||
| File / Folder | Zweck |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | Skills, die die KI-Agenten von Twenty erweitern. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### Entitätserkennung
|
||||
## Managing remotes
|
||||
|
||||
Das SDK erkennt Entitäten, indem es Ihre TypeScript-Dateien nach Aufrufen von **`export default define<Entity>({...})`** parst. Für jeden Entitätstyp gibt es eine entsprechende Hilfsfunktion, die aus `twenty-sdk` exportiert wird:
|
||||
|
||||
| Hilfsfunktion | Entitätstyp |
|
||||
| -------------------------------- | ------------------------------------------------------------------------ |
|
||||
| `defineObject` | Benutzerdefinierte Objektdefinitionen |
|
||||
| `defineLogicFunction` | Definitionen von Logikfunktionen |
|
||||
| `definePreInstallLogicFunction` | Pre-Installations-Logikfunktion (wird vor der Installation ausgeführt) |
|
||||
| `definePostInstallLogicFunction` | Post-Installations-Logikfunktion (wird nach der Installation ausgeführt) |
|
||||
| `defineFrontComponent` | Definitionen von Frontend-Komponenten |
|
||||
| `defineRole` | Rollendefinitionen |
|
||||
| `defineField` | Felderweiterungen für bestehende Objekte |
|
||||
| `defineView` | Gespeicherte View-Definitionen |
|
||||
| `defineNavigationMenuItem` | Definitionen von Navigationsmenüeinträgen |
|
||||
| `defineSkill` | Skill-Definitionen für KI-Agenten |
|
||||
|
||||
<Note>
|
||||
**Dateibenennung ist flexibel.** Die Entitätserkennung ist AST-basiert — das SDK durchsucht Ihre Quelldateien nach dem Muster `export default define<Entity>({...})`. Sie können Ihre Dateien und Ordner nach Belieben organisieren. Die Gruppierung nach Entitätstyp (z. B. `logic-functions/`, `roles/`) ist lediglich eine Konvention zur Codeorganisation, keine Voraussetzung.
|
||||
</Note>
|
||||
|
||||
Beispiel für eine erkannte Entität:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
Spätere Befehle fügen weitere Dateien und Ordner hinzu:
|
||||
|
||||
* `yarn twenty dev` generiert den typisierten `CoreApiClient` (für Arbeitsbereichsdaten über `/graphql`) automatisch in `node_modules/twenty-client-sdk/`. Der `MetadataApiClient` (für Arbeitsbereichskonfiguration und Datei-Uploads über `/metadata`) wird vorkompiliert ausgeliefert und ist sofort verfügbar. Importieren Sie sie jeweils aus `twenty-client-sdk/core` und `twenty-client-sdk/metadata`.
|
||||
* `yarn twenty add` fügt unter `src/` Entitätsdefinitionsdateien für Ihre benutzerdefinierten Objekte, Funktionen, Frontend-Komponenten, Rollen, Skills und mehr hinzu.
|
||||
|
||||
## Authentifizierung
|
||||
|
||||
Wenn Sie `yarn twenty auth:login` zum ersten Mal ausführen, werden Sie nach Folgendem gefragt:
|
||||
|
||||
* API-URL (standardmäßig http://localhost:3000 oder Ihr aktuelles Workspace-Profil)
|
||||
* API-Schlüssel
|
||||
|
||||
Ihre Anmeldedaten werden pro Benutzer in `~/.twenty/config.json` gespeichert. Sie können mehrere Profile verwalten und zwischen ihnen wechseln.
|
||||
|
||||
### Arbeitsbereiche verwalten
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Sobald Sie mit `yarn twenty auth:switch` den Arbeitsbereich gewechselt haben, verwenden alle nachfolgenden Befehle standardmäßig diesen Arbeitsbereich. Sie können es weiterhin vorübergehend mit `--workspace <name>` überschreiben.
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### Server starten
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## Manuelle Einrichtung (ohne Scaffolder)
|
||||
|
||||
Wir empfehlen zwar `create-twenty-app` für das beste Einstiegserlebnis, Sie können ein Projekt aber auch manuell einrichten. Installieren Sie die CLI nicht global. Fügen Sie stattdessen `twenty-sdk` als lokale Abhängigkeit hinzu und binden Sie ein einzelnes Skript in Ihrer package.json ein:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
Fügen Sie dann ein `twenty`-Skript hinzu:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -210,25 +393,19 @@ Fügen Sie dann ein `twenty`-Skript hinzu:
|
||||
}
|
||||
```
|
||||
|
||||
Jetzt können Sie alle Befehle über `yarn twenty <command>` ausführen, z. B. `yarn twenty dev`, `yarn twenty help` usw.
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## So verwenden Sie eine lokale Twenty-Instanz
|
||||
|
||||
Wenn Sie bereits lokal eine Twenty-Instanz ausführen (z. B. über `npx nx start twenty-server`), können Sie sich damit verbinden, anstatt Docker zu verwenden:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
* Authentifizierungsfehler: Führen Sie `yarn twenty auth:login` aus und stellen Sie sicher, dass Ihr API-Schlüssel die erforderlichen Berechtigungen hat.
|
||||
* Verbindung zum Server nicht möglich: Überprüfen Sie die API-URL und dass der Twenty-Server erreichbar ist.
|
||||
* Typen oder Client fehlen oder sind veraltet: Starten Sie `yarn twenty dev` neu — der typisierte Client wird automatisch generiert.
|
||||
* Dev-Modus synchronisiert nicht: Stellen Sie sicher, dass `yarn twenty dev` läuft und dass Änderungen von Ihrer Umgebung nicht ignoriert werden.
|
||||
If you run into issues:
|
||||
|
||||
Discord-Hilfekanal: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,34 +4,76 @@ description: Veröffentlichen Sie Ihre Twenty-App auf dem Twenty-Marktplatz oder
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Apps befinden sich derzeit in der Alpha-Testphase. Die Funktion ist funktionsfähig, entwickelt sich jedoch noch weiter.
|
||||
Apps befinden sich derzeit in der Alpha-Phase. Die Funktion ist funktionsfähig, entwickelt sich jedoch noch weiter.
|
||||
</Warning>
|
||||
|
||||
## Übersicht
|
||||
|
||||
Sobald Ihre App [lokal gebaut und getestet](/l/de/developers/extend/apps/building) wurde, haben Sie zwei Möglichkeiten, sie zu verteilen:
|
||||
|
||||
* **Auf npm veröffentlichen** — führen Sie Ihre App im Twenty-Marktplatz auf, damit jeder Arbeitsbereich sie entdecken und installieren kann.
|
||||
* **Einen Tarball bereitstellen** — Laden Sie Ihre App direkt auf einen bestimmten Twenty-Server für die interne oder private Nutzung hoch.
|
||||
* **Auf npm veröffentlichen** — führen Sie Ihre App im Twenty-Marktplatz auf, damit jeder Arbeitsbereich sie entdecken und installieren kann.
|
||||
|
||||
Beide Pfade beginnen mit demselben **Build**-Schritt.
|
||||
|
||||
## Erstellen Ihrer App
|
||||
|
||||
Der Befehl `build` kompiliert Ihre TypeScript-Quelltexte, transpiliert Logikfunktionen und Frontend-Komponenten und erzeugt eine `manifest.json`, die die Inhalte Ihrer App beschreibt:
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
Die Ausgabe wird in `.twenty/output/` geschrieben. Dieses Verzeichnis enthält alles, was für die Verteilung benötigt wird: kompilierter Code, Assets, das Manifest und eine Kopie Ihrer `package.json`.
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
Um zusätzlich ein `.tgz`-Tarball zu erstellen (wird intern vom Deploy-Befehl verwendet oder für die manuelle Verteilung):
|
||||
## Bereitstellung auf einem Server (Tarball)
|
||||
|
||||
Für Apps, die Sie nicht öffentlich verfügbar machen möchten — proprietäre Tools, ausschließlich für Unternehmen bestimmte Integrationen oder experimentelle Builds — können Sie einen Tarball direkt auf einem Twenty-Server bereitstellen.
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
Bevor Sie bereitstellen, benötigen Sie ein konfiguriertes Remote, das auf den Zielserver zeigt. Remotes speichern die Server-URL und Anmeldeinformationen lokal in `~/.twenty/config.json`.
|
||||
|
||||
Ein Remote hinzufügen:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build --tarball
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### Bereitstellen
|
||||
|
||||
Bauen und laden Sie Ihre App in einem Schritt auf den Server hoch:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### Eine bereitgestellte App freigeben
|
||||
|
||||
Tarball-Apps werden nicht im öffentlichen Marktplatz gelistet, daher entdecken andere Arbeitsbereiche auf demselben Server sie nicht durch Stöbern. So geben Sie eine bereitgestellte App frei:
|
||||
|
||||
1. Gehen Sie zu **Einstellungen > Anwendungen > Registrierungen** und öffnen Sie Ihre App
|
||||
2. Klicken Sie im Tab **Distribution** auf **Freigabelink kopieren**
|
||||
3. Teilen Sie diesen Link mit Nutzern in anderen Arbeitsbereichen — er führt sie direkt zur Installationsseite der App
|
||||
|
||||
Der Freigabelink verwendet die Basis-URL des Servers (ohne Workspace-Subdomain), sodass er für jeden Arbeitsbereich auf dem Server funktioniert.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### Versionsverwaltung
|
||||
|
||||
So veröffentlichen Sie ein Update:
|
||||
|
||||
1. Erhöhen Sie das Feld `version` in Ihrer `package.json`
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. Arbeitsbereiche, die die App installiert haben, sehen in ihren Einstellungen, dass ein Upgrade verfügbar ist.
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## Auf npm veröffentlichen
|
||||
|
||||
Die Veröffentlichung auf npm macht Ihre App im Twenty-Marktplatz auffindbar. Jeder Twenty-Arbeitsbereich kann Marktplatz-Apps direkt über die Benutzeroberfläche durchsuchen, installieren und aktualisieren.
|
||||
@@ -39,41 +81,42 @@ Die Veröffentlichung auf npm macht Ihre App im Twenty-Marktplatz auffindbar. Je
|
||||
### Anforderungen
|
||||
|
||||
* Ein [npm](https://www.npmjs.com)-Konto
|
||||
* Das Schlüsselwort `twenty-app` **muss** in Ihrem `package.json`-`keywords`-Array aufgeführt sein
|
||||
|
||||
### Das erforderliche Schlüsselwort hinzufügen
|
||||
|
||||
Der Twenty-Marktplatz entdeckt Apps, indem er die npm-Registry nach Paketen mit dem Schlüsselwort `twenty-app` durchsucht. Fügen Sie es zu Ihrer `package.json` hinzu:
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"],
|
||||
...
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Der Marktplatz sucht in der npm-Registry nach `keywords:twenty-app`. Ohne dieses Schlüsselwort erscheint Ihr Paket nicht im Marktplatz, selbst wenn es das Namenspräfix `twenty-app-` hat.
|
||||
</Note>
|
||||
### Marktplatz-Metadaten
|
||||
|
||||
### Schritte
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
1. **Erstellen Ihrer App:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
2. **Auf npm veröffentlichen:**
|
||||
See the [defineApplication accordion](/l/de/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
Dies führt `npm publish` aus dem Verzeichnis `.twenty/output/` aus.
|
||||
|
||||
Um unter einem bestimmten dist-tag zu veröffentlichen (z. B. `beta` oder `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
@@ -82,25 +125,17 @@ yarn twenty publish --tag beta
|
||||
|
||||
### So funktioniert die Marktplatz-Erkennung
|
||||
|
||||
Der Twenty-Server synchronisiert seinen Marktplatzkatalog **stündlich** mit der npm-Registry:
|
||||
The Twenty server syncs its marketplace catalog from the npm registry **every hour**.
|
||||
|
||||
1. Er sucht nach allen npm-Paketen mit dem Schlüsselwort `keywords:twenty-app`
|
||||
2. Für jedes Paket ruft er die `manifest.json` vom npm-CDN ab
|
||||
3. Die Metadaten der App (Name, Beschreibung, Autor, Logo, Screenshots, Kategorie) werden aus dem Manifest extrahiert und im Marktplatz angezeigt
|
||||
|
||||
Nach der Veröffentlichung kann es bis zu einer Stunde dauern, bis Ihre App im Marktplatz erscheint. Um die Synchronisierung sofort auszulösen, statt auf den nächsten stündlichen Lauf zu warten:
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
Um ein bestimmtes Remote anzusteuern:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync -r production
|
||||
```
|
||||
|
||||
Die im Marktplatz angezeigten Metadaten stammen aus Ihrem `defineApplication()`-Aufruf im Quellcode Ihrer App — Felder wie `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl` und `termsUrl`.
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
Wenn deine App keine `aboutDescription` in `defineApplication()` definiert, verwendet der Marktplatz automatisch die `README.md` deines Pakets von npm als Inhalt der Über-uns-Seite. Das bedeutet, dass du eine einzige README sowohl für npm als auch für den Twenty-Marktplatz pflegen kannst. Wenn du im Marktplatz eine andere Beschreibung möchtest, setze `aboutDescription` explizit.
|
||||
@@ -108,7 +143,7 @@ Wenn deine App keine `aboutDescription` in `defineApplication()` definiert, verw
|
||||
|
||||
### CI-Veröffentlichung
|
||||
|
||||
Das vorgefertigte Projekt enthält einen GitHub-Actions-Workflow, der bei jedem Release eine Veröffentlichung durchführt:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -133,121 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
Für andere CI-Systeme (GitLab CI, CircleCI usw.) gelten die gleichen drei Befehle: `yarn install`, `yarn twenty build` und anschließend `npm publish` aus `.twenty/output`.
|
||||
|
||||
<Tip>
|
||||
<Note>
|
||||
**npm-Provenance** ist optional, wird jedoch empfohlen. Das Veröffentlichen mit `--provenance` fügt Ihrem npm-Eintrag ein Vertrauensabzeichen hinzu, sodass Nutzer überprüfen können, dass das Paket aus einem bestimmten Commit in einer öffentlichen CI-Pipeline gebaut wurde. Siehe die [npm-Provenance-Dokumentation](https://docs.npmjs.com/generating-provenance-statements) für Einrichtungshinweise.
|
||||
</Tip>
|
||||
|
||||
## Bereitstellung auf einem Server (Tarball)
|
||||
|
||||
Für Apps, die Sie nicht öffentlich verfügbar machen möchten — proprietäre Tools, ausschließlich für Unternehmen bestimmte Integrationen oder experimentelle Builds — können Sie einen Tarball direkt auf einem Twenty-Server bereitstellen.
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
Bevor Sie bereitstellen, benötigen Sie ein konfiguriertes Remote, das auf den Zielserver zeigt. Remotes speichern die Server-URL und Anmeldeinformationen lokal in `~/.twenty/config.json`.
|
||||
|
||||
Ein Remote hinzufügen:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
Für einen lokalen Entwicklungsserver:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --local --as local
|
||||
```
|
||||
|
||||
Sie können sich in nicht interaktiven Umgebungen auch mit einem API-Schlüssel authentifizieren:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
|
||||
```
|
||||
|
||||
Ihre Remotes verwalten:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote list # List all configured remotes
|
||||
yarn twenty remote switch prod # Set the default remote
|
||||
yarn twenty remote status # Show active remote and auth status
|
||||
yarn twenty remote remove old # Remove a remote
|
||||
```
|
||||
|
||||
### Bereitstellen
|
||||
|
||||
Bauen und laden Sie Ihre App in einem Schritt auf den Server hoch:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
```
|
||||
|
||||
Dies baut die App mit `--tarball` und lädt anschließend den Tarball per GraphQL-Multipart-Upload auf das Standard-Remote hoch.
|
||||
|
||||
Um auf ein bestimmtes Remote bereitzustellen:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy -r production
|
||||
```
|
||||
|
||||
### Eine bereitgestellte App freigeben
|
||||
|
||||
Tarball-Apps werden nicht im öffentlichen Marktplatz gelistet, daher entdecken andere Arbeitsbereiche auf demselben Server sie nicht durch Stöbern. So geben Sie eine bereitgestellte App frei:
|
||||
|
||||
1. Gehen Sie zu **Einstellungen > Anwendungen > Registrierungen** und öffnen Sie Ihre App
|
||||
2. Klicken Sie im Tab **Distribution** auf **Freigabelink kopieren**
|
||||
3. Teilen Sie diesen Link mit Nutzern in anderen Arbeitsbereichen — er führt sie direkt zur Installationsseite der App
|
||||
|
||||
Der Freigabelink verwendet die Basis-URL des Servers (ohne Workspace-Subdomain), sodass er für jeden Arbeitsbereich auf dem Server funktioniert.
|
||||
|
||||
### Versionsverwaltung
|
||||
|
||||
So veröffentlichen Sie ein Update:
|
||||
|
||||
1. Erhöhen Sie das Feld `version` in Ihrer `package.json`
|
||||
2. Führen Sie `yarn twenty deploy` aus (oder `yarn twenty deploy -r production`)
|
||||
3. Arbeitsbereiche, die die App installiert haben, sehen in ihren Einstellungen, dass ein Upgrade verfügbar ist.
|
||||
</Note>
|
||||
|
||||
## Apps installieren
|
||||
|
||||
Sobald eine App veröffentlicht (npm) oder bereitgestellt (Tarball) wurde, installieren Arbeitsbereiche sie über die Benutzeroberfläche:
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
Oder über die Seite **Einstellungen > Anwendungen** in der Twenty-Oberfläche, wo sowohl Marktplatz- als auch per Tarball bereitgestellte Apps durchsucht und installiert werden können.
|
||||
|
||||
## Kategorien der App-Verteilung
|
||||
|
||||
Twenty organisiert Apps in drei Kategorien, basierend auf ihrer Vertriebsart:
|
||||
|
||||
| Kategorie | Wie es funktioniert | Im Marktplatz sichtbar? |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| **Entwicklung** | Lokale Apps im Entwicklungsmodus, die über `yarn twenty dev` ausgeführt werden. Zum Erstellen und Testen verwendet. | Nein |
|
||||
| **Veröffentlicht (npm)** | Auf npm veröffentlichte Apps mit dem Schlüsselwort `twenty-app`. Im Marktplatz gelistet, damit jeder Arbeitsbereich sie installieren kann. | Ja |
|
||||
| **Intern (Tarball)** | Apps, die per Tarball auf einen bestimmten Server bereitgestellt werden. Nur für Arbeitsbereiche auf diesem Server per Freigabelink verfügbar. | Nein |
|
||||
|
||||
<Tip>
|
||||
Beginnen Sie im **Entwicklungsmodus**, während Sie Ihre App erstellen. Wenn sie bereit ist, wählen Sie **Veröffentlicht** (npm) für die breite Verteilung oder **Intern** (Tarball) für die private Bereitstellung.
|
||||
</Tip>
|
||||
|
||||
## CLI-Referenz
|
||||
|
||||
| Befehl | Beschreibung | Wichtige Flags |
|
||||
| --------------------------- | --------------------------------------------------------------- | --------------------------------------------------- |
|
||||
| `yarn twenty build` | App kompilieren und Manifest erzeugen | `--tarball` — zusätzlich ein `.tgz`-Paket erstellen |
|
||||
| `yarn twenty publish` | Bauen und auf npm veröffentlichen | `--tag <tag>` — npm-dist-tag (z. B. `beta`, `next`) |
|
||||
| `yarn twenty deploy` | Tarball bauen und auf einen Server hochladen | `-r, --remote <name>` — Ziel-Remote |
|
||||
| `yarn twenty catalog-sync` | Synchronisierung des Marktplatzkatalogs auf dem Server auslösen | `-r, --remote <name>` — Ziel-Remote |
|
||||
| `yarn twenty install` | Eine bereitgestellte App in einem Arbeitsbereich installieren | `-r, --remote <name>` — Ziel-Remote |
|
||||
| `yarn twenty dev` | Lokale Änderungen beobachten und synchronisieren | Verwendet das Standard-Remote |
|
||||
| `yarn twenty remote add` | Eine Serververbindung hinzufügen | `--url`, `--token`, `--as`, `--local`, `--port` |
|
||||
| `yarn twenty remote list` | Konfigurierte Remotes auflisten | — |
|
||||
| `yarn twenty remote switch` | Standard-Remote festlegen | — |
|
||||
| `yarn twenty remote status` | Verbindungsstatus anzeigen | — |
|
||||
| `yarn twenty remote remove` | Ein Remote entfernen | — |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,73 +4,142 @@ description: Crea la tua prima app Twenty in pochi minuti.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Le app sono attualmente in fase alfa. La funzionalità è funzionante ma ancora in evoluzione.
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
Le app ti permettono di estendere Twenty con oggetti, campi, funzioni logiche, competenze IA e componenti UI personalizzati — il tutto gestito come codice.
|
||||
|
||||
**Cosa puoi creare:**
|
||||
|
||||
* Oggetti, campi, viste ed elementi di navigazione personalizzati per definire il tuo modello di dati
|
||||
* Funzioni logiche attivate da route HTTP, pianificazioni cron o eventi del database
|
||||
* Componenti front-end che vengono renderizzati direttamente all'interno della UI di Twenty
|
||||
* Abilità che estendono gli agenti IA di Twenty
|
||||
* Distribuisci un'app su più spazi di lavoro
|
||||
|
||||
## Prerequisiti
|
||||
|
||||
* Node.js 24+
|
||||
* Yarn 4
|
||||
* Docker (o un'istanza locale di Twenty in esecuzione)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## Per iniziare
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
Crea una nuova app utilizzando lo scaffolder ufficiale, quindi autenticati e inizia a sviluppare:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
> Usa l'opzione `--minimal` per creare un'installazione minima
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
Da qui puoi:
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
Vedi anche: le pagine di riferimento della CLI per [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) e [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
## Struttura del progetto (generata dallo scaffolder)
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
Quando esegui `npx create-twenty-app@latest my-twenty-app`, lo scaffolder:
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
* Copia un'applicazione base minimale in `my-twenty-app/`
|
||||
* Aggiunge una dipendenza locale `twenty-sdk` e la configurazione di Yarn 4
|
||||
* Crea file di configurazione e script collegati alla CLI `twenty`
|
||||
* Genera i file principali (configurazione dell'applicazione, ruolo predefinito per le funzioni logiche, funzioni di pre-installazione e post-installazione) più i file di esempio in base alla modalità di scaffolding
|
||||
<Warning>
|
||||
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](/l/it/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
Un'app appena creata con la modalità predefinita `--exhaustive` si presenta così:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Head over to [Building Apps](/l/it/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -83,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
Con `--minimal`, vengono creati solo i file principali (`application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` e `logic-functions/post-install.ts`).
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
A livello generale:
|
||||
### Key files
|
||||
|
||||
* **package.json**: Dichiara il nome dell'app, la versione, i motori (Node 24+, Yarn 4) e aggiunge `twenty-sdk` più uno script `twenty` che delega alla CLI locale `twenty`. Esegui `yarn twenty help` per elencare tutti i comandi disponibili.
|
||||
* **.gitignore**: Ignora i file generati comuni come `node_modules`, `.yarn`, `.twenty/`, `dist/`, `build/`, cartelle di coverage, file di log e file `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Bloccano e configurano la toolchain Yarn 4 utilizzata dal progetto.
|
||||
* **.nvmrc**: Fissa la versione di Node.js prevista dal progetto.
|
||||
* **.oxlintrc.json** e **tsconfig.json**: Forniscono linting e configurazione TypeScript per i sorgenti TypeScript della tua app.
|
||||
* **README.md**: Un breve README nella radice dell'app con istruzioni di base.
|
||||
* **public/**: Una cartella per archiviare risorse pubbliche (immagini, font, file statici) che saranno servite con la tua applicazione. I file collocati qui vengono caricati durante la sincronizzazione e sono accessibili in fase di esecuzione.
|
||||
* **src/**: Il luogo principale in cui definisci la tua applicazione come codice
|
||||
| File / Folder | Scopo |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | Abilità che estendono gli agenti IA di Twenty. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### Rilevamento delle entità
|
||||
## Managing remotes
|
||||
|
||||
L'SDK rileva le entità analizzando i tuoi file TypeScript alla ricerca di chiamate **`export default define<Entity>({...})`**. Ogni tipo di entità ha una corrispondente funzione helper esportata da `twenty-sdk`:
|
||||
|
||||
| Funzione helper | Tipo di entità |
|
||||
| -------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| `defineObject` | Definizioni di oggetti personalizzati |
|
||||
| `defineLogicFunction` | Definizioni di funzioni logiche |
|
||||
| `definePreInstallLogicFunction` | Funzione logica di pre-installazione (viene eseguita prima dell'installazione) |
|
||||
| `definePostInstallLogicFunction` | Funzione logica di post-installazione (viene eseguita dopo l'installazione) |
|
||||
| `defineFrontComponent` | Definizioni dei componenti front-end |
|
||||
| `defineRole` | Definizioni di ruoli |
|
||||
| `defineField` | Estensioni di campo per oggetti esistenti |
|
||||
| `defineView` | Definizioni di viste salvate |
|
||||
| `defineNavigationMenuItem` | Definizioni delle voci del menu di navigazione |
|
||||
| `defineSkill` | Definizioni delle competenze degli agenti IA |
|
||||
|
||||
<Note>
|
||||
**La denominazione dei file è flessibile.** Il rilevamento delle entità è basato sull'AST — l'SDK esegue la scansione dei file sorgente alla ricerca del pattern `export default define<Entity>({...})`. Puoi organizzare file e cartelle come preferisci. Raggruppare per tipo di entità (ad es., `logic-functions/`, `roles/`) è solo una convenzione per l'organizzazione del codice, non un requisito.
|
||||
</Note>
|
||||
|
||||
Esempio di entità rilevata:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
Comandi successivi aggiungeranno altri file e cartelle:
|
||||
|
||||
* `yarn twenty dev` genererà automaticamente il `CoreApiClient` tipizzato (per i dati dell'area di lavoro via `/graphql`) in `node_modules/twenty-client-sdk/`. Il `MetadataApiClient` (per la configurazione dell'area di lavoro e il caricamento di file via `/metadata`) è fornito precompilato ed è disponibile immediatamente. Importali da `twenty-client-sdk/core` e `twenty-client-sdk/metadata` rispettivamente.
|
||||
* `yarn twenty add` aggiungerà file di definizione delle entità sotto `src/` per i tuoi oggetti personalizzati, funzioni, componenti front-end, ruoli, competenze e altro ancora.
|
||||
|
||||
## Autenticazione
|
||||
|
||||
La prima volta che esegui `yarn twenty auth:login`, ti verranno richiesti:
|
||||
|
||||
* URL dell'API (predefinito a http://localhost:3000 o al profilo dello spazio di lavoro corrente)
|
||||
* Chiave API
|
||||
|
||||
Le tue credenziali sono archiviate per utente in `~/.twenty/config.json`. Puoi mantenere più profili e passare da uno all'altro.
|
||||
|
||||
### Gestione delle aree di lavoro
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Una volta che hai cambiato area di lavoro con `yarn twenty auth:switch`, tutti i comandi successivi utilizzeranno quell'area di lavoro per impostazione predefinita. Puoi comunque sovrascriverla temporaneamente con `--workspace <name>`.
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### Avvio del server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| Comando | Descrizione |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## Configurazione manuale (senza lo scaffolder)
|
||||
|
||||
Sebbene consigliamo di utilizzare `create-twenty-app` per la migliore esperienza iniziale, puoi anche configurare un progetto manualmente. Non installare la CLI globalmente. Invece, aggiungi `twenty-sdk` come dipendenza locale e collega un unico script nel tuo package.json:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
Quindi aggiungi uno script `twenty`:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -210,25 +393,19 @@ Quindi aggiungi uno script `twenty`:
|
||||
}
|
||||
```
|
||||
|
||||
Ora puoi eseguire tutti i comandi tramite `yarn twenty <command>`, ad es. `yarn twenty dev`, `yarn twenty help`, ecc.
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## Come utilizzare un'istanza locale di Twenty
|
||||
|
||||
Se stai già eseguendo un'istanza di Twenty in locale (ad es. tramite `npx nx start twenty-server`), puoi connetterti ad essa invece di usare Docker:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## Risoluzione dei problemi
|
||||
|
||||
* Errori di autenticazione: esegui `yarn twenty auth:login` e assicurati che la tua chiave API abbia i permessi richiesti.
|
||||
* Impossibile connettersi al server: verifica l'URL dell'API e che il server Twenty sia raggiungibile.
|
||||
* Tipi o client mancanti/obsoleti: riavvia `yarn twenty dev` — genera automaticamente il client tipizzato.
|
||||
* Modalità di sviluppo non sincronizzata: assicurati che `yarn twenty dev` sia in esecuzione e che le modifiche non vengano ignorate dal tuo ambiente.
|
||||
If you run into issues:
|
||||
|
||||
Canale di supporto su Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,34 +4,76 @@ description: Distribuisci la tua app Twenty nel marketplace oppure distribuiscil
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Le app sono attualmente in fase alfa. La funzionalità è funzionante ma ancora in evoluzione.
|
||||
Le app sono attualmente in fase alfa. La funzionalità funziona ma è ancora in evoluzione.
|
||||
</Warning>
|
||||
|
||||
## Panoramica
|
||||
|
||||
Una volta che la tua app è stata [compilata e testata localmente](/l/it/developers/extend/apps/building), hai due modalità per distribuirla:
|
||||
|
||||
* **Pubblica su npm** — elenca la tua app nel marketplace di Twenty affinché qualsiasi spazio di lavoro possa scoprirla e installarla.
|
||||
* **Distribuisci un tarball** — carica la tua app direttamente su un server Twenty specifico per uso interno o privato.
|
||||
* **Pubblica su npm** — elenca la tua app nel marketplace di Twenty affinché qualsiasi spazio di lavoro possa scoprirla e installarla.
|
||||
|
||||
Entrambi i percorsi partono dalla stessa fase di **build**.
|
||||
|
||||
## Compilazione della tua app
|
||||
|
||||
Il comando `build` compila i tuoi sorgenti TypeScript, transpila le funzioni di logica e i componenti front-end e genera un `manifest.json` che descrive i contenuti della tua app:
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
L'output viene scritto in `.twenty/output/`. Questa directory contiene tutto il necessario per la distribuzione: codice compilato, risorse, il manifest e una copia del tuo `package.json`.
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
Per creare anche un tarball `.tgz` (usato internamente dal comando di deploy o per la distribuzione manuale):
|
||||
## Distribuzione su un server (tarball)
|
||||
|
||||
Per le app che non vuoi rendere pubbliche — strumenti proprietari, integrazioni solo aziendali o build sperimentali — puoi distribuire un tarball direttamente su un server Twenty.
|
||||
|
||||
### Prerequisiti
|
||||
|
||||
Prima della distribuzione, ti serve un remote configurato che punti al server di destinazione. I remote memorizzano localmente l'URL del server e le credenziali di autenticazione in `~/.twenty/config.json`.
|
||||
|
||||
Aggiungi un remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build --tarball
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### Distribuzione
|
||||
|
||||
Compila e carica la tua app sul server in un solo passaggio:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### Condivisione di un'app distribuita
|
||||
|
||||
Le app in formato tarball non sono elencate nel marketplace pubblico, quindi altri spazi di lavoro sullo stesso server non le troveranno navigando. Per condividere un'app distribuita:
|
||||
|
||||
1. Vai su **Impostazioni > Applicazioni > Registrazioni** e apri la tua app
|
||||
2. Nella scheda **Distribuzione**, fai clic su **Copia link di condivisione**
|
||||
3. Condividi questo link con utenti su altri spazi di lavoro — li porterà direttamente alla pagina di installazione dell'app
|
||||
|
||||
Il link di condivisione utilizza l'URL di base del server (senza alcun sottodominio dello spazio di lavoro) così funziona per qualsiasi spazio di lavoro sul server.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### Gestione delle versioni
|
||||
|
||||
Per rilasciare un aggiornamento:
|
||||
|
||||
1. Incrementa il campo `version` nel tuo `package.json`
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. Gli spazi di lavoro che hanno l'app installata vedranno l'aggiornamento disponibile nelle proprie impostazioni
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## Pubblicazione su npm
|
||||
|
||||
La pubblicazione su npm rende la tua app scopribile nel marketplace di Twenty. Qualsiasi spazio di lavoro Twenty può sfogliare, installare e aggiornare le app del marketplace direttamente dall'interfaccia utente.
|
||||
@@ -39,41 +81,42 @@ La pubblicazione su npm rende la tua app scopribile nel marketplace di Twenty. Q
|
||||
### Requisiti
|
||||
|
||||
* Un account [npm](https://www.npmjs.com)
|
||||
* La parola chiave `twenty-app` **deve** essere elencata nell'array `keywords` del tuo `package.json`
|
||||
|
||||
### Aggiunta della parola chiave richiesta
|
||||
|
||||
Il marketplace di Twenty individua le app cercando nel registro npm i pacchetti con la parola chiave `twenty-app`. Aggiungila al tuo `package.json`:
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"],
|
||||
...
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Il marketplace cerca `keywords:twenty-app` sul registro npm. Senza questa parola chiave, il tuo pacchetto non apparirà nel marketplace anche se ha il prefisso nel nome `twenty-app-`.
|
||||
</Note>
|
||||
### Metadati del marketplace
|
||||
|
||||
### Passaggi
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
1. **Compila la tua app:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
2. **Pubblica su npm:**
|
||||
See the [defineApplication accordion](/l/it/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
Questo esegue `npm publish` dalla directory `.twenty/output/`.
|
||||
|
||||
Per pubblicare con un dist-tag specifico (ad es. `beta` o `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
@@ -82,25 +125,17 @@ yarn twenty publish --tag beta
|
||||
|
||||
### Come funziona l'individuazione nel marketplace
|
||||
|
||||
Il server Twenty sincronizza il proprio catalogo del marketplace dal registro npm **ogni ora**:
|
||||
Il server Twenty sincronizza il proprio catalogo del marketplace dal registro npm **ogni ora**.
|
||||
|
||||
1. Cerca tutti i pacchetti npm con `keywords:twenty-app`
|
||||
2. Per ogni pacchetto, recupera il `manifest.json` dalla CDN di npm
|
||||
3. I metadati dell'app (nome, descrizione, autore, logo, screenshot, categoria) vengono estratti dal manifest e visualizzati nel marketplace
|
||||
|
||||
Dopo la pubblicazione, la tua app può impiegare fino a un'ora per apparire nel marketplace. Per attivare subito la sincronizzazione invece di attendere la prossima esecuzione oraria:
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
Per puntare a un remote specifico:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync -r production
|
||||
```
|
||||
|
||||
I metadati mostrati nel marketplace provengono dalla chiamata a `defineApplication()` nel codice sorgente della tua app — campi come `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl` e `termsUrl`.
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
Se la tua app non definisce un `aboutDescription` in `defineApplication()`, il marketplace userà automaticamente il `README.md` del tuo pacchetto su npm come contenuto della pagina Informazioni. Questo significa che puoi mantenere un unico README sia per npm sia per il marketplace di Twenty. Se desideri una descrizione diversa nel marketplace, imposta esplicitamente `aboutDescription`.
|
||||
@@ -108,7 +143,7 @@ Se la tua app non definisce un `aboutDescription` in `defineApplication()`, il m
|
||||
|
||||
### Pubblicazione con CI
|
||||
|
||||
Il progetto generato include un workflow di GitHub Actions che pubblica a ogni release:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -133,121 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
Per altri sistemi CI (GitLab CI, CircleCI, ecc.), si applicano gli stessi tre comandi: `yarn install`, `yarn twenty build`, quindi `npm publish` da `.twenty/output`.
|
||||
|
||||
<Tip>
|
||||
<Note>
|
||||
**npm provenance** è opzionale ma consigliata. La pubblicazione con `--provenance` aggiunge un badge di attendibilità alla tua scheda npm, consentendo agli utenti di verificare che il pacchetto sia stato creato a partire da uno specifico commit in una pipeline CI pubblica. Consulta la [documentazione su npm provenance](https://docs.npmjs.com/generating-provenance-statements) per le istruzioni di configurazione.
|
||||
</Tip>
|
||||
|
||||
## Distribuzione su un server (tarball)
|
||||
|
||||
Per le app che non vuoi rendere pubbliche — strumenti proprietari, integrazioni solo aziendali o build sperimentali — puoi distribuire un tarball direttamente su un server Twenty.
|
||||
|
||||
### Prerequisiti
|
||||
|
||||
Prima della distribuzione, ti serve un remote configurato che punti al server di destinazione. I remote memorizzano localmente l'URL del server e le credenziali di autenticazione in `~/.twenty/config.json`.
|
||||
|
||||
Aggiungi un remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
Per un server di sviluppo locale:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --local --as local
|
||||
```
|
||||
|
||||
Puoi anche autenticarti con una chiave API per ambienti non interattivi:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
|
||||
```
|
||||
|
||||
Gestisci i tuoi remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote list # List all configured remotes
|
||||
yarn twenty remote switch prod # Set the default remote
|
||||
yarn twenty remote status # Show active remote and auth status
|
||||
yarn twenty remote remove old # Remove a remote
|
||||
```
|
||||
|
||||
### Distribuzione
|
||||
|
||||
Compila e carica la tua app sul server in un solo passaggio:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
```
|
||||
|
||||
Questo compila l'app con `--tarball`, quindi carica il tarball sul remote predefinito tramite un upload multipart GraphQL.
|
||||
|
||||
Per distribuire su un remote specifico:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy -r production
|
||||
```
|
||||
|
||||
### Condivisione di un'app distribuita
|
||||
|
||||
Le app in formato tarball non sono elencate nel marketplace pubblico, quindi altri spazi di lavoro sullo stesso server non le troveranno navigando. Per condividere un'app distribuita:
|
||||
|
||||
1. Vai su **Impostazioni > Applicazioni > Registrazioni** e apri la tua app
|
||||
2. Nella scheda **Distribuzione**, fai clic su **Copia link di condivisione**
|
||||
3. Condividi questo link con utenti su altri spazi di lavoro — li porterà direttamente alla pagina di installazione dell'app
|
||||
|
||||
Il link di condivisione utilizza l'URL di base del server (senza alcun sottodominio dello spazio di lavoro) così funziona per qualsiasi spazio di lavoro sul server.
|
||||
|
||||
### Gestione delle versioni
|
||||
|
||||
Per rilasciare un aggiornamento:
|
||||
|
||||
1. Incrementa il campo `version` nel tuo `package.json`
|
||||
2. Esegui `yarn twenty deploy` (oppure `yarn twenty deploy -r production`)
|
||||
3. Gli spazi di lavoro che hanno l'app installata vedranno l'aggiornamento disponibile nelle proprie impostazioni
|
||||
</Note>
|
||||
|
||||
## Installazione delle app
|
||||
|
||||
Una volta che un'app è stata pubblicata (npm) o distribuita (tarball), gli spazi di lavoro la installano tramite l'interfaccia utente:
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
Oppure dalla pagina **Impostazioni > Applicazioni** nell'interfaccia di Twenty, dove è possibile sfogliare e installare sia le app del marketplace sia quelle distribuite tramite tarball.
|
||||
|
||||
## Categorie di distribuzione delle app
|
||||
|
||||
Twenty organizza le app in tre categorie in base a come vengono distribuite:
|
||||
|
||||
| Categoria | Come funziona | Visibile nel marketplace? |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- |
|
||||
| **Sviluppo** | App in modalità di sviluppo locale eseguite tramite `yarn twenty dev`. Usate per la compilazione e i test. | No |
|
||||
| **Pubblicate (npm)** | App pubblicate su npm con la parola chiave `twenty-app`. Elencate nel marketplace per l'installazione da parte di qualsiasi spazio di lavoro. | Sì |
|
||||
| **Interne (tarball)** | App distribuite tramite tarball su un server specifico. Disponibili solo per gli spazi di lavoro su quel server tramite un link di condivisione. | No |
|
||||
|
||||
<Tip>
|
||||
Inizia in modalità **Sviluppo** mentre crei la tua app. Quando è pronta, scegli **Pubblicata** (npm) per un'ampia distribuzione oppure **Interna** (tarball) per una distribuzione privata.
|
||||
</Tip>
|
||||
|
||||
## Riferimento CLI
|
||||
|
||||
| Comando | Descrizione | Flag principali |
|
||||
| --------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------- |
|
||||
| `yarn twenty build` | Compila l'app e genera il manifest | `--tarball` — crea anche un pacchetto `.tgz` |
|
||||
| `yarn twenty publish` | Compila e pubblica su npm | `--tag <tag>` — dist-tag npm (ad es. `beta`, `next`) |
|
||||
| `yarn twenty deploy` | Compila e carica un tarball su un server | `-r, --remote <name>` — remote di destinazione |
|
||||
| `yarn twenty catalog-sync` | Attiva la sincronizzazione del catalogo del marketplace sul server | `-r, --remote <name>` — remote di destinazione |
|
||||
| `yarn twenty install` | Installa un'app distribuita su uno spazio di lavoro | `-r, --remote <name>` — remote di destinazione |
|
||||
| `yarn twenty dev` | Osserva e sincronizza le modifiche locali | Usa il remote predefinito |
|
||||
| `yarn twenty remote add` | Aggiungi una connessione al server | `--url`, `--token`, `--as`, `--local`, `--port` |
|
||||
| `yarn twenty remote list` | Elenca i remote configurati | — |
|
||||
| `yarn twenty remote switch` | Imposta il remote predefinito | — |
|
||||
| `yarn twenty remote status` | Mostra lo stato della connessione | — |
|
||||
| `yarn twenty remote remove` | Rimuovi un remote | — |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,84 +4,142 @@ description: Crie seu primeiro app do Twenty em minutos.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Os aplicativos estão atualmente em testes alfa. O recurso é funcional, mas ainda está evoluindo.
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
Os apps permitem que você estenda o Twenty com objetos, campos, funções de lógica, habilidades de IA e componentes de UI personalizados — tudo gerenciado como código.
|
||||
|
||||
**O que você pode fazer hoje:**
|
||||
|
||||
* Defina objetos e campos personalizados como código (modelo de dados gerenciado)
|
||||
* Crie funções de lógica com gatilhos personalizados (rotas HTTP, cron, eventos de banco de dados)
|
||||
* Defina habilidades para agentes de IA
|
||||
* Crie componentes de front-end que renderizam dentro da UI do Twenty
|
||||
* Implemente o mesmo aplicativo em vários espaços de trabalho
|
||||
|
||||
## Pré-requisitos
|
||||
|
||||
* Node.js 24+ e Yarn 4
|
||||
* Docker (para o servidor de desenvolvimento local do Twenty)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## Primeiros passos
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
Crie um novo aplicativo usando o gerador oficial, depois autentique-se e comece a desenvolver:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
cd my-twenty-app
|
||||
```
|
||||
|
||||
# Start dev mode: automatically syncs local changes to your workspace
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
O gerador de estrutura oferece suporte a dois modos para controlar quais arquivos de exemplo são incluídos:
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Default (exhaustive): all examples (object, field, logic function, front component, view, navigation menu item, skill, agent)
|
||||
npx create-twenty-app@latest my-app
|
||||
|
||||
# Minimal: only core files (application-config.ts and default-role.ts)
|
||||
npx create-twenty-app@latest my-app --minimal
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
A partir daqui você pode:
|
||||
<Warning>
|
||||
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](/l/pt/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty entity:add
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
```
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
Veja também: as páginas de referência da CLI para [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) e [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
## Estrutura do projeto (com scaffold)
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
Ao executar `npx create-twenty-app@latest my-twenty-app`, o gerador:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
* Copia um aplicativo base mínimo para `my-twenty-app/`
|
||||
* Adiciona uma dependência local `twenty-sdk` e a configuração do Yarn 4
|
||||
* Cria arquivos de configuração e scripts conectados à CLI `twenty`
|
||||
* Gera arquivos principais (configuração da aplicação, papel padrão para funções de lógica, funções de pré-instalação e pós-instalação) além de arquivos de exemplo com base no modo de geração de estrutura
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Um app recém-criado com o modo padrão `--exhaustive` fica assim:
|
||||
Head over to [Building Apps](/l/pt/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -94,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
Com `--minimal`, apenas os arquivos principais são criados (`application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` e `logic-functions/post-install.ts`).
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
Em alto nível:
|
||||
### Key files
|
||||
|
||||
* **package.json**: Declara o nome do app, versão, engines (Node 24+, Yarn 4), e adiciona `twenty-sdk` além de um script `twenty` que delega para a CLI `twenty` local. Execute `yarn twenty help` para listar todos os comandos disponíveis.
|
||||
* **.gitignore**: Ignora artefatos comuns como `node_modules`, `.yarn`, `generated/` (cliente tipado), `dist/`, `build/`, pastas de cobertura, arquivos de log e arquivos `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Bloqueiam e configuram a ferramenta Yarn 4 usada pelo projeto.
|
||||
* **.nvmrc**: Fixa a versão do Node.js esperada pelo projeto.
|
||||
* **.oxlintrc.json** e **tsconfig.json**: Fornecem lint e configuração do TypeScript para os fontes TypeScript do seu aplicativo.
|
||||
* **README.md**: Um README curto na raiz do aplicativo com instruções básicas.
|
||||
* **public/**: Uma pasta para armazenar recursos públicos (imagens, fontes, arquivos estáticos) que serão servidos com sua aplicação. Os arquivos colocados aqui são enviados durante a sincronização e ficam acessíveis em tempo de execução.
|
||||
* **src/**: O local principal onde você define seu aplicativo como código
|
||||
| File / Folder | Finalidade |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | Habilidades que estendem os agentes de IA do Twenty. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### Detecção de entidades
|
||||
## Managing remotes
|
||||
|
||||
O SDK detecta entidades analisando seus arquivos TypeScript em busca de chamadas **`export default define<Entity>({...})`**. Cada tipo de entidade tem uma função utilitária correspondente exportada de `twenty-sdk`:
|
||||
|
||||
| Função utilitária | Tipo de entidade |
|
||||
| -------------------------------- | -------------------------------------------------------------------- |
|
||||
| `defineObject` | Definições de objetos personalizados |
|
||||
| `defineLogicFunction` | Definições de funções de lógica |
|
||||
| `definePreInstallLogicFunction` | Função de lógica de pré-instalação (é executada antes da instalação) |
|
||||
| `definePostInstallLogicFunction` | Função de lógica de pós-instalação (é executada após a instalação) |
|
||||
| `defineFrontComponent` | Definições de componentes de front-end |
|
||||
| `defineRole` | Definições de papéis |
|
||||
| `defineField` | Extensões de campos para objetos existentes |
|
||||
| `defineView` | Definições de visualizações salvas |
|
||||
| `defineNavigationMenuItem` | Definições de itens do menu de navegação |
|
||||
| `defineSkill` | Definições de habilidades de agente de IA |
|
||||
|
||||
<Note>
|
||||
**A nomeação de arquivos é flexível.** A detecção de entidades é baseada em AST — o SDK varre seus arquivos fonte em busca do padrão `export default define<Entity>({...})`. Você pode organizar seus arquivos e pastas como quiser. Agrupar por tipo de entidade (por exemplo, `logic-functions/`, `roles/`) é apenas uma convenção para organização do código, não um requisito.
|
||||
</Note>
|
||||
|
||||
Exemplo de uma entidade detectada:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
Comandos posteriores adicionarão mais arquivos e pastas:
|
||||
|
||||
* `yarn twenty dev` will auto-generate two typed API clients in `node_modules/twenty-sdk/generated`: `CoreApiClient` (for workspace data via `/graphql`) and `MetadataApiClient` (for workspace configuration and file uploads via `/metadata`).
|
||||
* `yarn twenty entity:add` adicionará arquivos de definição de entidade em `src/` para seus objetos, funções, componentes de front-end, papéis e habilidades personalizados, entre outros.
|
||||
|
||||
## Autenticação
|
||||
|
||||
Na primeira vez que você executar `yarn twenty auth:login`, será solicitado o seguinte:
|
||||
|
||||
* URL da API (padrão: http://localhost:3000 ou o perfil do seu espaço de trabalho atual)
|
||||
* Chave de API
|
||||
|
||||
Suas credenciais são armazenadas por usuário em `~/.twenty/config.json`. Você pode manter vários perfis e alternar entre eles.
|
||||
|
||||
### Gerenciando espaços de trabalho
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Depois que você alternar os espaços de trabalho com `yarn twenty auth:switch`, todos os comandos subsequentes usarão esse espaço de trabalho por padrão. Você ainda pode substituí-lo temporariamente com `--workspace <name>`.
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### Iniciando o servidor
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| Comando | Descrição |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## Configuração manual (sem o gerador)
|
||||
|
||||
Embora recomendemos usar `create-twenty-app` para a melhor experiência inicial, você também pode configurar um projeto manualmente. Não instale a CLI globalmente. Em vez disso, adicione `twenty-sdk` como uma dependência local e configure um único script no seu package.json:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
Em seguida, adicione um script `twenty`:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -221,25 +393,19 @@ Em seguida, adicione um script `twenty`:
|
||||
}
|
||||
```
|
||||
|
||||
Now you can run all commands via `yarn twenty <command>`, e.g. `yarn twenty dev`, `yarn twenty help`, etc.
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## Como usar uma instância local do Twenty
|
||||
|
||||
Se você já estiver executando uma instância do Twenty localmente (por exemplo, via `npx nx start twenty-server`), você pode conectar-se a ela em vez de usar o Docker:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## Resolução de Problemas
|
||||
|
||||
* Erros de autenticação: execute `yarn twenty auth:login` e certifique-se de que sua chave de API tenha as permissões necessárias.
|
||||
* Não é possível conectar ao servidor: verifique a URL da API e se o servidor do Twenty está acessível.
|
||||
* Types or client missing/outdated: restart `yarn twenty dev` — it auto-generates the typed client.
|
||||
* Dev mode not syncing: ensure `yarn twenty dev` is running and that changes are not ignored by your environment.
|
||||
If you run into issues:
|
||||
|
||||
Canal de ajuda no Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,15 +4,75 @@ description: Distribua seu aplicativo Twenty no Marketplace ou implante-o intern
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Os aplicativos estão atualmente em testes alfa. O recurso é funcional, mas ainda está evoluindo.
|
||||
Os aplicativos estão atualmente em testes alfa. O recurso é funcional, mas ainda está evoluindo.
|
||||
</Warning>
|
||||
|
||||
## Visão Geral
|
||||
|
||||
Depois que seu aplicativo estiver [compilado e testado localmente](/l/pt/developers/extend/apps/building), você tem dois caminhos para distribuí-lo:
|
||||
|
||||
* **Implantar um tarball** — envie seu aplicativo diretamente para um servidor Twenty específico para uso interno ou privado.
|
||||
* **Publicar no npm** — liste seu aplicativo no Marketplace da Twenty para que qualquer espaço de trabalho possa descobrir e instalar.
|
||||
* **Enviar um tarball** — implante seu aplicativo em um servidor Twenty específico para uso interno sem torná-lo público.
|
||||
|
||||
Ambos os caminhos começam na mesma etapa de **build**.
|
||||
|
||||
## Compilando seu app
|
||||
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
## Implantando em um servidor (tarball)
|
||||
|
||||
Para aplicativos que você não quer disponibilizar publicamente — ferramentas proprietárias, integrações apenas para empresas ou builds experimentais — você pode implantar um tarball diretamente em um servidor Twenty.
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
Antes de implantar, você precisa de um remote configurado apontando para o servidor de destino. Os remotes armazenam a URL do servidor e as credenciais de autenticação localmente em `~/.twenty/config.json`.
|
||||
|
||||
Adicionar um remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### Implantando
|
||||
|
||||
Compile e envie seu aplicativo para o servidor em uma única etapa:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### Compartilhando um aplicativo implantado
|
||||
|
||||
Aplicativos em tarball não são listados no marketplace público, então outros espaços de trabalho no mesmo servidor não os descobrirão ao navegar. Para compartilhar um aplicativo implantado:
|
||||
|
||||
1. Vá para **Configurações > Aplicações > Registros** e abra seu aplicativo
|
||||
2. Na guia **Distribuição**, clique em **Copiar link de compartilhamento**
|
||||
3. Compartilhe esse link com usuários de outros espaços de trabalho — ele os leva diretamente para a página de instalação do aplicativo
|
||||
|
||||
O link de compartilhamento usa a URL base do servidor (sem qualquer subdomínio de espaço de trabalho), para funcionar em qualquer espaço de trabalho no servidor.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### Gerenciamento de versões
|
||||
|
||||
Para lançar uma atualização:
|
||||
|
||||
1. Atualize o campo `version` no seu `package.json`
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. Os espaços de trabalho que têm o aplicativo instalado verão a atualização disponível em suas configurações
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## Publicação no npm
|
||||
|
||||
@@ -21,29 +81,69 @@ Publicar no npm torna seu aplicativo descobrível no Marketplace da Twenty. Qual
|
||||
### Requisitos
|
||||
|
||||
* Uma conta no [npm](https://www.npmjs.com)
|
||||
* O nome do seu pacote **deve** usar o prefixo `twenty-app-` (por exemplo, `twenty-app-postcard-sender`)
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
### Etapas
|
||||
|
||||
1. **Compile seu aplicativo** — a CLI compila seus códigos-fonte TypeScript e gera o manifesto do aplicativo:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
2. **Publicar no npm** — envie o pacote compilado para o registro do npm:
|
||||
### Metadados do Marketplace
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx twenty publish
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
### Descoberta automática
|
||||
See the [defineApplication accordion](/l/pt/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
Pacotes com o prefixo `twenty-app-` são detectados automaticamente pelo catálogo do Marketplace da Twenty. Depois de publicado, seu aplicativo aparece no Marketplace em poucos minutos — sem necessidade de registro manual ou aprovação.
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
Para publicar sob uma dist-tag específica (por exemplo, `beta` ou `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish --tag beta
|
||||
```
|
||||
|
||||
### Como funciona a descoberta no marketplace
|
||||
|
||||
O servidor Twenty sincroniza seu catálogo do marketplace a partir do registro do npm **a cada hora**.
|
||||
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
Se o seu aplicativo não definir um `aboutDescription` em `defineApplication()`, o marketplace usará automaticamente o `README.md` do seu pacote no npm como conteúdo da página Sobre. Isso significa que você pode manter um único README tanto para o npm quanto para o marketplace da Twenty. Se quiser uma descrição diferente no marketplace, defina explicitamente `aboutDescription`.
|
||||
</Note>
|
||||
|
||||
### Publicação via CI
|
||||
|
||||
O projeto gerado inclui um workflow do GitHub Actions que publica a cada lançamento. Ele executa `app:build` e depois `npm publish --provenance` a partir da saída do build:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -68,52 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
Para outros sistemas de CI (GitLab CI, CircleCI etc.), aplicam-se os mesmos três comandos: `yarn install`, `npx twenty build` e depois `npm publish` a partir de `.twenty/output`.
|
||||
|
||||
<Tip>
|
||||
**Proveniência do npm** é opcional, mas recomendada. Publicar com `--provenance` adiciona um selo de confiança à sua listagem no npm, permitindo que os usuários verifiquem que o pacote foi construído a partir de um commit específico em um pipeline de CI público. Consulte a [documentação de proveniência do npm](https://docs.npmjs.com/generating-provenance-statements) para instruções de configuração.
|
||||
</Tip>
|
||||
|
||||
## Distribuição interna
|
||||
|
||||
Para aplicativos que você não quer disponibilizar publicamente — ferramentas proprietárias, integrações apenas para empresas ou builds experimentais — você pode enviar um tarball diretamente para um servidor Twenty.
|
||||
|
||||
### Enviar um tarball
|
||||
|
||||
Compile seu aplicativo e implante-o em um servidor específico em uma única etapa:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx twenty publish --server <server-url>
|
||||
```
|
||||
|
||||
Qualquer espaço de trabalho nesse servidor pode então instalar e atualizar o aplicativo na página de configurações de **Aplicativos**.
|
||||
|
||||
### Gerenciamento de versões
|
||||
|
||||
Para lançar uma atualização:
|
||||
|
||||
1. Atualize o campo `version` no seu `package.json`
|
||||
2. Envie um novo tarball com `npx twenty publish --server <server-url>`
|
||||
3. Os espaços de trabalho nesse servidor verão a atualização disponível nas suas configurações
|
||||
Para outros sistemas de CI (GitLab CI, CircleCI etc.), aplicam-se os mesmos três comandos: `yarn install`, `yarn twenty build` e, em seguida, `npm publish` a partir de `.twenty/output`.
|
||||
|
||||
<Note>
|
||||
Aplicativos internos ficam restritos ao servidor para o qual são enviados. Eles não aparecem no Marketplace público e não podem ser instalados por espaços de trabalho em outros servidores.
|
||||
**Proveniência do npm** é opcional, mas recomendada. Publicar com `--provenance` adiciona um selo de confiança à sua listagem no npm, permitindo que os usuários verifiquem que o pacote foi construído a partir de um commit específico em um pipeline de CI público. Consulte a [documentação de proveniência do npm](https://docs.npmjs.com/generating-provenance-statements) para instruções de configuração.
|
||||
</Note>
|
||||
|
||||
## Categorias de aplicativos
|
||||
## Instalando aplicativos
|
||||
|
||||
A Twenty organiza os aplicativos em três categorias com base em como são distribuídos:
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
| Categoria | Como Funciona | Visível no Marketplace? |
|
||||
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| **Desenvolvimento** | Aplicativos em modo de desenvolvimento local executados via `yarn twenty dev`. Usados para compilação e testes. | Não |
|
||||
| **Publicado** | Aplicativos publicados no npm com o prefixo `twenty-app-`. Listados no Marketplace para que qualquer espaço de trabalho possa instalar. | Sim |
|
||||
| **Interno** | Aplicativos implantados via tarball em um servidor específico. Disponível apenas para espaços de trabalho nesse servidor. | Não |
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
<Tip>
|
||||
Comece no modo de **Desenvolvimento** enquanto cria seu aplicativo. Quando estiver pronto, escolha **Publicado** (npm) para ampla distribuição ou **Interno** (tarball) para implantação privada.
|
||||
</Tip>
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -297,6 +297,16 @@ yarn command:prod cron:workflow:automated-cron-trigger
|
||||
**Modo somente ambiente:** Se você definir `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`, adicione estas variáveis ao seu arquivo `.env`.
|
||||
</Warning>
|
||||
|
||||
## Armazenamento S3
|
||||
|
||||
<Warning>
|
||||
Por padrão, o Twenty armazena os arquivos enviados no sistema de arquivos local. Para implantações em produção, use o S3 ou um serviço compatível com S3 (MinIO, DigitalOcean Spaces, etc.) para garantir que os arquivos persistam entre reinicializações do contêiner e possam escalar em várias instâncias de servidor.
|
||||
</Warning>
|
||||
|
||||
Defina `STORAGE_TYPE=S_3` e configure as variáveis `STORAGE_S3_*` pelo painel de administração ou `.env`. Veja a [referência de config-variables.ts](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts) para a lista completa de variáveis do S3.
|
||||
|
||||
Ao usar o S3 com recursos dependentes de CORS (por exemplo, downloads de arquivos no navegador), verifique se o seu bucket permite a origem do seu frontend do Twenty na sua configuração de CORS.
|
||||
|
||||
## Funções lógicas e interpretador de código
|
||||
|
||||
O Twenty oferece suporte a funções lógicas para fluxos de trabalho e ao interpretador de código para análise de dados com IA. Ambos executam código fornecido pelo usuário e exigem configuração explícita por motivos de segurança.
|
||||
|
||||
+59
-24
@@ -55,11 +55,12 @@ export const main = async (
|
||||
params: { companyId: string },
|
||||
) => {
|
||||
const { companyId } = params;
|
||||
|
||||
// Replace with your Twenty GraphQL endpoint
|
||||
// Replace with your Twenty GraphQL endpoints (/metadata for metadata and files or /graphql for your records)
|
||||
// Cloud: https://api.twenty.com/graphql
|
||||
// Self-hosted: https://your-domain.com/graphql
|
||||
const graphqlEndpoint = 'https://api.twenty.com/graphql';
|
||||
|
||||
const metadataGraphqlEndpoint = 'https://api.twenty.com/metadata';
|
||||
const dataGraphqlEndpoint = 'https://api.twenty.com/graphql';
|
||||
|
||||
// Replace with your API key from Settings → APIs
|
||||
const authToken = 'YOUR_API_KEY';
|
||||
@@ -79,11 +80,40 @@ export const main = async (
|
||||
const pdfBlob = await pdfResponse.blob();
|
||||
const pdfFile = new File([pdfBlob], filename, { type: 'application/pdf' });
|
||||
|
||||
// Step 2: Upload the file via GraphQL multipart upload
|
||||
const fieldMetadataIdQuery = `
|
||||
query FindUploadFileFieldMetadataId {
|
||||
objects {
|
||||
edges {
|
||||
node {
|
||||
nameSingular
|
||||
fieldsList {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// Step 2: Find a fieldMetadataId of "Attachment file" field in Attachments object with GraphQL API
|
||||
const response = await fetch(metadataGraphqlEndpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`
|
||||
},
|
||||
body: {
|
||||
query: fieldMetadataIdQuery,
|
||||
}
|
||||
});
|
||||
const result = await response.json();
|
||||
const uploadFileFieldMetadataId = result.data.objects.edges.find(object => object.node.nameSingular === 'attachment').node.fieldsList.find(field => field.name === 'file').id;
|
||||
|
||||
// Step 3: Upload the file via GraphQL multipart upload
|
||||
const uploadMutation = `
|
||||
mutation UploadFile($file: Upload!, $fileFolder: FileFolder) {
|
||||
uploadFile(file: $file, fileFolder: $fileFolder) {
|
||||
path
|
||||
mutation UploadFilesFieldFile($file: Upload!, $fieldMetadataId: String!) {
|
||||
uploadFilesFieldFile(file: $file, fieldMetadataId: $fieldMetadataId) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -91,12 +121,12 @@ export const main = async (
|
||||
const uploadForm = new FormData();
|
||||
uploadForm.append('operations', JSON.stringify({
|
||||
query: uploadMutation,
|
||||
variables: { file: null, fileFolder: 'Attachment' },
|
||||
variables: { file: null, fieldMetadataId: uploadFileFieldMetadataId },
|
||||
}));
|
||||
uploadForm.append('map', JSON.stringify({ '0': ['variables.file'] }));
|
||||
uploadForm.append('0', pdfFile);
|
||||
|
||||
const uploadResponse = await fetch(graphqlEndpoint, {
|
||||
const uploadResponse = await fetch(metadataGraphqlEndpoint, {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${authToken}` },
|
||||
body: uploadForm,
|
||||
@@ -108,15 +138,15 @@ export const main = async (
|
||||
throw new Error(`Upload failed: ${uploadResult.errors[0].message}`);
|
||||
}
|
||||
|
||||
const filePath = uploadResult.data?.uploadFile?.path;
|
||||
const fileId = uploadResult.data?.uploadFilesFieldFile?.id;
|
||||
|
||||
if (!filePath) {
|
||||
throw new Error('No file path returned from upload');
|
||||
if (!fileId) {
|
||||
throw new Error('No file id returned from upload');
|
||||
}
|
||||
|
||||
// Step 3: Create the attachment linked to the company
|
||||
// Step 4: Create the attachment linked to the company
|
||||
const attachmentMutation = `
|
||||
mutation CreateAttachment($data: AttachmentCreateInput!) {
|
||||
mutation CreateOneAttachment($data: AttachmentCreateInput!) {
|
||||
createAttachment(data: $data) {
|
||||
id
|
||||
name
|
||||
@@ -124,7 +154,7 @@ export const main = async (
|
||||
}
|
||||
`;
|
||||
|
||||
const attachmentResponse = await fetch(graphqlEndpoint, {
|
||||
const attachmentResponse = await fetch(dataGraphqlEndpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
@@ -135,8 +165,13 @@ export const main = async (
|
||||
variables: {
|
||||
data: {
|
||||
name: filename,
|
||||
fullPath: filePath,
|
||||
companyId,
|
||||
targetCompanyId: companyId,
|
||||
file: [
|
||||
{
|
||||
fileId: fileId,
|
||||
label: filename
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -156,14 +191,14 @@ export const main = async (
|
||||
|
||||
#### Para anexar a um objeto diferente
|
||||
|
||||
Substitua `companyId` pelo campo apropriado:
|
||||
Substitua `targetCompanyId` pelo campo apropriado:
|
||||
|
||||
| Objeto | Nome do Campo |
|
||||
| -------------------- | -------------------- |
|
||||
| Empresa | `companyId` |
|
||||
| Pessoa | `personId` |
|
||||
| Oportunidade | `opportunityId` |
|
||||
| Objeto personalizado | `yourCustomObjectId` |
|
||||
| Objeto | Nome do Campo |
|
||||
| -------------------- | -------------------------- |
|
||||
| Empresa | `targetCompanyId` |
|
||||
| Pessoa | `targetPersonId` |
|
||||
| Oportunidade | `targetOpportunityId` |
|
||||
| Objeto personalizado | `targetYourCustomObjectId` |
|
||||
|
||||
Atualize tanto o parâmetro da função como o objeto `variables.data` na mutação de anexo.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,73 +4,142 @@ description: Creați prima dvs. aplicație Twenty în câteva minute.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Aplicațiile sunt în prezent în testare alfa. Caracteristica funcționează, dar este încă în dezvoltare.
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
Aplicațiile vă permit să extindeți Twenty cu obiecte personalizate, câmpuri, funcții logice, abilități IA și componente UI — toate gestionate ca cod.
|
||||
|
||||
**Ce puteți construi:**
|
||||
|
||||
* Obiecte, câmpuri, vizualizări și elemente de navigare personalizate pentru a defini modelul dumneavoastră de date
|
||||
* Funcții logice declanșate de rute HTTP, programări cron sau evenimente din baza de date
|
||||
* Componente front-end care se afișează direct în interfața Twenty
|
||||
* Abilități care extind capabilitățile agenților AI ai Twenty
|
||||
* Implementați o aplicație în mai multe spații de lucru
|
||||
|
||||
## Cerințe
|
||||
|
||||
* Node.js 24+
|
||||
* Yarn 4
|
||||
* Docker (sau o instanță Twenty locală în execuție)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## Începeți
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
Creați o aplicație nouă folosind generatorul oficial, apoi autentificați-vă și începeți să dezvoltați:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
> Folosiți opțiunea `--minimal` pentru a genera o instalare minimă
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
De aici puteți:
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
Consultați și: paginile de referință CLI pentru [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) și [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
## Structura proiectului (generată)
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
Când rulați `npx create-twenty-app@latest my-twenty-app`, generatorul:
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
* Copiază o aplicație de bază minimală în `my-twenty-app/`
|
||||
* Adaugă o dependență locală `twenty-sdk` și configurația Yarn 4
|
||||
* Creează fișiere de configurare și scripturi conectate la CLI-ul `twenty`
|
||||
* Generează fișierele de bază (configurația aplicației, rolul implicit al funcțiilor, funcțiile de pre-instalare și post-instalare) plus fișiere de exemplu în funcție de modul de generare a scheletului.
|
||||
<Warning>
|
||||
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](/l/ro/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
O aplicație proaspăt generată cu modul implicit `--exhaustive` arată astfel:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Head over to [Building Apps](/l/ro/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -83,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
Cu `--minimal`, sunt create doar fișierele de bază (`application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` și `logic-functions/post-install.ts`).
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
Pe scurt:
|
||||
### Key files
|
||||
|
||||
* **package.json**: Declară numele aplicației, versiunea, motoarele (Node 24+, Yarn 4) și adaugă `twenty-sdk` plus un script `twenty` care deleagă către CLI-ul local `twenty`. Rulați `yarn twenty help` pentru a lista toate comenzile disponibile.
|
||||
* **.gitignore**: Ignoră artefacte comune precum `node_modules`, `.yarn`, `.twenty/`, `dist/`, `build/`, foldere de coverage, fișiere jurnal și fișiere `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Blochează și configurează lanțul de instrumente Yarn 4 folosit de proiect.
|
||||
* **.nvmrc**: Fixează versiunea Node.js așteptată de proiect.
|
||||
* **.oxlintrc.json** și **tsconfig.json**: Oferă linting și configurație TypeScript pentru fișierele TypeScript ale aplicației.
|
||||
* **README.md**: Un README scurt în rădăcina aplicației, cu instrucțiuni de bază.
|
||||
* **public/**: Un folder pentru stocarea resurselor publice (imagini, fonturi, fișiere statice) care vor fi servite împreună cu aplicația dvs. Fișierele plasate aici sunt încărcate în timpul sincronizării și sunt accesibile la rulare.
|
||||
* **src/**: Locul principal unde vă definiți aplicația sub formă de cod
|
||||
| File / Folder | Scop |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | Abilități care extind capabilitățile agenților AI ai Twenty. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### Detectarea entităților
|
||||
## Managing remotes
|
||||
|
||||
SDK-ul detectează entitățile analizând fișierele TypeScript pentru apeluri **`export default define<Entity>({...})`**. Fiecare tip de entitate are o funcție ajutătoare corespunzătoare, exportată din `twenty-sdk`:
|
||||
|
||||
| Funcție ajutătoare | Tipul entității |
|
||||
| -------------------------------- | -------------------------------------------------------------- |
|
||||
| `defineObject` | Definiții de obiecte personalizate |
|
||||
| `defineLogicFunction` | Definiții de funcții de logică |
|
||||
| `definePreInstallLogicFunction` | Funcție logică de pre-instalare (rulează înainte de instalare) |
|
||||
| `definePostInstallLogicFunction` | Funcție logică post-instalare (rulează după instalare) |
|
||||
| `defineFrontComponent` | Definiții ale componentelor de interfață |
|
||||
| `defineRole` | Definiții de rol |
|
||||
| `defineField` | Extensii de câmp pentru obiectele existente |
|
||||
| `defineView` | Definiții pentru vizualizări salvate |
|
||||
| `defineNavigationMenuItem` | Definiții pentru elemente de meniu de navigare |
|
||||
| `defineSkill` | Definiții ale abilităților agentului IA |
|
||||
|
||||
<Note>
|
||||
**Denumirea fișierelor este flexibilă.** Detectarea entităților se bazează pe AST — SDK-ul scanează fișierele sursă pentru tiparul `export default define<Entity>({...})`. Puteți organiza fișierele și folderele cum doriți. Gruparea după tipul de entitate (de exemplu, `logic-functions/`, `roles/`) este doar o convenție pentru organizarea codului, nu o cerință.
|
||||
</Note>
|
||||
|
||||
Exemplu de entitate detectată:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
Comenzile ulterioare vor adăuga mai multe fișiere și foldere:
|
||||
|
||||
* `yarn twenty dev` va genera automat `CoreApiClient` tipizat (pentru datele spațiului de lucru prin `/graphql`) în `node_modules/twenty-client-sdk/`. `MetadataApiClient` (pentru configurarea spațiului de lucru și încărcarea fișierelor prin `/metadata`) este livrat preconstruit și este disponibil imediat. Importați-le din `twenty-client-sdk/core` și `twenty-client-sdk/metadata`, respectiv.
|
||||
* `yarn twenty add` va adăuga fișiere de definire a entităților în `src/` pentru obiectele personalizate, funcțiile, componentele front-end, rolurile, abilitățile și altele.
|
||||
|
||||
## Autentificare
|
||||
|
||||
Prima dată când rulați `yarn twenty auth:login`, vi se vor solicita:
|
||||
|
||||
* URL-ul API (implicit http://localhost:3000 sau profilul spațiului de lucru curent)
|
||||
* Cheie API
|
||||
|
||||
Acreditările dvs. sunt stocate per utilizator în `~/.twenty/config.json`. Puteți menține mai multe profiluri și comuta între ele.
|
||||
|
||||
### Gestionarea spațiilor de lucru
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
După ce ați schimbat spațiul de lucru cu `yarn twenty auth:switch`, toate comenzile ulterioare vor folosi implicit acel spațiu de lucru. Îl puteți totuși suprascrie temporar cu `--workspace <name>`.
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### Pornirea serverului
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| Comandă | Descriere |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## Configurare manuală (fără generator)
|
||||
|
||||
Deși recomandăm utilizarea `create-twenty-app` pentru cea mai bună experiență de început, puteți configura și un proiect manual. Nu instalați CLI-ul global. În schimb, adăugați `twenty-sdk` ca dependență locală și conectați un singur script în package.json-ul dvs.:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
Apoi adăugați un script `twenty`:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -210,25 +393,19 @@ Apoi adăugați un script `twenty`:
|
||||
}
|
||||
```
|
||||
|
||||
Acum poți rula toate comenzile prin `yarn twenty <command>`, de ex. `yarn twenty dev`, `yarn twenty help`, etc.
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## Cum să folosești o instanță Twenty locală
|
||||
|
||||
Dacă rulezi deja local o instanță Twenty (de exemplu prin `npx nx start twenty-server`), te poți conecta la ea în loc să folosești Docker:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## Depanare
|
||||
|
||||
* Erori de autentificare: rulați `yarn twenty auth:login` și asigurați-vă că cheia API are permisiunile necesare.
|
||||
* Nu se poate conecta la server: verificați URL-ul API și că serverul Twenty este accesibil.
|
||||
* Tipuri sau client lipsă/învechite: repornește `yarn twenty dev` — acesta generează automat clientul tipizat.
|
||||
* Modul dev nu sincronizează: asigură-te că `yarn twenty dev` rulează și că modificările nu sunt ignorate de mediul tău.
|
||||
If you run into issues:
|
||||
|
||||
Canal de ajutor pe Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,34 +4,76 @@ description: Distribuie aplicația ta Twenty în marketplace sau implementeaz-o
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Aplicațiile sunt în prezent în testare alfa. Caracteristica funcționează, dar este încă în dezvoltare.
|
||||
Aplicațiile sunt în prezent în testare alfa. Caracteristica funcționează, dar este încă în dezvoltare.
|
||||
</Warning>
|
||||
|
||||
## Prezentare generală
|
||||
|
||||
După ce aplicația ta este [construită și testată local](/l/ro/developers/extend/apps/building), ai două căi pentru distribuire:
|
||||
|
||||
* **Publică pe npm** — listează aplicația ta în marketplace-ul Twenty pentru ca orice spațiu de lucru să o poată descoperi și instala.
|
||||
* **Implementați o arhivă tar** — încărcați aplicația direct pe un server Twenty anume pentru uz intern sau privat.
|
||||
* **Publică pe npm** — listează aplicația ta în marketplace-ul Twenty pentru ca orice spațiu de lucru să o poată descoperi și instala.
|
||||
|
||||
Ambele căi pornesc din aceeași etapă de **build**.
|
||||
|
||||
## Construirea aplicației
|
||||
|
||||
Comanda `build` compilează sursele TypeScript, transpilează funcțiile de logică și componentele de front-end și generează un `manifest.json` care descrie conținutul aplicației:
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
Rezultatul este scris în `.twenty/output/`. Acest director conține tot ce este necesar pentru distribuție: cod compilat, resurse, manifestul și o copie a fișierului tău `package.json`.
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
Pentru a crea și un pachet `.tgz` (folosit intern de comanda de implementare sau pentru distribuire manuală):
|
||||
## Implementare pe un server (tarball)
|
||||
|
||||
Pentru aplicațiile pe care nu le dorești disponibile public — instrumente proprietare, integrări doar pentru enterprise sau build-uri experimentale — poți implementa un tarball direct pe un server Twenty.
|
||||
|
||||
### Cerințe
|
||||
|
||||
Înainte de implementare, ai nevoie de un remote configurat care să indice serverul țintă. Remote-urile stochează local URL-ul serverului și credențialele de autentificare în `~/.twenty/config.json`.
|
||||
|
||||
Adaugă un remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build --tarball
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### Implementare
|
||||
|
||||
Construiește și încarcă aplicația ta pe server într-un singur pas:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### Partajarea unei aplicații implementate
|
||||
|
||||
Aplicațiile tarball nu sunt listate în marketplace-ul public, astfel încât alte spații de lucru de pe același server nu le vor descoperi prin navigare. Pentru a partaja o aplicație implementată:
|
||||
|
||||
1. Mergi la **Setări > Aplicații > Înregistrări** și deschide aplicația ta
|
||||
2. În fila **Distribuție**, fă clic pe **Copiază linkul de partajare**
|
||||
3. Partajează acest link cu utilizatori din alte spații de lucru — îi duce direct la pagina de instalare a aplicației
|
||||
|
||||
Linkul de partajare folosește URL-ul de bază al serverului (fără niciun subdomeniu de spațiu de lucru), astfel încât funcționează pentru orice spațiu de lucru de pe server.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### Gestionarea versiunilor
|
||||
|
||||
Pentru a lansa o actualizare:
|
||||
|
||||
1. Actualizează câmpul `version` din `package.json`
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. Spațiile de lucru care au aplicația instalată vor vedea actualizarea disponibilă în setările lor
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## Publicarea pe npm
|
||||
|
||||
Publicarea pe npm face ca aplicația ta să poată fi descoperită în marketplace-ul Twenty. Orice spațiu de lucru Twenty poate răsfoi, instala și actualiza aplicațiile din marketplace direct din interfață.
|
||||
@@ -39,41 +81,42 @@ Publicarea pe npm face ca aplicația ta să poată fi descoperită în marketpla
|
||||
### Cerințe
|
||||
|
||||
* Un cont [npm](https://www.npmjs.com)
|
||||
* Cuvântul cheie `twenty-app` trebuie să fie listat în array-ul `keywords` din `package.json`-ul tău
|
||||
|
||||
### Adăugarea cuvântului cheie necesar
|
||||
|
||||
Marketplace-ul Twenty descoperă aplicații căutând în registrul npm pachete cu cuvântul cheie `twenty-app`. Adaugă-l în `package.json`-ul tău:
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"],
|
||||
...
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Marketplace-ul caută `keywords:twenty-app` în registrul npm. Fără acest cuvânt cheie, pachetul tău nu va apărea în marketplace chiar dacă are prefixul de nume `twenty-app-`.
|
||||
</Note>
|
||||
### Metadate pentru marketplace
|
||||
|
||||
### Pași
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
1. **Construiește-ți aplicația:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
2. **Publică pe npm:**
|
||||
See the [defineApplication accordion](/l/ro/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
Aceasta rulează `npm publish` din directorul `.twenty/output/`.
|
||||
|
||||
Pentru a publica sub un dist-tag specific (de ex., `beta` sau `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
@@ -82,25 +125,17 @@ yarn twenty publish --tag beta
|
||||
|
||||
### Cum funcționează descoperirea în marketplace
|
||||
|
||||
Serverul Twenty sincronizează catalogul marketplace-ului din registrul npm la fiecare oră:
|
||||
The Twenty server syncs its marketplace catalog from the npm registry **every hour**.
|
||||
|
||||
1. Caută toate pachetele npm cu cuvântul cheie `keywords:twenty-app`
|
||||
2. Pentru fiecare pachet, preia `manifest.json` din CDN-ul npm
|
||||
3. Metadatele aplicației (nume, descriere, autor, logo, capturi de ecran, categorie) sunt extrase din manifest și afișate în marketplace
|
||||
|
||||
După publicare, poate dura până la o oră ca aplicația ta să apară în marketplace. Pentru a declanșa sincronizarea imediat, în loc să aștepți următoarea rulare orară:
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
Pentru a viza un remote specific:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync -r production
|
||||
```
|
||||
|
||||
Metadatele afișate în marketplace provin din apelul tău `defineApplication()` din codul sursă al aplicației — câmpuri precum `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl` și `termsUrl`.
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
Dacă aplicația ta nu definește un `aboutDescription` în `defineApplication()`, piața va folosi automat fișierul `README.md` al pachetului tău de pe npm drept conținut pentru pagina Despre. Acest lucru înseamnă că poți menține un singur README atât pentru npm, cât și pentru piața Twenty. Dacă vrei o descriere diferită în piață, setează explicit `aboutDescription`.
|
||||
@@ -108,7 +143,7 @@ Dacă aplicația ta nu definește un `aboutDescription` în `defineApplication()
|
||||
|
||||
### Publicare CI
|
||||
|
||||
Proiectul generat include un workflow GitHub Actions care publică la fiecare lansare:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -133,121 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
Pentru alte sisteme CI (GitLab CI, CircleCI etc.), se aplică aceleași trei comenzi: `yarn install`, `yarn twenty build`, apoi `npm publish` din `.twenty/output`.
|
||||
|
||||
<Tip>
|
||||
<Note>
|
||||
**npm provenance** este opțională, dar recomandată. Publicarea cu `--provenance` adaugă un badge de încredere la listarea ta în npm, permițând utilizatorilor să verifice că pachetul a fost construit dintr-un commit specific într-un pipeline CI public. Vezi [documentația npm provenance](https://docs.npmjs.com/generating-provenance-statements) pentru instrucțiuni de configurare.
|
||||
</Tip>
|
||||
|
||||
## Implementare pe un server (tarball)
|
||||
|
||||
Pentru aplicațiile pe care nu le dorești disponibile public — instrumente proprietare, integrări doar pentru enterprise sau build-uri experimentale — poți implementa un tarball direct pe un server Twenty.
|
||||
|
||||
### Cerințe
|
||||
|
||||
Înainte de implementare, ai nevoie de un remote configurat care să indice serverul țintă. Remote-urile stochează local URL-ul serverului și credențialele de autentificare în `~/.twenty/config.json`.
|
||||
|
||||
Adaugă un remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
Pentru un server de dezvoltare local:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --local --as local
|
||||
```
|
||||
|
||||
Te poți autentifica și cu o cheie API pentru medii neinteractive:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
|
||||
```
|
||||
|
||||
Gestionează-ți remote-urile:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote list # List all configured remotes
|
||||
yarn twenty remote switch prod # Set the default remote
|
||||
yarn twenty remote status # Show active remote and auth status
|
||||
yarn twenty remote remove old # Remove a remote
|
||||
```
|
||||
|
||||
### Implementare
|
||||
|
||||
Construiește și încarcă aplicația ta pe server într-un singur pas:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
```
|
||||
|
||||
Aceasta construiește aplicația cu `--tarball`, apoi încarcă tarball-ul către remote-ul implicit printr-o încărcare multipart GraphQL.
|
||||
|
||||
Pentru a implementa către un remote specific:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy -r production
|
||||
```
|
||||
|
||||
### Partajarea unei aplicații implementate
|
||||
|
||||
Aplicațiile tarball nu sunt listate în marketplace-ul public, astfel încât alte spații de lucru de pe același server nu le vor descoperi prin navigare. Pentru a partaja o aplicație implementată:
|
||||
|
||||
1. Mergi la **Setări > Aplicații > Înregistrări** și deschide aplicația ta
|
||||
2. În fila **Distribuție**, fă clic pe **Copiază linkul de partajare**
|
||||
3. Partajează acest link cu utilizatori din alte spații de lucru — îi duce direct la pagina de instalare a aplicației
|
||||
|
||||
Linkul de partajare folosește URL-ul de bază al serverului (fără niciun subdomeniu de spațiu de lucru), astfel încât funcționează pentru orice spațiu de lucru de pe server.
|
||||
|
||||
### Gestionarea versiunilor
|
||||
|
||||
Pentru a lansa o actualizare:
|
||||
|
||||
1. Actualizează câmpul `version` din `package.json`
|
||||
2. Rulează `yarn twenty deploy` (sau `yarn twenty deploy -r production`)
|
||||
3. Spațiile de lucru care au aplicația instalată vor vedea actualizarea disponibilă în setările lor
|
||||
</Note>
|
||||
|
||||
## Instalarea aplicațiilor
|
||||
|
||||
După ce o aplicație este publicată (npm) sau implementată (tarball), spațiile de lucru o instalează prin interfața utilizatorului (UI):
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
Sau din pagina **Setări > Aplicații** din Twenty UI, unde pot fi navigate și instalate atât aplicațiile din marketplace, cât și cele implementate prin tarball.
|
||||
|
||||
## Categorii de distribuție a aplicațiilor
|
||||
|
||||
Twenty organizează aplicațiile în trei categorii, în funcție de modul în care sunt distribuite:
|
||||
|
||||
| Categorie | Cum funcționează | Vizibilă în marketplace? |
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
||||
| **Dezvoltare** | Aplicații în modul de dezvoltare local, rulate prin `yarn twenty dev`. Folosite pentru construire și testare. | Nu |
|
||||
| **Publicat (npm)** | Aplicații publicate pe npm cu cuvântul cheie `twenty-app`. Listate în marketplace pentru ca orice spațiu de lucru să le poată instala. | Da |
|
||||
| **Intern (tarball)** | Aplicații implementate prin tarball pe un server specific. Disponibile doar pentru spațiile de lucru de pe acel server printr-un link de partajare. | Nu |
|
||||
|
||||
<Tip>
|
||||
Pornește în modul **Dezvoltare** în timp ce îți construiești aplicația. Când este gata, alege **Publicat** (npm) pentru distribuire largă sau **Intern** (tarball) pentru implementare privată.
|
||||
</Tip>
|
||||
|
||||
## Referință CLI
|
||||
|
||||
| Comandă | Descriere | Opțiuni cheie |
|
||||
| --------------------------- | ---------------------------------------------------------------- | ----------------------------------------------------- |
|
||||
| `yarn twenty build` | Compilează aplicația și generează manifestul | `--tarball` — creează și un pachet `.tgz` |
|
||||
| `yarn twenty publish` | Construiește și publică pe npm | `--tag <tag>` — dist-tag npm (de ex., `beta`, `next`) |
|
||||
| `yarn twenty deploy` | Construiește și încarcă un tarball pe un server | `-r, --remote <name>` — remote țintă |
|
||||
| `yarn twenty catalog-sync` | Declanșează sincronizarea catalogului marketplace-ului pe server | `-r, --remote <name>` — remote țintă |
|
||||
| `yarn twenty install` | Instalează o aplicație implementată pe un spațiu de lucru | `-r, --remote <name>` — remote țintă |
|
||||
| `yarn twenty dev` | Monitorizează și sincronizează modificările locale | Folosește remote-ul implicit |
|
||||
| `yarn twenty remote add` | Adaugă o conexiune la server | `--url`, `--token`, `--as`, `--local`, `--port` |
|
||||
| `yarn twenty remote list` | Listează remote-urile configurate | — |
|
||||
| `yarn twenty remote switch` | Setează remote-ul implicit | — |
|
||||
| `yarn twenty remote status` | Afișează starea conexiunii | — |
|
||||
| `yarn twenty remote remove` | Elimină un remote | — |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,73 +4,142 @@ description: Создайте своё первое приложение Twenty
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Приложения сейчас проходят альфа-тестирование. Функциональность работает, но продолжает развиваться.
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
Приложения позволяют расширять Twenty с помощью пользовательских объектов, полей, логических функций, навыков ИИ и UI-компонентов — всё это управляется как код.
|
||||
|
||||
**Что вы можете создать:**
|
||||
|
||||
* Пользовательские объекты, поля, представления и элементы навигации для формирования вашей модели данных
|
||||
* Логические функции, запускаемые маршрутами HTTP, расписаниями cron или событиями базы данных
|
||||
* Фронтенд-компоненты, которые непосредственно отображаются внутри интерфейса Twenty
|
||||
* Навыки, расширяющие возможности ИИ-агентов Twenty
|
||||
* Разверните приложение в нескольких рабочих пространствах
|
||||
|
||||
## Требования
|
||||
|
||||
* Node.js 24+
|
||||
* Yarn 4
|
||||
* Docker (или запущенный локальный экземпляр Twenty)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## Начало работы
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
Создайте новое приложение с помощью официального генератора, затем выполните аутентификацию и начните разработку:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
> Используйте параметр `--minimal`, чтобы создать минимальную установку
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
Отсюда вы можете:
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
Смотрите также: страницы справки CLI для [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) и [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
## Структура проекта (сгенерированного)
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
Когда вы запускаете `npx create-twenty-app@latest my-twenty-app`, генератор:
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
* Копирует минимальное базовое приложение в `my-twenty-app/`
|
||||
* Добавляет локальную зависимость `twenty-sdk` и конфигурацию Yarn 4
|
||||
* Создаёт файлы конфигурации и скрипты, подключённые к CLI `twenty`
|
||||
* Генерирует основные файлы (конфигурацию приложения, роль функций по умолчанию, предустановочную и послеустановочную функции), а также примерные файлы в зависимости от выбранного режима создания каркаса
|
||||
<Warning>
|
||||
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](/l/ru/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
Сгенерированное с помощью каркаса приложение с режимом по умолчанию `--exhaustive` выглядит так:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Head over to [Building Apps](/l/ru/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -83,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
С `--minimal` создаются только основные файлы (`application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` и `logic-functions/post-install.ts`).
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
В общих чертах:
|
||||
### Key files
|
||||
|
||||
* **package.json**: Объявляет имя приложения, версию, движки (Node 24+, Yarn 4) и добавляет `twenty-sdk`, а также скрипт `twenty`, который делегирует выполнение локальному CLI `twenty`. Выполните `yarn twenty help`, чтобы вывести список всех доступных команд.
|
||||
* **.gitignore**: Игнорирует распространённые артефакты, такие как `node_modules`, `.yarn`, `.twenty/`, `dist/`, `build/`, каталоги coverage, файлы журналов и файлы `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Фиксируют и настраивают используемый в проекте инструментарий Yarn 4.
|
||||
* **.nvmrc**: Фиксирует версию Node.js, ожидаемую проектом.
|
||||
* **.oxlintrc.json** и **tsconfig.json**: Обеспечивают линтинг и конфигурацию TypeScript для исходников вашего приложения на TypeScript.
|
||||
* **README.md**: Короткий README в корне приложения с базовыми инструкциями.
|
||||
* **public/**: Папка для хранения общедоступных ресурсов (изображений, шрифтов, статических файлов), которые будут отдаваться вашим приложением. Файлы, размещённые здесь, загружаются во время синхронизации и доступны во время выполнения.
|
||||
* **src/**: Основное место, где вы определяете приложение как код
|
||||
| File / Folder | Назначение |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | Навыки, расширяющие возможности ИИ-агентов Twenty. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### Обнаружение сущностей
|
||||
## Managing remotes
|
||||
|
||||
SDK обнаруживает сущности, разбирая ваши файлы TypeScript в поисках вызовов **`export default define<Entity>({...})`**. Для каждого типа сущности существует соответствующая вспомогательная функция, экспортируемая из `twenty-sdk`:
|
||||
|
||||
| Вспомогательная функция | Тип сущности |
|
||||
| -------------------------------- | ------------------------------------------------------------------ |
|
||||
| `defineObject` | Определения пользовательских объектов |
|
||||
| `defineLogicFunction` | Определения логических функций |
|
||||
| `definePreInstallLogicFunction` | Предустановочная логическая функция (запускается до установки) |
|
||||
| `definePostInstallLogicFunction` | Послеустановочная логическая функция (запускается после установки) |
|
||||
| `defineFrontComponent` | Определения компонентов фронтенда |
|
||||
| `defineRole` | Определения ролей |
|
||||
| `defineField` | Расширения полей для существующих объектов |
|
||||
| `defineView` | Определения сохранённых представлений |
|
||||
| `defineNavigationMenuItem` | Определения пунктов меню навигации |
|
||||
| `defineSkill` | Определения навыков агента ИИ |
|
||||
|
||||
<Note>
|
||||
**Имена файлов заданы гибко.** Обнаружение сущностей основано на AST — SDK сканирует ваши исходные файлы в поисках шаблона `export default define<Entity>({...})`. Вы можете организовывать файлы и папки как угодно. Группировка по типу сущности (например, `logic-functions/`, `roles/`) — это лишь соглашение для организации кода, а не требование.
|
||||
</Note>
|
||||
|
||||
Пример обнаруженной сущности:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
Позднее команды добавят больше файлов и папок:
|
||||
|
||||
* `yarn twenty dev` автоматически сгенерирует типизированный `CoreApiClient` (для данных рабочего пространства через `/graphql`) в `node_modules/twenty-client-sdk/`. `MetadataApiClient` (для конфигурации рабочего пространства и загрузки файлов через `/metadata`) поставляется в предсобранном виде и доступен сразу. Импортируйте их из `twenty-client-sdk/core` и `twenty-client-sdk/metadata` соответственно.
|
||||
* `yarn twenty add` добавит файлы определений сущностей в `src/` для ваших пользовательских объектов, функций, фронтенд-компонентов, ролей, навыков и многого другого.
|
||||
|
||||
## Аутентификация
|
||||
|
||||
При первом запуске `yarn twenty auth:login` вам будет предложено указать:
|
||||
|
||||
* URL API (по умолчанию http://localhost:3000 или текущий профиль рабочего пространства)
|
||||
* Ключ API
|
||||
|
||||
Ваши учётные данные хранятся для каждого пользователя в `~/.twenty/config.json`. Вы можете хранить несколько профилей и переключаться между ними.
|
||||
|
||||
### Управление рабочими пространствами
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
После переключения рабочего пространства с помощью `yarn twenty auth:switch` все последующие команды по умолчанию будут использовать это рабочее пространство. Вы по-прежнему можете временно переопределить это с помощью `--workspace <name>`.
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### Запуск сервера
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| Команда | Описание |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## Ручная настройка (без генератора)
|
||||
|
||||
Хотя мы рекомендуем использовать `create-twenty-app` для наилучшего старта, вы также можете настроить проект вручную. Не устанавливайте CLI глобально. Вместо этого добавьте `twenty-sdk` как локальную зависимость и настройте один скрипт в вашем package.json:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
Затем добавьте скрипт `twenty`:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -210,25 +393,19 @@ yarn add -D twenty-sdk
|
||||
}
|
||||
```
|
||||
|
||||
Теперь вы можете запускать все команды через `yarn twenty <command>`, например, `yarn twenty dev`, `yarn twenty help` и т. д.
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## Как использовать локальный экземпляр Twenty
|
||||
|
||||
Если у вас уже запущен локально экземпляр Twenty (например, через `npx nx start twenty-server`), вы можете подключиться к нему вместо использования Docker:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## Устранение неполадок
|
||||
|
||||
* Ошибки аутентификации: выполните `yarn twenty auth:login` и убедитесь, что у вашего ключа API есть необходимые права.
|
||||
* Не удаётся подключиться к серверу: проверьте URL API и доступность сервера Twenty.
|
||||
* Типы или клиент отсутствуют/устарели: перезапустите `yarn twenty dev` — он автоматически генерирует типизированный клиент.
|
||||
* Режим разработки не синхронизируется: убедитесь, что запущен `yarn twenty dev`, и что ваша среда не игнорирует изменения.
|
||||
If you run into issues:
|
||||
|
||||
Канал помощи в Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,34 +4,76 @@ description: Распространяйте своё приложение Twenty
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Приложения сейчас проходят альфа-тестирование. Функциональность работает, но продолжает развиваться.
|
||||
Приложения сейчас проходят альфа-тестирование. Функция работает, но продолжает развиваться.
|
||||
</Warning>
|
||||
|
||||
## Обзор
|
||||
|
||||
После того как ваше приложение [собрано и протестировано локально](/l/ru/developers/extend/apps/building), у вас есть два пути для его распространения:
|
||||
|
||||
* **Опубликовать в npm** — разместите ваше приложение в маркетплейсе Twenty, чтобы любое рабочее пространство могло его найти и установить.
|
||||
* **Разверните tar-архив** — загрузите своё приложение напрямую на конкретный сервер Twenty для внутреннего или частного использования.
|
||||
* **Опубликовать в npm** — разместите ваше приложение в маркетплейсе Twenty, чтобы любое рабочее пространство могло его найти и установить.
|
||||
|
||||
Оба пути начинаются с одного и того же шага **build**.
|
||||
|
||||
## Сборка вашего приложения
|
||||
|
||||
Команда `build` компилирует ваши исходники TypeScript, транспилирует функции логики и фронтенд-компоненты и генерирует `manifest.json`, который описывает содержимое вашего приложения:
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
Выходные данные записываются в `.twenty/output/`. Этот каталог содержит всё необходимое для распространения: скомпилированный код, ресурсы, манифест и копию вашего `package.json`.
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
Чтобы также создать tarball `.tgz` (который внутренне используется командой deploy или для ручного распространения):
|
||||
## Развертывание на сервер (tarball)
|
||||
|
||||
Для приложений, которые вы не хотите делать общедоступными — собственные инструменты, интеграции только для предприятий или экспериментальные сборки — вы можете развернуть tarball напрямую на сервер Twenty.
|
||||
|
||||
### Требования
|
||||
|
||||
Перед развертыванием вам нужен настроенный remote, указывающий на целевой сервер. Remotes локально хранят URL сервера и учётные данные аутентификации в `~/.twenty/config.json`.
|
||||
|
||||
Добавьте remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build --tarball
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### Развертывание
|
||||
|
||||
Соберите и загрузите ваше приложение на сервер в одном шаге:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### Общий доступ к развернутому приложению
|
||||
|
||||
Приложения в формате tarball не отображаются в публичном маркетплейсе, поэтому другие рабочие пространства на том же сервере не найдут их при просмотре. Чтобы поделиться развернутым приложением:
|
||||
|
||||
1. Перейдите в **Настройки > Приложения > Регистрации** и откройте ваше приложение
|
||||
2. На вкладке **Распространение** нажмите **Копировать ссылку для общего доступа**
|
||||
3. Поделитесь этой ссылкой с пользователями в других рабочих пространствах — она ведёт их прямо на страницу установки приложения
|
||||
|
||||
Ссылка общего доступа использует базовый URL сервера (без какого-либо поддомена рабочего пространства), поэтому она работает для любого рабочего пространства на сервере.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### Управление версиями
|
||||
|
||||
Чтобы выпустить обновление:
|
||||
|
||||
1. Обновите значение поля `version` в файле `package.json`
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. Рабочие пространства, в которых установлено приложение, увидят доступное обновление в своих настройках
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## Публикация в npm
|
||||
|
||||
Публикация в npm делает ваше приложение видимым в маркетплейсе Twenty. Любое рабочее пространство Twenty может просматривать, устанавливать и обновлять приложения из маркетплейса непосредственно из интерфейса.
|
||||
@@ -39,41 +81,42 @@ yarn twenty build --tarball
|
||||
### Требования
|
||||
|
||||
* Учётная запись [npm](https://www.npmjs.com)
|
||||
* Ключевое слово `twenty-app` **обязательно** должно быть указано в массиве `keywords` вашего `package.json`
|
||||
|
||||
### Добавление обязательного ключевого слова
|
||||
|
||||
Маркетплейс Twenty находит приложения, ища в реестре npm пакеты с ключевым словом `twenty-app`. Добавьте его в ваш `package.json`:
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"],
|
||||
...
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Маркетплейс ищет в реестре npm по `keywords:twenty-app`. Без этого ключевого слова ваш пакет не появится в маркетплейсе, даже если в его имени есть префикс `twenty-app-`.
|
||||
</Note>
|
||||
### Метаданные маркетплейса
|
||||
|
||||
### Шаги
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
1. **Сборка вашего приложения:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
2. **Публикация в npm:**
|
||||
See the [defineApplication accordion](/l/ru/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
Это выполняет `npm publish` из каталога `.twenty/output/`.
|
||||
|
||||
Чтобы опубликовать с определённым dist-tag (например, `beta` или `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
@@ -82,25 +125,17 @@ yarn twenty publish --tag beta
|
||||
|
||||
### Как работает обнаружение приложений в маркетплейсе
|
||||
|
||||
Сервер Twenty синхронизирует каталог маркетплейса из реестра npm **каждый час**:
|
||||
Сервер Twenty синхронизирует каталог маркетплейса из реестра npm **каждый час**.
|
||||
|
||||
1. Он ищет все пакеты npm с ключевым словом `keywords:twenty-app`
|
||||
2. Для каждого пакета он извлекает `manifest.json` с CDN npm
|
||||
3. Метаданные приложения (name, description, author, logo, screenshots, category) извлекаются из манифеста и отображаются в маркетплейсе
|
||||
|
||||
После публикации может пройти до одного часа, прежде чем ваше приложение появится в маркетплейсе. Чтобы запустить синхронизацию немедленно, не дожидаясь следующего почасового запуска:
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
Чтобы указать конкретный remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync -r production
|
||||
```
|
||||
|
||||
Метаданные, отображаемые в маркетплейсе, берутся из вызова `defineApplication()` в исходном коде вашего приложения — из таких полей, как `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl` и `termsUrl`.
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
Если ваше приложение не определяет `aboutDescription` в `defineApplication()`, маркетплейс автоматически использует `README.md` вашего пакета из npm в качестве содержимого страницы «О приложении». Это означает, что вы можете поддерживать единый README как для npm, так и для маркетплейса Twenty. Если вы хотите другое описание в маркетплейсе, явно задайте `aboutDescription`.
|
||||
@@ -108,7 +143,7 @@ yarn twenty catalog-sync -r production
|
||||
|
||||
### Публикация через CI
|
||||
|
||||
Сгенерированный шаблоном проект включает рабочий процесс GitHub Actions, который выполняет публикацию при каждом релизе:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -133,121 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
Для других CI-систем (GitLab CI, CircleCI и др.) применимы те же три команды: `yarn install`, `yarn twenty build`, затем `npm publish` из `.twenty/output`.
|
||||
|
||||
<Tip>
|
||||
<Note>
|
||||
**npm provenance** — опционально, но рекомендуется. Публикация с флагом `--provenance` добавляет к вашему пакету в npm значок доверия, позволяя пользователям проверить, что пакет был собран из конкретного коммита в общедоступном конвейере CI. См. инструкции по настройке в [документации по npm provenance](https://docs.npmjs.com/generating-provenance-statements).
|
||||
</Tip>
|
||||
|
||||
## Развертывание на сервер (tarball)
|
||||
|
||||
Для приложений, которые вы не хотите делать общедоступными — собственные инструменты, интеграции только для предприятий или экспериментальные сборки — вы можете развернуть tarball напрямую на сервер Twenty.
|
||||
|
||||
### Требования
|
||||
|
||||
Перед развертыванием вам нужен настроенный remote, указывающий на целевой сервер. Remotes локально хранят URL сервера и учётные данные аутентификации в `~/.twenty/config.json`.
|
||||
|
||||
Добавьте remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
Для локального сервера разработки:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --local --as local
|
||||
```
|
||||
|
||||
Вы также можете аутентифицироваться с помощью API-ключа в неинтерактивных средах:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
|
||||
```
|
||||
|
||||
Управляйте remotes:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote list # List all configured remotes
|
||||
yarn twenty remote switch prod # Set the default remote
|
||||
yarn twenty remote status # Show active remote and auth status
|
||||
yarn twenty remote remove old # Remove a remote
|
||||
```
|
||||
|
||||
### Развертывание
|
||||
|
||||
Соберите и загрузите ваше приложение на сервер в одном шаге:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
```
|
||||
|
||||
Это собирает приложение с флагом `--tarball`, затем загружает tarball на remote по умолчанию через GraphQL multipart upload.
|
||||
|
||||
Чтобы развернуть на конкретный remote:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy -r production
|
||||
```
|
||||
|
||||
### Общий доступ к развернутому приложению
|
||||
|
||||
Приложения в формате tarball не отображаются в публичном маркетплейсе, поэтому другие рабочие пространства на том же сервере не найдут их при просмотре. Чтобы поделиться развернутым приложением:
|
||||
|
||||
1. Перейдите в **Настройки > Приложения > Регистрации** и откройте ваше приложение
|
||||
2. На вкладке **Распространение** нажмите **Копировать ссылку для общего доступа**
|
||||
3. Поделитесь этой ссылкой с пользователями в других рабочих пространствах — она ведёт их прямо на страницу установки приложения
|
||||
|
||||
Ссылка общего доступа использует базовый URL сервера (без какого-либо поддомена рабочего пространства), поэтому она работает для любого рабочего пространства на сервере.
|
||||
|
||||
### Управление версиями
|
||||
|
||||
Чтобы выпустить обновление:
|
||||
|
||||
1. Обновите значение поля `version` в файле `package.json`
|
||||
2. Выполните `yarn twenty deploy` (или `yarn twenty deploy -r production`)
|
||||
3. Рабочие пространства, в которых установлено приложение, увидят доступное обновление в своих настройках
|
||||
</Note>
|
||||
|
||||
## Установка приложений
|
||||
|
||||
После публикации приложения (npm) или его развертывания (tarball) рабочие пространства устанавливают его через интерфейс:
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
Или со страницы **Настройки > Приложения** в интерфейсе Twenty, где можно просматривать и устанавливать как приложения из маркетплейса, так и развернутые через tarball.
|
||||
|
||||
## Категории распространения приложений
|
||||
|
||||
Twenty группирует приложения в три категории в зависимости от способа их распространения:
|
||||
|
||||
| Категория | Как это работает | Отображается в маркетплейсе? |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
|
||||
| **Разработка** | Локальные приложения в режиме разработки, запущенные через `yarn twenty dev`. Используются для сборки и тестирования. | Нет |
|
||||
| **Опубликовано (npm)** | Приложения, опубликованные в npm с ключевым словом `twenty-app`. Отображаются в маркетплейсе, доступные для установки любому рабочему пространству. | Да |
|
||||
| **Внутренние (tarball)** | Приложения, развернутые через tarball на конкретном сервере. Доступны только рабочим пространствам на этом сервере по ссылке общего доступа. | Нет |
|
||||
|
||||
<Tip>
|
||||
Начните в режиме **Разработка** во время создания приложения. Когда будет готово, выберите **Опубликовано** (npm) для широкого распространения или **Внутренний** (tarball) для приватного развертывания.
|
||||
</Tip>
|
||||
|
||||
## Справочник по CLI
|
||||
|
||||
| Команда | Описание | Основные флаги |
|
||||
| --------------------------- | -------------------------------------------------------- | ------------------------------------------------------- |
|
||||
| `yarn twenty build` | Скомпилировать приложение и сгенерировать манифест | `--tarball` — также создать пакет `.tgz` |
|
||||
| `yarn twenty publish` | Собрать и опубликовать в npm | `--tag <tag>` — dist-tag npm (например, `beta`, `next`) |
|
||||
| `yarn twenty deploy` | Собрать и загрузить tarball на сервер | `-r, --remote <name>` — целевой удалённый репозиторий |
|
||||
| `yarn twenty catalog-sync` | Запустить на сервере синхронизацию каталога маркетплейса | `-r, --remote <name>` — целевой удалённый репозиторий |
|
||||
| `yarn twenty install` | Установить развернутое приложение в рабочем пространстве | `-r, --remote <name>` — целевой remote |
|
||||
| `yarn twenty dev` | Отслеживать и синхронизировать локальные изменения | Использует remote по умолчанию |
|
||||
| `yarn twenty remote add` | Добавить подключение к серверу | `--url`, `--token`, `--as`, `--local`, `--port` |
|
||||
| `yarn twenty remote list` | Показать настроенные remotes | — |
|
||||
| `yarn twenty remote switch` | Установить remote по умолчанию | — |
|
||||
| `yarn twenty remote status` | Показать статус подключения | — |
|
||||
| `yarn twenty remote remove` | Удалить remote | — |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,73 +4,142 @@ description: İlk Twenty uygulamanızı dakikalar içinde oluşturun.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Uygulamalar şu anda alfa testinde. Özellik işlevsel ancak hâlâ gelişmekte.
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
Uygulamalar, Twenty'yi özel nesneler, alanlar, mantık işlevleri, Yapay Zeka yetenekleri ve UI bileşenleriyle genişletmenizi sağlar — tümü kod olarak yönetilir.
|
||||
|
||||
**Oluşturabilecekleriniz:**
|
||||
|
||||
* Veri modelinizi şekillendirmek için özel nesneler, alanlar, görünümler ve gezinti öğeleri
|
||||
* HTTP rotaları, cron zamanlamaları veya veritabanı olayları tarafından tetiklenen mantık işlevleri
|
||||
* Twenty'nin UI'si içinde doğrudan görüntülenen ön uç bileşenleri
|
||||
* Twenty'nin yapay zeka ajanlarını genişleten beceriler
|
||||
* Bir uygulamayı birden çok çalışma alanına dağıtın
|
||||
|
||||
## Ön Gereksinimler
|
||||
|
||||
* Node.js 24+
|
||||
* Yarn 4
|
||||
* Docker (veya çalışan yerel bir Twenty örneği)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## Başlarken
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
Resmi iskelet oluşturucu aracını kullanarak yeni bir uygulama oluşturun, ardından kimlik doğrulaması yapıp geliştirmeye başlayın:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
> Minimal bir kurulum iskeleti oluşturmak için `--minimal` seçeneğini kullanın
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
Buradan şunları yapabilirsiniz:
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
Ayrıca bkz.: [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) ve [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk) için CLI başvuru sayfaları.
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
## Proje yapısı (şablondan oluşturulmuş)
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
`npx create-twenty-app@latest my-twenty-app` komutunu çalıştırdığınızda iskelet oluşturucu şunları yapar:
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
* Minimal bir temel uygulamayı `my-twenty-app/` içine kopyalar
|
||||
* Yerel bir `twenty-sdk` bağımlılığı ve Yarn 4 yapılandırması ekler
|
||||
* `twenty` CLI ile bağlantılı yapılandırma dosyaları ve betikler oluşturur
|
||||
* İskelet oluşturma moduna bağlı olarak çekirdek dosyaları (uygulama yapılandırması, varsayılan işlev rolü, kurulum öncesi ve kurulum sonrası işlevler) ile örnek dosyaları üretir
|
||||
<Warning>
|
||||
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](/l/tr/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
Varsayılan `--exhaustive` moduyla yeni oluşturulmuş bir uygulama şu şekilde görünür:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Head over to [Building Apps](/l/tr/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -83,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
`--minimal` ile yalnızca çekirdek dosyalar oluşturulur (`application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` ve `logic-functions/post-install.ts`).
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
Genel hatlarıyla:
|
||||
### Key files
|
||||
|
||||
* **package.json**: Uygulama adını, sürümünü, motorları (Node 24+, Yarn 4) bildirir ve `twenty-sdk` ile yerel `twenty` CLI'sine yetki devreden bir `twenty` betiği ekler. Tüm mevcut komutları listelemek için `yarn twenty help` komutunu çalıştırın.
|
||||
* **.gitignore**: `node_modules`, `.yarn`, `.twenty/`, `dist/`, `build/`, kapsam klasörleri, günlük dosyaları ve `.env*` dosyaları gibi yaygın artifaktları yok sayar.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Proje tarafından kullanılan Yarn 4 araç zincirini kilitler ve yapılandırır.
|
||||
* **.nvmrc**: Projenin beklediği Node.js sürümünü sabitler.
|
||||
* **.oxlintrc.json** ve **tsconfig.json**: Uygulamanızın TypeScript kaynakları için linting ve TypeScript yapılandırması sağlar.
|
||||
* **README.md**: Uygulama kökünde temel talimatların yer aldığı kısa bir README.
|
||||
* **public/**: Uygulamanızla birlikte sunulacak genel varlıkları (görseller, yazı tipleri, statik dosyalar) depolamak için bir klasör. Buraya yerleştirilen dosyalar senkronizasyon sırasında yüklenir ve çalışma zamanında erişilebilir olur.
|
||||
* **src/**: Uygulamanızı kod olarak tanımladığınız ana yer
|
||||
| File / Folder | Amaç |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | Twenty'nin yapay zeka ajanlarının yeteneklerini genişleten beceriler. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### Varlık algılama
|
||||
## Managing remotes
|
||||
|
||||
SDK, TypeScript dosyalarınızı **`export default define<Entity>({...})`** çağrılarını arayarak ayrıştırıp varlıkları algılar. Her varlık türünün, `twenty-sdk` tarafından dışa aktarılan karşılık gelen bir yardımcı fonksiyonu vardır:
|
||||
|
||||
| Yardımcı fonksiyon | Varlık türü |
|
||||
| -------------------------------- | -------------------------------------------------------- |
|
||||
| `defineObject` | Özel nesne tanımları |
|
||||
| `defineLogicFunction` | Mantık işlevi tanımları |
|
||||
| `definePreInstallLogicFunction` | Kurulum öncesi mantık işlevi (kurulumdan önce çalışır) |
|
||||
| `definePostInstallLogicFunction` | Kurulum sonrası mantık işlevi (kurulumdan sonra çalışır) |
|
||||
| `defineFrontComponent` | Ön bileşen tanımları |
|
||||
| `defineRole` | Rol tanımları |
|
||||
| `defineField` | Mevcut nesneler için alan genişletmeleri |
|
||||
| `defineView` | Kaydedilmiş görünüm tanımları |
|
||||
| `defineNavigationMenuItem` | Gezinme menüsü öğesi tanımları |
|
||||
| `defineSkill` | Yapay zekâ ajanı yetenek tanımları |
|
||||
|
||||
<Note>
|
||||
**Dosya adlandırma esnektir.** Varlık algılama AST tabanlıdır — SDK, kaynak dosyalarınızı `export default define<Entity>({...})` desenini bulmak için tarar. Dosyalarınızı ve klasörlerinizi dilediğiniz gibi düzenleyebilirsiniz. Varlık türüne göre gruplama (örn. `logic-functions/`, `roles/`) bir gereklilik değil, yalnızca kod organizasyonu için bir gelenektir.
|
||||
</Note>
|
||||
|
||||
Algılanan bir varlığa örnek:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
İlerideki komutlar daha fazla dosya ve klasör ekleyecektir:
|
||||
|
||||
* `yarn twenty dev`, türlendirilmiş `CoreApiClient`'i (çalışma alanı verileri için `/graphql` aracılığıyla) `node_modules/twenty-client-sdk/` içine otomatik olarak oluşturur. `MetadataApiClient` (çalışma alanı yapılandırması ve dosya yüklemeleri için `/metadata` aracılığıyla) önceden derlenmiş olarak gelir ve hemen kullanılabilir. Bunları sırasıyla `twenty-client-sdk/core` ve `twenty-client-sdk/metadata` içinden içe aktarın.
|
||||
* `yarn twenty add`, özel nesneleriniz, fonksiyonlarınız, ön bileşenleriniz, rolleriniz, yetenekleriniz ve daha fazlası için `src/` altında varlık tanım dosyaları ekler.
|
||||
|
||||
## Kimlik Doğrulama
|
||||
|
||||
`yarn twenty auth:login` komutunu ilk kez çalıştırdığınızda, sizden şunlar istenir:
|
||||
|
||||
* API URL’si (varsayılan: http://localhost:3000 veya mevcut çalışma alanı profiliniz)
|
||||
* API anahtarı
|
||||
|
||||
Kimlik bilgileriniz kullanıcı başına `~/.twenty/config.json` içinde saklanır. Birden fazla profili yönetebilir ve aralarında geçiş yapabilirsiniz.
|
||||
|
||||
### Çalışma alanlarını yönetme
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
`yarn twenty auth:switch` ile çalışma alanlarını değiştirdikten sonra, sonraki tüm komutlar varsayılan olarak o çalışma alanını kullanacaktır. Yine de bunu geçici olarak `--workspace <name>` ile geçersiz kılabilirsiniz.
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### Sunucuyu Başlatma
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| Komut | Açıklama |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## Manuel kurulum (iskelet oluşturucu olmadan)
|
||||
|
||||
En iyi başlangıç deneyimi için `create-twenty-app` kullanmanızı önersek de, bir projeyi manuel olarak da kurabilirsiniz. CLI'yi global olarak kurmayın. Bunun yerine `twenty-sdk`'yi yerel bir bağımlılık olarak ekleyin ve package.json içinde tek bir betik tanımlayın:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
Ardından bir `twenty` betiği ekleyin:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -210,25 +393,19 @@ Ardından bir `twenty` betiği ekleyin:
|
||||
}
|
||||
```
|
||||
|
||||
Artık tüm komutları `yarn twenty <command>` üzerinden çalıştırabilirsiniz; örn. `yarn twenty dev`, `yarn twenty help` vb.
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## Yerel bir Twenty örneği nasıl kullanılır?
|
||||
|
||||
Zaten yerel olarak bir Twenty örneği çalıştırıyorsanız (örneğin `npx nx start twenty-server` ile), Docker kullanmak yerine ona bağlanabilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
* Kimlik doğrulama hataları: `yarn twenty auth:login` çalıştırın ve API anahtarınızın gerekli izinlere sahip olduğundan emin olun.
|
||||
* Sunucuya bağlanılamıyor: API URL’sini ve Twenty sunucusunun erişilebilir olduğunu doğrulayın.
|
||||
* Türler veya istemci eksik/eski: `yarn twenty dev` komutunu yeniden çalıştırın — tiplendirilmiş istemciyi otomatik olarak oluşturur.
|
||||
* Geliştirme modu eşitlenmiyor: `yarn twenty dev`'in çalıştığından ve değişikliklerin ortamınız tarafından yok sayılmadığından emin olun.
|
||||
If you run into issues:
|
||||
|
||||
Discord Yardım Kanalı: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,34 +4,76 @@ description: Twenty uygulamanızı pazaryerine sunun ya da dahili olarak dağıt
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Uygulamalar şu anda alfa testinde. Özellik işlevsel ancak hâlâ gelişmekte.
|
||||
Uygulamalar şu anda alfa aşamasında. Özellik işlevsel ancak hâlâ gelişmekte.
|
||||
</Warning>
|
||||
|
||||
## Genel Bakış
|
||||
|
||||
Uygulamanız [yerelde derlenip test edildikten sonra](/l/tr/developers/extend/apps/building), dağıtım için iki yolunuz vardır:
|
||||
|
||||
* **npm’ye yayımlama** — uygulamanızı Twenty pazaryerinde listeleyin; böylece herhangi bir çalışma alanı keşfedip yükleyebilir.
|
||||
* **Bir tar arşivi dağıtın** — uygulamanızı dahili veya özel kullanım için doğrudan belirli bir Twenty sunucusuna yükleyin.
|
||||
* **npm’ye yayımlama** — uygulamanızı Twenty pazaryerinde listeleyin; böylece herhangi bir çalışma alanı keşfedip yükleyebilir.
|
||||
|
||||
Her iki yol da aynı **build** adımından başlar.
|
||||
|
||||
## Uygulamanızı derleme
|
||||
|
||||
`build` komutu TypeScript kaynaklarınızı derler, mantık işlevlerini ve ön uç bileşenlerini transpile eder ve uygulamanızın içeriğini açıklayan bir `manifest.json` üretir:
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
Çıktı `.twenty/output/` dizinine yazılır. Bu dizin, dağıtım için gereken her şeyi içerir: derlenmiş kod, varlıklar, manifest ve `package.json` dosyanızın bir kopyası.
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
Ayrıca bir `.tgz` tarball oluşturmak için (deploy komutu tarafından dahili olarak kullanılır veya el ile dağıtım için):
|
||||
## Sunucuya dağıtım (tarball)
|
||||
|
||||
Genel kullanıma açık olmasını istemediğiniz uygulamalar — sahipli araçlar, yalnızca kurumsal entegrasyonlar veya deneysel derlemeler — için bir tarball’ı doğrudan bir Twenty sunucusuna dağıtabilirsiniz.
|
||||
|
||||
### Ön Gereksinimler
|
||||
|
||||
Dağıtmadan önce, hedef sunucuyu işaret eden yapılandırılmış bir remote’a ihtiyacınız vardır. Remote’lar sunucu URL’sini ve kimlik doğrulama bilgilerini yerel olarak `~/.twenty/config.json` içinde saklar.
|
||||
|
||||
Bir remote ekleyin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build --tarball
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### Dağıtım
|
||||
|
||||
Uygulamanızı tek adımda derleyip sunucuya yükleyin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### Dağıtılmış bir uygulamayı paylaşma
|
||||
|
||||
Tarball uygulamaları genel pazar yerinde listelenmez; bu nedenle aynı sunucudaki diğer çalışma alanları gezinerek onları keşfedemez. Dağıtılmış bir uygulamayı paylaşmak için:
|
||||
|
||||
1. **Ayarlar > Uygulamalar > Kayıtlar** bölümüne gidin ve uygulamanızı açın
|
||||
2. **Dağıtım** sekmesinde, **Paylaşım bağlantısını kopyala**’ya tıklayın
|
||||
3. Bu bağlantıyı diğer çalışma alanlarındaki kullanıcılarla paylaşın — onları doğrudan uygulamanın yükleme sayfasına götürür
|
||||
|
||||
Paylaşım bağlantısı, sunucunun temel URL’sini (herhangi bir çalışma alanı alt alan adı olmadan) kullanır; böylece sunucudaki herhangi bir çalışma alanı için çalışır.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### Sürüm yönetimi
|
||||
|
||||
Bir güncelleme yayımlamak için:
|
||||
|
||||
1. `package.json` içindeki `version` alanını artırın
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. Uygulamayı kurmuş olan çalışma alanları, ayarlarında mevcut güncellemeyi görecektir
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## npm’ye yayımlama
|
||||
|
||||
npm’ye yayımlamak, uygulamanızın Twenty pazaryerinde keşfedilebilir olmasını sağlar. Herhangi bir Twenty çalışma alanı, pazaryeri uygulamalarına doğrudan arayüzden göz atabilir, yükleyebilir ve güncelleyebilir.
|
||||
@@ -39,41 +81,42 @@ npm’ye yayımlamak, uygulamanızın Twenty pazaryerinde keşfedilebilir olmas
|
||||
### Gereksinimler
|
||||
|
||||
* Bir [npm](https://www.npmjs.com) hesabı
|
||||
* `twenty-app` anahtar kelimesi `package.json` dosyanızdaki `keywords` dizisinde **mutlaka** listelenmelidir
|
||||
|
||||
### Gerekli anahtar kelimeyi ekleme
|
||||
|
||||
Twenty pazar yeri, npm kayıt defterinde `twenty-app` anahtar kelimesine sahip paketleri arayarak uygulamaları keşfeder. Bunu `package.json` dosyanıza ekleyin:
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"],
|
||||
...
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Pazar yeri, npm kayıt defterinde `keywords:twenty-app` araması yapar. Bu anahtar kelime olmadan, adında `twenty-app-` öneki bulunsa bile paketiniz pazar yerinde görünmez.
|
||||
</Note>
|
||||
### Pazaryeri meta verileri
|
||||
|
||||
### Adımlar
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
1. **Uygulamanızı derleyin:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
2. **npm’ye yayımlayın:**
|
||||
See the [defineApplication accordion](/l/tr/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
Bu, `.twenty/output/` dizininden `npm publish` komutunu çalıştırır.
|
||||
|
||||
Belirli bir dist-tag altında yayımlamak için (ör. `beta` veya `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
@@ -82,25 +125,17 @@ yarn twenty publish --tag beta
|
||||
|
||||
### Pazar yerinde keşif nasıl çalışır
|
||||
|
||||
Twenty sunucusu pazar yeri kataloğunu npm kayıt defterinden **her saat** eşitler:
|
||||
The Twenty server syncs its marketplace catalog from the npm registry **every hour**.
|
||||
|
||||
1. `keywords:twenty-app` anahtar kelimesine sahip tüm npm paketlerini arar
|
||||
2. Her paket için `manifest.json` dosyasını npm CDN’inden getirir
|
||||
3. Uygulamanın meta verileri (ad, açıklama, yazar, logo, ekran görüntüleri, kategori) manifest dosyasından çıkarılır ve pazar yerinde görüntülenir
|
||||
|
||||
Yayımladıktan sonra, uygulamanızın pazar yerinde görünmesi bir saate kadar sürebilir. Bir sonraki saatlik çalışmayı beklemek yerine eşitlemeyi hemen tetiklemek için:
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
Belirli bir remote’u hedeflemek için:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync -r production
|
||||
```
|
||||
|
||||
Pazar yerinde gösterilen meta veriler, uygulamanızın kaynak kodundaki `defineApplication()` çağrısından gelir — `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl` ve `termsUrl` gibi alanlar.
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
Uygulamanız `defineApplication()` içinde bir `aboutDescription` tanımlamıyorsa, pazaryeri, hakkında sayfasının içeriği olarak paketinizin npm'deki `README.md` dosyasını otomatik olarak kullanır. Bu, hem npm hem de Twenty pazaryeri için tek bir README dosyası kullanabileceğiniz anlamına gelir. Pazaryerinde farklı bir açıklama istiyorsanız, `aboutDescription` değerini açıkça ayarlayın.
|
||||
@@ -108,7 +143,7 @@ Uygulamanız `defineApplication()` içinde bir `aboutDescription` tanımlamıyor
|
||||
|
||||
### CI üzerinden yayımlama
|
||||
|
||||
İskelet proje, her sürümde yayımlayan bir GitHub Actions iş akışını içerir:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -133,121 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
Diğer CI sistemleri (GitLab CI, CircleCI, vb.) için de aynı üç komut geçerlidir: `yarn install`, `yarn twenty build` ve ardından `.twenty/output` dizininden `npm publish`.
|
||||
|
||||
<Tip>
|
||||
<Note>
|
||||
**npm provenance** isteğe bağlıdır ancak önerilir. `--provenance` ile yayımlamak, npm listenize bir güven rozeti ekler ve kullanıcıların paketin herkese açık bir CI ardışık düzenindeki belirli bir commit’ten oluşturulduğunu doğrulamasını sağlar. Kurulum talimatları için [npm provenance belgelerine](https://docs.npmjs.com/generating-provenance-statements) bakın.
|
||||
</Tip>
|
||||
|
||||
## Sunucuya dağıtım (tarball)
|
||||
|
||||
Genel kullanıma açık olmasını istemediğiniz uygulamalar — sahipli araçlar, yalnızca kurumsal entegrasyonlar veya deneysel derlemeler — için bir tarball’ı doğrudan bir Twenty sunucusuna dağıtabilirsiniz.
|
||||
|
||||
### Ön Gereksinimler
|
||||
|
||||
Dağıtmadan önce, hedef sunucuyu işaret eden yapılandırılmış bir remote’a ihtiyacınız vardır. Remote’lar sunucu URL’sini ve kimlik doğrulama bilgilerini yerel olarak `~/.twenty/config.json` içinde saklar.
|
||||
|
||||
Bir remote ekleyin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
Yerel bir geliştirme sunucusu için:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --local --as local
|
||||
```
|
||||
|
||||
Etkileşimli olmayan ortamlar için bir API anahtarıyla da kimlik doğrulayabilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
|
||||
```
|
||||
|
||||
Remote’larınızı yönetin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote list # List all configured remotes
|
||||
yarn twenty remote switch prod # Set the default remote
|
||||
yarn twenty remote status # Show active remote and auth status
|
||||
yarn twenty remote remove old # Remove a remote
|
||||
```
|
||||
|
||||
### Dağıtım
|
||||
|
||||
Uygulamanızı tek adımda derleyip sunucuya yükleyin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
```
|
||||
|
||||
Bu, uygulamayı `--tarball` ile derler ve ardından tarball’ı varsayılan remote’a GraphQL çok parçalı yükleme ile yükler.
|
||||
|
||||
Belirli bir remote’a dağıtmak için:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy -r production
|
||||
```
|
||||
|
||||
### Dağıtılmış bir uygulamayı paylaşma
|
||||
|
||||
Tarball uygulamaları genel pazar yerinde listelenmez; bu nedenle aynı sunucudaki diğer çalışma alanları gezinerek onları keşfedemez. Dağıtılmış bir uygulamayı paylaşmak için:
|
||||
|
||||
1. **Ayarlar > Uygulamalar > Kayıtlar** bölümüne gidin ve uygulamanızı açın
|
||||
2. **Dağıtım** sekmesinde, **Paylaşım bağlantısını kopyala**’ya tıklayın
|
||||
3. Bu bağlantıyı diğer çalışma alanlarındaki kullanıcılarla paylaşın — onları doğrudan uygulamanın yükleme sayfasına götürür
|
||||
|
||||
Paylaşım bağlantısı, sunucunun temel URL’sini (herhangi bir çalışma alanı alt alan adı olmadan) kullanır; böylece sunucudaki herhangi bir çalışma alanı için çalışır.
|
||||
|
||||
### Sürüm yönetimi
|
||||
|
||||
Bir güncelleme yayımlamak için:
|
||||
|
||||
1. `package.json` içindeki `version` alanını artırın
|
||||
2. `yarn twenty deploy` (veya `yarn twenty deploy -r production`) komutunu çalıştırın
|
||||
3. Uygulamayı kurmuş olan çalışma alanları, ayarlarında mevcut güncellemeyi görecektir
|
||||
</Note>
|
||||
|
||||
## Uygulamaları yükleme
|
||||
|
||||
Bir uygulama yayımlandığında (npm) veya dağıtıldığında (tarball), çalışma alanları onu kullanıcı arayüzü (UI) aracılığıyla yükler:
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
Veya Twenty kullanıcı arayüzündeki **Ayarlar > Uygulamalar** sayfasından; burada hem pazar yerindeki hem de tarball ile dağıtılmış uygulamalar görüntülenip yüklenebilir.
|
||||
|
||||
## Uygulama dağıtım kategorileri
|
||||
|
||||
Twenty, uygulamaları nasıl dağıtıldıklarına göre üç kategoriye ayırır:
|
||||
|
||||
| Kategori | Nasıl Çalışır | Pazaryerinde görünür mü? |
|
||||
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
||||
| **Geliştirme** | `yarn twenty dev` ile çalışan yerel geliştirme modu uygulamaları. Derleme ve test için kullanılır. | Hayır |
|
||||
| **Yayımlanmış (npm)** | `twenty-app` anahtar kelimesiyle npm’ye yayımlanan uygulamalar. Herhangi bir çalışma alanının yükleyebilmesi için pazaryerinde listelenir. | Evet |
|
||||
| **Dahili (tarball)** | Bir tarball aracılığıyla belirli bir sunucuya dağıtılan uygulamalar. Yalnızca o sunucudaki çalışma alanları için bir paylaşım bağlantısı aracılığıyla kullanılabilir. | Hayır |
|
||||
|
||||
<Tip>
|
||||
Uygulamanızı geliştirirken **Geliştirme** modunda başlayın. Hazır olduğunda, geniş dağıtım için **Yayımlanmış** (npm) ya da özel dağıtım için **Dahili** (tarball) seçeneğini tercih edin.
|
||||
</Tip>
|
||||
|
||||
## CLI başvurusu
|
||||
|
||||
| Komut | Açıklama | Temel bayraklar |
|
||||
| --------------------------- | --------------------------------------------------- | -------------------------------------------------- |
|
||||
| `yarn twenty build` | Uygulamayı derleyin ve manifest oluşturun | `--tarball` — ayrıca bir `.tgz` paket oluşturur |
|
||||
| `yarn twenty publish` | Derleyin ve npm’ye yayımlayın | `--tag <tag>` — npm dist-tag (örn. `beta`, `next`) |
|
||||
| `yarn twenty deploy` | Derleyin ve tarball’ı bir sunucuya yükleyin | `-r, --remote <name>` — hedef remote |
|
||||
| `yarn twenty catalog-sync` | Sunucuda pazar yeri katalog eşitlemesini tetikleyin | `-r, --remote <name>` — hedef remote |
|
||||
| `yarn twenty install` | Dağıtılmış bir uygulamayı bir çalışma alanına kurun | `-r, --remote <name>` — hedef remote |
|
||||
| `yarn twenty dev` | Yerel değişiklikleri izleyin ve eşitleyin | Varsayılan remote’u kullanır |
|
||||
| `yarn twenty remote add` | Bir sunucu bağlantısı ekleyin | `--url`, `--token`, `--as`, `--local`, `--port` |
|
||||
| `yarn twenty remote list` | Yapılandırılmış remote’ları listeleyin | — |
|
||||
| `yarn twenty remote switch` | Varsayılan remote’u ayarlayın | — |
|
||||
| `yarn twenty remote status` | Bağlantı durumunu gösterin | — |
|
||||
| `yarn twenty remote remove` | Bir remote’u kaldırın | — |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,73 +4,142 @@ description: 几分钟内创建你的第一个 Twenty 应用。
|
||||
---
|
||||
|
||||
<Warning>
|
||||
应用目前处于 Alpha 测试阶段。 该功能可用,但仍在演进中。
|
||||
Apps are currently in alpha. The feature works but is still evolving.
|
||||
</Warning>
|
||||
|
||||
应用可通过自定义对象、字段、逻辑函数、AI 技能和 UI 组件来扩展 Twenty——全部以代码进行管理。
|
||||
|
||||
**你可以构建的内容:**
|
||||
|
||||
* 自定义对象、字段、视图和导航项,以塑造你的数据模型
|
||||
* 由 HTTP 路由、cron 调度或数据库事件触发的逻辑函数
|
||||
* 在 Twenty 的 UI 中直接渲染的前端组件
|
||||
* 用于扩展 Twenty 的 AI 代理的技能
|
||||
* 将同一个应用部署到多个工作空间
|
||||
|
||||
## 先决条件
|
||||
|
||||
* Node.js 24+
|
||||
* Yarn 4
|
||||
* Docker (或正在运行的本地 Twenty 实例)
|
||||
Before you begin, make sure the following is installed on your machine:
|
||||
|
||||
## 开始使用
|
||||
* **Node.js 24+** — [Download here](https://nodejs.org/)
|
||||
* **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
|
||||
* **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.
|
||||
|
||||
使用官方脚手架创建一个新应用,然后进行身份验证并开始开发:
|
||||
## Step 1: Scaffold your app
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
> 使用 `--minimal` 选项生成最简安装脚手架
|
||||
You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.
|
||||
|
||||
从这里您可以:
|
||||
This creates a new folder called `my-twenty-app` with everything you need.
|
||||
|
||||
<Note>
|
||||
The scaffolder supports these flags:
|
||||
|
||||
* `--minimal` — scaffold only the essential files, no examples (default)
|
||||
* `--exhaustive` — scaffold all example entities
|
||||
* `--name <name>` — set the app name (skips the prompt)
|
||||
* `--display-name <displayName>` — set the display name (skips the prompt)
|
||||
* `--description <description>` — set the description (skips the prompt)
|
||||
* `--skip-local-instance` — skip the local server setup prompt
|
||||
</Note>
|
||||
|
||||
## Step 2: Set up a local Twenty instance
|
||||
|
||||
The scaffolder will ask:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
|
||||
* **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
|
||||
* **Type `no`** — Choose this if you already have a Twenty server running locally.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
</div>
|
||||
|
||||
## Step 3: Sign in to your workspace
|
||||
|
||||
Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
</div>
|
||||
|
||||
## Step 4: Authorize the app
|
||||
|
||||
After you sign in, you will see an authorization screen. This lets your app interact with your workspace.
|
||||
|
||||
Click **Authorize** to continue.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
</div>
|
||||
|
||||
Once authorized, your terminal will confirm that everything is set up.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
</div>
|
||||
|
||||
## Step 5: Start developing
|
||||
|
||||
Go into your new app folder and start the development server:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the pre-install function
|
||||
yarn twenty function:execute --preInstall
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
另请参阅:[create-twenty-app](https://www.npmjs.com/package/create-twenty-app) 和 [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk) 的 CLI 参考页面。
|
||||
This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.
|
||||
|
||||
## 项目结构(脚手架生成)
|
||||
For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:
|
||||
|
||||
当你运行 `npx create-twenty-app@latest my-twenty-app` 时,脚手架将:
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --verbose
|
||||
```
|
||||
|
||||
* 将一个最小的基础应用复制到 `my-twenty-app/` 中
|
||||
* 添加本地 `twenty-sdk` 依赖和 Yarn 4 配置
|
||||
* 创建与 `twenty` CLI 关联的配置文件和脚本
|
||||
* 生成核心文件(应用配置、默认函数角色、安装前/安装后函数),并基于脚手架模式生成示例文件
|
||||
<Warning>
|
||||
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](/l/zh/developers/extend/apps/publishing) for details.
|
||||
</Warning>
|
||||
|
||||
使用默认 `--exhaustive` 模式新搭建的应用如下所示:
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
|
||||
</div>
|
||||
|
||||
## Step 6: See your app in Twenty
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
</div>
|
||||
|
||||
Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
|
||||
</div>
|
||||
|
||||
Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
|
||||
</div>
|
||||
|
||||
You are all set! Edit any file in `src/` and the changes will be picked up automatically.
|
||||
|
||||
Head over to [Building Apps](/l/zh/developers/extend/apps/building) for a detailed guide on creating objects, logic functions, front components, skills, and more.
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
The scaffolder generates the following file structure (shown with `--exhaustive` mode, which includes examples for every entity type):
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -83,124 +152,238 @@ my-twenty-app/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
```
|
||||
|
||||
使用 `--minimal` 时,只会创建核心文件(`application-config.ts`、`roles/default-role.ts`、`logic-functions/pre-install.ts` 和 `logic-functions/post-install.ts`)。
|
||||
By default (`--minimal`), only the core files are created: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts`, and `logic-functions/post-install.ts`. Use `--exhaustive` to include all the example files shown above.
|
||||
|
||||
总体来说:
|
||||
### Key files
|
||||
|
||||
* **package.json**:声明应用名称、版本、引擎(Node 24+、Yarn 4),并添加 `twenty-sdk` 以及一个 `twenty` 脚本,该脚本会委托给本地的 `twenty` CLI。 运行 `yarn twenty help` 以列出所有可用命令。
|
||||
* **.gitignore**:忽略常见产物,如 `node_modules`、`.yarn`、`.twenty/`、`dist/`、`build/`、覆盖率文件夹、日志文件以及 `.env*` 文件。
|
||||
* **yarn.lock**、**.yarnrc.yml**、**.yarn/**:锁定并配置项目使用的 Yarn 4 工具链。
|
||||
* **.nvmrc**:固定项目期望的 Node.js 版本。
|
||||
* **.oxlintrc.json** 和 **tsconfig.json**:为应用的 TypeScript 源码提供 Lint 与 TypeScript 配置。
|
||||
* **README.md**:应用根目录中的简短 README,包含基本说明。
|
||||
* **public/**: 一个用于存储公共资源(图像、字体、静态文件)的文件夹,这些资源将随你的应用程序一起提供。 放置在此处的文件会在同步期间上传,并可在运行时访问。
|
||||
* **src/**:你以代码形式定义应用的主要位置
|
||||
| File / Folder | 目的 |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/roles/` | Defines roles that control what your logic functions can access. |
|
||||
| `src/logic-functions/` | Server-side functions triggered by routes, cron schedules, or database events. |
|
||||
| `src/front-components/` | React components that render inside Twenty's UI. |
|
||||
| `src/objects/` | Custom object definitions to extend your data model. |
|
||||
| `src/fields/` | Custom fields added to existing objects. |
|
||||
| `src/views/` | Saved view configurations. |
|
||||
| `src/navigation-menu-items/` | Custom links in the sidebar navigation. |
|
||||
| `src/skills/` | 用于扩展 Twenty 的 AI 代理的技能. |
|
||||
| `src/agents/` | AI agents with custom prompts. |
|
||||
| `src/page-layouts/` | Custom page layouts for record views. |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
|
||||
### 实体检测
|
||||
## Managing remotes
|
||||
|
||||
该 SDK 通过在你的 TypeScript 文件中解析 **`export default define<Entity>({...})`** 调用来检测实体。 每种实体类型都有一个从 `twenty-sdk` 导出的对应辅助函数:
|
||||
|
||||
| 辅助函数 | 实体类型 |
|
||||
| -------------------------------- | ---------------- |
|
||||
| `defineObject` | 自定义对象定义 |
|
||||
| `defineLogicFunction` | 逻辑函数定义 |
|
||||
| `definePreInstallLogicFunction` | 安装前逻辑函数(在安装之前运行) |
|
||||
| `definePostInstallLogicFunction` | 安装后逻辑函数(在安装之后运行) |
|
||||
| `defineFrontComponent` | 前端组件定义 |
|
||||
| `defineRole` | 角色定义 |
|
||||
| `defineField` | 现有对象的字段扩展 |
|
||||
| `defineView` | 已保存的视图定义 |
|
||||
| `defineNavigationMenuItem` | 导航菜单项定义 |
|
||||
| `defineSkill` | AI 代理技能定义 |
|
||||
|
||||
<Note>
|
||||
**文件命名是灵活的。** 实体检测基于 AST — SDK 会扫描你的源文件以查找 `export default define<Entity>({...})` 模式。 你可以按照自己的喜好组织文件和文件夹。 按实体类型分组(例如 `logic-functions/`、`roles/`)只是代码组织的一种约定,并非必需。
|
||||
</Note>
|
||||
|
||||
已检测实体的示例:
|
||||
|
||||
```typescript
|
||||
// This file can be named anything and placed anywhere in src/
|
||||
import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '...',
|
||||
nameSingular: 'postCard',
|
||||
// ... rest of config
|
||||
});
|
||||
```
|
||||
|
||||
后续命令将添加更多文件和文件夹:
|
||||
|
||||
* `yarn twenty dev` 会自动生成类型化的 `CoreApiClient`(通过 `/graphql` 获取工作区数据),并写入 `node_modules/twenty-client-sdk/`。 `MetadataApiClient`(通过 `/metadata` 处理工作区配置和文件上传)为预构建版本,可立即使用。 分别从 `twenty-client-sdk/core` 和 `twenty-client-sdk/metadata` 导入它们。
|
||||
* `yarn twenty add` 会在 `src/` 下为你的自定义对象、函数、前端组件、角色、技能等添加实体定义文件。
|
||||
|
||||
## 身份验证
|
||||
|
||||
首次运行 `yarn twenty auth:login` 时,你将被提示输入:
|
||||
|
||||
* API URL(默认为 http://localhost:3000 或你当前的工作空间配置)
|
||||
* API 密钥
|
||||
|
||||
你的凭据按用户存储在 `~/.twenty/config.json` 中。 你可以维护多个配置文件并在它们之间切换。
|
||||
|
||||
### 管理工作空间
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn twenty auth:login
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# List all configured workspaces
|
||||
yarn twenty auth:list
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn twenty auth:switch
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn twenty auth:status
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
使用 `yarn twenty auth:switch` 切换工作空间后,后续所有命令将默认使用该工作空间。 你仍可通过 `--workspace <name>` 临时覆盖。
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
|
||||
## Local development server (`yarn twenty server`)
|
||||
|
||||
The CLI can manage a local Twenty server running in Docker. This is the same server started automatically when you scaffold an app with `create-twenty-app`, but you can also manage it manually.
|
||||
|
||||
### 启动服务器
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
This pulls the `twentycrm/twenty-app-dev:latest` Docker image (if not already present), creates a container named `twenty-app-dev`, and starts it on port **2020**. The CLI waits until the server passes its health check before returning.
|
||||
|
||||
Two Docker volumes are created to persist data between restarts:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL database
|
||||
* `twenty-app-dev-storage` — file storage
|
||||
|
||||
If port 2020 is already in use, you can start on a different port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
The CLI automatically configures the container's internal `NODE_PORT` and `SERVER_URL` to match the chosen port, so logic functions, OAuth, and all other internal networking work correctly.
|
||||
|
||||
Once started, the server is automatically registered as the `local` remote in your CLI config.
|
||||
|
||||
### Checking server status
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Displays whether the server is running, its URL, and the default login credentials (`tim@apple.dev` / `tim@apple.dev`).
|
||||
|
||||
### Viewing server logs
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streams the container logs. Use `--lines` to control how many recent lines to show:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Stopping the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stops the container. Your data is preserved in the Docker volumes — the next `start` picks up where you left off.
|
||||
|
||||
### Resetting the server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Removes the container **and** deletes both Docker volumes, wiping all data. The next `start` creates a fresh instance.
|
||||
|
||||
<Note>
|
||||
The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
|
||||
</Note>
|
||||
|
||||
### Command reference
|
||||
|
||||
| 命令 | 描述 |
|
||||
| -------------------------------------- | ---------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the local server (pulls image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show server status, URL, and credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
|
||||
| `yarn twenty server reset` | Delete all data and start fresh |
|
||||
|
||||
## CI with GitHub Actions
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
|
||||
The workflow:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
|
||||
## 手动设置(不使用脚手架)
|
||||
|
||||
虽然我们建议使用 `create-twenty-app` 以获得最佳的上手体验,但你也可以手动设置项目。 不要全局安装 CLI。 相反,请将 `twenty-sdk` 添加为本地依赖,并在你的 package.json 中配置一个脚本:
|
||||
If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.
|
||||
|
||||
**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
然后添加一个 `twenty` 脚本:
|
||||
**2. Add a `twenty` script to your `package.json`:**
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -210,25 +393,19 @@ yarn add -D twenty-sdk
|
||||
}
|
||||
```
|
||||
|
||||
现在你可以通过 `yarn twenty <command>` 运行所有命令,例如 `yarn twenty dev`、`yarn twenty help` 等。
|
||||
You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.
|
||||
|
||||
## 如何使用本地 Twenty 实例
|
||||
|
||||
如果你已经在本地运行一个 Twenty 实例(例如通过 `npx nx start twenty-server`),你可以连接到它,而不是使用 Docker:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# During scaffolding — skip Docker, connect to your running instance
|
||||
npx create-twenty-app@latest my-app --port 3000
|
||||
|
||||
# Or after scaffolding — add a remote pointing to your instance
|
||||
yarn twenty remote add --local --port 3000
|
||||
```
|
||||
<Note>
|
||||
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
|
||||
</Note>
|
||||
|
||||
## 故障排除
|
||||
|
||||
* 身份验证错误:运行 `yarn twenty auth:login`,并确保你的 API 密钥具有所需权限。
|
||||
* 无法连接到服务器:请验证 API URL,并确保 Twenty 服务器可达。
|
||||
* 类型或客户端缺失/过期:重启 `yarn twenty dev` — 它会自动生成类型化客户端。
|
||||
* 开发模式未同步:确保 `yarn twenty dev` 正在运行,并且你的环境不会忽略变更。
|
||||
If you run into issues:
|
||||
|
||||
Discord 帮助频道:https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
* Make sure **Docker is running** before starting the scaffolder with a local instance.
|
||||
* Make sure you are using **Node.js 24+** (`node -v` to check).
|
||||
* Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
|
||||
* Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.
|
||||
|
||||
Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
|
||||
|
||||
@@ -4,34 +4,76 @@ description: 将你的 Twenty 应用分发到应用市场,或进行内部部
|
||||
---
|
||||
|
||||
<Warning>
|
||||
应用目前处于 Alpha 测试阶段。 该功能可用,但仍在演进中。
|
||||
应用目前处于 Alpha 阶段。 该功能可用,但仍在演进中。
|
||||
</Warning>
|
||||
|
||||
## 概览
|
||||
|
||||
一旦你的应用已[在本地构建并完成测试](/l/zh/developers/extend/apps/building),你可以通过两种方式进行分发:
|
||||
|
||||
* **发布到 npm** — 将你的应用在 Twenty 应用市场上架,供任何工作区发现并安装。
|
||||
* **部署 tar 包** — 直接将你的应用上传到特定的 Twenty 服务器,以供内部或私有使用。
|
||||
* **发布到 npm** — 将你的应用在 Twenty 应用市场上架,供任何工作区发现并安装。
|
||||
|
||||
两种路径都从同一个**构建**步骤开始。
|
||||
|
||||
## 构建你的应用
|
||||
|
||||
`build` 命令会编译你的 TypeScript 源码,转译逻辑函数和前端组件,并生成一个描述你应用内容的 `manifest.json`:
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
输出将写入 `.twenty/output/`。 此目录包含分发所需的一切:已编译的代码、资源、清单,以及你的 `package.json` 副本。
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
|
||||
要同时创建一个 `.tgz` 压缩包(由部署命令在内部使用,或用于手动分发):
|
||||
## 部署到服务器(tar 包)
|
||||
|
||||
对于你不希望公开的应用(专有工具、仅供企业使用的集成或实验性构建),你可以将 tar 包直接部署到某台 Twenty 服务器。
|
||||
|
||||
### 先决条件
|
||||
|
||||
在部署之前,你需要配置一个指向目标服务器的远程。 远程会将服务器 URL 和身份验证凭据本地存储在 `~/.twenty/config.json` 中。
|
||||
|
||||
添加远程:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build --tarball
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### 部署
|
||||
|
||||
一步构建并将你的应用上传到服务器:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
# To deploy to a specific remote:
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### 共享已部署的应用
|
||||
|
||||
通过 tar 包分发的应用不会出现在公共市场中,因此同一服务器上的其他工作区无法通过浏览发现它们。 要共享已部署的应用:
|
||||
|
||||
1. 前往 **Settings > Applications > Registrations** 并打开你的应用
|
||||
2. 在 **Distribution** 选项卡中,点击 **Copy share link**
|
||||
3. 将此链接分享给其他工作区的用户 — 它会将他们直接带到该应用的安装页面
|
||||
|
||||
该分享链接使用服务器的基础 URL(不包含任何工作区子域),因此适用于该服务器上的任意工作区。
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### 版本管理
|
||||
|
||||
要发布更新:
|
||||
|
||||
1. 更新 `package.json` 中的 `version` 字段
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. 已安装该应用的工作区会在其设置中看到可用的升级
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
## 发布到 npm
|
||||
|
||||
发布到 npm 可让你的应用在 Twenty 应用市场中被发现。 任何 Twenty 工作区都可以直接通过 UI 浏览、安装和升级应用市场中的应用。
|
||||
@@ -39,41 +81,42 @@ yarn twenty build --tarball
|
||||
### 要求
|
||||
|
||||
* 一个 [npm](https://www.npmjs.com) 账户
|
||||
* 在你的 `package.json` 的 `keywords` 数组中**必须**包含 `twenty-app` 关键字
|
||||
|
||||
### 添加所需关键字
|
||||
|
||||
Twenty 市场通过在 npm 注册表中搜索带有 `twenty-app` 关键字的包来发现应用。 将其添加到你的 `package.json`:
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"name": "twenty-app-postcard-sender",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["twenty-app"],
|
||||
...
|
||||
"keywords": ["twenty-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
该市场会在 npm 注册表中搜索 `keywords:twenty-app`。 没有此关键字,即使包名带有 `twenty-app-` 前缀,你的包也不会出现在市场中。
|
||||
</Note>
|
||||
### 应用市场元数据
|
||||
|
||||
### 步骤
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
|
||||
1. **构建你的应用:**
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
universalIdentifier: '...',
|
||||
displayName: 'My App',
|
||||
description: 'A great app',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
logoUrl: 'public/logo.png',
|
||||
screenshots: [
|
||||
'public/screenshot-1.png',
|
||||
'public/screenshot-2.png',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
2. **发布到 npm:**
|
||||
See the [defineApplication accordion](/l/zh/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
|
||||
### Publish
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
这会在 `.twenty/output/` 目录下运行 `npm publish`。
|
||||
|
||||
要在特定的 dist-tag(例如 `beta` 或 `next`)下发布:
|
||||
|
||||
```bash filename="Terminal"
|
||||
@@ -82,25 +125,17 @@ yarn twenty publish --tag beta
|
||||
|
||||
### 应用市场的发现机制如何运作
|
||||
|
||||
Twenty 服务器会**每小时**从 npm 注册表同步其市场目录:
|
||||
The Twenty server syncs its marketplace catalog from the npm registry **every hour**.
|
||||
|
||||
1. 它会搜索所有带有 `keywords:twenty-app` 关键字的 npm 包
|
||||
2. 对于每个包,它会从 npm CDN 获取 `manifest.json`
|
||||
3. 应用的元数据(名称、描述、作者、徽标、屏幕截图、类别)将从清单中提取,并显示在市场中
|
||||
|
||||
发布后,你的应用最多可能需要一小时才会出现在市场中。 要立即触发同步,而无需等待下一次每小时同步:
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync
|
||||
# To target a specific remote:
|
||||
# yarn twenty catalog-sync --remote production
|
||||
```
|
||||
|
||||
要指定特定的远程:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty catalog-sync -r production
|
||||
```
|
||||
|
||||
市场中显示的元数据来自你在应用源代码中调用的 `defineApplication()` —— 诸如 `displayName`、`description`、`author`、`category`、`logoUrl`、`screenshots`、`aboutDescription`、`websiteUrl` 和 `termsUrl` 等字段。
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
|
||||
<Note>
|
||||
如果您的应用未在 `defineApplication()` 中定义 `aboutDescription`,市场将自动使用 npm 上您的软件包的 `README.md` 作为关于页面内容。 这意味着您可以为 npm 和 Twenty 市场维护同一个 README。 如果您希望在市场中使用不同的描述,请显式设置 `aboutDescription`。
|
||||
@@ -108,7 +143,7 @@ yarn twenty catalog-sync -r production
|
||||
|
||||
### CI 发布
|
||||
|
||||
脚手架项目包含一个 GitHub Actions 工作流,会在每次发版时自动发布:
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -133,121 +168,24 @@ jobs:
|
||||
- run: npx twenty build
|
||||
- run: npm publish --provenance --access public
|
||||
working-directory: .twenty/output
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
对于其他 CI 系统(GitLab CI、CircleCI 等),同样适用以下三条命令:`yarn install`、`yarn twenty build`,然后在 `.twenty/output` 目录下执行 `npm publish`。
|
||||
|
||||
<Tip>
|
||||
<Note>
|
||||
**npm provenance** 可选,但建议启用。 使用 `--provenance` 发布会在你的 npm 列表中添加可信徽章,使用户可以验证该包是由公共 CI 流水线中的特定提交构建的。 有关设置说明,请参见 [npm provenance 文档](https://docs.npmjs.com/generating-provenance-statements)。
|
||||
</Tip>
|
||||
|
||||
## 部署到服务器(tar 包)
|
||||
|
||||
对于你不希望公开的应用(专有工具、仅供企业使用的集成或实验性构建),你可以将 tar 包直接部署到某台 Twenty 服务器。
|
||||
|
||||
### 先决条件
|
||||
|
||||
在部署之前,你需要配置一个指向目标服务器的远程。 远程会将服务器 URL 和身份验证凭据本地存储在 `~/.twenty/config.json` 中。
|
||||
|
||||
添加远程:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
对于本地开发服务器:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --local --as local
|
||||
```
|
||||
|
||||
对于非交互式环境,你也可以使用 API 密钥进行身份验证:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --url https://your-twenty-server.com --token <api-key> --as production
|
||||
```
|
||||
|
||||
管理你的远程:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote list # List all configured remotes
|
||||
yarn twenty remote switch prod # Set the default remote
|
||||
yarn twenty remote status # Show active remote and auth status
|
||||
yarn twenty remote remove old # Remove a remote
|
||||
```
|
||||
|
||||
### 部署
|
||||
|
||||
一步构建并将你的应用上传到服务器:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
```
|
||||
|
||||
这会使用 `--tarball` 构建应用,然后通过 GraphQL 多部分上传将该 tar 包上传到默认远程。
|
||||
|
||||
部署到特定远程:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy -r production
|
||||
```
|
||||
|
||||
### 共享已部署的应用
|
||||
|
||||
通过 tar 包分发的应用不会出现在公共市场中,因此同一服务器上的其他工作区无法通过浏览发现它们。 要共享已部署的应用:
|
||||
|
||||
1. 前往 **Settings > Applications > Registrations** 并打开你的应用
|
||||
2. 在 **Distribution** 选项卡中,点击 **Copy share link**
|
||||
3. 将此链接分享给其他工作区的用户 — 它会将他们直接带到该应用的安装页面
|
||||
|
||||
该分享链接使用服务器的基础 URL(不包含任何工作区子域),因此适用于该服务器上的任意工作区。
|
||||
|
||||
### 版本管理
|
||||
|
||||
要发布更新:
|
||||
|
||||
1. 更新 `package.json` 中的 `version` 字段
|
||||
2. 运行 `yarn twenty deploy`(或 `yarn twenty deploy -r production`)
|
||||
3. 已安装该应用的工作区会在其设置中看到可用的升级
|
||||
</Note>
|
||||
|
||||
## 安装应用
|
||||
|
||||
一旦应用已发布(npm)或已部署(tar 包),各工作区即可通过 UI 进行安装:
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
或者在 Twenty UI 的 **Settings > Applications** 页面中浏览并安装来自市场或通过 tar 包部署的应用。
|
||||
|
||||
## 应用分发类别
|
||||
|
||||
Twenty 会根据分发方式将应用归为三类:
|
||||
|
||||
| 类别 | 工作原理 | 在应用市场中可见? |
|
||||
| ------------- | -------------------------------------------------- | --------- |
|
||||
| **开发** | 通过 `yarn twenty dev` 运行的本地开发模式应用。 用于构建和测试。 | 否 |
|
||||
| **已发布(npm)** | 发布到 npm 且包含 `twenty-app` 关键字的应用。 在应用市场上架,供任何工作区安装。 | 是 |
|
||||
| **内部(tar 包)** | 通过 tar 包部署到特定服务器的应用。 仅通过分享链接对该服务器上的工作区可用。 | 否 |
|
||||
|
||||
<Tip>
|
||||
在构建你的应用时,从**开发**模式开始。 准备就绪后,选择用于广泛分发的**已发布**(npm),或用于私有部署的**内部**(tar 包)。
|
||||
</Tip>
|
||||
|
||||
## CLI 参考
|
||||
|
||||
| 命令 | 描述 | 关键选项 |
|
||||
| --------------------------- | ---------------- | ------------------------------------------- |
|
||||
| `yarn twenty build` | 编译应用并生成清单 | `--tarball` — 同时创建一个 `.tgz` 包 |
|
||||
| `yarn twenty publish` | 构建并发布到 npm | `--tag <tag>` — npm 分发标签(例如 `beta`、`next`) |
|
||||
| `yarn twenty deploy` | 构建并将 tar 包上传到服务器 | `-r, --remote <name>` — 目标远程 |
|
||||
| `yarn twenty catalog-sync` | 在服务器上触发市场目录同步 | `-r, --remote <name>` — 目标远程 |
|
||||
| `yarn twenty install` | 在某个工作区安装已部署的应用 | `-r, --remote <name>` — 目标远程 |
|
||||
| `yarn twenty dev` | 监听并同步本地更改 | 使用默认远程 |
|
||||
| `yarn twenty remote add` | 添加服务器连接 | `--url`,`--token`,`--as`,`--local`,`--port` |
|
||||
| `yarn twenty remote list` | 列出已配置的远程 | — |
|
||||
| `yarn twenty remote switch` | 设置默认远程 | — |
|
||||
| `yarn twenty remote status` | 显示连接状态 | — |
|
||||
| `yarn twenty remote remove` | 移除远程 | — |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user