@promptowl/contextnest-community 1.7.0 → 1.8.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/CONFIGURATION.md +182 -181
- package/LICENSE.md +142 -142
- package/README.md +224 -224
- package/dist/{chunk-43DOX4LH.js → chunk-PJTAUVD7.js} +11 -1
- package/dist/{chunk-QMLAXQES.js → chunk-PLAHCDQG.js} +59 -1
- package/dist/{chunk-VD5QX2ZQ.js → chunk-XNGOO6RI.js} +1 -1
- package/dist/{chunk-MOXICJPD.js → chunk-Z3Y46ZGU.js} +62 -3
- package/dist/index.js +745 -35
- package/dist/{migrations.postgres-3HMGLKOV.js → migrations.postgres-VCG45LMK.js} +35 -1
- package/dist/{review-service-2FSKW425.js → review-service-G5US3SMG.js} +4 -4
- package/dist/{stewardship-service-I2JAFYJU.js → stewardship-service-ZXAMFTXO.js} +2 -2
- package/dist/{version-service-FJWVTZKR.js → version-service-B3SDOJQE.js} +2 -2
- package/dist/web3/assets/{hootie-_U3ECslt.svg → hootie-C2ocYkn4.svg} +8 -8
- package/dist/web3/assets/{index-DpM8J4RN.js → index-Den-5nzY.js} +239 -224
- package/dist/web3/assets/index-Jfj-2MHm.css +1 -0
- package/dist/web3/index.html +14 -14
- package/package.json +152 -152
- package/dist/web3/assets/index-24dBhQSQ.css +0 -1
package/README.md
CHANGED
|
@@ -1,224 +1,224 @@
|
|
|
1
|
-
# ContextNest Community Edition
|
|
2
|
-
|
|
3
|
-
**Self-hosted context governance server for AI workflows.** Part of the [PromptOwl](https://promptowl.ai) platform.
|
|
4
|
-
|
|
5
|
-
> ⚠️ **Commercial Software.** ContextNest Community Edition is proprietary software licensed by Promptowl LLC. A free [PromptOwl account](https://app.promptowl.ai) is required to use it. Redistribution, hosting-as-a-service, and competitive use are prohibited. See [LICENSE.md](./LICENSE.md) for full terms.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## What it is
|
|
10
|
-
|
|
11
|
-
ContextNest Community Edition is a self-hosted server that lets you:
|
|
12
|
-
|
|
13
|
-
- Store, version, and govern markdown-based context documents ("nests")
|
|
14
|
-
- Import an existing folder or vault of markdown files in one step
|
|
15
|
-
- Apply stewardship workflows — draft, pending review, approved
|
|
16
|
-
- Share nests with collaborators or publish them read-only to the public
|
|
17
|
-
- Serve approved context to AI agents via MCP, HTTP, or CLI
|
|
18
|
-
- Sync with the PromptOwl hosted platform for multi-user collaboration
|
|
19
|
-
|
|
20
|
-
The server runs locally or on your own infrastructure. Your PromptOwl account handles authentication, entitlement, and governance metadata.
|
|
21
|
-
|
|
22
|
-
## Quickstart
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
# 1. Run the community server
|
|
26
|
-
npx @promptowl/contextnest-community
|
|
27
|
-
|
|
28
|
-
# 2. Open the server in your browser
|
|
29
|
-
# http://localhost:3838
|
|
30
|
-
# On first boot with no license, it lands on the License Setup Page.
|
|
31
|
-
|
|
32
|
-
# 3. Paste your PromptOwl license key (pk_...) — see "License setup" below
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The server listens on `http://localhost:3838` by default. Without a valid license the server still runs and serves reads, but write actions return `503` until you activate. See [CONFIGURATION.md](./CONFIGURATION.md) for all environment variables (port, auth mode, storage, telemetry).
|
|
36
|
-
|
|
37
|
-
> **Optional:** scaffold a local nest with the open-source CLI before connecting:
|
|
38
|
-
> ```bash
|
|
39
|
-
> npx @promptowl/contextnest-cli init
|
|
40
|
-
> ```
|
|
41
|
-
|
|
42
|
-
## License setup
|
|
43
|
-
|
|
44
|
-
ContextNest Community Edition requires a PromptOwl Community License key (`pk_...`). Getting and activating one:
|
|
45
|
-
|
|
46
|
-
### 1. Create the key (free)
|
|
47
|
-
|
|
48
|
-
1. Sign up or log in at <https://app.promptowl.ai>
|
|
49
|
-
2. Open the **Overview** menu → **Community License**
|
|
50
|
-
3. Click **Create a Community License key**
|
|
51
|
-
4. Copy the generated key — it starts with `pk_`
|
|
52
|
-
|
|
53
|
-
### 2. Activate the server
|
|
54
|
-
|
|
55
|
-
Pick **one** of two ways:
|
|
56
|
-
|
|
57
|
-
**A. Browser setup page (recommended for first run)**
|
|
58
|
-
|
|
59
|
-
1. Start the server: `npx @promptowl/contextnest-community`
|
|
60
|
-
2. Open <http://localhost:3838> — with no license installed, the server boots into **setup mode** and shows the **License Setup Page**
|
|
61
|
-
3. Paste your `pk_...` key and submit
|
|
62
|
-
4. The server validates it against PromptOwl, writes it to your `.env`, and exits setup mode — no restart needed
|
|
63
|
-
|
|
64
|
-
**B. Environment variable (recommended for Docker / CI / scripted deploys)**
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
PROMPTOWL_KEY=pk_... npx @promptowl/contextnest-community
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
The key is read at boot. The server validates against PromptOwl on startup; if valid, it goes straight into licensed mode.
|
|
71
|
-
|
|
72
|
-
### 3. How licensing behaves at runtime
|
|
73
|
-
|
|
74
|
-
- **Unlicensed / setup mode** — reads work; every non-GET (write) request returns `503` until a valid key is installed.
|
|
75
|
-
- **Live revocation** — a long-poll watcher tracks license state against PromptOwl. If your key is revoked, the server blocks writes within seconds (no restart required) and returns to setup mode.
|
|
76
|
-
- **Admin identity follows the license** — the admin user is whichever PromptOwl account owns the installed key, resolved live per request. Transferring the license to another account immediately promotes the new owner and demotes the old one.
|
|
77
|
-
|
|
78
|
-
For redistribution, hosted-service, OEM, or regulated-industry licensing, contact **hoot@promptowl.ai**.
|
|
79
|
-
|
|
80
|
-
## System requirements
|
|
81
|
-
|
|
82
|
-
- **Node.js** 20.x or later
|
|
83
|
-
- **PromptOwl account** — free signup at <https://app.promptowl.ai/signup>
|
|
84
|
-
- **OS:** Windows, macOS, or Linux
|
|
85
|
-
- **Disk:** ~200 MB for the server, plus storage for your nests
|
|
86
|
-
|
|
87
|
-
## What you get
|
|
88
|
-
|
|
89
|
-
| Feature | Community Edition | Enterprise |
|
|
90
|
-
|---|:---:|:---:|
|
|
91
|
-
| Self-hosted context server | ✅ | ✅ |
|
|
92
|
-
| SQLite or PostgreSQL / Cloud SQL backend | ✅ | ✅ |
|
|
93
|
-
| Configurable nest storage (external / GCS volume mount) | ✅ | ✅ |
|
|
94
|
-
| Markdown + YAML frontmatter vaults | ✅ | ✅ |
|
|
95
|
-
| Import existing folder / vault | ✅ | ✅ |
|
|
96
|
-
| Markdown rendering + wiki cross-linking | ✅ | ✅ |
|
|
97
|
-
| External-edit detection + version diff | ✅ | ✅ |
|
|
98
|
-
| Stewardship workflow (draft/review/approve) | ✅ | ✅ |
|
|
99
|
-
| Per-nest sharing + collaborators | ✅ | ✅ |
|
|
100
|
-
| Public read-only nests | ✅ | ✅ |
|
|
101
|
-
| Custom logo / branding | ✅ | ✅ |
|
|
102
|
-
| Admin password reset + user removal (in-platform) | ✅ | ✅ |
|
|
103
|
-
| Wiki backlinks, outline, hover-preview, link health | ✅ | ✅ |
|
|
104
|
-
| Rich editor — tables, callouts, toggles, code highlight, find/replace | ✅ | ✅ |
|
|
105
|
-
| Steward version revert | ✅ | ✅ |
|
|
106
|
-
| MCP server for AI agents | ✅ | ✅ |
|
|
107
|
-
| Centralized multi-tenant admin console | — | ✅ |
|
|
108
|
-
| SSO / SAML / SCIM | — | ✅ |
|
|
109
|
-
| Audit log streaming | — | ✅ |
|
|
110
|
-
| Policy transforms (redaction, summarization) | — | ✅ |
|
|
111
|
-
| Priority support and SLA | — | ✅ |
|
|
112
|
-
|
|
113
|
-
For Enterprise pricing and features, contact **hoot@promptowl.ai** or visit <https://promptowl.ai/contextnest/>.
|
|
114
|
-
|
|
115
|
-
## What's new in 1.6.0
|
|
116
|
-
|
|
117
|
-
- **PostgreSQL / Cloud SQL backend** — run the server on PostgreSQL alongside SQLite via an async DB adapter, so metadata survives on Cloud Run and other deployments where local disk isn't durable. Supports the Cloud SQL Auth Proxy (unix socket) and TCP + TLS. New `DB_*` env vars (`DB_DRIVER`, `DATABASE_URL`, `CLOUD_SQL_CONNECTION_NAME`, `DB_HOST`/`DB_PORT`/`DB_USER`/`DB_PASSWORD`/`DB_NAME`, `DB_POOL_MAX`, `DB_SSL`, `DB_SSL_CA`); SQLite stays the default when nothing is configured. See [CONFIGURATION.md](./CONFIGURATION.md).
|
|
118
|
-
- **Configurable `NEST_STORAGE_ROOT`** — store nest vault files (markdown + version history) outside `DATA_ROOT` — e.g. on a Cloud Storage (GCS) volume mount — while the database stays on `DATA_ROOT`. Defaults to `<DATA_ROOT>/nests`, so existing deployments are unchanged. On a GCS FUSE mount, set `DRIFT_SCAN_INTERVAL_MS=0` and run a single instance.
|
|
119
|
-
- **Security fix** — the admin guard on `/admin/settings` (GET/PATCH) is now correctly awaited; without it a non-admin could read or change server-wide settings in key mode.
|
|
120
|
-
- **AdminLoginModal respects `PROMPTOWL_SIGN_IN_GATE`** — the "Sign in with PromptOwl" affordance follows the configured gate (`open` / `admin-only` / `disabled`).
|
|
121
|
-
- **Drift scanner toggle** — `DRIFT_SCAN_INTERVAL_MS=0` now actually disables the drift scanner (previously reset to the 30s default).
|
|
122
|
-
- **Safer folder sync** — unsynced-folder detection no longer treats a configured nest storage root as a sync candidate, preventing accidental duplication/removal of live nests when `NEST_STORAGE_ROOT` is nested under `DATA_ROOT`.
|
|
123
|
-
|
|
124
|
-
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
125
|
-
|
|
126
|
-
## What's new in 1.3.0
|
|
127
|
-
|
|
128
|
-
- **Server super-admins** — emails listed in `access.yaml: super_admins` administer every nest (change visibility, manage collaborators and stewards) without being added per-nest. Owner-only operations (delete, transfer) still require the nest owner. See [STEWARDSHIP.md](./STEWARDSHIP.md).
|
|
129
|
-
- **License persistence under `DATA_ROOT`** — `PROMPTOWL_KEY` now writes to `$DATA_ROOT/.env` (was `$cwd/.env`, which is root-owned `/app` in the official Docker image and silently lost the key on container recreate). The License Setup Page also surfaces write failures instead of failing quietly. Override via `ENV_FILE_PATH`. See [CONFIGURATION.md](./CONFIGURATION.md).
|
|
130
|
-
- **Case-insensitive email** across registration, login, invite, and access checks. Migration dedupes existing accounts that differ only in case; fixes "I can't log in because I capitalized my email" and access-guard / lockout mismatches.
|
|
131
|
-
- **Document version history + inline diff** — every saved version is browsable in the document detail view, and an inline diff highlights what changed between any two versions.
|
|
132
|
-
- **Nest Overview / index landing** — every nest opens on a grouped table-of-contents with a "recently edited" strip instead of a flat list.
|
|
133
|
-
- **Public/private toggle on the nest header** — visibility is set directly from the header, not buried in a dialog.
|
|
134
|
-
- **Review queue surfaces submitted-for-review edits** — reviewers see the pending versions a contributor staged, not just net-new documents.
|
|
135
|
-
- **Internal-folder sync over MCP** — agents can list a nest's unsynced filesystem folders and pull them into the nest on demand. New `unsynced-service.ts` + MCP tools, covered by `test/unsynced-folder.test.ts` and `test/mcp-unsynced.test.ts`.
|
|
136
|
-
- **Telemetry `batch_id` + user email** — usage events carry a stable `batch_id` (de-duped on the receiver) and the authenticated user email alongside the user id, so the PromptOwl ingest bridge can meter credits to the right account.
|
|
137
|
-
- **Hyperlink navigation fix** — hyperlinks in the editor and viewer navigate to their configured target URL correctly.
|
|
138
|
-
- **Repo / DX** — `CLAUDE.md` at the repo root with project-specific guidance for Claude Code; `claude.yml` (PR assistant) and `claude-code-review.yml` (auto review on PRs) GitHub Actions workflows.
|
|
139
|
-
|
|
140
|
-
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
141
|
-
|
|
142
|
-
## What's new in 1.2.0
|
|
143
|
-
|
|
144
|
-
- **Admin user management (no email server needed)** — `POST /auth/admin/reset-password/:userId` sets a user's password or returns a one-time temp password; `DELETE /auth/users/:userId` removes a user and revokes their API keys, sessions, and role rows. New self-service **Change password** in the user menu blocks reusing the current password.
|
|
145
|
-
- **`PROMPTOWL_SIGN_IN_GATE`** — `open` / `admin-only` / `disabled` restricts "Sign in with PromptOwl" (admin reaches it via `?admin=1`). See [CONFIGURATION.md](./CONFIGURATION.md).
|
|
146
|
-
- **Plain-text agent view** — `?format=markdown` on a node returns frontmatter + body as `text/markdown` for LLM-friendly consumption.
|
|
147
|
-
- **Steward version revert** — `POST .../revert` restores an earlier version as a new one; pending-review docs are now editable (saving withdraws the review).
|
|
148
|
-
- **Editor — always-editable surface** — Notion-style buttery headline, selection bubble toolbar (format-on-highlight), turn-into block conversion, Cmd+F find & replace, rich blocks (tables, callouts, toggles, syntax-highlighted code, columns), and wiki/code-safety fixes.
|
|
149
|
-
- **Wiki usability** — backlinks panel ("Linked from N documents"), outline/TOC for 3+-heading docs, hover-preview on `[[wiki links]]`, multi-tag AND filtering with clickable chips, per-doc copy link, rename-safety warning for title-form links, link-health report (broken links + orphans), recently-edited strip.
|
|
150
|
-
- **Sharing clarity** — share button reads "Share nest"; dialog clarifies nest-wide scope; deep links open documents directly.
|
|
151
|
-
- **Security** — hardened scanner gate (PolinRider + Shai-Hulud preflight) in `bin/`.
|
|
152
|
-
|
|
153
|
-
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
154
|
-
|
|
155
|
-
## What's new in 1.1.0
|
|
156
|
-
|
|
157
|
-
- **Vault import** — import an existing folder of markdown files into a new nest in one step, from the dashboard ("Import folder") or via the API. Frontmatter, wiki links, and folder structure are preserved.
|
|
158
|
-
- **Nest sharing + collaborators** — set per-nest visibility and add collaborators with read or write access. A Share affordance is now inline in the document view.
|
|
159
|
-
- **Public read-only nests** — flip a nest to `visibility=public` to serve it to unauthenticated readers (bypasses auth for GETs only); writes still require a key.
|
|
160
|
-
- **Custom logo / branding** — set `LOGO_URL` to show your own logo in the UI header and login screen. See [CONFIGURATION.md](./CONFIGURATION.md).
|
|
161
|
-
- **Governance** — nest owners can self-approve their own changes; new per-nest auto-approve toggle; role-based action gating (buttons reflect the viewer's role); stewards can edit scope during a role change.
|
|
162
|
-
- **Editor** — `[[wikilink]]` autocomplete, broken-link click creates a new doc with the title pre-filled, tag chips filter the nest list, Notion-style H1 title, click-to-edit, and an unsaved-changes warning.
|
|
163
|
-
- **Stability** — added an error boundary so a render error in one view no longer blanks the whole app; bumped `uuid` to 14.
|
|
164
|
-
|
|
165
|
-
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
166
|
-
|
|
167
|
-
## What's new in 1.0.1
|
|
168
|
-
|
|
169
|
-
- **Document hashing pipeline** — external-edit detection, conflict-aware safe-publish, and inline version diffs powered by `@promptowl/contextnest-engine`. When a file is edited outside the UI, the editor shows an "External edit detected" banner with a side-by-side diff and an adopt / keep choice.
|
|
170
|
-
- **Markdown rendering** — new `DocumentViewer` (react-markdown + remark-gfm + wikilink support) renders CLI/MCP-authored markdown correctly, with a view/edit toggle.
|
|
171
|
-
- **License revocation now blocks writes synchronously** — revoke flips an in-process "writes blocked" flag immediately; the next write returns `503`.
|
|
172
|
-
- **Dashboard stats** — new `GET /stats` endpoint surfaces nest / document / user counts.
|
|
173
|
-
- **Docker fix** — Dockerfile now installs via npm against the shipped `package-lock.json`; base image bumped to `node:22-slim`.
|
|
174
|
-
|
|
175
|
-
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
176
|
-
|
|
177
|
-
## Licensing
|
|
178
|
-
|
|
179
|
-
ContextNest Community Edition is **commercial software**. It is **not open source**.
|
|
180
|
-
|
|
181
|
-
**You may:**
|
|
182
|
-
- Install and run the Software on devices You own or control
|
|
183
|
-
- Use the Software for internal business purposes, tied to a valid PromptOwl account
|
|
184
|
-
- Make backup and archival copies
|
|
185
|
-
|
|
186
|
-
**You may not:**
|
|
187
|
-
- Redistribute, resell, rent, lease, or sublicense the Software
|
|
188
|
-
- Offer the Software as a hosted, managed, or software-as-a-service product to third parties
|
|
189
|
-
- Reverse engineer, decompile, or create derivative works
|
|
190
|
-
- Use the Software to build a competing product or service
|
|
191
|
-
- Remove copyright, trademark, or license notices
|
|
192
|
-
|
|
193
|
-
Full license text: [LICENSE.md](./LICENSE.md)
|
|
194
|
-
|
|
195
|
-
**For redistribution, hosted-service, OEM, or regulated-industry use,** contact **hoot@promptowl.ai** for a commercial license agreement.
|
|
196
|
-
|
|
197
|
-
## Platform terms
|
|
198
|
-
|
|
199
|
-
Because the Software requires a PromptOwl account, the following terms also apply to Your use:
|
|
200
|
-
|
|
201
|
-
- **End User License Agreement** — <https://promptowl.ai/eula/>
|
|
202
|
-
- **Terms of Service** — <https://promptowl.ai/terms-of-service/>
|
|
203
|
-
- **Privacy Policy** — <https://promptowl.ai/privacy-policy/>
|
|
204
|
-
- **Acceptable Use Policy** — <https://promptowl.ai/acceptable-use/>
|
|
205
|
-
- **Disclaimer** — <https://promptowl.ai/disclaimer/>
|
|
206
|
-
- **Cookie Policy** — <https://promptowl.ai/cookies/>
|
|
207
|
-
|
|
208
|
-
## Support
|
|
209
|
-
|
|
210
|
-
- **Documentation:** <https://promptowl.ai/contextnest/>
|
|
211
|
-
- **Product questions:** <https://promptowl.ai/contact-us/>
|
|
212
|
-
- **Support & bugs:** `hoot@promptowl.ai`
|
|
213
|
-
- **Commercial licensing:** `hoot@promptowl.ai` (subject: *ContextNest Commercial License*)
|
|
214
|
-
|
|
215
|
-
## AI output disclaimer
|
|
216
|
-
|
|
217
|
-
The Software injects content into large language models. AI output may be inaccurate, incomplete, or inappropriate for your use case. You are responsible for reviewing and validating any AI-generated content before relying on it, particularly in business-critical or regulated contexts. Do not deploy the Software in medical, legal, financial-advisory, or safety-critical environments without appropriate human oversight.
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
**Copyright © 2026 Promptowl LLC.** All rights reserved.
|
|
222
|
-
"ContextNest" and "PromptOwl" are trademarks of Promptowl LLC.
|
|
223
|
-
|
|
224
|
-
Promptowl LLC · 3060 Mercer University Dr Ste 110 · Atlanta, GA 30341 · USA
|
|
1
|
+
# ContextNest Community Edition
|
|
2
|
+
|
|
3
|
+
**Self-hosted context governance server for AI workflows.** Part of the [PromptOwl](https://promptowl.ai) platform.
|
|
4
|
+
|
|
5
|
+
> ⚠️ **Commercial Software.** ContextNest Community Edition is proprietary software licensed by Promptowl LLC. A free [PromptOwl account](https://app.promptowl.ai) is required to use it. Redistribution, hosting-as-a-service, and competitive use are prohibited. See [LICENSE.md](./LICENSE.md) for full terms.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What it is
|
|
10
|
+
|
|
11
|
+
ContextNest Community Edition is a self-hosted server that lets you:
|
|
12
|
+
|
|
13
|
+
- Store, version, and govern markdown-based context documents ("nests")
|
|
14
|
+
- Import an existing folder or vault of markdown files in one step
|
|
15
|
+
- Apply stewardship workflows — draft, pending review, approved
|
|
16
|
+
- Share nests with collaborators or publish them read-only to the public
|
|
17
|
+
- Serve approved context to AI agents via MCP, HTTP, or CLI
|
|
18
|
+
- Sync with the PromptOwl hosted platform for multi-user collaboration
|
|
19
|
+
|
|
20
|
+
The server runs locally or on your own infrastructure. Your PromptOwl account handles authentication, entitlement, and governance metadata.
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# 1. Run the community server
|
|
26
|
+
npx @promptowl/contextnest-community
|
|
27
|
+
|
|
28
|
+
# 2. Open the server in your browser
|
|
29
|
+
# http://localhost:3838
|
|
30
|
+
# On first boot with no license, it lands on the License Setup Page.
|
|
31
|
+
|
|
32
|
+
# 3. Paste your PromptOwl license key (pk_...) — see "License setup" below
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The server listens on `http://localhost:3838` by default. Without a valid license the server still runs and serves reads, but write actions return `503` until you activate. See [CONFIGURATION.md](./CONFIGURATION.md) for all environment variables (port, auth mode, storage, telemetry).
|
|
36
|
+
|
|
37
|
+
> **Optional:** scaffold a local nest with the open-source CLI before connecting:
|
|
38
|
+
> ```bash
|
|
39
|
+
> npx @promptowl/contextnest-cli init
|
|
40
|
+
> ```
|
|
41
|
+
|
|
42
|
+
## License setup
|
|
43
|
+
|
|
44
|
+
ContextNest Community Edition requires a PromptOwl Community License key (`pk_...`). Getting and activating one:
|
|
45
|
+
|
|
46
|
+
### 1. Create the key (free)
|
|
47
|
+
|
|
48
|
+
1. Sign up or log in at <https://app.promptowl.ai>
|
|
49
|
+
2. Open the **Overview** menu → **Community License**
|
|
50
|
+
3. Click **Create a Community License key**
|
|
51
|
+
4. Copy the generated key — it starts with `pk_`
|
|
52
|
+
|
|
53
|
+
### 2. Activate the server
|
|
54
|
+
|
|
55
|
+
Pick **one** of two ways:
|
|
56
|
+
|
|
57
|
+
**A. Browser setup page (recommended for first run)**
|
|
58
|
+
|
|
59
|
+
1. Start the server: `npx @promptowl/contextnest-community`
|
|
60
|
+
2. Open <http://localhost:3838> — with no license installed, the server boots into **setup mode** and shows the **License Setup Page**
|
|
61
|
+
3. Paste your `pk_...` key and submit
|
|
62
|
+
4. The server validates it against PromptOwl, writes it to your `.env`, and exits setup mode — no restart needed
|
|
63
|
+
|
|
64
|
+
**B. Environment variable (recommended for Docker / CI / scripted deploys)**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
PROMPTOWL_KEY=pk_... npx @promptowl/contextnest-community
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The key is read at boot. The server validates against PromptOwl on startup; if valid, it goes straight into licensed mode.
|
|
71
|
+
|
|
72
|
+
### 3. How licensing behaves at runtime
|
|
73
|
+
|
|
74
|
+
- **Unlicensed / setup mode** — reads work; every non-GET (write) request returns `503` until a valid key is installed.
|
|
75
|
+
- **Live revocation** — a long-poll watcher tracks license state against PromptOwl. If your key is revoked, the server blocks writes within seconds (no restart required) and returns to setup mode.
|
|
76
|
+
- **Admin identity follows the license** — the admin user is whichever PromptOwl account owns the installed key, resolved live per request. Transferring the license to another account immediately promotes the new owner and demotes the old one.
|
|
77
|
+
|
|
78
|
+
For redistribution, hosted-service, OEM, or regulated-industry licensing, contact **hoot@promptowl.ai**.
|
|
79
|
+
|
|
80
|
+
## System requirements
|
|
81
|
+
|
|
82
|
+
- **Node.js** 20.x or later
|
|
83
|
+
- **PromptOwl account** — free signup at <https://app.promptowl.ai/signup>
|
|
84
|
+
- **OS:** Windows, macOS, or Linux
|
|
85
|
+
- **Disk:** ~200 MB for the server, plus storage for your nests
|
|
86
|
+
|
|
87
|
+
## What you get
|
|
88
|
+
|
|
89
|
+
| Feature | Community Edition | Enterprise |
|
|
90
|
+
|---|:---:|:---:|
|
|
91
|
+
| Self-hosted context server | ✅ | ✅ |
|
|
92
|
+
| SQLite or PostgreSQL / Cloud SQL backend | ✅ | ✅ |
|
|
93
|
+
| Configurable nest storage (external / GCS volume mount) | ✅ | ✅ |
|
|
94
|
+
| Markdown + YAML frontmatter vaults | ✅ | ✅ |
|
|
95
|
+
| Import existing folder / vault | ✅ | ✅ |
|
|
96
|
+
| Markdown rendering + wiki cross-linking | ✅ | ✅ |
|
|
97
|
+
| External-edit detection + version diff | ✅ | ✅ |
|
|
98
|
+
| Stewardship workflow (draft/review/approve) | ✅ | ✅ |
|
|
99
|
+
| Per-nest sharing + collaborators | ✅ | ✅ |
|
|
100
|
+
| Public read-only nests | ✅ | ✅ |
|
|
101
|
+
| Custom logo / branding | ✅ | ✅ |
|
|
102
|
+
| Admin password reset + user removal (in-platform) | ✅ | ✅ |
|
|
103
|
+
| Wiki backlinks, outline, hover-preview, link health | ✅ | ✅ |
|
|
104
|
+
| Rich editor — tables, callouts, toggles, code highlight, find/replace | ✅ | ✅ |
|
|
105
|
+
| Steward version revert | ✅ | ✅ |
|
|
106
|
+
| MCP server for AI agents | ✅ | ✅ |
|
|
107
|
+
| Centralized multi-tenant admin console | — | ✅ |
|
|
108
|
+
| SSO / SAML / SCIM | — | ✅ |
|
|
109
|
+
| Audit log streaming | — | ✅ |
|
|
110
|
+
| Policy transforms (redaction, summarization) | — | ✅ |
|
|
111
|
+
| Priority support and SLA | — | ✅ |
|
|
112
|
+
|
|
113
|
+
For Enterprise pricing and features, contact **hoot@promptowl.ai** or visit <https://promptowl.ai/contextnest/>.
|
|
114
|
+
|
|
115
|
+
## What's new in 1.6.0
|
|
116
|
+
|
|
117
|
+
- **PostgreSQL / Cloud SQL backend** — run the server on PostgreSQL alongside SQLite via an async DB adapter, so metadata survives on Cloud Run and other deployments where local disk isn't durable. Supports the Cloud SQL Auth Proxy (unix socket) and TCP + TLS. New `DB_*` env vars (`DB_DRIVER`, `DATABASE_URL`, `CLOUD_SQL_CONNECTION_NAME`, `DB_HOST`/`DB_PORT`/`DB_USER`/`DB_PASSWORD`/`DB_NAME`, `DB_POOL_MAX`, `DB_SSL`, `DB_SSL_CA`); SQLite stays the default when nothing is configured. See [CONFIGURATION.md](./CONFIGURATION.md).
|
|
118
|
+
- **Configurable `NEST_STORAGE_ROOT`** — store nest vault files (markdown + version history) outside `DATA_ROOT` — e.g. on a Cloud Storage (GCS) volume mount — while the database stays on `DATA_ROOT`. Defaults to `<DATA_ROOT>/nests`, so existing deployments are unchanged. On a GCS FUSE mount, set `DRIFT_SCAN_INTERVAL_MS=0` and run a single instance.
|
|
119
|
+
- **Security fix** — the admin guard on `/admin/settings` (GET/PATCH) is now correctly awaited; without it a non-admin could read or change server-wide settings in key mode.
|
|
120
|
+
- **AdminLoginModal respects `PROMPTOWL_SIGN_IN_GATE`** — the "Sign in with PromptOwl" affordance follows the configured gate (`open` / `admin-only` / `disabled`).
|
|
121
|
+
- **Drift scanner toggle** — `DRIFT_SCAN_INTERVAL_MS=0` now actually disables the drift scanner (previously reset to the 30s default).
|
|
122
|
+
- **Safer folder sync** — unsynced-folder detection no longer treats a configured nest storage root as a sync candidate, preventing accidental duplication/removal of live nests when `NEST_STORAGE_ROOT` is nested under `DATA_ROOT`.
|
|
123
|
+
|
|
124
|
+
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
125
|
+
|
|
126
|
+
## What's new in 1.3.0
|
|
127
|
+
|
|
128
|
+
- **Server super-admins** — emails listed in `access.yaml: super_admins` administer every nest (change visibility, manage collaborators and stewards) without being added per-nest. Owner-only operations (delete, transfer) still require the nest owner. See [STEWARDSHIP.md](./STEWARDSHIP.md).
|
|
129
|
+
- **License persistence under `DATA_ROOT`** — `PROMPTOWL_KEY` now writes to `$DATA_ROOT/.env` (was `$cwd/.env`, which is root-owned `/app` in the official Docker image and silently lost the key on container recreate). The License Setup Page also surfaces write failures instead of failing quietly. Override via `ENV_FILE_PATH`. See [CONFIGURATION.md](./CONFIGURATION.md).
|
|
130
|
+
- **Case-insensitive email** across registration, login, invite, and access checks. Migration dedupes existing accounts that differ only in case; fixes "I can't log in because I capitalized my email" and access-guard / lockout mismatches.
|
|
131
|
+
- **Document version history + inline diff** — every saved version is browsable in the document detail view, and an inline diff highlights what changed between any two versions.
|
|
132
|
+
- **Nest Overview / index landing** — every nest opens on a grouped table-of-contents with a "recently edited" strip instead of a flat list.
|
|
133
|
+
- **Public/private toggle on the nest header** — visibility is set directly from the header, not buried in a dialog.
|
|
134
|
+
- **Review queue surfaces submitted-for-review edits** — reviewers see the pending versions a contributor staged, not just net-new documents.
|
|
135
|
+
- **Internal-folder sync over MCP** — agents can list a nest's unsynced filesystem folders and pull them into the nest on demand. New `unsynced-service.ts` + MCP tools, covered by `test/unsynced-folder.test.ts` and `test/mcp-unsynced.test.ts`.
|
|
136
|
+
- **Telemetry `batch_id` + user email** — usage events carry a stable `batch_id` (de-duped on the receiver) and the authenticated user email alongside the user id, so the PromptOwl ingest bridge can meter credits to the right account.
|
|
137
|
+
- **Hyperlink navigation fix** — hyperlinks in the editor and viewer navigate to their configured target URL correctly.
|
|
138
|
+
- **Repo / DX** — `CLAUDE.md` at the repo root with project-specific guidance for Claude Code; `claude.yml` (PR assistant) and `claude-code-review.yml` (auto review on PRs) GitHub Actions workflows.
|
|
139
|
+
|
|
140
|
+
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
141
|
+
|
|
142
|
+
## What's new in 1.2.0
|
|
143
|
+
|
|
144
|
+
- **Admin user management (no email server needed)** — `POST /auth/admin/reset-password/:userId` sets a user's password or returns a one-time temp password; `DELETE /auth/users/:userId` removes a user and revokes their API keys, sessions, and role rows. New self-service **Change password** in the user menu blocks reusing the current password.
|
|
145
|
+
- **`PROMPTOWL_SIGN_IN_GATE`** — `open` / `admin-only` / `disabled` restricts "Sign in with PromptOwl" (admin reaches it via `?admin=1`). See [CONFIGURATION.md](./CONFIGURATION.md).
|
|
146
|
+
- **Plain-text agent view** — `?format=markdown` on a node returns frontmatter + body as `text/markdown` for LLM-friendly consumption.
|
|
147
|
+
- **Steward version revert** — `POST .../revert` restores an earlier version as a new one; pending-review docs are now editable (saving withdraws the review).
|
|
148
|
+
- **Editor — always-editable surface** — Notion-style buttery headline, selection bubble toolbar (format-on-highlight), turn-into block conversion, Cmd+F find & replace, rich blocks (tables, callouts, toggles, syntax-highlighted code, columns), and wiki/code-safety fixes.
|
|
149
|
+
- **Wiki usability** — backlinks panel ("Linked from N documents"), outline/TOC for 3+-heading docs, hover-preview on `[[wiki links]]`, multi-tag AND filtering with clickable chips, per-doc copy link, rename-safety warning for title-form links, link-health report (broken links + orphans), recently-edited strip.
|
|
150
|
+
- **Sharing clarity** — share button reads "Share nest"; dialog clarifies nest-wide scope; deep links open documents directly.
|
|
151
|
+
- **Security** — hardened scanner gate (PolinRider + Shai-Hulud preflight) in `bin/`.
|
|
152
|
+
|
|
153
|
+
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
154
|
+
|
|
155
|
+
## What's new in 1.1.0
|
|
156
|
+
|
|
157
|
+
- **Vault import** — import an existing folder of markdown files into a new nest in one step, from the dashboard ("Import folder") or via the API. Frontmatter, wiki links, and folder structure are preserved.
|
|
158
|
+
- **Nest sharing + collaborators** — set per-nest visibility and add collaborators with read or write access. A Share affordance is now inline in the document view.
|
|
159
|
+
- **Public read-only nests** — flip a nest to `visibility=public` to serve it to unauthenticated readers (bypasses auth for GETs only); writes still require a key.
|
|
160
|
+
- **Custom logo / branding** — set `LOGO_URL` to show your own logo in the UI header and login screen. See [CONFIGURATION.md](./CONFIGURATION.md).
|
|
161
|
+
- **Governance** — nest owners can self-approve their own changes; new per-nest auto-approve toggle; role-based action gating (buttons reflect the viewer's role); stewards can edit scope during a role change.
|
|
162
|
+
- **Editor** — `[[wikilink]]` autocomplete, broken-link click creates a new doc with the title pre-filled, tag chips filter the nest list, Notion-style H1 title, click-to-edit, and an unsaved-changes warning.
|
|
163
|
+
- **Stability** — added an error boundary so a render error in one view no longer blanks the whole app; bumped `uuid` to 14.
|
|
164
|
+
|
|
165
|
+
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
166
|
+
|
|
167
|
+
## What's new in 1.0.1
|
|
168
|
+
|
|
169
|
+
- **Document hashing pipeline** — external-edit detection, conflict-aware safe-publish, and inline version diffs powered by `@promptowl/contextnest-engine`. When a file is edited outside the UI, the editor shows an "External edit detected" banner with a side-by-side diff and an adopt / keep choice.
|
|
170
|
+
- **Markdown rendering** — new `DocumentViewer` (react-markdown + remark-gfm + wikilink support) renders CLI/MCP-authored markdown correctly, with a view/edit toggle.
|
|
171
|
+
- **License revocation now blocks writes synchronously** — revoke flips an in-process "writes blocked" flag immediately; the next write returns `503`.
|
|
172
|
+
- **Dashboard stats** — new `GET /stats` endpoint surfaces nest / document / user counts.
|
|
173
|
+
- **Docker fix** — Dockerfile now installs via npm against the shipped `package-lock.json`; base image bumped to `node:22-slim`.
|
|
174
|
+
|
|
175
|
+
Full history in [CHANGELOG.md](./CHANGELOG.md).
|
|
176
|
+
|
|
177
|
+
## Licensing
|
|
178
|
+
|
|
179
|
+
ContextNest Community Edition is **commercial software**. It is **not open source**.
|
|
180
|
+
|
|
181
|
+
**You may:**
|
|
182
|
+
- Install and run the Software on devices You own or control
|
|
183
|
+
- Use the Software for internal business purposes, tied to a valid PromptOwl account
|
|
184
|
+
- Make backup and archival copies
|
|
185
|
+
|
|
186
|
+
**You may not:**
|
|
187
|
+
- Redistribute, resell, rent, lease, or sublicense the Software
|
|
188
|
+
- Offer the Software as a hosted, managed, or software-as-a-service product to third parties
|
|
189
|
+
- Reverse engineer, decompile, or create derivative works
|
|
190
|
+
- Use the Software to build a competing product or service
|
|
191
|
+
- Remove copyright, trademark, or license notices
|
|
192
|
+
|
|
193
|
+
Full license text: [LICENSE.md](./LICENSE.md)
|
|
194
|
+
|
|
195
|
+
**For redistribution, hosted-service, OEM, or regulated-industry use,** contact **hoot@promptowl.ai** for a commercial license agreement.
|
|
196
|
+
|
|
197
|
+
## Platform terms
|
|
198
|
+
|
|
199
|
+
Because the Software requires a PromptOwl account, the following terms also apply to Your use:
|
|
200
|
+
|
|
201
|
+
- **End User License Agreement** — <https://promptowl.ai/eula/>
|
|
202
|
+
- **Terms of Service** — <https://promptowl.ai/terms-of-service/>
|
|
203
|
+
- **Privacy Policy** — <https://promptowl.ai/privacy-policy/>
|
|
204
|
+
- **Acceptable Use Policy** — <https://promptowl.ai/acceptable-use/>
|
|
205
|
+
- **Disclaimer** — <https://promptowl.ai/disclaimer/>
|
|
206
|
+
- **Cookie Policy** — <https://promptowl.ai/cookies/>
|
|
207
|
+
|
|
208
|
+
## Support
|
|
209
|
+
|
|
210
|
+
- **Documentation:** <https://promptowl.ai/contextnest/>
|
|
211
|
+
- **Product questions:** <https://promptowl.ai/contact-us/>
|
|
212
|
+
- **Support & bugs:** `hoot@promptowl.ai`
|
|
213
|
+
- **Commercial licensing:** `hoot@promptowl.ai` (subject: *ContextNest Commercial License*)
|
|
214
|
+
|
|
215
|
+
## AI output disclaimer
|
|
216
|
+
|
|
217
|
+
The Software injects content into large language models. AI output may be inaccurate, incomplete, or inappropriate for your use case. You are responsible for reviewing and validating any AI-generated content before relying on it, particularly in business-critical or regulated contexts. Do not deploy the Software in medical, legal, financial-advisory, or safety-critical environments without appropriate human oversight.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
**Copyright © 2026 Promptowl LLC.** All rights reserved.
|
|
222
|
+
"ContextNest" and "PromptOwl" are trademarks of Promptowl LLC.
|
|
223
|
+
|
|
224
|
+
Promptowl LLC · 3060 Mercer University Dr Ste 110 · Atlanta, GA 30341 · USA
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
getDb,
|
|
4
4
|
insertOrReplace,
|
|
5
5
|
nowExpr
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PLAHCDQG.js";
|
|
7
7
|
import {
|
|
8
8
|
ANON_USER_ID
|
|
9
9
|
} from "./chunk-SLTQACJW.js";
|
|
@@ -921,6 +921,15 @@ async function buildTitleMap(nestId) {
|
|
|
921
921
|
return /* @__PURE__ */ new Map();
|
|
922
922
|
}
|
|
923
923
|
}
|
|
924
|
+
function folderForNode(nodeId) {
|
|
925
|
+
return nodeId.replace(/^nodes\//, "").split("/").slice(0, -1).join("/");
|
|
926
|
+
}
|
|
927
|
+
async function describeNode(nestId, nodeId) {
|
|
928
|
+
const titles = await buildTitleMap(nestId);
|
|
929
|
+
const title = titles.get(nodeId) || nodeId;
|
|
930
|
+
const folder = folderForNode(nodeId);
|
|
931
|
+
return folder ? `${title} (in ${folder})` : title;
|
|
932
|
+
}
|
|
924
933
|
|
|
925
934
|
// src/shared/access.ts
|
|
926
935
|
var PERMISSION_LEVELS = {
|
|
@@ -1580,6 +1589,7 @@ export {
|
|
|
1580
1589
|
deleteNest,
|
|
1581
1590
|
engineCache,
|
|
1582
1591
|
buildTitleMap,
|
|
1592
|
+
describeNode,
|
|
1583
1593
|
collabPermToRole,
|
|
1584
1594
|
assignSteward,
|
|
1585
1595
|
removeSteward,
|
|
@@ -20,6 +20,7 @@ if (envFileLoaded && !isTestRun) {
|
|
|
20
20
|
}
|
|
21
21
|
var canonicalEnvFile = process.env.ENV_FILE_PATH || join(dataRoot(), ".env");
|
|
22
22
|
var canonicalEnvLoaded = null;
|
|
23
|
+
var slackUrlWarned = false;
|
|
23
24
|
if (!isTestRun && canonicalEnvFile !== envFileLoaded && existsSync(canonicalEnvFile)) {
|
|
24
25
|
dotenv.config({ path: canonicalEnvFile, override: true });
|
|
25
26
|
canonicalEnvLoaded = canonicalEnvFile;
|
|
@@ -189,6 +190,26 @@ var config = {
|
|
|
189
190
|
get AUTH_MODE() {
|
|
190
191
|
return process.env.AUTH_MODE || "key";
|
|
191
192
|
},
|
|
193
|
+
/**
|
|
194
|
+
* Optional Slack incoming-webhook URL for team notifications (review
|
|
195
|
+
* submitted/approved/rejected, nest shared). Empty/unset = connector off.
|
|
196
|
+
* https only — a webhook carries an implicit secret in its path, so it
|
|
197
|
+
* never travels plaintext.
|
|
198
|
+
*/
|
|
199
|
+
get SLACK_WEBHOOK_URL() {
|
|
200
|
+
const raw = process.env.SLACK_WEBHOOK_URL?.trim();
|
|
201
|
+
if (!raw) return null;
|
|
202
|
+
if (!/^https:\/\//i.test(raw)) {
|
|
203
|
+
if (!slackUrlWarned) {
|
|
204
|
+
slackUrlWarned = true;
|
|
205
|
+
console.warn(
|
|
206
|
+
"[config] SLACK_WEBHOOK_URL rejected: must be an https:// URL. Slack notifications disabled."
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
return raw;
|
|
212
|
+
},
|
|
192
213
|
/**
|
|
193
214
|
* CORS origin allowlist. Comma-separated list of origins or "*".
|
|
194
215
|
* Defaults to "*" in open mode (read-heavy, no credentials to steal)
|
|
@@ -781,6 +802,43 @@ function runMigrations(db) {
|
|
|
781
802
|
})();
|
|
782
803
|
recordMigration("012_merge_case_colliding_users");
|
|
783
804
|
}
|
|
805
|
+
if (!hasMigration("013_node_deletion_tombstones")) {
|
|
806
|
+
db.transaction(() => {
|
|
807
|
+
db.exec(`
|
|
808
|
+
CREATE TABLE IF NOT EXISTS node_deletions (
|
|
809
|
+
nest_id TEXT NOT NULL REFERENCES nests(id) ON DELETE CASCADE,
|
|
810
|
+
node_id TEXT NOT NULL,
|
|
811
|
+
deleted_by TEXT,
|
|
812
|
+
deleted_at TEXT NOT NULL,
|
|
813
|
+
PRIMARY KEY (nest_id, node_id)
|
|
814
|
+
);
|
|
815
|
+
CREATE INDEX IF NOT EXISTS idx_node_deletions_time
|
|
816
|
+
ON node_deletions(nest_id, deleted_at);
|
|
817
|
+
`);
|
|
818
|
+
})();
|
|
819
|
+
recordMigration("013_node_deletion_tombstones");
|
|
820
|
+
}
|
|
821
|
+
if (!hasMigration("014_api_events")) {
|
|
822
|
+
db.transaction(() => {
|
|
823
|
+
db.exec(`
|
|
824
|
+
CREATE TABLE IF NOT EXISTS api_events (
|
|
825
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
826
|
+
ts TEXT NOT NULL,
|
|
827
|
+
kind TEXT NOT NULL CHECK(kind IN ('api', 'mcp')),
|
|
828
|
+
method TEXT, -- HTTP method (api rows)
|
|
829
|
+
path TEXT, -- request path (api rows)
|
|
830
|
+
tool TEXT, -- tool name (mcp rows)
|
|
831
|
+
nest_id TEXT,
|
|
832
|
+
user_id TEXT,
|
|
833
|
+
user_email TEXT,
|
|
834
|
+
status INTEGER, -- HTTP status (api rows)
|
|
835
|
+
duration_ms INTEGER
|
|
836
|
+
);
|
|
837
|
+
CREATE INDEX IF NOT EXISTS idx_api_events_ts ON api_events(ts);
|
|
838
|
+
`);
|
|
839
|
+
})();
|
|
840
|
+
recordMigration("014_api_events");
|
|
841
|
+
}
|
|
784
842
|
}
|
|
785
843
|
function mergeCaseCollidingUsers(db) {
|
|
786
844
|
const groups = db.prepare(
|
|
@@ -998,7 +1056,7 @@ async function initDb() {
|
|
|
998
1056
|
if (config.DB_DRIVER === "postgres") {
|
|
999
1057
|
const { Pool } = await import("pg");
|
|
1000
1058
|
const { PostgresAdapter } = await import("./adapter.postgres-YOODX2BI.js");
|
|
1001
|
-
const { runPostgresMigrations } = await import("./migrations.postgres-
|
|
1059
|
+
const { runPostgresMigrations } = await import("./migrations.postgres-VCG45LMK.js");
|
|
1002
1060
|
const pool = new Pool(buildPgConfig());
|
|
1003
1061
|
adapter = new PostgresAdapter(pool);
|
|
1004
1062
|
await runPostgresMigrations(adapter);
|