@percepta/create 3.0.1 → 3.1.0
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/README.md +6 -5
- package/dist/{chunk-GEVZERMP.js → chunk-7NPWSTCY.js} +3 -1
- package/dist/{chunk-R4FWPE4A.js → chunk-DCM7JOSC.js} +2 -2
- package/dist/index.js +207 -60
- package/dist/{init-Z4VGBHAK.js → init-NP6GRXLL.js} +1 -1
- package/dist/{status-MITGDLTT.js → status-BTHGN6QH.js} +1 -1
- package/dist/{sync-J4SFZHDX.js → sync-3Q27L7XZ.js} +1 -1
- package/dist/{upstream-AQI7P4EU.js → upstream-C5KFAHVR.js} +1 -1
- package/package.json +1 -1
- package/templates/webapp/.github/workflows/__APP_NAME__-ryvn-release.yaml +3 -2
- package/templates/webapp/AGENTS.md +8 -2
- package/templates/webapp/Dockerfile +0 -1
- package/templates/webapp/README.md +1 -0
- package/templates/webapp/agent-skills/database.md +1 -0
- package/templates/webapp/agent-skills/deploy.md +24 -27
- package/templates/webapp/agent-skills/oneshot.md +3 -3
- package/templates/webapp/deploy/README.md +8 -6
- package/templates/webapp/deploy/ryvn/__APP_NAME__.service.yaml +0 -2
- package/templates/webapp/deploy/ryvn/environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml +11 -27
- package/templates/webapp/drizzle.config.ts +15 -6
- package/templates/webapp/env.example.template +1 -0
- package/templates/webapp/eslint.config.mjs +7 -0
- package/templates/webapp/package.json.template +6 -6
- package/templates/webapp/scripts/open-ryvn-deploy-pr.ts +377 -0
- package/templates/webapp/scripts/seed.ts +1 -1
- package/templates/webapp/scripts/setup-database.ts +14 -0
- package/templates/webapp/src/app/global-error.tsx +2 -0
- package/templates/webapp/src/config/getEnvConfig.ts +1 -0
- package/templates/webapp/src/drizzle/db.ts +3 -0
- package/templates/webapp/src/drizzle/searchPath.test.ts +21 -0
- package/templates/webapp/src/drizzle/searchPath.ts +16 -0
- package/templates/webapp/src/styles/globals.css +0 -7
|
@@ -130,6 +130,7 @@ pnpm docker:down
|
|
|
130
130
|
| `DATABASE_USERNAME` | `postgres` | Database user |
|
|
131
131
|
| `DATABASE_PASSWORD` | `postgres` | Database password |
|
|
132
132
|
| `DATABASE_NAME` | `__DB_NAME__` | Database name |
|
|
133
|
+
| `DATABASE_SCHEMA` | - | Optional Postgres schema/search path |
|
|
133
134
|
| `DATABASE_USE_SSL` | `false` | Enable SSL connections |
|
|
134
135
|
|
|
135
136
|
## Key Concepts
|
|
@@ -10,7 +10,7 @@ When this app was created with `@percepta/create`, the IaC files were generated
|
|
|
10
10
|
- `deploy/ryvn/environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml` — percepta-test installation
|
|
11
11
|
- `.github/workflows/__APP_NAME__-ryvn-release.yaml` (at the repo root) — release workflow that builds the Docker image and creates a Ryvn release on push to `main`. Path filter scoped to `packages/__APP_NAME__/` so unrelated changes don't trigger builds.
|
|
12
12
|
|
|
13
|
-
Per-app values (URLs, k8s service names, database
|
|
13
|
+
Per-app values (URLs, k8s service names, database schema) are substituted at create-time. The Better Auth and encryption secrets are declared as Ryvn-managed secrets so their values are set after the infra PR merges, not committed to git. Shared platform values (Inngest and OTel endpoints) are baked in as literals because they're stable across percepta-test apps.
|
|
14
14
|
|
|
15
15
|
See [`deploy/README.md`](../deploy/README.md) for the file-by-file breakdown.
|
|
16
16
|
|
|
@@ -19,43 +19,39 @@ See [`deploy/README.md`](../deploy/README.md) for the file-by-file breakdown.
|
|
|
19
19
|
- The app repo is under the `Percepta-Core` GitHub org. If not yet, run `gh repo create Percepta-Core/__APP_NAME__ --private --source=. --push` from the monorepo root.
|
|
20
20
|
- The Percepta-Core org has `RYVN_CLIENT_ID`, `RYVN_CLIENT_SECRET`, and `NPM_TOKEN` as org-level GitHub secrets (already in place).
|
|
21
21
|
- The `percepta-internal-terraform` installation provides the shared PostgreSQL — already deployed on percepta-test.
|
|
22
|
-
-
|
|
22
|
+
- `git` and `gh` are installed and authenticated.
|
|
23
|
+
- The infra repo (`Percepta-Core/infra`) is checked out locally or can be cloned by the deploy script.
|
|
23
24
|
|
|
24
25
|
## Deploy
|
|
25
26
|
|
|
26
27
|
### Step 1: Open the infra PR
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
Run the generated deploy helper from this package directory:
|
|
29
30
|
|
|
30
31
|
```bash
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
cp deploy/ryvn/$NAME.service.yaml \
|
|
35
|
-
$INFRA/ryvn/$NAME.service.yaml
|
|
32
|
+
pnpm deploy:percepta-test -- --yes
|
|
33
|
+
```
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
$INFRA/ryvn/environments/percepta-test/installations/$NAME.env.percepta-test.serviceinstallation.yaml
|
|
35
|
+
This script:
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
gh pr create --fill
|
|
46
|
-
```
|
|
37
|
+
- uses `INFRA_REPO` or `--infra <path>` when provided
|
|
38
|
+
- otherwise uses a sibling `../infra` checkout, cloning `Percepta-Core/infra` there if needed
|
|
39
|
+
- copies the Ryvn service and installation YAML into infra
|
|
40
|
+
- appends a `postgresql_schema "__APP_NAME_SNAKE__"` resource to `terraform/percepta-internal/databases.tf`
|
|
41
|
+
- opens one PR against `Percepta-Core/infra`
|
|
47
42
|
|
|
48
43
|
Get the PR reviewed and merged.
|
|
49
44
|
|
|
50
|
-
### Step 2: Set
|
|
45
|
+
### Step 2: Set Ryvn secrets
|
|
51
46
|
|
|
52
|
-
After the infra PR merges,
|
|
47
|
+
After the infra PR merges, set the base Ryvn secrets for this installation:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
BETTER_AUTH_SECRET=$(openssl rand -base64 32)
|
|
51
|
+
ENCRYPTION_SECRET_KEY=$(openssl rand -hex 16)
|
|
52
|
+
```
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|--------|-------|
|
|
56
|
-
| `BETTER_AUTH_SECRET` | `openssl rand -base64 32` |
|
|
57
|
-
| `ENCRYPTION_SECRET_KEY` | `openssl rand -hex 16` |
|
|
58
|
-
| `LANGFUSE_SECRET_KEY` | from 1Password: "Percepta Test Secrets" |
|
|
54
|
+
Also set any app-specific secrets the implementation added, such as `OPENAI_API_KEY`.
|
|
59
55
|
|
|
60
56
|
### Step 3: Trigger the first deploy
|
|
61
57
|
|
|
@@ -76,16 +72,17 @@ The app will be available at **https://__APP_NAME__.percepta-test.aitco.dev**.
|
|
|
76
72
|
|
|
77
73
|
## Troubleshooting
|
|
78
74
|
|
|
79
|
-
- **Pod crash-looping** →
|
|
75
|
+
- **Pod crash-looping** → check `ryvn logs`; missing Ryvn secrets from Step 2 are the most common cause after a fresh deploy.
|
|
80
76
|
- **Database connection refused** → verify `DATABASE_USE_SSL=true` and that `percepta-internal-terraform` is deployed.
|
|
77
|
+
- **Database schema missing** → verify the infra PR added `postgresql_schema "__APP_NAME_SNAKE__"` and Ryvn applied `percepta-internal-terraform`.
|
|
81
78
|
- **Inngest can't reach the app** → `INNGEST_APP_URL` must use the k8s service name `__APP_NAME__-web-server`. The scaffolded YAML gets this right; if you renamed anything, double-check.
|
|
82
|
-
- **Image build fails** → check `NPM_TOKEN`
|
|
79
|
+
- **Image build fails fetching @percepta packages** → check the `NPM_TOKEN` GitHub org secret. The workflow passes it as a build arg.
|
|
83
80
|
|
|
84
81
|
For Ryvn CLI operations, use the `/use-ryvn` skill.
|
|
85
82
|
|
|
86
83
|
## Updating shared platform values
|
|
87
84
|
|
|
88
|
-
The Inngest
|
|
85
|
+
The Inngest and OTel URLs are baked as literals in every webapp's installation YAML. If percepta-test infra ever changes those endpoints, update them with a single grep across the infra repo:
|
|
89
86
|
|
|
90
87
|
```bash
|
|
91
88
|
grep -rl "inngest.percepta-test.svc.cluster.local:8288" ryvn/environments/percepta-test/installations/
|
|
@@ -122,7 +122,7 @@ If it fails, fix the errors before moving to the next chunk. Do not accumulate b
|
|
|
122
122
|
### Implementation Rules
|
|
123
123
|
|
|
124
124
|
- **Use `@percepta/design` components.** Do not write custom UI for things that exist in the design system (Button, Dialog, Table, Card, Input, etc.). Read `node_modules/@percepta/design/dist/src/index.d.ts` to see what's available.
|
|
125
|
-
- **Use
|
|
125
|
+
- **Use robust loading states.** `@percepta/components` is optional; add it first if you want `AsyncContent`.
|
|
126
126
|
- **Use `getEnvConfig()` for env vars.** Never use `process.env` directly.
|
|
127
127
|
- **Use `getLogger()` for logging.** Never use `console.log`. Use safe/unsafe field separation.
|
|
128
128
|
- **Follow the singleton pattern** for new services. Follow the existing `DatabaseService` singleton pattern in the codebase.
|
|
@@ -179,8 +179,8 @@ git init
|
|
|
179
179
|
git add -A
|
|
180
180
|
git commit -m "Initial implementation of <app-name>"
|
|
181
181
|
|
|
182
|
-
# Create the repo under
|
|
183
|
-
gh repo create
|
|
182
|
+
# Create the repo under the Percepta-Core org
|
|
183
|
+
gh repo create Percepta-Core/<app-name> --private --source=. --push
|
|
184
184
|
```
|
|
185
185
|
|
|
186
186
|
If `gh` is not authenticated, tell the user to run `gh auth login` and then continue.
|
|
@@ -12,21 +12,23 @@ deploy/
|
|
|
12
12
|
└── __APP_NAME__.env.percepta-test.serviceinstallation.yaml # percepta-test installation
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
These files are pre-filled with all values needed to deploy to `https://__APP_NAME__.percepta-test.aitco.dev`. The
|
|
15
|
+
These files are pre-filled with all base values needed to deploy to `https://__APP_NAME__.percepta-test.aitco.dev`. The generated `pnpm deploy:percepta-test -- --yes` helper opens the required `Percepta-Core/infra` PR.
|
|
16
16
|
|
|
17
17
|
## Deploying
|
|
18
18
|
|
|
19
|
-
Tell Claude "deploy this app to percepta-test" — it'll follow [`agent-skills/deploy.md`](../agent-skills/deploy.md), which
|
|
19
|
+
Tell Claude "deploy this app to percepta-test" — it'll follow [`agent-skills/deploy.md`](../agent-skills/deploy.md), which runs the generated PR helper and then verifies Ryvn.
|
|
20
20
|
|
|
21
21
|
## What's in these files
|
|
22
22
|
|
|
23
|
-
**`__APP_NAME__.service.yaml`** — tells Ryvn how to build the Docker image. Points at `Percepta-Core/__APP_NAME__` (change the repo if you've named the GitHub repo differently). The `NPM_TOKEN`
|
|
23
|
+
**`__APP_NAME__.service.yaml`** — tells Ryvn how to build the Docker image. Points at `Percepta-Core/__APP_NAME__` (change the repo if you've named the GitHub repo differently). The release workflow passes `NPM_TOKEN` as a build arg from GitHub org secrets.
|
|
24
24
|
|
|
25
25
|
**`__APP_NAME__.env.percepta-test.serviceinstallation.yaml`** — configures the deployment on `percepta-test`. Three categories of values are baked in:
|
|
26
26
|
|
|
27
|
-
1. **Per-app values** that vary by app name (URLs, k8s service names) — substituted at create-time.
|
|
28
|
-
2. **Shared platform values** (Inngest
|
|
29
|
-
3. **
|
|
27
|
+
1. **Per-app values** that vary by app name (URLs, k8s service names, database schema) — substituted at create-time.
|
|
28
|
+
2. **Shared platform values** (Inngest and OTel endpoints) — copied as literals from existing percepta-test installations. These are stable across percepta-test apps.
|
|
29
|
+
3. **Database wiring** — points at the shared `demos` database and a per-app schema created by the infra PR.
|
|
30
|
+
|
|
31
|
+
`BETTER_AUTH_SECRET` and `ENCRYPTION_SECRET_KEY` are declared as Ryvn-managed secrets. Set their values in Ryvn after the infra PR merges; the scaffold does not commit deployment secret values to git.
|
|
30
32
|
|
|
31
33
|
## Repo layout note
|
|
32
34
|
|
|
@@ -38,29 +38,33 @@ spec:
|
|
|
38
38
|
- __APP_NAME__.percepta-test.aitco.dev
|
|
39
39
|
|
|
40
40
|
env:
|
|
41
|
-
# Database
|
|
41
|
+
# Database — shared `demos` DB on the percepta-internal Postgres instance.
|
|
42
|
+
# Tables live under a per-app schema created by the infra PR. DATABASE_SCHEMA
|
|
43
|
+
# pins the connection search_path so Drizzle migrations + queries land there.
|
|
42
44
|
- name: DATABASE_HOST
|
|
43
45
|
valueFrom:
|
|
44
46
|
secretKeyRef:
|
|
45
|
-
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.
|
|
47
|
+
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_postgresql_secret_name }}"
|
|
46
48
|
key: host
|
|
47
49
|
- name: DATABASE_PORT
|
|
48
50
|
valueFrom:
|
|
49
51
|
secretKeyRef:
|
|
50
|
-
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.
|
|
52
|
+
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_postgresql_secret_name }}"
|
|
51
53
|
key: port
|
|
52
54
|
- name: DATABASE_USERNAME
|
|
53
55
|
valueFrom:
|
|
54
56
|
secretKeyRef:
|
|
55
|
-
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.
|
|
57
|
+
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_postgresql_secret_name }}"
|
|
56
58
|
key: username
|
|
57
59
|
- name: DATABASE_PASSWORD
|
|
58
60
|
valueFrom:
|
|
59
61
|
secretKeyRef:
|
|
60
|
-
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.
|
|
62
|
+
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_postgresql_secret_name }}"
|
|
61
63
|
key: password
|
|
62
64
|
- name: DATABASE_NAME
|
|
63
|
-
value: "
|
|
65
|
+
value: "demos"
|
|
66
|
+
- name: DATABASE_SCHEMA
|
|
67
|
+
value: "__APP_NAME_SNAKE__"
|
|
64
68
|
- name: DATABASE_USE_SSL
|
|
65
69
|
value: "true"
|
|
66
70
|
|
|
@@ -74,12 +78,9 @@ spec:
|
|
|
74
78
|
value: https://__APP_NAME__.percepta-test.aitco.dev
|
|
75
79
|
- key: BETTER_AUTH_URL
|
|
76
80
|
value: https://__APP_NAME__.percepta-test.aitco.dev
|
|
77
|
-
|
|
78
|
-
# Auth — generated random, set in Ryvn UI (openssl rand -base64 32)
|
|
81
|
+
# Set these in Ryvn after the infra PR merges.
|
|
79
82
|
- key: BETTER_AUTH_SECRET
|
|
80
83
|
isSecret: true
|
|
81
|
-
|
|
82
|
-
# Encryption — generated random, set in Ryvn UI (openssl rand -hex 16)
|
|
83
84
|
- key: ENCRYPTION_SECRET_KEY
|
|
84
85
|
isSecret: true
|
|
85
86
|
|
|
@@ -95,14 +96,6 @@ spec:
|
|
|
95
96
|
- key: INNGEST_SERVE_HOST
|
|
96
97
|
value: http://__APP_NAME__-web-server.percepta-test.svc.cluster.local:3000/api/inngest
|
|
97
98
|
|
|
98
|
-
# Langfuse (shared percepta-test instance) — secret key set in Ryvn UI from 1Password
|
|
99
|
-
- key: LANGFUSE_BASE_URL
|
|
100
|
-
value: https://percepta-test.aitco.dev/evals
|
|
101
|
-
- key: LANGFUSE_PUBLIC_KEY
|
|
102
|
-
value: pk-lf-cc45f2c9-5286-4966-849b-42fd45059390
|
|
103
|
-
- key: LANGFUSE_SECRET_KEY
|
|
104
|
-
isSecret: true
|
|
105
|
-
|
|
106
99
|
# OpenTelemetry
|
|
107
100
|
- key: OTEL_METRICS_EXPORTER_OTLP_ENDPOINT
|
|
108
101
|
value: http://otel-collector-opentelemetry-collector.percepta-test.svc.cluster.local:4318/v1/metrics
|
|
@@ -110,12 +103,3 @@ spec:
|
|
|
110
103
|
value: "60000"
|
|
111
104
|
- key: LOG_LEVEL
|
|
112
105
|
value: debug
|
|
113
|
-
|
|
114
|
-
# Set the values for these in the Ryvn UI after the infra PR merges:
|
|
115
|
-
# BETTER_AUTH_SECRET — generate: openssl rand -base64 32
|
|
116
|
-
# ENCRYPTION_SECRET_KEY — generate: openssl rand -hex 16
|
|
117
|
-
# LANGFUSE_SECRET_KEY — copy from 1Password "Percepta Test Secrets"
|
|
118
|
-
secrets:
|
|
119
|
-
- name: BETTER_AUTH_SECRET
|
|
120
|
-
- name: ENCRYPTION_SECRET_KEY
|
|
121
|
-
- name: LANGFUSE_SECRET_KEY
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { loadEnvConfig } from "@next/env";
|
|
2
2
|
import type { Config } from "drizzle-kit";
|
|
3
3
|
import { getEnvConfig } from "./src/config/getEnvConfig";
|
|
4
|
+
import { getPgSearchPathOption } from "./src/drizzle/searchPath";
|
|
4
5
|
|
|
5
6
|
loadEnvConfig(process.cwd());
|
|
6
7
|
|
|
@@ -10,20 +11,28 @@ const {
|
|
|
10
11
|
DATABASE_USERNAME: user,
|
|
11
12
|
DATABASE_PASSWORD: password,
|
|
12
13
|
DATABASE_NAME: database,
|
|
14
|
+
DATABASE_SCHEMA: databaseSchema,
|
|
13
15
|
DATABASE_USE_SSL: useSSL,
|
|
14
16
|
} = getEnvConfig();
|
|
15
17
|
|
|
18
|
+
const schemaFilter = databaseSchema?.trim() || undefined;
|
|
19
|
+
const searchPathOption = getPgSearchPathOption(schemaFilter);
|
|
20
|
+
const connectionParams = new URLSearchParams();
|
|
21
|
+
if (useSSL) connectionParams.set("sslmode", "require");
|
|
22
|
+
if (searchPathOption) connectionParams.set("options", searchPathOption);
|
|
23
|
+
|
|
24
|
+
const connectionString =
|
|
25
|
+
`postgresql://${encodeURIComponent(user)}:${encodeURIComponent(password)}` +
|
|
26
|
+
`@${host}:${port}/${encodeURIComponent(database)}` +
|
|
27
|
+
(connectionParams.size > 0 ? `?${connectionParams.toString()}` : "");
|
|
28
|
+
|
|
16
29
|
const config: Config = {
|
|
17
30
|
schema: "./src/drizzle/schema",
|
|
18
31
|
out: "./src/drizzle/migrations",
|
|
19
32
|
dialect: "postgresql",
|
|
33
|
+
...(schemaFilter ? { schemaFilter: [schemaFilter] } : {}),
|
|
20
34
|
dbCredentials: {
|
|
21
|
-
|
|
22
|
-
port,
|
|
23
|
-
user,
|
|
24
|
-
password,
|
|
25
|
-
database,
|
|
26
|
-
ssl: useSSL ? "require" : false,
|
|
35
|
+
url: connectionString,
|
|
27
36
|
},
|
|
28
37
|
};
|
|
29
38
|
|
|
@@ -24,6 +24,7 @@ export default [
|
|
|
24
24
|
rules: {
|
|
25
25
|
...nextPlugin.configs.recommended.rules,
|
|
26
26
|
...nextPlugin.configs["core-web-vitals"].rules,
|
|
27
|
+
"react/react-in-jsx-scope": "off",
|
|
27
28
|
},
|
|
28
29
|
},
|
|
29
30
|
{
|
|
@@ -49,4 +50,10 @@ export default [
|
|
|
49
50
|
"n/no-process-env": "error",
|
|
50
51
|
},
|
|
51
52
|
},
|
|
53
|
+
{
|
|
54
|
+
files: ["src/config/clientEnvConfig.ts"],
|
|
55
|
+
rules: {
|
|
56
|
+
"n/no-process-env": "off",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
52
59
|
];
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"db:studio": "drizzle-kit studio",
|
|
22
22
|
"db:create-user": "tsx ./scripts/create-user.ts",
|
|
23
23
|
"db:seed": "tsx ./scripts/seed.ts",
|
|
24
|
+
"deploy:percepta-test": "tsx ./scripts/open-ryvn-deploy-pr.ts",
|
|
24
25
|
"test": "vitest run",
|
|
25
26
|
"test:watch": "vitest"
|
|
26
27
|
},
|
|
@@ -47,11 +48,10 @@
|
|
|
47
48
|
"@opentelemetry/api": "^1.9.0",
|
|
48
49
|
"@opentelemetry/auto-instrumentations-node": "^0.62.1",
|
|
49
50
|
"@opentelemetry/sdk-node": "^0.203.0",
|
|
50
|
-
"@percepta/design": "
|
|
51
|
-
"@percepta/
|
|
52
|
-
"@percepta/
|
|
53
|
-
"@percepta/
|
|
54
|
-
"@percepta/utils": "^0.1.5",
|
|
51
|
+
"@percepta/design": "0.3.2",
|
|
52
|
+
"@percepta/logger": "0.0.6",
|
|
53
|
+
"@percepta/next-utils": "0.1.0",
|
|
54
|
+
"@percepta/utils": "0.1.10",
|
|
55
55
|
"@radix-ui/react-slot": "^1.2.3",
|
|
56
56
|
"@tanstack/react-query": "^5.81.5",
|
|
57
57
|
"@tanstack/react-virtual": "^3.13.12",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@next/eslint-plugin-next": "^15.3.5",
|
|
98
|
-
"@percepta/build": "
|
|
98
|
+
"@percepta/build": "0.4.0",
|
|
99
99
|
"@tailwindcss/postcss": "^4.1.11",
|
|
100
100
|
"@types/formidable": "^3.4.5",
|
|
101
101
|
"@types/he": "^1.2.3",
|