@tpsdev-ai/flair 0.32.0 → 0.34.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 +64 -64
- package/SECURITY.md +7 -0
- package/config.yaml +34 -0
- package/dist/cli.js +659 -111
- package/dist/component-env.js +286 -0
- package/dist/deploy.js +190 -3
- package/dist/doctor-client.js +357 -7
- package/dist/hook-install.js +39 -9
- package/dist/lib/auth-resolve.js +85 -2
- package/dist/lib/launchd-management.js +328 -0
- package/dist/lib/mcp-enable.js +19 -0
- package/dist/resources/AdminInstance.js +20 -2
- package/dist/resources/Memory.js +24 -2
- package/dist/resources/OAuth.js +41 -25
- package/dist/resources/auth-middleware.js +26 -0
- package/dist/resources/dcr-gate.js +194 -0
- package/dist/resources/in-process-api.js +5 -1
- package/dist/resources/mcp-handler.js +91 -4
- package/dist/resources/mcp-oauth.js +89 -7
- package/dist/resources/mcp-tools.js +40 -0
- package/dist/resources/oauth-discovery.js +242 -0
- package/dist/resources/oauth-wellknown.js +111 -0
- package/dist/resources/rate-limit.js +400 -0
- package/docs/auth.md +122 -5
- package/docs/deploying-on-fabric.md +35 -2
- package/docs/deployment.md +1 -1
- package/docs/embedding-in-a-harper-app.md +6 -1
- package/docs/hosted-on-fabric.md +1 -1
- package/docs/mcp-clients.md +28 -4
- package/docs/quickstart.md +29 -4
- package/docs/the-team.md +8 -4
- package/docs/troubleshooting.md +37 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,55 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
> **The identity and memory substrate for AI agents. Crypto-pinned. Federated. Self-hosted.**
|
|
8
8
|
|
|
9
|
-
Every agent framework gives you chat history. None give you *identity*. Flair gives an agent three things that survive a restart and follow it between orchestrators:
|
|
10
|
-
|
|
11
|
-
- **Identity** — an Ed25519 keypair. The agent signs every request. No shared secrets.
|
|
12
|
-
- **Memory** — persistent knowledge with semantic search, embedded in-process. No API calls.
|
|
13
|
-
- **Soul** — the personality, values and procedures that make it *that* agent.
|
|
14
|
-
|
|
15
|
-
Self-hosted on [Harper](https://harper.fast) as a single process. No sidecars, no vector database, no embedding API.
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
┌──────────────────────────────────────────────────────────────────┐
|
|
19
|
-
│ same agent, same memory, every harness │
|
|
20
|
-
│ │
|
|
21
|
-
│ Claude Code ─┐ │
|
|
22
|
-
│ Cursor ─┤ │
|
|
23
|
-
│ Codex CLI ─┼─[ flair-mcp ]─┐ │
|
|
24
|
-
│ Gemini CLI ─┤ │ │
|
|
25
|
-
│ Continue.dev ─┤ │ ┌──────────────────────┐ │
|
|
26
|
-
│ Goose ─┘ ├─▶ │ Flair (self-hosted) │ │
|
|
27
|
-
│ LangGraph ─[ langgraph-flair ]──│ Ed25519 / HNSW / │ │
|
|
28
|
-
│ OpenClaw ─[ openclaw-flair ]──│ Soul + Memory │ │
|
|
29
|
-
│ n8n ─[ n8n-nodes-flair ]──└──────────┬───────────┘ │
|
|
30
|
-
│ Hermes ─[ hermes-flair ]─┘ │ federation │
|
|
31
|
-
│ Pi agent ─[ pi-flair ]─┘ │ (hub/spoke) │
|
|
32
|
-
│ ▼ │
|
|
33
|
-
│ ┌──────────────────────┐ │
|
|
34
|
-
│ │ Flair (Fabric hub) │ │
|
|
35
|
-
│ └──────────────────────┘ │
|
|
36
|
-
└──────────────────────────────────────────────────────────────────┘
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
11 harness surfaces today. Pick whichever you're shipping in; the memory layer doesn't care. **[Full integrations catalog →](docs/integrations.md)**
|
|
9
|
+
Every agent framework gives you chat history. None give you *identity*. Flair gives an agent three things that survive a restart and follow it between orchestrators: an **identity** it proves with an Ed25519 keypair, **memory** it searches by meaning rather than by keyword, and a **soul** — the personality, values and procedures that make it *that* agent.
|
|
40
10
|
|
|
41
11
|
## Quick start
|
|
42
12
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
### Already on Harper? Load Flair as a component
|
|
46
|
-
|
|
47
|
-
Flair *is* a Harper component. Deploy it into the instance your application already runs in and call its resources directly — `await h.post({ agentId, content })` is a **method call**, not a network call. No second service to operate, no HTTP round trip, and no key to distribute: a caller in the same process is already inside the trust boundary and names the agent it is acting as, per call.
|
|
48
|
-
|
|
49
|
-
Adding it takes nothing away. The HTTP surface keeps serving MCP clients and remote agents exactly as before.
|
|
50
|
-
|
|
51
|
-
**→ [Embedding Flair in a Harper app](docs/embedding-in-a-harper-app.md)** — the whole in-process contract, measured against a real instance: resolving the resource, the table-vs-resource distinction that decides whether your memories are scoped at all, N agents in one process, and registering agents with no shell on the node.
|
|
52
|
-
|
|
53
|
-
### Everywhere else — install the CLI
|
|
54
|
-
|
|
55
|
-
A laptop, a VPS, an MCP client, or any language over HTTP. Needs **Node.js 22+** and a **user-writable npm global prefix**.
|
|
56
|
-
|
|
57
|
-
> ⚠️ **Never `sudo npm install -g @tpsdev-ai/flair`.** A root-owned install can't write the embedding model into its own package directory, so semantic search silently degrades to keyword-only. `flair init` and `flair doctor` will warn you loudly. Use `nvm`, or point npm at your home directory: `npm config set prefix ~/.npm-global` and add `~/.npm-global/bin` to `PATH`.
|
|
13
|
+
Runs on a laptop, a VPS, or anywhere Node does. Needs **Node.js 22+**.
|
|
58
14
|
|
|
59
15
|
```bash
|
|
60
16
|
# 1. Install the CLI (no sudo)
|
|
@@ -79,19 +35,30 @@ Step 4 finds the memory you never keyword-matched:
|
|
|
79
35
|
|
|
80
36
|
That trailing figure is a rank score, normalized so the top hit is always near 100% — ordering, not confidence.
|
|
81
37
|
|
|
82
|
-
`flair init` installs and starts Harper, creates the agent's Ed25519 keypair, verifies semantic search actually works, wires every MCP client it detects (Claude Code, Cursor, Codex CLI, Gemini CLI)
|
|
38
|
+
`flair init` installs and starts Harper, creates the agent's Ed25519 keypair, verifies semantic search actually works, wires every MCP client it detects (Claude Code, Cursor, Codex CLI, Gemini CLI), and runs a smoke test. Restart your MCP client afterwards, then ask the agent *"what do you remember about me?"*
|
|
83
39
|
|
|
84
40
|
> **Pass `--agent`.** A bare `flair init` bootstraps the instance and stops there — no agent, no keypair, no MCP wiring.
|
|
85
41
|
|
|
86
42
|
Full walkthrough with expected output at every step: **[docs/quickstart.md](docs/quickstart.md)**.
|
|
87
43
|
|
|
44
|
+
### One install, one binary
|
|
45
|
+
|
|
46
|
+
`npm install -g @tpsdev-ai/flair` puts a single command on your `PATH`: `flair`. That is the whole install, and it needs a **user-writable npm global prefix** — which is why step 1 says *no sudo*. A root-owned install can't write the embedding model into its own package directory, so semantic search silently degrades to keyword-only. Use `nvm`, or point npm at your home directory — `npm config set prefix ~/.npm-global`, then add `~/.npm-global/bin` to `PATH`. `flair init` and `flair doctor` both check for this and say so loudly.
|
|
47
|
+
|
|
48
|
+
Two different things get called "MCP" here, and you get them differently:
|
|
49
|
+
|
|
50
|
+
- **The server has an MCP surface built in.** `/mcp` is a JSON-RPC endpoint exposing 12 curated tools, guarded by OAuth bearer tokens. It ships inside the package — and it is **off by default**: until you set `FLAIR_MCP_OAUTH` *and* a public issuer (`FLAIR_MCP_ISSUER`, falling back to `FLAIR_PUBLIC_URL`), no `/mcp` route is registered and the path returns 404. No documented client setup uses it today.
|
|
51
|
+
- **What your MCP client actually talks to is a separate package** — `@tpsdev-ai/flair-mcp`, a stdio adapter — and that one is deliberately not installed globally. `flair init` writes `npx -y @tpsdev-ai/flair-mcp@<version>` into each client's config, pinned to the CLI's own version, so the client fetches it on demand and there is no second global package to keep in step.
|
|
52
|
+
|
|
53
|
+
`@tpsdev-ai/flair-client` is likewise its own package: add it to a project when you want to call Flair from your own code ([JavaScript / TypeScript](#javascript--typescript)).
|
|
54
|
+
|
|
88
55
|
### Where the agent's key lives
|
|
89
56
|
|
|
90
57
|
`flair init --agent mybot` writes the private key to `~/.flair/keys/mybot.key` (mode `0600`) and the public half beside it as `mybot.pub`. Only the **public** key is registered on the instance; the private key never leaves the machine. `--keys-dir` writes both somewhere else.
|
|
91
58
|
|
|
92
59
|
**Back that file up — it is the agent's identity, and there is one copy.** Memories are not encrypted with it, so losing it costs the identity, not the data: the agent can no longer sign, and every HTTP call it makes fails. Recovery is `flair agent rotate-key mybot`, which mints a new pair and re-registers the public half — it needs the admin password `flair init` wrote to `~/.flair/admin-pass`, so back that up too. Otherwise treat the key like an SSH key: one per agent per host, never copied between machines ([docs/secrets-and-keys.md](docs/secrets-and-keys.md)).
|
|
93
60
|
|
|
94
|
-
|
|
61
|
+
Keys are how an agent *outside* the process proves who it is. Code running inside the same Harper instance needs no key at all — see [Embedded in a Harper app](#embedded-in-a-harper-app-in-process).
|
|
95
62
|
|
|
96
63
|
### Useful flags
|
|
97
64
|
|
|
@@ -138,9 +105,35 @@ Write a memory, then find it by meaning. The same memory is visible to every har
|
|
|
138
105
|
|
|
139
106
|
One Ed25519 identity, one memory store, three MCP-capable CLIs. A memory written from Claude Code is retrievable from Codex CLI and Gemini CLI a moment later. Identity and history aren't bound to one orchestrator's runtime.
|
|
140
107
|
|
|
108
|
+
## One agent, every harness
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
112
|
+
│ same agent, same memory, every harness │
|
|
113
|
+
│ │
|
|
114
|
+
│ Claude Code ─┐ │
|
|
115
|
+
│ Cursor ─┤ │
|
|
116
|
+
│ Codex CLI ─┼─[ flair-mcp ]─┐ │
|
|
117
|
+
│ Gemini CLI ─┤ │ │
|
|
118
|
+
│ Continue.dev ─┤ │ ┌──────────────────────┐ │
|
|
119
|
+
│ Goose ─┘ ├─▶ │ Flair (self-hosted) │ │
|
|
120
|
+
│ LangGraph ─[ langgraph-flair ]──│ Ed25519 / HNSW / │ │
|
|
121
|
+
│ OpenClaw ─[ openclaw-flair ]──│ Soul + Memory │ │
|
|
122
|
+
│ n8n ─[ n8n-nodes-flair ]──└──────────┬───────────┘ │
|
|
123
|
+
│ Hermes ─[ hermes-flair ]─┘ │ federation │
|
|
124
|
+
│ Pi agent ─[ pi-flair ]─┘ │ (hub/spoke) │
|
|
125
|
+
│ ▼ │
|
|
126
|
+
│ ┌──────────────────────┐ │
|
|
127
|
+
│ │ Flair (Fabric hub) │ │
|
|
128
|
+
│ └──────────────────────┘ │
|
|
129
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
11 harness surfaces today. Pick whichever you're shipping in; the memory layer doesn't care. **[Full integrations catalog →](docs/integrations.md)**
|
|
133
|
+
|
|
141
134
|
## How it works
|
|
142
135
|
|
|
143
|
-
Flair is a native [Harper v5](https://harper.fast) application. Harper handles HTTP, persistence (RocksDB), and application logic in one process.
|
|
136
|
+
Flair is a native [Harper v5](https://harper.fast) application. Harper handles HTTP, persistence (RocksDB), and application logic in one process — self-hosted, with no sidecars, no vector database and no embedding API.
|
|
144
137
|
|
|
145
138
|
```
|
|
146
139
|
Agent ──[Ed25519-signed request]──▶ Flair (Harper)
|
|
@@ -178,24 +171,22 @@ See **[DESIGN.md](DESIGN.md)** for the invariants behind the three primitives
|
|
|
178
171
|
| **Web admin** | Server-rendered UI for principals, connectors, IdPs and instance config. No separate dashboard service. |
|
|
179
172
|
| **Benchmarks** | [`flair-bench`](packages/flair-bench/README.md) scores candidate embedding models against the same recall corpus Flair's CI gates on. Runs standalone — no Flair install, no server. |
|
|
180
173
|
|
|
181
|
-
Trust-graded recall reaches the authenticated HTTP API and the
|
|
174
|
+
Trust-graded recall reaches the authenticated HTTP API and the built-in `/mcp` tools today — the latter being off by default, see [One install, one binary](#one-install-one-binary). CLI, `@tpsdev-ai/flair-client` and `flair-mcp` exposure is a follow-up. REM needs a configured generative backend (Ollama, OpenAI, Anthropic, …) — without one, `flair rem rapid` fails with `Reflection error: No generative backend configured`.
|
|
182
175
|
|
|
183
176
|
## How Flair compares
|
|
184
177
|
|
|
185
|
-
|
|
186
|
-
|---|---|---|---|---|---|
|
|
187
|
-
| **Identity model** | **Ed25519 per agent (crypto-pinned)** | tenant-isolation | per-user soft tenant | runtime-bound | account-scoped |
|
|
188
|
-
| **Federation (peer-to-peer)** | **yes — hub/spoke validated** | no | no | no | no |
|
|
189
|
-
| **Cross-orchestrator** | **11+ harnesses, same memory** | several | several | runtime-bound | vendor-locked |
|
|
190
|
-
| **Soul / persistent character** | **first-class** | optional | persona-shaped | optional | no |
|
|
191
|
-
|
|
192
|
-
Parity rows are omitted: Mem0, Honcho and Letta are all open-source, self-hostable, and do semantic search. Those are table stakes here.
|
|
178
|
+
Every product here does semantic recall over stored memories. These are the dimensions they actually differ on.
|
|
193
179
|
|
|
194
|
-
|
|
180
|
+
| | Flair | Mem0 | Honcho | Letta (MemGPT) | [SageOx](https://sageox.ai) | Built-ins (OAI/Anthropic/Google) |
|
|
181
|
+
|---|---|---|---|---|---|---|
|
|
182
|
+
| **Where memories live** | infrastructure you run | self-host or Mem0 Cloud | self-host or hosted API | self-host or Letta Cloud | SageOx cloud | vendor cloud |
|
|
183
|
+
| **Memory is scoped to** | the agent, via an Ed25519 keypair | tenant / user | per-user tenant | the runtime | the team | the account |
|
|
184
|
+
| **Reaches other orchestrators** | 11 harnesses, incl. workflow and agent frameworks | several | several | Letta's runtime | 14+ coding agents and editors, via hooks, plugins and instruction files | no |
|
|
185
|
+
| **Sync between instances you run** | hub/spoke federation | no | no | no | one hosted service | one hosted service |
|
|
186
|
+
| **Captures in-person conversation** | no | no | no | no | yes — Ox Dot | no |
|
|
187
|
+
| **Per-agent persistent character** | first-class (Soul) | optional | persona-shaped | optional | team context, not per-agent | no |
|
|
195
188
|
|
|
196
|
-
- Mem0's
|
|
197
|
-
- Honcho's **persona model** is more developed, if rich personality modeling is the priority.
|
|
198
|
-
- Letta's **runtime integration** is tighter, if you're building on their agent loop.
|
|
189
|
+
**Where Flair loses.** [SageOx's Ox Dot](https://sageox.ai) records in-person meetings, standups and whiteboard sessions and pipes them into shared context; Flair has no ambient capture of anything that isn't already text in a tool. Mem0's hosted sync is more polished. Honcho's persona model is more developed. Letta's integration with its own agent loop is tighter than anything Flair offers. And there is no Flair-operated cloud — running it is your job.
|
|
199
190
|
|
|
200
191
|
## Integration
|
|
201
192
|
|
|
@@ -298,7 +289,11 @@ Sign `agentId:timestamp:nonce:METHOD:/path` with the agent's private key. Protoc
|
|
|
298
289
|
|
|
299
290
|
### Embedded in a Harper app (in-process)
|
|
300
291
|
|
|
301
|
-
|
|
292
|
+
The second front door, and the one to take if your code already runs on Harper.
|
|
293
|
+
|
|
294
|
+
Flair *is* a Harper component. Deploy it into the instance your application already runs in and call its resources directly — `await h.post({ agentId, content })` is a **method call**, not a network call. No second service to operate, no HTTP round trip, and no key to distribute: a caller in the same process is already inside the trust boundary and names the agent it is acting as, per call.
|
|
295
|
+
|
|
296
|
+
Adding it takes nothing away. The HTTP surface keeps serving MCP clients and remote agents exactly as before.
|
|
302
297
|
|
|
303
298
|
```javascript
|
|
304
299
|
import { server } from "harper";
|
|
@@ -312,7 +307,11 @@ const h = await collectionResource(Memory, agentContext("mybot"));
|
|
|
312
307
|
await h.post({ agentId: "mybot", content: "...", durability: "standard" });
|
|
313
308
|
```
|
|
314
309
|
|
|
315
|
-
`databases.flair.Memory` is the **table** (raw storage); the exported `Memory` class is the **resource**, where auth, read-scoping, visibility and embedding live. `new Memory(...)` is not a substitute for `collectionResource` — a create needs a collection-bound instance only Harper can produce. Both helpers refuse a missing agent id rather than defaulting it, because a resource invoked with no context resolves to Flair's trusted `internal` verdict and runs unfiltered across every agent.
|
|
310
|
+
`databases.flair.Memory` is the **table** (raw storage); the exported `Memory` class is the **resource**, where auth, read-scoping, visibility and embedding live. `new Memory(...)` is not a substitute for `collectionResource` — a create needs a collection-bound instance only Harper can produce. Both helpers refuse a missing agent id rather than defaulting it, because a resource invoked with no context resolves to Flair's trusted `internal` verdict and runs unfiltered across every agent.
|
|
311
|
+
|
|
312
|
+
**This path needs no key at all.** Keys are how an agent *outside* the process proves who it is. Code running inside the same Harper instance asserts identity through the call context instead — `agentContext("mybot")` — which Flair reads and acts on with no signature, no `Agent`-table lookup and no registration. That is deliberate: same-process code could write the storage tables directly, so demanding a signature from it would be theatre. It is also why that id must come from your own server-side state and never from request data.
|
|
313
|
+
|
|
314
|
+
**→ [Embedding Flair in a Harper app](docs/embedding-in-a-harper-app.md)** — the whole in-process contract, measured against a real instance: resolving the resource, the table-vs-resource distinction that decides whether your memories are scoped at all, N agents in one process, and registering agents with no shell on the node.
|
|
316
315
|
|
|
317
316
|
### Auth across surfaces
|
|
318
317
|
|
|
@@ -357,6 +356,7 @@ Full model, threat analysis and recommendations in [SECURITY.md](SECURITY.md).
|
|
|
357
356
|
- Ed25519 cryptographic identity — agents sign every request.
|
|
358
357
|
- Writes are always agent-scoped. An agent can only write its own records.
|
|
359
358
|
- Reads are open within the org: any agent can read any other agent's non-private memory, no grant required. `private` is the one owner-only exception ([DESIGN.md](DESIGN.md#access-model-open-within-the-org-closed-at-the-federation-edge)).
|
|
359
|
+
- Which memories are non-private is decided at write time, from durability: `permanent`/`persistent` default to `shared`, `standard`/`ephemeral` to `private`. A write that names neither is `standard`, so it lands `private`. Say what you mean with `--visibility shared|private` (CLI) or `visibility` (MCP / SDK); a write response names the visibility the record landed on, so it never has to be inferred.
|
|
360
360
|
- The admin password is generated by `flair init` and written to `~/.flair/admin-pass` (mode 0600). The CLI prints the path, never the value. Prefer `--admin-pass-file` over `--admin-pass` so it stays out of `ps` and shell history.
|
|
361
361
|
- Key rotation via `flair agent rotate-key`.
|
|
362
362
|
|
package/SECURITY.md
CHANGED
|
@@ -69,6 +69,13 @@ centralized read-scope rule), not application logic:
|
|
|
69
69
|
**Private memories are strictly owner-only** — a memory written with
|
|
70
70
|
`visibility: private` is returned only to its author, never to another agent.
|
|
71
71
|
|
|
72
|
+
**A write that does not name a visibility gets one anyway.** The server derives
|
|
73
|
+
it from the memory's durability: `permanent`/`persistent` → `shared`,
|
|
74
|
+
`standard`/`ephemeral` → `private`. Durability itself defaults to `standard`,
|
|
75
|
+
so a write naming neither is stamped `private` and is owner-only. An explicit
|
|
76
|
+
`visibility` on the write always overrides the rule, and the response to a
|
|
77
|
+
create names the value the record actually landed on.
|
|
78
|
+
|
|
72
79
|
### Cross-Agent Access (within an org)
|
|
73
80
|
|
|
74
81
|
Within an org, an agent reads every non-private memory directly — no grant
|
package/config.yaml
CHANGED
|
@@ -6,6 +6,40 @@ rest: true
|
|
|
6
6
|
# http:
|
|
7
7
|
# port: 19926
|
|
8
8
|
|
|
9
|
+
# Harper does not read a component's `.env` implicitly — it only loads env
|
|
10
|
+
# files a component ASKS for, via this plugin. Without this block a `.env`
|
|
11
|
+
# sitting next to config.yaml is inert: the file is present and its values
|
|
12
|
+
# never reach `process.env`. That is exactly what a deployed instance hit —
|
|
13
|
+
# `FLAIR_PUBLIC_URL` was set in the deployed component's `.env` and OAuth
|
|
14
|
+
# discovery kept advertising a loopback issuer (flair#1005, #1000).
|
|
15
|
+
#
|
|
16
|
+
# MUST STAY FIRST. Config keys are iterated in file order by Harper's
|
|
17
|
+
# component loader, and each plugin's initial entry load is awaited before
|
|
18
|
+
# the next key is processed — so declaring this above `jsResource` is what
|
|
19
|
+
# guarantees `process.env` is populated before `dist/resources/*.js` are
|
|
20
|
+
# imported. Most consumers read `process.env` per request and would not care
|
|
21
|
+
# (resources/OAuth.ts, resources/AdminInstance.ts, resources/XAA.ts,
|
|
22
|
+
# resources/a2a-url.ts), but `resources/mcp-oauth.ts` decides at MODULE LOAD
|
|
23
|
+
# whether to mount `/mcp`; move this below `jsResource` and that decision is
|
|
24
|
+
# made against an env that has not been loaded yet.
|
|
25
|
+
#
|
|
26
|
+
# No `.env` is required, which is the case for essentially every local
|
|
27
|
+
# install: when the glob matches nothing the plugin never fires and emits
|
|
28
|
+
# nothing. Measured — a boot log with this block and no `.env` differs from
|
|
29
|
+
# one without the block only in the PID and in non-deterministic table-init
|
|
30
|
+
# ordering. (A MALFORMED declaration is loud, not silent: a pattern
|
|
31
|
+
# containing '..' produced both an `Ignoring invalid loadEnv files pattern`
|
|
32
|
+
# warning and a `Could not load component 'loadEnv'` error, which is the
|
|
33
|
+
# positive control for that silence.)
|
|
34
|
+
#
|
|
35
|
+
# Application variables only. Harper composes its OWN configuration before
|
|
36
|
+
# component `.env` files load, so Harper-level settings cannot be set this
|
|
37
|
+
# way; `HARPER_CONFIG` / `HARPER_DEFAULT_CONFIG` / `HARPER_SET_CONFIG` are
|
|
38
|
+
# refused at the injection point and warned about (harper#1513). Those
|
|
39
|
+
# belong in the process environment or harper-config.yaml.
|
|
40
|
+
loadEnv:
|
|
41
|
+
files: '.env'
|
|
42
|
+
|
|
9
43
|
graphqlSchema:
|
|
10
44
|
files: schemas/*.graphql
|
|
11
45
|
|