@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.
Files changed (108) hide show
  1. package/.github/workflows/cd.yml +42 -0
  2. package/.github/workflows/ci.yml +60 -0
  3. package/.github/workflows/publish.yml +52 -0
  4. package/.nvmrc +1 -0
  5. package/.oxlintrc.json +37 -0
  6. package/.yarnrc.yml +1 -0
  7. package/AGENTS.md +85 -0
  8. package/CHANGELOG.md +7 -0
  9. package/CLAUDE.md +85 -0
  10. package/SETUP.md +47 -0
  11. package/docs/superpowers/plans/2026-10-13-zalo-oa-phase-1-stages-1-2.md +275 -0
  12. package/docs/superpowers/plans/2026-10-13-zalo-oa-phase-2.md +311 -0
  13. package/docs/superpowers/specs/2026-10-13-zalo-oa-phase-1-stage-1-2-design.md +225 -0
  14. package/docs/superpowers/specs/2026-10-13-zalo-oa-phase-2-design.md +203 -0
  15. package/docs/zalo-oa/break-tasks-v0.md +150 -0
  16. package/docs/zalo-oa/design/anh-zalooa-credential.png +0 -0
  17. package/docs/zalo-oa/design/config-node.png +0 -0
  18. package/docs/zalo-oa/design/content-and-variable.png +0 -0
  19. package/docs/zalo-oa/design/detail-zbs-message-template.png +0 -0
  20. package/docs/zalo-oa/design/dropdown-choose-template.png +0 -0
  21. package/docs/zalo-oa/design/list-oa-account-empty-state.png +0 -0
  22. package/docs/zalo-oa/design/list-oa-account.png +0 -0
  23. package/docs/zalo-oa/design/more-options.png +0 -0
  24. package/docs/zalo-oa/design/new-note-send-zalooa.png +0 -0
  25. package/docs/zalo-oa/design/zbs-message-template-filter.png +0 -0
  26. package/docs/zalo-oa/design/zbs-message-template.png +0 -0
  27. package/docs/zalo-oa/public-domain.md +186 -0
  28. package/docs/zalo-oa/requirements/sync-person.md +49 -0
  29. package/docs/zalo-oa/spec-v0.md +532 -0
  30. package/locales/en.json +1 -0
  31. package/package.json +2 -2
  32. package/src/__tests__/application-config.test.ts +14 -0
  33. package/src/__tests__/global-setup.ts +56 -0
  34. package/src/__tests__/run-twenty.ts +66 -0
  35. package/src/__tests__/schema.integration-test.ts +46 -0
  36. package/src/application-config.ts +20 -0
  37. package/src/command-menu-items/zalo-sync.command-menu-item.ts +14 -0
  38. package/src/constants/universal-identifiers.ts +46 -0
  39. package/src/default-role.ts +23 -0
  40. package/src/front-components/__tests__/zalo-sync-sidebar.spec.tsx +51 -0
  41. package/src/front-components/chat/__tests__/zalo-chat-stream.spec.tsx +89 -0
  42. package/src/front-components/chat/zalo-chat-stream-view.tsx +359 -0
  43. package/src/front-components/settings/__tests__/zalo-settings.spec.tsx +75 -0
  44. package/src/front-components/settings/zalo-settings-view.tsx +633 -0
  45. package/src/logic-functions/__tests__/token-refresh-and-sender.spec.ts +64 -0
  46. package/src/logic-functions/__tests__/zalo-customer-sync.logic-function.spec.ts +69 -0
  47. package/src/logic-functions/__tests__/zalo-message-sync.logic-function.spec.ts +114 -0
  48. package/src/logic-functions/__tests__/zalo-oauth-exchange.logic-function.spec.ts +50 -0
  49. package/src/logic-functions/__tests__/zalo-template-sync.logic-function.spec.ts +81 -0
  50. package/src/objects/__tests__/app-and-connection-objects.spec.ts +37 -0
  51. package/src/objects/__tests__/remaining-objects.spec.ts +38 -0
  52. package/src/objects/zalo-app.object.ts +95 -0
  53. package/src/objects/zalo-message.object.ts +109 -0
  54. package/src/objects/zalo-oa-connection.object.ts +158 -0
  55. package/src/objects/zalo-user-identity.object.ts +107 -0
  56. package/src/objects/zalo-zbs-template.object.ts +113 -0
  57. package/src/page-layout-tabs/person-zalo-chat.page-layout-tab.ts +35 -0
  58. package/src/settings-menu-items/zalo-settings.settings-menu-item.ts +15 -0
  59. package/src/types/zalo-conversation-response.type.ts +22 -0
  60. package/src/types/zalo-message-send-response.type.ts +8 -0
  61. package/src/types/zalo-oa-profile-response.type.ts +10 -0
  62. package/src/types/zalo-parsed-shared-info.type.ts +5 -0
  63. package/src/types/zalo-template-response.type.ts +48 -0
  64. package/src/types/zalo-token-response.type.ts +8 -0
  65. package/src/types/zalo-user-detail-response.type.ts +21 -0
  66. package/src/types/zalo-user-list-response.type.ts +10 -0
  67. package/src/utils/__tests__/execute-workspace-graphql.util.spec.ts +48 -0
  68. package/src/utils/__tests__/format-phone-for-zalo.util.spec.ts +22 -0
  69. package/src/utils/__tests__/parse-zalo-shared-info-text.util.spec.ts +42 -0
  70. package/src/utils/__tests__/verify-zalo-webhook-signature.util.spec.ts +71 -0
  71. package/src/utils/calculate-zalo-webhook-signature.util.ts +13 -0
  72. package/src/utils/execute-workspace-graphql.util.ts +101 -0
  73. package/src/utils/format-phone-for-zalo.util.ts +18 -0
  74. package/src/utils/parse-zalo-shared-info-text.util.ts +23 -0
  75. package/src/utils/verify-zalo-webhook-signature.util.ts +81 -0
  76. package/src/zalo-client/exchange-zalo-code.client.ts +30 -0
  77. package/src/zalo-client/fetch-zalo-conversation.client.ts +31 -0
  78. package/src/zalo-client/fetch-zalo-oa-info.client.ts +18 -0
  79. package/src/zalo-client/fetch-zalo-templates.client.ts +160 -0
  80. package/src/zalo-client/fetch-zalo-user-detail.client.ts +24 -0
  81. package/src/zalo-client/fetch-zalo-user-list.client.ts +34 -0
  82. package/src/zalo-client/refresh-zalo-token.client.ts +28 -0
  83. package/src/zalo-client/send-zalo-message.client.ts +45 -0
  84. package/tsconfig.json +37 -0
  85. package/tsconfig.spec.json +9 -0
  86. package/vitest.config.ts +31 -0
  87. package/vitest.unit.config.ts +14 -0
  88. package/manifest.json +0 -690
  89. package/src/front-components/zalo-chat-stream.front-component.mjs +0 -160
  90. package/src/front-components/zalo-chat-stream.front-component.mjs.map +0 -7
  91. package/src/front-components/zalo-settings.front-component.mjs +0 -202
  92. package/src/front-components/zalo-settings.front-component.mjs.map +0 -7
  93. package/src/front-components/zalo-sync-sidebar.front-component.mjs +0 -146
  94. package/src/front-components/zalo-sync-sidebar.front-component.mjs.map +0 -7
  95. package/src/logic-functions/health-check.mjs +0 -38
  96. package/src/logic-functions/health-check.mjs.map +0 -7
  97. package/src/logic-functions/zalo-customer-sync.logic-function.mjs +0 -338
  98. package/src/logic-functions/zalo-customer-sync.logic-function.mjs.map +0 -7
  99. package/src/logic-functions/zalo-message-sender.logic-function.mjs +0 -115
  100. package/src/logic-functions/zalo-message-sender.logic-function.mjs.map +0 -7
  101. package/src/logic-functions/zalo-message-sync.logic-function.mjs +0 -261
  102. package/src/logic-functions/zalo-message-sync.logic-function.mjs.map +0 -7
  103. package/src/logic-functions/zalo-oauth-exchange.logic-function.mjs +0 -116
  104. package/src/logic-functions/zalo-oauth-exchange.logic-function.mjs.map +0 -7
  105. package/src/logic-functions/zalo-template-sync.logic-function.mjs +0 -311
  106. package/src/logic-functions/zalo-template-sync.logic-function.mjs.map +0 -7
  107. package/src/logic-functions/zalo-token-refresh.logic-function.mjs +0 -236
  108. 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
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ All notable changes to this application are documented in this file.
4
+
5
+ ## 0.1.0
6
+
7
+ - Initial application scaffolded with `twenty app init`
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).