@percepta/create 3.1.0 → 3.1.3

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 (62) hide show
  1. package/README.md +15 -10
  2. package/dist/{chunk-7NPWSTCY.js → chunk-CO3YWUD6.js} +31 -2
  3. package/dist/{chunk-WMJT7CB5.js → chunk-V5EJIUBJ.js} +5 -2
  4. package/dist/index.js +93 -73
  5. package/dist/{init-NP6GRXLL.js → init-EQZ2TCSJ.js} +2 -2
  6. package/dist/{status-BTHGN6QH.js → status-QW5TQDYY.js} +1 -1
  7. package/dist/{sync-3Q27L7XZ.js → sync-RLBZDOFB.js} +1 -1
  8. package/dist/{upstream-C5KFAHVR.js → upstream-TQFVPMEG.js} +1 -1
  9. package/package.json +3 -2
  10. package/templates/monorepo/.dockerignore +18 -0
  11. package/templates/monorepo/gitignore.template +1 -0
  12. package/templates/webapp/.github/workflows/__APP_NAME__-ryvn-release.yaml +6 -2
  13. package/templates/webapp/.github/workflows/__APP_NAME__-terraform-ryvn-release.yaml +98 -0
  14. package/templates/webapp/AGENTS.md +17 -5
  15. package/templates/webapp/Dockerfile +16 -7
  16. package/templates/webapp/README.md +64 -2
  17. package/templates/webapp/agent-skills/deploy.md +50 -51
  18. package/templates/webapp/agent-skills/inngest.md +4 -4
  19. package/templates/webapp/agent-skills/langfuse.md +15 -14
  20. package/templates/webapp/agent-skills/llm.md +59 -0
  21. package/templates/webapp/agent-skills/oneshot.md +14 -1
  22. package/templates/webapp/agent-skills/ryvn.md +1 -1
  23. package/templates/webapp/deploy/README.md +41 -16
  24. package/templates/webapp/deploy/ryvn/__APP_NAME__-terraform.service.yaml +10 -0
  25. package/templates/webapp/deploy/ryvn/__APP_NAME__.service.yaml +2 -2
  26. package/templates/webapp/deploy/ryvn/environments/percepta-test/installations/__APP_NAME__-terraform.env.percepta-test.serviceinstallation.yaml +11 -0
  27. package/templates/webapp/deploy/ryvn/environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml +60 -11
  28. package/templates/webapp/env.example.template +20 -2
  29. package/templates/webapp/eslint.config.mjs +7 -0
  30. package/templates/webapp/gitignore.template +1 -0
  31. package/templates/webapp/next.config.ts +9 -0
  32. package/templates/webapp/package.json.template +6 -2
  33. package/templates/webapp/scripts/deploy-percepta-test.ts +837 -0
  34. package/templates/webapp/scripts/migrate.ts +3 -0
  35. package/templates/webapp/scripts/open-ryvn-deploy-pr.ts +152 -32
  36. package/templates/webapp/scripts/seed.ts +1 -1
  37. package/templates/webapp/scripts/setup-database.ts +2 -1
  38. package/templates/webapp/scripts/start.sh +3 -2
  39. package/templates/webapp/scripts/with-local-env.ts +75 -0
  40. package/templates/webapp/src/app/(app)/layout.tsx +1 -5
  41. package/templates/webapp/src/app/(auth)/auth/signin/CredentialsSignInForm.tsx +11 -1
  42. package/templates/webapp/src/app/(auth)/auth/signup/CredentialsSignUpForm.tsx +113 -0
  43. package/templates/webapp/src/app/(auth)/auth/signup/page.tsx +30 -0
  44. package/templates/webapp/src/app/global-error.tsx +1 -1
  45. package/templates/webapp/src/components/FaroProvider.tsx +2 -4
  46. package/templates/webapp/src/components/form/FormItem.tsx +2 -2
  47. package/templates/webapp/src/config/getEnvConfig.ts +14 -0
  48. package/templates/webapp/src/drizzle/db.ts +2 -1
  49. package/templates/webapp/src/drizzle/migrations/0000_eager_grandmaster.sql +3 -3
  50. package/templates/webapp/src/drizzle/migrations/meta/0000_snapshot.json +7 -19
  51. package/templates/webapp/src/drizzle/ssl.ts +5 -0
  52. package/templates/webapp/src/instrumentation.ts +102 -10
  53. package/templates/webapp/src/lib/auth/index.ts +1 -1
  54. package/templates/webapp/src/lib/auth-client.ts +1 -1
  55. package/templates/webapp/src/services/llm/LLMService.ts +88 -0
  56. package/templates/webapp/src/services/llm/LlmProviderService.ts +85 -0
  57. package/templates/webapp/src/services/observability/initFaro.ts +1 -1
  58. package/templates/webapp/terraform/schema/main.tf +4 -0
  59. package/templates/webapp/terraform/schema/outputs.tf +9 -0
  60. package/templates/webapp/terraform/schema/variables.tf +19 -0
  61. package/templates/webapp/terraform/schema/versions.tf +38 -0
  62. package/templates/webapp/.github/workflows/__APP_NAME__-terraform.yml +0 -28
@@ -0,0 +1,59 @@
1
+ # LLM Calls
2
+
3
+ Use this guide when the app needs backend model calls, streaming responses, or structured generation.
4
+
5
+ ## Default Pattern
6
+
7
+ Use `LLMService` from `src/services/llm/LLMService.ts`. Do not instantiate provider clients directly in routes, tRPC routers, or Inngest functions.
8
+
9
+ ```typescript
10
+ import { LLMService } from "@/services/llm/LLMService";
11
+
12
+ const result = await LLMService.create().generateText({
13
+ telemetryFunctionId: "summarize-document",
14
+ system: "You summarize documents for internal operators.",
15
+ prompt: `Summarize this document:\n\n${documentText}`,
16
+ });
17
+
18
+ return result.text;
19
+ ```
20
+
21
+ For streaming:
22
+
23
+ ```typescript
24
+ const stream = LLMService.create().streamText({
25
+ telemetryFunctionId: "chat-response",
26
+ system: "You are a concise assistant.",
27
+ messages,
28
+ });
29
+ ```
30
+
31
+ ## Providers
32
+
33
+ `LlmProviderService` chooses a provider at call time:
34
+
35
+ 1. `LLM_PROVIDER`, when explicitly set.
36
+ 2. Anthropic when `ANTHROPIC_API_KEY` is available.
37
+ 3. OpenAI when `OPENAI_API_KEY` is available.
38
+
39
+ `LLM_MODEL` can override the default model. A per-call `modelId` or `provider` passed to `LLMService` overrides env defaults.
40
+
41
+ ## Deployment
42
+
43
+ For `percepta-test`, `deploy:percepta-test` attaches the `demos-commons` Ryvn variable group. That group provides the shared `ANTHROPIC_API_KEY` and Langfuse project keys, so generated demo apps do not need per-app LLM secrets.
44
+
45
+ ## Local Development
46
+
47
+ Local LLM calls are optional. If needed, set a provider key once in your shell profile or `~/.config/percepta/create.env`:
48
+
49
+ ```bash
50
+ ANTHROPIC_API_KEY=sk-ant-...
51
+ ```
52
+
53
+ `pnpm dev` loads `~/.config/percepta/create.env` automatically. Do not put shared demo keys in committed files. Do not require local Langfuse or a local LGTM stack unless the task is specifically about telemetry.
54
+
55
+ ## Observability
56
+
57
+ `LLMService` enables AI SDK telemetry by default and attaches provider/model metadata to each call. When `LANGFUSE_*` values are configured, the template's OpenTelemetry bootstrap sends LLM spans to Langfuse. In `percepta-test`, those values are inherited from the environment.
58
+
59
+ Use a stable `telemetryFunctionId` for every meaningful LLM operation, such as `extract-invoice-fields` or `draft-member-message`.
@@ -78,12 +78,16 @@ Cover:
78
78
  2. **API routes** — which tRPC routers and procedures
79
79
  3. **Pages** — which routes/pages in the app
80
80
  4. **Background jobs** — which Inngest events and functions (if any)
81
- 5. **LLM integration** — which service to use, how to wire it (if any)
81
+ 5. **LLM integration** — use `LLMService` from `src/services/llm/LLMService.ts` when model calls are needed
82
82
 
83
83
  ### Decision: Langfuse
84
84
 
85
85
  Read [agent-skills/langfuse.md](langfuse.md) to understand Langfuse. **Use Langfuse if the app calls LLMs.** Skip it otherwise. The template already has the integration wired — you just need to ensure env vars are set.
86
86
 
87
+ ### Decision: LLM Calls
88
+
89
+ Read [agent-skills/llm.md](llm.md) when the app calls a model. Use `LLMService` for backend model calls and set a stable `telemetryFunctionId` for each LLM operation. Do not create provider clients directly in app code.
90
+
87
91
  ### Decision: Inngest
88
92
 
89
93
  Read [agent-skills/inngest.md](inngest.md) to understand Inngest. **Use Inngest if the app has background jobs, scheduled tasks, or multi-step agent pipelines.** The template has the scaffold — you add events and functions.
@@ -125,6 +129,7 @@ If it fails, fix the errors before moving to the next chunk. Do not accumulate b
125
129
  - **Use robust loading states.** `@percepta/components` is optional; add it first if you want `AsyncContent`.
126
130
  - **Use `getEnvConfig()` for env vars.** Never use `process.env` directly.
127
131
  - **Use `getLogger()` for logging.** Never use `console.log`. Use safe/unsafe field separation.
132
+ - **Use `LLMService` for model calls.** It handles provider selection and Langfuse/OTEL telemetry metadata.
128
133
  - **Follow the singleton pattern** for new services. Follow the existing `DatabaseService` singleton pattern in the codebase.
129
134
  - **Use `protectedProcedure`** for authenticated tRPC routes.
130
135
 
@@ -141,6 +146,14 @@ pnpm docker:up
141
146
  pnpm db:setup-and-migrate
142
147
  ```
143
148
 
149
+ If the app uses Inngest functions, start the local Inngest dev server in a separate terminal:
150
+
151
+ ```bash
152
+ pnpm inngest:dev
153
+ ```
154
+
155
+ Do not start local LGTM, OTEL collector, Faro, or Langfuse services unless the task is specifically about telemetry. Those integrations are optional locally and are wired by the Ryvn environment for deploys.
156
+
144
157
  ### Step 2: Start the dev server
145
158
 
146
159
  ```bash
@@ -8,7 +8,7 @@ Ryvn is the deployment platform used by Percepta to manage cloud infrastructure.
8
8
  |-------------|---------|---------------|
9
9
  | `percepta-test` | Internal dev/test | `<app>.percepta-test.aitco.dev` |
10
10
 
11
- New apps are deployed to **percepta-test**. This environment has a shared PostgreSQL instance, Inngest server, Langfuse, and OTEL collector.
11
+ New apps are deployed to **percepta-test** using the existing-environment deploy motion. This environment must already have shared PostgreSQL, Inngest, OTEL collector, LGTM stack, and Langfuse installations before app deploys run. The service installation points at the shared Langfuse URL and attaches the `demos-commons` variable group for shared demo Langfuse project keys.
12
12
 
13
13
  ## Deploying This App
14
14
 
@@ -1,41 +1,66 @@
1
1
  # Deploy
2
2
 
3
- This directory holds infrastructure-as-code for deploying __APP_TITLE__ to Percepta environments.
3
+ This directory holds Ryvn infrastructure-as-code for deploying __APP_TITLE__ to Percepta environments.
4
4
 
5
5
  ```
6
6
  deploy/
7
7
  └── ryvn/
8
- ├── __APP_NAME__.service.yaml # Ryvn Service definition
8
+ ├── __APP_NAME__.service.yaml
9
+ ├── __APP_NAME__-terraform.service.yaml
9
10
  └── environments/
10
11
  └── percepta-test/
11
12
  └── installations/
12
- └── __APP_NAME__.env.percepta-test.serviceinstallation.yaml # percepta-test installation
13
+ ├── __APP_NAME__.env.percepta-test.serviceinstallation.yaml
14
+ └── __APP_NAME__-terraform.env.percepta-test.serviceinstallation.yaml
13
15
  ```
14
16
 
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.
17
+ These files deploy to `https://__APP_NAME__.percepta-test.aitco.dev`.
18
+
19
+ The default deploy helper performs the existing-environment deploy motion: it assumes the target Ryvn environment already has the shared platform services installed, then wires this app into them. For `percepta-test`, that means shared Postgres, Inngest, the OTEL collector, the LGTM stack, and Langfuse must already exist before app deploy starts. Fresh-environment platform bootstrap is a separate motion and should be handled by a Ryvn blueprint or environment-specific platform rollout.
20
+
21
+ The helper talks directly to Ryvn: it preflights the existing platform services, creates/updates the services, runs the GitHub Actions release workflows, creates the schema installation, approves the schema Terraform plan, creates the web installation, patches generated secrets, waits for health, and verifies the health and app routes.
16
22
 
17
23
  ## Deploying
18
24
 
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.
25
+ Tell Claude "deploy this app to percepta-test" or run:
26
+
27
+ ```bash
28
+ pnpm deploy:percepta-test -- --yes
29
+ ```
30
+
31
+ The helper expects a clean, committed git worktree because GitHub Actions builds from the pushed repo. It can create `Percepta-Core/__REPO_NAME__` if it does not exist yet, and it pushes the current branch to `main` before triggering releases.
20
32
 
21
33
  ## What's in these files
22
34
 
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.
35
+ **`__APP_NAME__.service.yaml`** — Ryvn server service for the web app. It points at `Percepta-Core/__REPO_NAME__` and builds from `packages/__APP_NAME__/`.
36
+
37
+ **`__APP_NAME__-terraform.service.yaml`** — Ryvn Terraform service that owns the per-app Postgres schema in the shared `demos` database.
38
+
39
+ **`__APP_NAME__.env.percepta-test.serviceinstallation.yaml`** — web app installation for `percepta-test`. It wires the shared platform services, ingress, health probes, database connection, Inngest, OTEL/LGTM telemetry, the Langfuse base URL, and the shared demo variable group.
40
+
41
+ **`__APP_NAME__-terraform.env.percepta-test.serviceinstallation.yaml`** — schema installation for `percepta-test`.
42
+
43
+ **`percepta-test.secrets.env`** — generated locally and ignored by git. The deploy helper patches app-specific auth/encryption secrets into the Ryvn installation; shared Langfuse and LLM demo keys are inherited from a Ryvn variable group.
44
+
45
+ ## Platform Wiring
24
46
 
25
- **`__APP_NAME__.env.percepta-test.serviceinstallation.yaml`** configures the deployment on `percepta-test`. Three categories of values are baked in:
47
+ `pnpm deploy:percepta-test` checks these existing `percepta-test` installations before it mutates GitHub or Ryvn app resources:
26
48
 
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.
49
+ - `percepta-internal-terraform` for the shared Postgres instance.
50
+ - `inngest-test` for background jobs and function callbacks.
51
+ - `otel-collector` for trace, metric, and log collection.
52
+ - `lgtm-stack-helm` for Loki, Grafana, Tempo, and Mimir.
53
+ - `langfuse` for LLM tracing and eval observability.
54
+ - `demos-commons` variable group for shared demo configuration, including the Anthropic API key and Langfuse demo project keys.
30
55
 
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.
56
+ The service installation sets `LANGFUSE_BASE_URL` to the shared `percepta-test` Langfuse URL, sets `LLM_PROVIDER=anthropic`, and attaches `demos-commons` for `ANTHROPIC_API_KEY`, `LANGFUSE_PUBLIC_KEY`, and sensitive `LANGFUSE_SECRET_KEY`. Individual demo apps do not need LLM or Langfuse keys in `percepta-test.secrets.env`.
32
57
 
33
- ## Repo layout note
58
+ ## Notes
34
59
 
35
- These files assume this repo is a **monorepo** with the app at `packages/__APP_NAME__/` (the layout produced by `@percepta/create`). The `service.yaml` sets `context: packages/__APP_NAME__` accordingly. If you've flattened this into a single-package repo, change `context:` and `dockerfile:` to `.` and `Dockerfile`.
60
+ The release workflows live at the repo root under `.github/workflows/`. The web workflow uses the org-level `NPM_TOKEN` secret for private `@percepta/*` packages; do not add a repo-level token unless the org secret is unavailable.
36
61
 
37
- The release workflow lives at `.github/workflows/__APP_NAME__-ryvn-release.yaml` (at the repo root, where GitHub Actions picks it up). It's path-filtered to `packages/__APP_NAME__/`, so changes to other packages won't trigger this app's deploy. Multiple webapps in the same monorepo each get their own `<name>-ryvn-release.yaml` and don't collide.
62
+ For the old GitOps PR path, use `pnpm deploy:percepta-test:pr -- --phase service --yes` and then `pnpm deploy:percepta-test:pr -- --phase installation --yes`.
38
63
 
39
- ## Adding more environments
64
+ ## Adding More Environments
40
65
 
41
- Copy `environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml` to a new `environments/<env>/installations/__APP_NAME__.env.<env>.serviceinstallation.yaml` and change the `environment:`, host, and any environment-specific values.
66
+ Copy the two `percepta-test` installation manifests to `environments/<env>/installations/`, then change the `environment:`, host, and environment-specific config.
@@ -0,0 +1,10 @@
1
+ kind: Service
2
+ metadata:
3
+ name: __APP_NAME__-terraform
4
+ spec:
5
+ type: terraform
6
+ repo: Percepta-Core/__REPO_NAME__
7
+ autoApprove: false
8
+ build:
9
+ path: packages/__APP_NAME__/terraform/schema
10
+ tagPrefix: __APP_NAME__-terraform@
@@ -3,7 +3,7 @@ metadata:
3
3
  name: __APP_NAME__
4
4
  spec:
5
5
  type: server
6
- repo: Percepta-Core/__APP_NAME__
6
+ repo: Percepta-Core/__REPO_NAME__
7
7
  build:
8
- context: packages/__APP_NAME__
8
+ context: .
9
9
  dockerfile: packages/__APP_NAME__/Dockerfile
@@ -0,0 +1,11 @@
1
+ kind: ServiceInstallation
2
+ metadata:
3
+ name: __APP_NAME__-terraform
4
+ spec:
5
+ service: __APP_NAME__-terraform
6
+ environment: percepta-test
7
+ config: |
8
+ aws_region: {{ .ryvn.env.state.cluster_region }}
9
+ database_secret_name: {{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_secrets_manager_secret_name }}
10
+ database_name: demos
11
+ schema_name: __APP_NAME_SNAKE__
@@ -10,8 +10,23 @@ spec:
10
10
  service:
11
11
  port: 3000
12
12
 
13
+ startupEnabled: true
14
+ startupProbe:
15
+ httpGet:
16
+ path: /api/healthz
17
+ port: 3000
18
+ failureThreshold: 30
19
+ periodSeconds: 10
13
20
  livenessEnabled: true
21
+ livenessProbe:
22
+ httpGet:
23
+ path: /api/healthz
24
+ port: 3000
14
25
  readinessEnabled: true
26
+ readinessProbe:
27
+ httpGet:
28
+ path: /api/readyz
29
+ port: 3000
15
30
 
16
31
  resources:
17
32
  requests:
@@ -39,8 +54,9 @@ spec:
39
54
 
40
55
  env:
41
56
  # 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.
57
+ # Tables live under a per-app schema created by the __APP_NAME__-terraform
58
+ # Ryvn service. DATABASE_SCHEMA pins the connection search_path so Drizzle
59
+ # migrations + queries land there.
44
60
  - name: DATABASE_HOST
45
61
  valueFrom:
46
62
  secretKeyRef:
@@ -78,13 +94,11 @@ spec:
78
94
  value: https://__APP_NAME__.percepta-test.aitco.dev
79
95
  - key: BETTER_AUTH_URL
80
96
  value: https://__APP_NAME__.percepta-test.aitco.dev
81
- # Set these in Ryvn after the infra PR merges.
82
- - key: BETTER_AUTH_SECRET
83
- isSecret: true
84
- - key: ENCRYPTION_SECRET_KEY
85
- isSecret: true
97
+ # deploy:percepta-test patches BETTER_AUTH_SECRET and ENCRYPTION_SECRET_KEY
98
+ # from deploy/ryvn/percepta-test.secrets.env after the installation exists.
99
+ # Secret values are intentionally not declared in GitOps IaC.
86
100
 
87
- # Inngest (shared percepta-test instance)
101
+ # Inngest (shared percepta-test platform service)
88
102
  - key: INNGEST_BASE_URL
89
103
  value: http://inngest.percepta-test.svc.cluster.local:8288
90
104
  - key: INNGEST_EVENT_KEY
@@ -96,10 +110,45 @@ spec:
96
110
  - key: INNGEST_SERVE_HOST
97
111
  value: http://__APP_NAME__-web-server.percepta-test.svc.cluster.local:3000/api/inngest
98
112
 
99
- # OpenTelemetry
100
- - key: OTEL_METRICS_EXPORTER_OTLP_ENDPOINT
113
+ # Observability (shared percepta-test OTEL collector + LGTM stack)
114
+ # Application logs are emitted to stdout and collected by the shared OTEL
115
+ # collector. Traces and metrics are exported over OTLP HTTP.
116
+ - key: OTEL_SERVICE_NAME
117
+ value: __APP_NAME__
118
+ - key: OTEL_RESOURCE_ATTRIBUTES
119
+ value: service.namespace=__REPO_NAME__,deployment.environment=percepta-test
120
+ - key: OTEL_TRACES_EXPORTER
121
+ value: otlp
122
+ - key: OTEL_METRICS_EXPORTER
123
+ value: otlp
124
+ - key: OTEL_LOGS_EXPORTER
125
+ value: none
126
+ - key: OTEL_EXPORTER_OTLP_PROTOCOL
127
+ value: http/protobuf
128
+ - key: OTEL_EXPORTER_OTLP_ENDPOINT
129
+ value: http://otel-collector-opentelemetry-collector.percepta-test.svc.cluster.local:4318
130
+ - key: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
131
+ value: http://otel-collector-opentelemetry-collector.percepta-test.svc.cluster.local:4318/v1/traces
132
+ - key: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
101
133
  value: http://otel-collector-opentelemetry-collector.percepta-test.svc.cluster.local:4318/v1/metrics
102
- - key: OTEL_EXPORT_INTERVAL_MS
134
+ - key: OTEL_METRIC_EXPORT_INTERVAL
103
135
  value: "60000"
136
+ - key: NEXT_PUBLIC_FARO_APP_NAME
137
+ value: __APP_NAME__
138
+ - key: NEXT_PUBLIC_FARO_APP_VERSION
139
+ value: "0.1.0"
140
+ - key: NEXT_PUBLIC_FARO_APP_ENVIRONMENT
141
+ value: percepta-test
104
142
  - key: LOG_LEVEL
105
143
  value: debug
144
+
145
+ # Langfuse (shared percepta-test platform service). Project keys come from
146
+ # the demos-commons Ryvn variable group below.
147
+ - key: LANGFUSE_BASE_URL
148
+ value: https://langfuse.percepta-test.aitco.dev
149
+
150
+ # LLM provider (shared demo Anthropic key comes from demos-commons).
151
+ - key: LLM_PROVIDER
152
+ value: anthropic
153
+ variableGroups:
154
+ - name: demos-commons
@@ -19,9 +19,9 @@ BETTER_AUTH_URL=http://localhost:3000
19
19
  ENCRYPTION_SECRET_KEY=generate-with-node-e-console-log-require-crypto-randomBytes-16-toString-hex
20
20
 
21
21
  # Inngest (Background Jobs)
22
- # INNGEST_BASE_URL=
22
+ INNGEST_BASE_URL=http://localhost:8288
23
23
  # INNGEST_SIGNING_KEY=
24
- # INNGEST_EVENT_KEY=
24
+ INNGEST_EVENT_KEY=local
25
25
 
26
26
  # Grafana Faro (client-side observability)
27
27
  # Leave NEXT_PUBLIC_FARO_COLLECTOR_URL empty to disable in local development.
@@ -36,6 +36,24 @@ NEXT_PUBLIC_FARO_APP_ENVIRONMENT=development
36
36
  # LANGFUSE_PUBLIC_KEY=
37
37
  # LANGFUSE_SECRET_KEY=
38
38
 
39
+ # LLM providers
40
+ # Deployed percepta-test apps inherit ANTHROPIC_API_KEY from the demos-commons
41
+ # Ryvn variable group. For local LLM testing, set ANTHROPIC_API_KEY once in your
42
+ # shell profile or ~/.config/percepta/create.env.
43
+ # ANTHROPIC_API_KEY=
44
+ # OPENAI_API_KEY=
45
+ # LLM_PROVIDER=anthropic
46
+ # LLM_MODEL=claude-sonnet-4-5-20250929
47
+
48
+ # OpenTelemetry (server-side traces and metrics)
49
+ # OTEL_SERVICE_NAME=__APP_NAME__
50
+ # OTEL_TRACES_EXPORTER=otlp
51
+ # OTEL_METRICS_EXPORTER=otlp
52
+ # OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
53
+ # OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
54
+ # OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
55
+ # OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4318/v1/metrics
56
+
39
57
  # AWS (uses default credential chain in development)
40
58
  # AWS_REGION=us-east-1
41
59
  # AWS_ACCESS_KEY_ID=
@@ -11,6 +11,7 @@ export default [
11
11
  {
12
12
  ignores: [
13
13
  "pnpm-lock.yaml",
14
+ "package.json",
14
15
  ".next/**",
15
16
  "next-env.d.ts",
16
17
  "public/**",
@@ -56,4 +57,10 @@ export default [
56
57
  "n/no-process-env": "off",
57
58
  },
58
59
  },
60
+ {
61
+ files: ["scripts/with-local-env.ts"],
62
+ rules: {
63
+ "n/no-process-env": "off",
64
+ },
65
+ },
59
66
  ];
@@ -33,6 +33,7 @@ yarn-error.log*
33
33
  # env files (can opt-in for committing if needed)
34
34
  .env*
35
35
  !.env.example
36
+ deploy/ryvn/*.secrets.env
36
37
 
37
38
  # vercel
38
39
  .vercel
@@ -1,8 +1,17 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
1
3
  import type { NextConfig } from "next";
2
4
 
5
+ const appDir = path.dirname(fileURLToPath(import.meta.url));
6
+ const monorepoRoot = path.resolve(appDir, "../..");
7
+
3
8
  const nextConfig: NextConfig = {
4
9
  // Enable standalone output for Docker:
5
10
  output: "standalone",
11
+ outputFileTracingRoot: monorepoRoot,
12
+ turbopack: {
13
+ root: monorepoRoot,
14
+ },
6
15
  };
7
16
 
8
17
  export default nextConfig;
@@ -6,13 +6,14 @@
6
6
  "node": ">=18.0.0"
7
7
  },
8
8
  "scripts": {
9
- "dev": "next dev --turbopack",
9
+ "dev": "tsx ./scripts/with-local-env.ts next dev --turbopack",
10
10
  "build": "next build",
11
11
  "start": "next start",
12
12
  "lint": "eslint .",
13
13
  "setup": "pnpm docker:up && pnpm db:setup-and-migrate && pnpm db:seed",
14
14
  "docker:up": "docker compose up -d",
15
15
  "docker:down": "docker compose down",
16
+ "inngest:dev": "pnpm dlx inngest-cli@latest dev -u http://localhost:3000/api/inngest",
16
17
  "db:generate": "drizzle-kit generate",
17
18
  "db:migrate": "tsx ./scripts/migrate.ts",
18
19
  "db:setup": "tsx ./scripts/setup-database.ts",
@@ -21,11 +22,13 @@
21
22
  "db:studio": "drizzle-kit studio",
22
23
  "db:create-user": "tsx ./scripts/create-user.ts",
23
24
  "db:seed": "tsx ./scripts/seed.ts",
24
- "deploy:percepta-test": "tsx ./scripts/open-ryvn-deploy-pr.ts",
25
+ "deploy:percepta-test": "tsx ./scripts/deploy-percepta-test.ts",
26
+ "deploy:percepta-test:pr": "tsx ./scripts/open-ryvn-deploy-pr.ts",
25
27
  "test": "vitest run",
26
28
  "test:watch": "vitest"
27
29
  },
28
30
  "dependencies": {
31
+ "@ai-sdk/anthropic": "^2.0.23",
29
32
  "@ai-sdk/openai": "^2.0.23",
30
33
  "@aws-sdk/client-s3": "^3.888.0",
31
34
  "@aws-sdk/client-secrets-manager": "^3.914.0",
@@ -47,6 +50,7 @@
47
50
  "@next/env": "^15.3.5",
48
51
  "@opentelemetry/api": "^1.9.0",
49
52
  "@opentelemetry/auto-instrumentations-node": "^0.62.1",
53
+ "@opentelemetry/exporter-trace-otlp-proto": "^0.203.0",
50
54
  "@opentelemetry/sdk-node": "^0.203.0",
51
55
  "@percepta/design": "0.3.2",
52
56
  "@percepta/logger": "0.0.6",