@khoahaha7903/zalo-oa 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/cd.yml +42 -0
- package/.github/workflows/ci.yml +60 -0
- package/.github/workflows/publish.yml +52 -0
- package/.nvmrc +1 -0
- package/.oxlintrc.json +37 -0
- package/.yarnrc.yml +1 -0
- package/AGENTS.md +85 -0
- package/CHANGELOG.md +7 -0
- package/CLAUDE.md +85 -0
- package/SETUP.md +47 -0
- package/docs/superpowers/plans/2026-10-13-zalo-oa-phase-1-stages-1-2.md +275 -0
- package/docs/superpowers/plans/2026-10-13-zalo-oa-phase-2.md +311 -0
- package/docs/superpowers/specs/2026-10-13-zalo-oa-phase-1-stage-1-2-design.md +225 -0
- package/docs/superpowers/specs/2026-10-13-zalo-oa-phase-2-design.md +203 -0
- package/docs/zalo-oa/break-tasks-v0.md +150 -0
- package/docs/zalo-oa/design/anh-zalooa-credential.png +0 -0
- package/docs/zalo-oa/design/config-node.png +0 -0
- package/docs/zalo-oa/design/content-and-variable.png +0 -0
- package/docs/zalo-oa/design/detail-zbs-message-template.png +0 -0
- package/docs/zalo-oa/design/dropdown-choose-template.png +0 -0
- package/docs/zalo-oa/design/list-oa-account-empty-state.png +0 -0
- package/docs/zalo-oa/design/list-oa-account.png +0 -0
- package/docs/zalo-oa/design/more-options.png +0 -0
- package/docs/zalo-oa/design/new-note-send-zalooa.png +0 -0
- package/docs/zalo-oa/design/zbs-message-template-filter.png +0 -0
- package/docs/zalo-oa/design/zbs-message-template.png +0 -0
- package/docs/zalo-oa/public-domain.md +186 -0
- package/docs/zalo-oa/requirements/sync-person.md +49 -0
- package/docs/zalo-oa/spec-v0.md +532 -0
- package/locales/en.json +1 -0
- package/package.json +2 -2
- package/src/__tests__/application-config.test.ts +14 -0
- package/src/__tests__/global-setup.ts +56 -0
- package/src/__tests__/run-twenty.ts +66 -0
- package/src/__tests__/schema.integration-test.ts +46 -0
- package/src/application-config.ts +20 -0
- package/src/command-menu-items/zalo-sync.command-menu-item.ts +14 -0
- package/src/constants/universal-identifiers.ts +46 -0
- package/src/default-role.ts +23 -0
- package/src/front-components/__tests__/zalo-sync-sidebar.spec.tsx +51 -0
- package/src/front-components/chat/__tests__/zalo-chat-stream.spec.tsx +89 -0
- package/src/front-components/chat/zalo-chat-stream-view.tsx +359 -0
- package/src/front-components/settings/__tests__/zalo-settings.spec.tsx +75 -0
- package/src/front-components/settings/zalo-settings-view.tsx +633 -0
- package/src/logic-functions/__tests__/token-refresh-and-sender.spec.ts +64 -0
- package/src/logic-functions/__tests__/zalo-customer-sync.logic-function.spec.ts +69 -0
- package/src/logic-functions/__tests__/zalo-message-sync.logic-function.spec.ts +114 -0
- package/src/logic-functions/__tests__/zalo-oauth-exchange.logic-function.spec.ts +50 -0
- package/src/logic-functions/__tests__/zalo-template-sync.logic-function.spec.ts +81 -0
- package/src/objects/__tests__/app-and-connection-objects.spec.ts +37 -0
- package/src/objects/__tests__/remaining-objects.spec.ts +38 -0
- package/src/objects/zalo-app.object.ts +95 -0
- package/src/objects/zalo-message.object.ts +109 -0
- package/src/objects/zalo-oa-connection.object.ts +158 -0
- package/src/objects/zalo-user-identity.object.ts +107 -0
- package/src/objects/zalo-zbs-template.object.ts +113 -0
- package/src/page-layout-tabs/person-zalo-chat.page-layout-tab.ts +35 -0
- package/src/settings-menu-items/zalo-settings.settings-menu-item.ts +15 -0
- package/src/types/zalo-conversation-response.type.ts +22 -0
- package/src/types/zalo-message-send-response.type.ts +8 -0
- package/src/types/zalo-oa-profile-response.type.ts +10 -0
- package/src/types/zalo-parsed-shared-info.type.ts +5 -0
- package/src/types/zalo-template-response.type.ts +48 -0
- package/src/types/zalo-token-response.type.ts +8 -0
- package/src/types/zalo-user-detail-response.type.ts +21 -0
- package/src/types/zalo-user-list-response.type.ts +10 -0
- package/src/utils/__tests__/execute-workspace-graphql.util.spec.ts +48 -0
- package/src/utils/__tests__/format-phone-for-zalo.util.spec.ts +22 -0
- package/src/utils/__tests__/parse-zalo-shared-info-text.util.spec.ts +42 -0
- package/src/utils/__tests__/verify-zalo-webhook-signature.util.spec.ts +71 -0
- package/src/utils/calculate-zalo-webhook-signature.util.ts +13 -0
- package/src/utils/execute-workspace-graphql.util.ts +101 -0
- package/src/utils/format-phone-for-zalo.util.ts +18 -0
- package/src/utils/parse-zalo-shared-info-text.util.ts +23 -0
- package/src/utils/verify-zalo-webhook-signature.util.ts +81 -0
- package/src/zalo-client/exchange-zalo-code.client.ts +30 -0
- package/src/zalo-client/fetch-zalo-conversation.client.ts +31 -0
- package/src/zalo-client/fetch-zalo-oa-info.client.ts +18 -0
- package/src/zalo-client/fetch-zalo-templates.client.ts +160 -0
- package/src/zalo-client/fetch-zalo-user-detail.client.ts +24 -0
- package/src/zalo-client/fetch-zalo-user-list.client.ts +34 -0
- package/src/zalo-client/refresh-zalo-token.client.ts +28 -0
- package/src/zalo-client/send-zalo-message.client.ts +45 -0
- package/tsconfig.json +37 -0
- package/tsconfig.spec.json +9 -0
- package/vitest.config.ts +31 -0
- package/vitest.unit.config.ts +14 -0
- package/manifest.json +0 -690
- package/src/front-components/zalo-chat-stream.front-component.mjs +0 -160
- package/src/front-components/zalo-chat-stream.front-component.mjs.map +0 -7
- package/src/front-components/zalo-settings.front-component.mjs +0 -202
- package/src/front-components/zalo-settings.front-component.mjs.map +0 -7
- package/src/front-components/zalo-sync-sidebar.front-component.mjs +0 -146
- package/src/front-components/zalo-sync-sidebar.front-component.mjs.map +0 -7
- package/src/logic-functions/health-check.mjs +0 -38
- package/src/logic-functions/health-check.mjs.map +0 -7
- package/src/logic-functions/zalo-customer-sync.logic-function.mjs +0 -338
- package/src/logic-functions/zalo-customer-sync.logic-function.mjs.map +0 -7
- package/src/logic-functions/zalo-message-sender.logic-function.mjs +0 -115
- package/src/logic-functions/zalo-message-sender.logic-function.mjs.map +0 -7
- package/src/logic-functions/zalo-message-sync.logic-function.mjs +0 -261
- package/src/logic-functions/zalo-message-sync.logic-function.mjs.map +0 -7
- package/src/logic-functions/zalo-oauth-exchange.logic-function.mjs +0 -116
- package/src/logic-functions/zalo-oauth-exchange.logic-function.mjs.map +0 -7
- package/src/logic-functions/zalo-template-sync.logic-function.mjs +0 -311
- package/src/logic-functions/zalo-template-sync.logic-function.mjs.map +0 -7
- package/src/logic-functions/zalo-token-refresh.logic-function.mjs +0 -236
- package/src/logic-functions/zalo-token-refresh.logic-function.mjs.map +0 -7
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: CD
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
types: [labeled]
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
env:
|
|
14
|
+
TWENTY_DEPLOY_URL: http://localhost:2020
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: cd-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
deploy-and-install:
|
|
22
|
+
if: >-
|
|
23
|
+
github.event_name == 'push' ||
|
|
24
|
+
(github.event_name == 'pull_request' && github.event.label.name == 'deploy')
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
31
|
+
|
|
32
|
+
- name: Deploy
|
|
33
|
+
uses: twentyhq/twenty/.github/actions/deploy-twenty-app@main
|
|
34
|
+
with:
|
|
35
|
+
api-url: ${{ env.TWENTY_DEPLOY_URL }}
|
|
36
|
+
api-key: ${{ secrets.TWENTY_DEPLOY_API_KEY }}
|
|
37
|
+
|
|
38
|
+
- name: Install
|
|
39
|
+
uses: twentyhq/twenty/.github/actions/install-twenty-app@main
|
|
40
|
+
with:
|
|
41
|
+
api-url: ${{ env.TWENTY_DEPLOY_URL }}
|
|
42
|
+
api-key: ${{ secrets.TWENTY_DEPLOY_API_KEY }}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request: {}
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
env:
|
|
13
|
+
TWENTY_VERSION: latest
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: ci-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Spawn Twenty test instance
|
|
27
|
+
id: twenty
|
|
28
|
+
uses: twentyhq/twenty/.github/actions/spawn-twenty-app-dev-test@main
|
|
29
|
+
with:
|
|
30
|
+
twenty-version: ${{ env.TWENTY_VERSION }}
|
|
31
|
+
|
|
32
|
+
- name: Enable Corepack
|
|
33
|
+
run: corepack enable
|
|
34
|
+
|
|
35
|
+
- name: Setup Node.js
|
|
36
|
+
uses: actions/setup-node@v4
|
|
37
|
+
with:
|
|
38
|
+
node-version-file: '.nvmrc'
|
|
39
|
+
cache: yarn
|
|
40
|
+
|
|
41
|
+
- name: Install Twenty CLI
|
|
42
|
+
run: npm install -g twenty@2.51.3
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies
|
|
45
|
+
run: yarn install --immutable
|
|
46
|
+
|
|
47
|
+
- name: Lint
|
|
48
|
+
run: yarn lint
|
|
49
|
+
|
|
50
|
+
- name: Typecheck
|
|
51
|
+
run: yarn typecheck
|
|
52
|
+
|
|
53
|
+
- name: Unit tests
|
|
54
|
+
run: yarn test:unit
|
|
55
|
+
|
|
56
|
+
- name: Run integration tests
|
|
57
|
+
run: yarn test
|
|
58
|
+
env:
|
|
59
|
+
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
|
60
|
+
TWENTY_API_KEY: ${{ steps.twenty.outputs.api-key }}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Publishes the app to npm with provenance (npm trusted publishing).
|
|
2
|
+
#
|
|
3
|
+
# One-time setup:
|
|
4
|
+
# 1. On npmjs.com open your package > Settings > Trusted Publisher and register
|
|
5
|
+
# this repository and this workflow file (publish.yml).
|
|
6
|
+
# See https://docs.npmjs.com/trusted-publishers
|
|
7
|
+
# 2. Push a version tag (e.g. `git tag v1.0.0 && git push --tags`) or run the
|
|
8
|
+
# workflow manually from the Actions tab.
|
|
9
|
+
#
|
|
10
|
+
# Publishing with provenance certifies which GitHub repository the package is
|
|
11
|
+
# built from. This is also how you claim ownership of your app in a Twenty
|
|
12
|
+
# marketplace: the claim flow verifies you own the GitHub account or
|
|
13
|
+
# organization the provenance points to.
|
|
14
|
+
name: Publish
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
push:
|
|
18
|
+
tags:
|
|
19
|
+
- 'v*'
|
|
20
|
+
workflow_dispatch:
|
|
21
|
+
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
# Required for npm trusted publishing (OIDC provenance).
|
|
25
|
+
id-token: write
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
publish:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- name: Checkout
|
|
32
|
+
uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Setup Node.js
|
|
35
|
+
uses: actions/setup-node@v4
|
|
36
|
+
with:
|
|
37
|
+
node-version: 24
|
|
38
|
+
registry-url: https://registry.npmjs.org
|
|
39
|
+
|
|
40
|
+
- name: Update npm
|
|
41
|
+
# Trusted publishing requires npm 11.5.1 or later.
|
|
42
|
+
run: npm install -g npm@latest
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies
|
|
45
|
+
run: yarn install --immutable
|
|
46
|
+
|
|
47
|
+
- name: Publish to npm
|
|
48
|
+
# Uncomment if publishing from a private source repo: npm rejects
|
|
49
|
+
# OIDC provenance for private repos
|
|
50
|
+
# env:
|
|
51
|
+
# TWENTY_APP_PUBLISH_DISABLE_PROVENANCE: 'true'
|
|
52
|
+
run: yarn twenty app:publish
|
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
24.5.0
|
package/.oxlintrc.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
|
3
|
+
"plugins": ["typescript"],
|
|
4
|
+
"categories": {
|
|
5
|
+
"correctness": "off"
|
|
6
|
+
},
|
|
7
|
+
"ignorePatterns": ["node_modules", "dist"],
|
|
8
|
+
"rules": {
|
|
9
|
+
"no-unused-vars": "off",
|
|
10
|
+
|
|
11
|
+
"typescript/no-unused-vars": [
|
|
12
|
+
"warn",
|
|
13
|
+
{
|
|
14
|
+
"argsIgnorePattern": "^_"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"typescript/no-explicit-any": "off"
|
|
18
|
+
},
|
|
19
|
+
"overrides": [
|
|
20
|
+
{
|
|
21
|
+
"files": ["**/*.logic-function.ts", "**/logic-functions/**/*.ts"],
|
|
22
|
+
"rules": {
|
|
23
|
+
"no-restricted-imports": [
|
|
24
|
+
"error",
|
|
25
|
+
{
|
|
26
|
+
"patterns": [
|
|
27
|
+
{
|
|
28
|
+
"group": ["twenty-shared", "twenty-shared/*"],
|
|
29
|
+
"message": "Logic functions must not import from twenty-shared directly. Import runtime types and helpers from `twenty-sdk/logic-function` instead so the logic-function bundle stays minimal."
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
package/.yarnrc.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nodeLinker: node-modules
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
## Base documentation
|
|
2
|
+
|
|
3
|
+
- Getting started:
|
|
4
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/quick-start.md
|
|
5
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/concepts.md
|
|
6
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/project-structure.md
|
|
7
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/local-server.md
|
|
8
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/scaffolding.md
|
|
9
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/troubleshooting.md
|
|
10
|
+
- Config:
|
|
11
|
+
- https://docs.twenty.com/developers/extend/apps/config/overview.md
|
|
12
|
+
- https://docs.twenty.com/developers/extend/apps/config/application.md
|
|
13
|
+
- https://docs.twenty.com/developers/extend/apps/config/roles.md
|
|
14
|
+
- https://docs.twenty.com/developers/extend/apps/config/install-hooks.md
|
|
15
|
+
- https://docs.twenty.com/developers/extend/apps/config/public-assets.md
|
|
16
|
+
- Data:
|
|
17
|
+
- https://docs.twenty.com/developers/extend/apps/data/overview.md
|
|
18
|
+
- https://docs.twenty.com/developers/extend/apps/data/objects.md
|
|
19
|
+
- https://docs.twenty.com/developers/extend/apps/data/extending-objects.md
|
|
20
|
+
- https://docs.twenty.com/developers/extend/apps/data/relations.md
|
|
21
|
+
- Logic:
|
|
22
|
+
- https://docs.twenty.com/developers/extend/apps/logic/overview.md
|
|
23
|
+
- https://docs.twenty.com/developers/extend/apps/logic/logic-functions.md
|
|
24
|
+
- https://docs.twenty.com/developers/extend/apps/logic/skills-and-agents.md
|
|
25
|
+
- https://docs.twenty.com/developers/extend/apps/logic/connections.md
|
|
26
|
+
- Layout:
|
|
27
|
+
- https://docs.twenty.com/developers/extend/apps/layout/overview.md
|
|
28
|
+
- https://docs.twenty.com/developers/extend/apps/layout/views.md
|
|
29
|
+
- https://docs.twenty.com/developers/extend/apps/layout/navigation-menu-items.md
|
|
30
|
+
- https://docs.twenty.com/developers/extend/apps/layout/page-layouts.md
|
|
31
|
+
- https://docs.twenty.com/developers/extend/apps/layout/front-components.md
|
|
32
|
+
- https://docs.twenty.com/developers/extend/apps/layout/command-menu-items.md
|
|
33
|
+
- Operations:
|
|
34
|
+
- https://docs.twenty.com/developers/extend/apps/operations/overview.md
|
|
35
|
+
- https://docs.twenty.com/developers/extend/apps/operations/cli.md
|
|
36
|
+
- https://docs.twenty.com/developers/extend/apps/operations/testing.md
|
|
37
|
+
- https://docs.twenty.com/developers/extend/apps/operations/publishing.md
|
|
38
|
+
- Rich app example: https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples/postcard
|
|
39
|
+
|
|
40
|
+
## Front components
|
|
41
|
+
|
|
42
|
+
For front component work, follow the official `develop-app` skill when installed. Install the official skills with `npx skills add https://github.com/twentyhq/twenty/tree/agent-skills --skill '*'`. Apply these essentials even when no skills are installed:
|
|
43
|
+
|
|
44
|
+
- For every visible front component, use `twenty-ui` components by default. Reuse an equivalent Twenty UI control before writing a custom control or adding another UI library. Plain HTML is appropriate for layout containers and content without a Twenty UI equivalent.
|
|
45
|
+
- Import from public family subpaths: `twenty-ui/components/input` for `MainButton` and `LightButton`, `twenty-ui/primitives/input` for foundational controls, `twenty-ui/primitives/typography` for text, and the matching family for other components. Import individual icons from `twenty-ui/icon`, never `IconsProvider` or `useIcons`. Keep `twenty-ui`, `twenty-sdk` and `twenty-client-sdk` pinned to the same version in `devDependencies`.
|
|
46
|
+
- The renderer supplies styles and the workspace theme. Use `useTheme()` from `twenty-ui/theme` inside the component for spacing, colors, typography and radii. Do not add a root `ThemeProvider`, force a color scheme, or copy standalone stylesheet setup into a front component. Never dereference theme tokens at module top level, since entity files also run during manifest extraction.
|
|
47
|
+
- Use component props before custom styles. Keep layouts compact and responsive to widget width, give inputs visible labels and icon-only actions accessible names, and handle loading, empty, error, disabled and saving states. Verify light and dark themes, narrow widths and long values.
|
|
48
|
+
- Use `openCommandConfirmationModal` or `CommandModal` from `twenty-sdk/front-component` for confirmation dialogs and `enqueueSnackbar` for notifications. Do not render `Dialog`, `AlertDialog`, native `dialog` elements or native browser popovers directly. Use Twenty UI `Dropdown` for menus and pickers.
|
|
49
|
+
- Components run in a Web Worker with a sandboxed, partial `window` and `document`. Prefer CSS for layout and width-based queries. `canvas` and `scrollIntoView` are unsupported; consult the current runtime limitations before using other browser APIs.
|
|
50
|
+
- Keep the `.tsx` entity's direct `export default defineFrontComponent({ ... })` call. The SDK mounts the component, so do not call `react-dom/client` or use browser globals at module top level.
|
|
51
|
+
- Read workspace data with `CoreApiClient` from `twenty-client-sdk/core` and selection with `useSelectedRecordIds()` from `twenty-sdk/front-component`. Call third-party APIs from logic functions; secret application variables never reach a front component.
|
|
52
|
+
|
|
53
|
+
Read the [front component guide](https://docs.twenty.com/developers/extend/apps/layout/front-components.md) before implementation for the renderer setup and runtime limitations. Use [Twenty UI getting started](https://docs.twenty.com/ui/getting-started.md), [components](https://docs.twenty.com/ui/components/overview.md), [primitives](https://docs.twenty.com/ui/primitives/overview.md) and [theming](https://docs.twenty.com/ui/theming.md) to find the relevant component page and check its current props and composition.
|
|
54
|
+
|
|
55
|
+
## UUID requirement
|
|
56
|
+
|
|
57
|
+
- All generated UUIDs must be valid UUID v4.
|
|
58
|
+
|
|
59
|
+
## Common Pitfalls
|
|
60
|
+
|
|
61
|
+
- Creating a view without a navigationMenuItem associated. This will make the view available on the left sidebar.
|
|
62
|
+
- Creating a front component that overflows its widget. Fit the available width and let content determine height, unless the component is the tab's single `heightBehavior: 'TAB_VIEWPORT'` widget and owns internal scrolling.
|
|
63
|
+
|
|
64
|
+
## Best practice
|
|
65
|
+
|
|
66
|
+
It's highly recommended to create new app entities using `yarn twenty dev:add`. These are the options:
|
|
67
|
+
|
|
68
|
+
| Entity type | Command | Generated file |
|
|
69
|
+
| -------------------- | ---------------------------------------- | ------------------------------------- |
|
|
70
|
+
| Object | `yarn twenty dev:add object` | `src/objects/<name>.ts` |
|
|
71
|
+
| Field | `yarn twenty dev:add field` | `src/fields/<name>.ts` |
|
|
72
|
+
| Logic function | `yarn twenty dev:add logicFunction` | `src/logic-functions/<name>.ts` |
|
|
73
|
+
| Front component | `yarn twenty dev:add frontComponent` | `src/front-components/<name>.tsx` |
|
|
74
|
+
| Role | `yarn twenty dev:add role` | `src/roles/<name>.ts` |
|
|
75
|
+
| Skill | `yarn twenty dev:add skill` | `src/skills/<name>.ts` |
|
|
76
|
+
| Agent | `yarn twenty dev:add agent` | `src/agents/<name>.ts` |
|
|
77
|
+
| View | `yarn twenty dev:add view` | `src/views/<name>.ts` |
|
|
78
|
+
| Navigation menu item | `yarn twenty dev:add navigationMenuItem` | `src/navigation-menu-items/<name>.ts` |
|
|
79
|
+
| Page layout | `yarn twenty dev:add pageLayout` | `src/page-layouts/<name>.ts` |
|
|
80
|
+
| Page layout tab | `yarn twenty dev:add pageLayoutTab` | `src/page-layout-tabs/<name>.ts` |
|
|
81
|
+
| Command menu item | `yarn twenty dev:add commandMenuItem` | `src/command-menu-items/<name>.ts` |
|
|
82
|
+
| View field | `yarn twenty dev:add viewField` | `src/view-fields/<name>.ts` |
|
|
83
|
+
| Connection provider | `yarn twenty dev:add connectionProvider` | `src/connection-providers/<name>.ts` |
|
|
84
|
+
|
|
85
|
+
This helps automatically generate required IDs etc.
|
package/CHANGELOG.md
ADDED
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
## Base documentation
|
|
2
|
+
|
|
3
|
+
- Getting started:
|
|
4
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/quick-start.md
|
|
5
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/concepts.md
|
|
6
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/project-structure.md
|
|
7
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/local-server.md
|
|
8
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/scaffolding.md
|
|
9
|
+
- https://docs.twenty.com/developers/extend/apps/getting-started/troubleshooting.md
|
|
10
|
+
- Config:
|
|
11
|
+
- https://docs.twenty.com/developers/extend/apps/config/overview.md
|
|
12
|
+
- https://docs.twenty.com/developers/extend/apps/config/application.md
|
|
13
|
+
- https://docs.twenty.com/developers/extend/apps/config/roles.md
|
|
14
|
+
- https://docs.twenty.com/developers/extend/apps/config/install-hooks.md
|
|
15
|
+
- https://docs.twenty.com/developers/extend/apps/config/public-assets.md
|
|
16
|
+
- Data:
|
|
17
|
+
- https://docs.twenty.com/developers/extend/apps/data/overview.md
|
|
18
|
+
- https://docs.twenty.com/developers/extend/apps/data/objects.md
|
|
19
|
+
- https://docs.twenty.com/developers/extend/apps/data/extending-objects.md
|
|
20
|
+
- https://docs.twenty.com/developers/extend/apps/data/relations.md
|
|
21
|
+
- Logic:
|
|
22
|
+
- https://docs.twenty.com/developers/extend/apps/logic/overview.md
|
|
23
|
+
- https://docs.twenty.com/developers/extend/apps/logic/logic-functions.md
|
|
24
|
+
- https://docs.twenty.com/developers/extend/apps/logic/skills-and-agents.md
|
|
25
|
+
- https://docs.twenty.com/developers/extend/apps/logic/connections.md
|
|
26
|
+
- Layout:
|
|
27
|
+
- https://docs.twenty.com/developers/extend/apps/layout/overview.md
|
|
28
|
+
- https://docs.twenty.com/developers/extend/apps/layout/views.md
|
|
29
|
+
- https://docs.twenty.com/developers/extend/apps/layout/navigation-menu-items.md
|
|
30
|
+
- https://docs.twenty.com/developers/extend/apps/layout/page-layouts.md
|
|
31
|
+
- https://docs.twenty.com/developers/extend/apps/layout/front-components.md
|
|
32
|
+
- https://docs.twenty.com/developers/extend/apps/layout/command-menu-items.md
|
|
33
|
+
- Operations:
|
|
34
|
+
- https://docs.twenty.com/developers/extend/apps/operations/overview.md
|
|
35
|
+
- https://docs.twenty.com/developers/extend/apps/operations/cli.md
|
|
36
|
+
- https://docs.twenty.com/developers/extend/apps/operations/testing.md
|
|
37
|
+
- https://docs.twenty.com/developers/extend/apps/operations/publishing.md
|
|
38
|
+
- Rich app example: https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples/postcard
|
|
39
|
+
|
|
40
|
+
## Front components
|
|
41
|
+
|
|
42
|
+
For front component work, follow the official `develop-app` skill when installed. Install the official skills with `npx skills add https://github.com/twentyhq/twenty/tree/agent-skills --skill '*'`. Apply these essentials even when no skills are installed:
|
|
43
|
+
|
|
44
|
+
- For every visible front component, use `twenty-ui` components by default. Reuse an equivalent Twenty UI control before writing a custom control or adding another UI library. Plain HTML is appropriate for layout containers and content without a Twenty UI equivalent.
|
|
45
|
+
- Import from public family subpaths: `twenty-ui/components/input` for `MainButton` and `LightButton`, `twenty-ui/primitives/input` for foundational controls, `twenty-ui/primitives/typography` for text, and the matching family for other components. Import individual icons from `twenty-ui/icon`, never `IconsProvider` or `useIcons`. Keep `twenty-ui`, `twenty-sdk` and `twenty-client-sdk` pinned to the same version in `devDependencies`.
|
|
46
|
+
- The renderer supplies styles and the workspace theme. Use `useTheme()` from `twenty-ui/theme` inside the component for spacing, colors, typography and radii. Do not add a root `ThemeProvider`, force a color scheme, or copy standalone stylesheet setup into a front component. Never dereference theme tokens at module top level, since entity files also run during manifest extraction.
|
|
47
|
+
- Use component props before custom styles. Keep layouts compact and responsive to widget width, give inputs visible labels and icon-only actions accessible names, and handle loading, empty, error, disabled and saving states. Verify light and dark themes, narrow widths and long values.
|
|
48
|
+
- Use `openCommandConfirmationModal` or `CommandModal` from `twenty-sdk/front-component` for confirmation dialogs and `enqueueSnackbar` for notifications. Do not render `Dialog`, `AlertDialog`, native `dialog` elements or native browser popovers directly. Use Twenty UI `Dropdown` for menus and pickers.
|
|
49
|
+
- Components run in a Web Worker with a sandboxed, partial `window` and `document`. Prefer CSS for layout and width-based queries. `canvas` and `scrollIntoView` are unsupported; consult the current runtime limitations before using other browser APIs.
|
|
50
|
+
- Keep the `.tsx` entity's direct `export default defineFrontComponent({ ... })` call. The SDK mounts the component, so do not call `react-dom/client` or use browser globals at module top level.
|
|
51
|
+
- Read workspace data with `CoreApiClient` from `twenty-client-sdk/core` and selection with `useSelectedRecordIds()` from `twenty-sdk/front-component`. Call third-party APIs from logic functions; secret application variables never reach a front component.
|
|
52
|
+
|
|
53
|
+
Read the [front component guide](https://docs.twenty.com/developers/extend/apps/layout/front-components.md) before implementation for the renderer setup and runtime limitations. Use [Twenty UI getting started](https://docs.twenty.com/ui/getting-started.md), [components](https://docs.twenty.com/ui/components/overview.md), [primitives](https://docs.twenty.com/ui/primitives/overview.md) and [theming](https://docs.twenty.com/ui/theming.md) to find the relevant component page and check its current props and composition.
|
|
54
|
+
|
|
55
|
+
## UUID requirement
|
|
56
|
+
|
|
57
|
+
- All generated UUIDs must be valid UUID v4.
|
|
58
|
+
|
|
59
|
+
## Common Pitfalls
|
|
60
|
+
|
|
61
|
+
- Creating a view without a navigationMenuItem associated. This will make the view available on the left sidebar.
|
|
62
|
+
- Creating a front component that overflows its widget. Fit the available width and let content determine height, unless the component is the tab's single `heightBehavior: 'TAB_VIEWPORT'` widget and owns internal scrolling.
|
|
63
|
+
|
|
64
|
+
## Best practice
|
|
65
|
+
|
|
66
|
+
It's highly recommended to create new app entities using `yarn twenty dev:add`. These are the options:
|
|
67
|
+
|
|
68
|
+
| Entity type | Command | Generated file |
|
|
69
|
+
| -------------------- | ---------------------------------------- | ------------------------------------- |
|
|
70
|
+
| Object | `yarn twenty dev:add object` | `src/objects/<name>.ts` |
|
|
71
|
+
| Field | `yarn twenty dev:add field` | `src/fields/<name>.ts` |
|
|
72
|
+
| Logic function | `yarn twenty dev:add logicFunction` | `src/logic-functions/<name>.ts` |
|
|
73
|
+
| Front component | `yarn twenty dev:add frontComponent` | `src/front-components/<name>.tsx` |
|
|
74
|
+
| Role | `yarn twenty dev:add role` | `src/roles/<name>.ts` |
|
|
75
|
+
| Skill | `yarn twenty dev:add skill` | `src/skills/<name>.ts` |
|
|
76
|
+
| Agent | `yarn twenty dev:add agent` | `src/agents/<name>.ts` |
|
|
77
|
+
| View | `yarn twenty dev:add view` | `src/views/<name>.ts` |
|
|
78
|
+
| Navigation menu item | `yarn twenty dev:add navigationMenuItem` | `src/navigation-menu-items/<name>.ts` |
|
|
79
|
+
| Page layout | `yarn twenty dev:add pageLayout` | `src/page-layouts/<name>.ts` |
|
|
80
|
+
| Page layout tab | `yarn twenty dev:add pageLayoutTab` | `src/page-layout-tabs/<name>.ts` |
|
|
81
|
+
| Command menu item | `yarn twenty dev:add commandMenuItem` | `src/command-menu-items/<name>.ts` |
|
|
82
|
+
| View field | `yarn twenty dev:add viewField` | `src/view-fields/<name>.ts` |
|
|
83
|
+
| Connection provider | `yarn twenty dev:add connectionProvider` | `src/connection-providers/<name>.ts` |
|
|
84
|
+
|
|
85
|
+
This helps automatically generate required IDs etc.
|
package/SETUP.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Setup
|
|
2
|
+
|
|
3
|
+
Follow these steps to get your app running locally.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js (version specified in `.nvmrc`)
|
|
8
|
+
- Yarn 4
|
|
9
|
+
- Docker (to run the local Twenty server)
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Install dependencies:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
yarn install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The committed `yarn.lock` pins exact, integrity-checked versions, so this
|
|
20
|
+
resolves nothing from the registry.
|
|
21
|
+
|
|
22
|
+
2. Start the local Twenty server:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
yarn twenty docker:start
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Check the server status at any time with `yarn twenty docker:status`.
|
|
29
|
+
|
|
30
|
+
3. Start the development server and sync your app:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
yarn twenty dev
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
4. Open [http://localhost:2020](http://localhost:2020) and log in with the default development credentials: `tim@apple.dev` / `tim@apple.dev`.
|
|
37
|
+
|
|
38
|
+
## Verifying your setup
|
|
39
|
+
|
|
40
|
+
- `yarn lint` - Lint the project with oxlint
|
|
41
|
+
- `yarn typecheck` - Type-check the project
|
|
42
|
+
- `yarn test:unit` - Run unit tests
|
|
43
|
+
- `yarn test` - Run integration tests
|
|
44
|
+
|
|
45
|
+
## Troubleshooting
|
|
46
|
+
|
|
47
|
+
See the [troubleshooting guide](https://docs.twenty.com/developers/extend/apps/getting-started/troubleshooting) or ask on [Discord](https://discord.gg/cx5n4Jzs57).
|