@salsita-ai/sdk 0.50.0-develop.c28cfb7ded → 0.50.0-develop.ca72986c39

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 (53) hide show
  1. package/README.md +13 -12
  2. package/dist/application-spec/generate-application/code/generate-application-code.d.ts +3 -2
  3. package/dist/application-spec/generate-application/code/generate-application-code.js +1 -1
  4. package/dist/application-spec/generate-application/code/project-scaffolding.d.ts +9 -4
  5. package/dist/application-spec/generate-application/code/project-scaffolding.js +2 -2
  6. package/dist/application-spec/generate-application/code/templates/frontend-config.js +3 -5
  7. package/dist/application-spec/generate-application/code/templates/gitignore.js +1 -2
  8. package/dist/application-spec/generate-application/code/templates/globals.js +3 -4
  9. package/dist/application-spec/generate-application/code/templates/index.d.ts +1 -0
  10. package/dist/application-spec/generate-application/code/templates/index.js +1 -1
  11. package/dist/application-spec/generate-application/code/templates/root-tsconfig.d.ts +6 -0
  12. package/dist/application-spec/generate-application/code/templates/root-tsconfig.js +2 -0
  13. package/dist/application-spec/generate-application/code/templates/skills/phoenix-cli-skill.js +1 -1
  14. package/dist/application-spec/generate-application/code/templates/skills/phoenix-review-skill.js +1 -1
  15. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +5 -4
  16. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +2 -2
  17. package/dist/application-spec/generate-application/code/templates/tsconfig.d.ts +5 -0
  18. package/dist/application-spec/generate-application/code/templates/tsconfig.js +1 -1
  19. package/dist/application-spec/generate-application/code/templates/webhooks-config.js +2 -3
  20. package/dist/application-spec/parse-application-files/categorize/categorize-files.d.ts +10 -0
  21. package/dist/application-spec/parse-application-files/categorize/categorize-files.js +1 -1
  22. package/dist/application-spec/parse-application-files/categorize/earlier-generated-tsconfig.d.ts +9 -0
  23. package/dist/application-spec/parse-application-files/categorize/earlier-generated-tsconfig.js +1 -0
  24. package/dist/client/phoenix-api.d.ts +367 -0
  25. package/dist/docs/index.json +1 -1
  26. package/dist/docs/phoenix/deployments.mdx +2 -6
  27. package/dist/docs/phoenix/getting-started.mdx +1 -0
  28. package/dist/docs/phoenix/localization.mdx +4 -4
  29. package/dist/docs/phoenix/migration-guide.mdx +19 -8
  30. package/dist/docs/phoenix/phoenix-cli.mdx +36 -6
  31. package/dist/docs/phoenix/project-structure.mdx +17 -5
  32. package/dist/docs/phoenix/sdk-builder-workflow.mdx +1 -1
  33. package/dist/docs/phoenix/webhooks.mdx +4 -4
  34. package/dist/globals/index.d.ts +2 -0
  35. package/dist/phoenix/application-spec/application-spec-builder.js +1 -1
  36. package/dist/phoenix/application-spec/project-files.js +1 -1
  37. package/dist/phoenix/cli.js +1 -1
  38. package/dist/phoenix/commands/check.js +1 -1
  39. package/dist/phoenix/commands/deps/deps.d.ts +52 -0
  40. package/dist/phoenix/commands/deps/deps.js +3 -0
  41. package/dist/phoenix/commands/deps/index.d.ts +1 -0
  42. package/dist/phoenix/commands/deps/index.js +1 -0
  43. package/dist/phoenix/commands/deps/sdk-manifest.d.ts +12 -0
  44. package/dist/phoenix/commands/deps/sdk-manifest.js +1 -0
  45. package/dist/phoenix/commands/dev.js +5 -5
  46. package/dist/phoenix/commands/index.d.ts +1 -0
  47. package/dist/phoenix/commands/index.js +1 -1
  48. package/dist/phoenix/services/application-spec-project-watcher.d.ts +2 -0
  49. package/dist/phoenix/services/application-spec-project-watcher.js +2 -2
  50. package/dist/phoenix/services/swc.js +1 -1
  51. package/dist/phoenix/utils/index.d.ts +1 -0
  52. package/dist/phoenix/utils/index.js +1 -1
  53. package/package.json +3 -6
@@ -55,6 +55,38 @@ export interface paths {
55
55
  readonly patch?: never
56
56
  readonly trace?: never
57
57
  }
58
+ readonly '/auth/callback': {
59
+ readonly parameters: {
60
+ readonly query?: never
61
+ readonly header?: never
62
+ readonly path?: never
63
+ readonly cookie?: never
64
+ }
65
+ readonly get: operations['completeBrowserLogin']
66
+ readonly put?: never
67
+ readonly post?: never
68
+ readonly delete?: never
69
+ readonly options?: never
70
+ readonly head?: never
71
+ readonly patch?: never
72
+ readonly trace?: never
73
+ }
74
+ readonly '/auth/config': {
75
+ readonly parameters: {
76
+ readonly query?: never
77
+ readonly header?: never
78
+ readonly path?: never
79
+ readonly cookie?: never
80
+ }
81
+ readonly get: operations['getBrowserAuthConfig']
82
+ readonly put?: never
83
+ readonly post?: never
84
+ readonly delete?: never
85
+ readonly options?: never
86
+ readonly head?: never
87
+ readonly patch?: never
88
+ readonly trace?: never
89
+ }
58
90
  readonly '/auth/identity': {
59
91
  readonly parameters: {
60
92
  readonly query?: never
@@ -72,6 +104,39 @@ export interface paths {
72
104
  readonly patch?: never
73
105
  readonly trace?: never
74
106
  }
107
+ readonly '/auth/login': {
108
+ readonly parameters: {
109
+ readonly query?: never
110
+ readonly header?: never
111
+ readonly path?: never
112
+ readonly cookie?: never
113
+ }
114
+ readonly get: operations['startBrowserLogin']
115
+ readonly put?: never
116
+ readonly post?: never
117
+ readonly delete?: never
118
+ readonly options?: never
119
+ readonly head?: never
120
+ readonly patch?: never
121
+ readonly trace?: never
122
+ }
123
+ readonly '/auth/logout': {
124
+ readonly parameters: {
125
+ readonly query?: never
126
+ readonly header?: never
127
+ readonly path?: never
128
+ readonly cookie?: never
129
+ }
130
+ readonly get?: never
131
+ readonly put?: never
132
+ /** @description Destroy the local session and return the fixed Cognito hosted logout URL. Requires the exact shared Studio Origin. */
133
+ readonly post: operations['endBrowserSession']
134
+ readonly delete?: never
135
+ readonly options?: never
136
+ readonly head?: never
137
+ readonly patch?: never
138
+ readonly trace?: never
139
+ }
75
140
  readonly '/auth/me': {
76
141
  readonly parameters: {
77
142
  readonly query?: never
@@ -89,6 +154,23 @@ export interface paths {
89
154
  readonly patch?: never
90
155
  readonly trace?: never
91
156
  }
157
+ readonly '/auth/session': {
158
+ readonly parameters: {
159
+ readonly query?: never
160
+ readonly header?: never
161
+ readonly path?: never
162
+ readonly cookie?: never
163
+ }
164
+ /** @description Read the opaque browser session and current account status/memberships. Requires the exact shared Studio Origin. */
165
+ readonly get: operations['getBrowserSession']
166
+ readonly put?: never
167
+ readonly post?: never
168
+ readonly delete?: never
169
+ readonly options?: never
170
+ readonly head?: never
171
+ readonly patch?: never
172
+ readonly trace?: never
173
+ }
92
174
  readonly '/auth/token': {
93
175
  readonly parameters: {
94
176
  readonly query?: never
@@ -1620,6 +1702,114 @@ export interface operations {
1620
1702
  }
1621
1703
  }
1622
1704
  }
1705
+ readonly completeBrowserLogin: {
1706
+ readonly parameters: {
1707
+ readonly query: {
1708
+ readonly code: string
1709
+ readonly state: string
1710
+ }
1711
+ readonly header?: never
1712
+ readonly path?: never
1713
+ readonly cookie?: never
1714
+ }
1715
+ readonly requestBody?: never
1716
+ readonly responses: {
1717
+ /** @description Redirect to the configured sign-in or Studio destination. */
1718
+ readonly 302: {
1719
+ headers: {
1720
+ readonly [name: string]: unknown
1721
+ }
1722
+ content: {
1723
+ readonly 'application/json': Record<string, unknown>
1724
+ }
1725
+ }
1726
+ /** @description Bad Request! */
1727
+ readonly 400: {
1728
+ headers: {
1729
+ readonly [name: string]: unknown
1730
+ }
1731
+ content: {
1732
+ readonly 'application/json': components['schemas']['BadRequestError']
1733
+ }
1734
+ }
1735
+ /** @description Unauthorized! */
1736
+ readonly 401: {
1737
+ headers: {
1738
+ readonly [name: string]: unknown
1739
+ }
1740
+ content: {
1741
+ readonly 'application/json': components['schemas']['UnauthorizedError']
1742
+ }
1743
+ }
1744
+ /** @description Forbidden! */
1745
+ readonly 403: {
1746
+ headers: {
1747
+ readonly [name: string]: unknown
1748
+ }
1749
+ content: {
1750
+ readonly 'application/json': components['schemas']['ForbiddenError']
1751
+ }
1752
+ }
1753
+ /** @description Not Found! */
1754
+ readonly 404: {
1755
+ headers: {
1756
+ readonly [name: string]: unknown
1757
+ }
1758
+ content: {
1759
+ readonly 'application/json': components['schemas']['NotFoundError']
1760
+ }
1761
+ }
1762
+ /** @description Service Unavailable! */
1763
+ readonly 503: {
1764
+ headers: {
1765
+ readonly [name: string]: unknown
1766
+ }
1767
+ content: {
1768
+ readonly 'application/json': components['schemas']['ServiceUnavailableError']
1769
+ }
1770
+ }
1771
+ /** @description An unexpected error occurred! */
1772
+ readonly default: {
1773
+ headers: {
1774
+ readonly [name: string]: unknown
1775
+ }
1776
+ content: {
1777
+ readonly 'application/json': components['schemas']['DefaultResponse']
1778
+ }
1779
+ }
1780
+ }
1781
+ }
1782
+ readonly getBrowserAuthConfig: {
1783
+ readonly parameters: {
1784
+ readonly query?: never
1785
+ readonly header?: never
1786
+ readonly path?: never
1787
+ readonly cookie?: never
1788
+ }
1789
+ readonly requestBody?: never
1790
+ readonly responses: {
1791
+ /** @description Shared Studio origin when browser sign-in is configured; null otherwise. */
1792
+ readonly 200: {
1793
+ headers: {
1794
+ readonly [name: string]: unknown
1795
+ }
1796
+ content: {
1797
+ readonly 'application/json': {
1798
+ readonly studioOrigin: string | null
1799
+ }
1800
+ }
1801
+ }
1802
+ /** @description An unexpected error occurred! */
1803
+ readonly default: {
1804
+ headers: {
1805
+ readonly [name: string]: unknown
1806
+ }
1807
+ content: {
1808
+ readonly 'application/json': components['schemas']['DefaultResponse']
1809
+ }
1810
+ }
1811
+ }
1812
+ }
1623
1813
  readonly resolveIdentity: {
1624
1814
  readonly parameters: {
1625
1815
  readonly query?: never
@@ -1699,6 +1889,112 @@ export interface operations {
1699
1889
  }
1700
1890
  }
1701
1891
  }
1892
+ readonly startBrowserLogin: {
1893
+ readonly parameters: {
1894
+ readonly query?: never
1895
+ readonly header?: never
1896
+ readonly path?: never
1897
+ readonly cookie?: never
1898
+ }
1899
+ readonly requestBody?: never
1900
+ readonly responses: {
1901
+ /** @description Redirect to the configured sign-in or Studio destination. */
1902
+ readonly 302: {
1903
+ headers: {
1904
+ readonly [name: string]: unknown
1905
+ }
1906
+ content: {
1907
+ readonly 'application/json': Record<string, unknown>
1908
+ }
1909
+ }
1910
+ /** @description Bad Request! */
1911
+ readonly 400: {
1912
+ headers: {
1913
+ readonly [name: string]: unknown
1914
+ }
1915
+ content: {
1916
+ readonly 'application/json': components['schemas']['BadRequestError']
1917
+ }
1918
+ }
1919
+ /** @description Not Found! */
1920
+ readonly 404: {
1921
+ headers: {
1922
+ readonly [name: string]: unknown
1923
+ }
1924
+ content: {
1925
+ readonly 'application/json': components['schemas']['NotFoundError']
1926
+ }
1927
+ }
1928
+ /** @description An unexpected error occurred! */
1929
+ readonly default: {
1930
+ headers: {
1931
+ readonly [name: string]: unknown
1932
+ }
1933
+ content: {
1934
+ readonly 'application/json': components['schemas']['DefaultResponse']
1935
+ }
1936
+ }
1937
+ }
1938
+ }
1939
+ readonly endBrowserSession: {
1940
+ readonly parameters: {
1941
+ readonly query?: never
1942
+ readonly header?: never
1943
+ readonly path?: never
1944
+ readonly cookie?: never
1945
+ }
1946
+ readonly requestBody?: never
1947
+ readonly responses: {
1948
+ /** @description Navigate to this URL to finish hosted logout. */
1949
+ readonly 200: {
1950
+ headers: {
1951
+ readonly [name: string]: unknown
1952
+ }
1953
+ content: {
1954
+ readonly 'application/json': {
1955
+ /** Format: uri */
1956
+ readonly logoutUrl: string
1957
+ }
1958
+ }
1959
+ }
1960
+ /** @description Bad Request! */
1961
+ readonly 400: {
1962
+ headers: {
1963
+ readonly [name: string]: unknown
1964
+ }
1965
+ content: {
1966
+ readonly 'application/json': components['schemas']['BadRequestError']
1967
+ }
1968
+ }
1969
+ /** @description Forbidden! */
1970
+ readonly 403: {
1971
+ headers: {
1972
+ readonly [name: string]: unknown
1973
+ }
1974
+ content: {
1975
+ readonly 'application/json': components['schemas']['ForbiddenError']
1976
+ }
1977
+ }
1978
+ /** @description Not Found! */
1979
+ readonly 404: {
1980
+ headers: {
1981
+ readonly [name: string]: unknown
1982
+ }
1983
+ content: {
1984
+ readonly 'application/json': components['schemas']['NotFoundError']
1985
+ }
1986
+ }
1987
+ /** @description An unexpected error occurred! */
1988
+ readonly default: {
1989
+ headers: {
1990
+ readonly [name: string]: unknown
1991
+ }
1992
+ content: {
1993
+ readonly 'application/json': components['schemas']['DefaultResponse']
1994
+ }
1995
+ }
1996
+ }
1997
+ }
1702
1998
  readonly getApiSession: {
1703
1999
  readonly parameters: {
1704
2000
  readonly query?: never
@@ -1748,6 +2044,77 @@ export interface operations {
1748
2044
  }
1749
2045
  }
1750
2046
  }
2047
+ readonly getBrowserSession: {
2048
+ readonly parameters: {
2049
+ readonly query?: never
2050
+ readonly header?: never
2051
+ readonly path?: never
2052
+ readonly cookie?: never
2053
+ }
2054
+ readonly requestBody?: never
2055
+ readonly responses: {
2056
+ /** @description Current account and fixed session expiry, in Unix milliseconds. */
2057
+ readonly 200: {
2058
+ headers: {
2059
+ readonly [name: string]: unknown
2060
+ }
2061
+ content: {
2062
+ readonly 'application/json': {
2063
+ readonly expiresAt: number
2064
+ /** Format: uuid */
2065
+ readonly userId: string
2066
+ readonly workspaces: readonly {
2067
+ /** Format: uuid */
2068
+ readonly customerId: string
2069
+ readonly name: string
2070
+ /** @enum {string} */
2071
+ readonly role: 'user' | 'admin' | 'superadmin'
2072
+ readonly slug: string
2073
+ readonly tags: readonly string[]
2074
+ /** @enum {string} */
2075
+ readonly type: 'standard' | 'sdk_builder'
2076
+ }[]
2077
+ }
2078
+ }
2079
+ }
2080
+ /** @description Unauthorized! */
2081
+ readonly 401: {
2082
+ headers: {
2083
+ readonly [name: string]: unknown
2084
+ }
2085
+ content: {
2086
+ readonly 'application/json': components['schemas']['UnauthorizedError']
2087
+ }
2088
+ }
2089
+ /** @description Forbidden! */
2090
+ readonly 403: {
2091
+ headers: {
2092
+ readonly [name: string]: unknown
2093
+ }
2094
+ content: {
2095
+ readonly 'application/json': components['schemas']['ForbiddenError']
2096
+ }
2097
+ }
2098
+ /** @description Not Found! */
2099
+ readonly 404: {
2100
+ headers: {
2101
+ readonly [name: string]: unknown
2102
+ }
2103
+ content: {
2104
+ readonly 'application/json': components['schemas']['NotFoundError']
2105
+ }
2106
+ }
2107
+ /** @description An unexpected error occurred! */
2108
+ readonly default: {
2109
+ headers: {
2110
+ readonly [name: string]: unknown
2111
+ }
2112
+ content: {
2113
+ readonly 'application/json': components['schemas']['DefaultResponse']
2114
+ }
2115
+ }
2116
+ }
2117
+ }
1751
2118
  readonly exchangeAuthCode: {
1752
2119
  readonly parameters: {
1753
2120
  readonly query?: never
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-10-14T19:37:05.683Z",
2
+ "generatedAt": "2026-10-15T09:04:15.149Z",
3
3
  "categories": [
4
4
  {
5
5
  "name": "Phoenix",
@@ -281,9 +281,7 @@ Phoenix provides two helper functions for reading environment variables with val
281
281
  **`createEnvReader`** - General purpose environment reader used in frontend and deployment contexts:
282
282
 
283
283
  ```typescript
284
- import { bool, str } from 'envalid'
285
-
286
- import { createEnvReader } from '@salsita-ai/sdk/common/env'
284
+ import { bool, createEnvReader, str } from '@salsita-ai/sdk/common/env'
287
285
 
288
286
  // Create a reader function
289
287
  const readEnv = createEnvReader({
@@ -301,9 +299,7 @@ console.log(env.SERVER_URL) // Typed and validated
301
299
 
302
300
  ```typescript
303
301
  // webhooks/webhooks.config.ts
304
- import { str } from 'envalid'
305
-
306
- import { createEnvReader } from '@salsita-ai/sdk/common/env'
302
+ import { createEnvReader, str } from '@salsita-ai/sdk/common/env'
307
303
 
308
304
  export const readRuntimeConfig = createEnvReader({
309
305
  AWS_S3_PUBLIC_RESOURCES_BUCKET: str(),
@@ -26,6 +26,7 @@ The Phoenix CLI (`phoenix` command) is the unified tool for all configurator dev
26
26
  - `phoenix dev` - Start the development server with hot reload
27
27
  - `phoenix build` - Build the configurator for production
28
28
  - `phoenix sync` - Synchronize dependencies and generated code
29
+ - `phoenix deps` - Add the SDK's missing peer dependencies to `package.json` and move out-of-range ones into range
29
30
  - `phoenix check` - Validate domain configuration and code
30
31
  - `phoenix fix` - Auto-fix common issues in domain files
31
32
 
@@ -408,7 +408,7 @@ function EntityList({ entities }) {
408
408
  When you need to do more complex text formatting with placeholders or embedded elements, you can reach for Lingui's `Trans` macro directly:
409
409
 
410
410
  ```tsx
411
- import { Trans, msg } from '@lingui/macro'
411
+ import { Trans } from '@lingui/react/macro'
412
412
 
413
413
  function WelcomeMessage({ userName, itemCount }) {
414
414
  return (
@@ -423,14 +423,14 @@ function WelcomeMessage({ userName, itemCount }) {
423
423
 
424
424
  ## Server-Side Translations for Webhooks
425
425
 
426
- The localization system isn't just for the frontend — it works in server-side webhook handlers too. PDF and email tasks render React templates with the same `@lingui/macro` toolchain (`<Trans>`, `msg`) you already use in UI components. The task context exposes `ctx.resolveLocalizable` already bound to the request locale and domain fallback chain, and the React builders use it for localizable subjects, attachment filenames, bodies, headers, footers, and watermark text.
426
+ The localization system isn't just for the frontend — it works in server-side webhook handlers too. PDF and email tasks render React templates with the same Lingui macros (`<Trans>` from `@lingui/react/macro`, `msg` from `@lingui/core/macro`) you already use in UI components. The task context exposes `ctx.resolveLocalizable` already bound to the request locale and domain fallback chain, and the React builders use it for localizable subjects, attachment filenames, bodies, headers, footers, and watermark text.
427
427
 
428
428
  ### In the handler
429
429
 
430
430
  Use the `msg` template tag for one-off strings you pass into builder methods:
431
431
 
432
432
  ```tsx
433
- import { msg } from '@lingui/macro'
433
+ import { msg } from '@lingui/core/macro'
434
434
 
435
435
  export const emailTask = phx.webhooks.taskFactory.createSendEmailTask((resources, data, ctx) => {
436
436
  return ctx.emailTaskBuilder
@@ -450,7 +450,7 @@ export const emailTask = phx.webhooks.taskFactory.createSendEmailTask((resources
450
450
  Use `<Trans>` for inline strings — exactly as in the frontend — and `<HtmlHelpers.Localized>` to render localizable values pulled from the domain (e.g. `$root.$summary[].title`, which are typed as `MessageDescriptor` or `MultilingualString`):
451
451
 
452
452
  ```tsx
453
- import { Trans } from '@lingui/macro'
453
+ import { Trans } from '@lingui/react/macro'
454
454
 
455
455
  import { HtmlHelpers } from '@salsita-ai/sdk/webhook'
456
456
 
@@ -251,8 +251,19 @@ rm src/frontend/frontend.tsx
251
251
  # Remove empty domain/frontend folders after moving all files
252
252
  rmdir src/domain/implementation src/domain/data src/domain
253
253
  rmdir src/frontend/systems/transformers src/frontend/systems src/frontend/ui src/frontend/admin-pages src/frontend
254
+
255
+ # Remove the root TypeScript settings (sync writes the file again)
256
+ rm tsconfig.json
254
257
  ```
255
258
 
259
+ With the application-spec pipeline (`phoenix.applicationFlow` in `package.json`; see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)), the project's TypeScript settings are generated into `.phoenix/tsconfig.json`. Sync writes the root `tsconfig.json` only into a project that has none, as a single line that extends them:
260
+
261
+ ```json
262
+ { "extends": "./.phoenix/tsconfig.json" }
263
+ ```
264
+
265
+ A root `tsconfig.json` from the old multi-folder template, or one written by hand, stays as it is and does not pick up the generated settings or the global `phx` types in `.phoenix/globals.d.ts`, so `pnpm ts:check` fails. Delete it, or replace its content with the line above, before the first sync.
266
+
256
267
  ### 10. Create Mocks (Optional)
257
268
 
258
269
  If you have mock files, move them to `mocks/`:
@@ -390,7 +401,7 @@ pnpm install
390
401
 
391
402
  1. Run type check: `pnpm ts:check`
392
403
  2. Update any broken type imports
393
- 3. Ensure `tsconfig.json` paths are correct (auto-generated by Phoenix)
404
+ 3. With the application-spec pipeline (`phoenix.applicationFlow`; see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)), check that the root `tsconfig.json` is the one-line file that extends `.phoenix/tsconfig.json` (see [step 9](#9-remove-auto-generated-files))
394
405
 
395
406
  ## Checklist
396
407
 
@@ -433,13 +444,13 @@ Use this checklist to verify migration completeness:
433
444
 
434
445
  The following files are no longer needed - they are auto-generated by the CLI:
435
446
 
436
- | File | Replacement |
437
- | --------------------------- | -------------------------------------------- |
438
- | `src/domain/domain.ts` | Auto-generated in `.phoenix/domain.ts` |
439
- | `src/frontend/frontend.tsx` | Auto-generated in `.phoenix/configurator.ts` |
440
- | `tsconfig.json` | Auto-generated by CLI |
441
- | `eslint.config.js` | Auto-generated by CLI |
442
- | `prettier.config.js` | Auto-generated by CLI |
447
+ | File | Replacement |
448
+ | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
449
+ | `src/domain/domain.ts` | Auto-generated in `.phoenix/domain.ts` |
450
+ | `src/frontend/frontend.tsx` | Auto-generated in `.phoenix/configurator.ts` |
451
+ | `tsconfig.json` | Delete before the first sync; with the application-spec pipeline, sync writes a one-line file that extends `.phoenix/tsconfig.json` |
452
+ | `eslint.config.js` | Auto-generated by CLI |
453
+ | `prettier.config.js` | Auto-generated by CLI |
443
454
 
444
455
  ## Builder Options Moved to YAML
445
456
 
@@ -137,7 +137,7 @@ The same streams are available in the editor's **Logs** sidebar panel with per-s
137
137
 
138
138
  Runs all code quality checks in sequence:
139
139
 
140
- 1. **TypeScript** — Type checking with `tsc`
140
+ 1. **TypeScript** — Type checking with `tsc`, with the project's root `tsconfig.json`, or with `.phoenix/tsconfig.json` when the project has none (see [Project Structure](?path=/docs/phoenix-project-structure--docs#root-level-files))
141
141
  2. **ESLint** — Linting rules, over `src/`; a project with no files there passes
142
142
  3. **Prettier** — Code formatting
143
143
 
@@ -147,12 +147,23 @@ Auto-fixes ESLint and Prettier issues. Equivalent to running `eslint --fix` and
147
147
 
148
148
  ## Environment Variables
149
149
 
150
- When you run `deployment:prepare-local` or `deployment:prepare`, the CLI communicates with the Phoenix server, which generates environment variables and writes them to `.env.generated`.
150
+ When you run `deployment:prepare-local` or `deployment:prepare`, the CLI communicates with the Phoenix server, which generates environment variables and writes them to `.env.generated`. `phoenix dev` does the same for its development deployment when it starts.
151
+
152
+ ### The generated env file
153
+
154
+ A project has one generated env file. Phoenix keeps it in `.phoenix/`, as `.phoenix/.env.generated`, unless the project has a `.env.generated` in its root, which then is the one that counts.
155
+
156
+ - `phoenix dev` reads and writes `.phoenix/.env.generated` in a project without a root `.env.generated`, and creates no file in the project root. In a project that has a root `.env.generated`, it reads and writes that file and `.phoenix/.env.generated` is not used.
157
+ - The deployment and environment commands (`deployment:prepare`, `deployment:prepare-dev`, `deployment:prepare-local`, `deployment:build-envs` and the others with an `--outFile` option) write `.env.generated` in the project root unless `--outFile` or `OUT_FILE` names another file. Deploy pipelines read it there. Once one of them has written it, `phoenix dev` and `phoenix build` use it.
158
+ - Everything that reads environment variables follows the same rule: the root `.env.generated` when it exists, otherwise `.phoenix/.env.generated`. The two files are never merged.
159
+ - `phoenix clean` removes `.phoenix/` and with it `.phoenix/.env.generated`; the next `phoenix dev` prepares the development deployment again. A root `.env.generated` stays.
160
+
161
+ This holds for a project on the application-spec pipeline. In a project on the legacy pipeline (see [Current and legacy project tooling](#current-and-legacy-project-tooling)), `phoenix dev` always reads and writes `.env.generated` in the project root.
151
162
 
152
163
  ### Data Flow
153
164
 
154
165
  ```
155
- spec/application.yaml → Server prepares environment → CLI writes .env.generated → Frontend/Webhooks read it
166
+ spec/application.yaml → Server prepares environment → CLI writes the generated env file → Frontend/Webhooks read it
156
167
  ```
157
168
 
158
169
  ### Project Scripts
@@ -173,7 +184,7 @@ A project may have other scripts than these five, such as `sync`, `test` or `ver
173
184
 
174
185
  ### Server-Generated Variables
175
186
 
176
- These are automatically computed by the server and written to `.env.generated`:
187
+ These are automatically computed by the server and written to the generated env file:
177
188
 
178
189
  | Variable | Purpose |
179
190
  | -------------------------------- | ------------------------------------------------------- |
@@ -261,7 +272,7 @@ A development environment keeps the AI assistant's conversation when the assista
261
272
  Environment variables are resolved in this order (highest to lowest priority):
262
273
 
263
274
  1. Process environment variables (shell)
264
- 2. `.env.generated` (created by deployment commands)
275
+ 2. [The generated env file](#the-generated-env-file): `.env.generated` in the project root when the project has one, otherwise `.phoenix/.env.generated`
265
276
  3. `.env` (manual overrides)
266
277
 
267
278
  ### Generated Config Files
@@ -300,7 +311,8 @@ The dev server watches for changes in:
300
311
 
301
312
  - `spec/**/*.yaml` — Domain specification files
302
313
  - `src/**/*.{ts,tsx,yaml,yml,json,html,css}` — Source files
303
- - `.env`, `.env.generated` — Environment files (triggers full Vite restart)
314
+ - `.env` — Environment file; a change restarts the Vite dev server
315
+ - `.env.generated`, `.phoenix/.env.generated` — Generated env files; a change rebuilds the project files. Only a file that exists when `phoenix dev` starts is watched: a root `.env.generated` that a deployment command creates while dev runs is not watched; restart `phoenix dev` to use it.
304
316
 
305
317
  When linked SDK packages are detected (`phoenix link`), changes to SDK dist files are also watched.
306
318
 
@@ -398,6 +410,24 @@ With the application-spec pipeline (see [Current and legacy project tooling](#cu
398
410
  | ---------------- | --------------- | ------- | ------------------------------ |
399
411
  | `--force` / `-f` | `FORCE_REBUILD` | `false` | Force full rebuild, skip cache |
400
412
 
413
+ ### `phoenix deps`
414
+
415
+ Brings `package.json` in line with the SDK's peer dependencies: the packages the SDK's code imports and the project installs next to it, so the project and the SDK share one copy. The `peerDependencies` of the installed `@salsita-ai/sdk` decide which packages and which versions. `@clerk/clerk-react` is needed only when the spec sets `useClerk`.
416
+
417
+ ```bash
418
+ pnpm phoenix deps
419
+ pnpm install
420
+ ```
421
+
422
+ - A missing peer is added at the lowest version of the SDK's range, as an exact version, in alphabetical order: type packages (`@types/*`) to `devDependencies`, the others to `dependencies`.
423
+ - A peer declared with a version range whose lowest version falls outside the SDK's range is set to the lowest version of the SDK's range, in the field that declares it. The output says when that is a downgrade.
424
+ - A peer declared with a specifier that is not a version range, such as `workspace:`, `npm:`, `catalog:`, `file:`, `link:` or a git URL, stays as it is.
425
+ - `@salsita-ai/common`, `@salsita-ai/contracts`, `@salsita-ai/platform-project-sdk`, `@salsita-ai/platform-common` and `@salsita-ai/platform-contracts` are removed, because `@salsita-ai/sdk` replaces them. No other entry is removed.
426
+
427
+ Every other part of `package.json` keeps its order and formatting. `phoenix deps` installs nothing: it lists each change and names `pnpm install` as the next step, or says that nothing needed to change. Running it again changes nothing. It reads the spec to learn whether the project uses Clerk, so it stops with the spec's errors when the spec does not parse.
428
+
429
+ This holds for a project on the application-spec pipeline. In a project on the legacy pipeline (see [Current and legacy project tooling](#current-and-legacy-project-tooling)), `phoenix deps` changes nothing and says that `phoenix sync` manages the dependencies.
430
+
401
431
  ### Current and legacy project tooling
402
432
 
403
433
  Use the `phoenix` binary for projects that still use domain-spec generation. The CLI selects a