@promptowl/contextnest-community 1.0.1 → 1.2.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.
@@ -1,46 +1,20 @@
1
- import {
2
- canUserApprove,
3
- resolveStewardsForNode
4
- } from "./chunk-K22GWPT4.js";
5
1
  import {
6
2
  createVersion,
7
3
  setApprovedVersion
8
- } from "./chunk-JMZ75ZCD.js";
4
+ } from "./chunk-LO54V4AU.js";
5
+ import {
6
+ buildTitleMap,
7
+ canUserApprove,
8
+ engineCache,
9
+ resolveStewardsForNode
10
+ } from "./chunk-5MT4ZBVF.js";
9
11
  import {
10
- config,
11
12
  getDb
12
- } from "./chunk-KQCWNHDM.js";
13
+ } from "./chunk-G62P54ET.js";
13
14
 
14
15
  // src/governance/review-service.ts
15
16
  import { v4 as uuid } from "uuid";
16
17
 
17
- // src/nodes/engine.ts
18
- import { join } from "path";
19
- import {
20
- NestStorage,
21
- GraphQueryEngine,
22
- VersionManager
23
- } from "@promptowl/contextnest-engine";
24
- var NestEngineCache = class {
25
- cache = /* @__PURE__ */ new Map();
26
- get(nestId) {
27
- let engine = this.cache.get(nestId);
28
- if (!engine) {
29
- const nestPath = join(config.DATA_ROOT, "nests", nestId);
30
- const storage = new NestStorage(nestPath);
31
- const query = new GraphQueryEngine(storage);
32
- const versions = new VersionManager(storage);
33
- engine = { storage, query, versions };
34
- this.cache.set(nestId, engine);
35
- }
36
- return engine;
37
- }
38
- evict(nestId) {
39
- this.cache.delete(nestId);
40
- }
41
- };
42
- var engineCache = new NestEngineCache();
43
-
44
18
  // src/governance/safe-publish.ts
45
19
  import {
46
20
  publishDocument,
@@ -209,7 +183,7 @@ function cancelReview(params) {
209
183
  ).run(params.nestId, params.nodeId, pending.version);
210
184
  return getReviewRequest(pending.id);
211
185
  }
212
- function getReviewQueue(params) {
186
+ async function getReviewQueue(params) {
213
187
  const db = getDb();
214
188
  let whereClauses = [];
215
189
  const args = [];
@@ -244,6 +218,15 @@ function getReviewQueue(params) {
244
218
  );
245
219
  });
246
220
  }
221
+ const titleMapsByNest = /* @__PURE__ */ new Map();
222
+ const nestIds = new Set(requests.map((r) => r.nestId));
223
+ for (const nid of nestIds) {
224
+ titleMapsByNest.set(nid, await buildTitleMap(nid));
225
+ }
226
+ requests = requests.map((r) => ({
227
+ ...r,
228
+ title: titleMapsByNest.get(r.nestId)?.get(r.nodeId)
229
+ }));
247
230
  return { requests, total };
248
231
  }
249
232
  function getReviewHistory(nestId, nodeId) {
@@ -283,7 +266,6 @@ function rowToReviewRequest(row) {
283
266
  }
284
267
 
285
268
  export {
286
- engineCache,
287
269
  safePublishDocument,
288
270
  submitForReview,
289
271
  approve,
@@ -38,6 +38,20 @@ var config = {
38
38
  get PROMPTOWL_KEY() {
39
39
  return process.env.PROMPTOWL_KEY || "";
40
40
  },
41
+ /**
42
+ * Restrict "Sign in with PromptOwl":
43
+ * "open" — anyone may sign in with PromptOwl (default)
44
+ * "admin-only" — only the license owner (admin) may; everyone else
45
+ * uses email/password. Admin reaches it via the login
46
+ * page's admin route (?admin=1).
47
+ * "disabled" — nobody may sign in with PromptOwl.
48
+ * Enforced server-side at the device entry points (POST /auth/device,
49
+ * GET /auth/device/poll) and the identity point (POST /auth/promptowl).
50
+ */
51
+ get PROMPTOWL_SIGN_IN_GATE() {
52
+ const v = (process.env.PROMPTOWL_SIGN_IN_GATE || "open").trim().toLowerCase();
53
+ return v === "admin-only" || v === "disabled" ? v : "open";
54
+ },
41
55
  /**
42
56
  * Path to the .env file the server reads its config from. Used by
43
57
  * the license install flow to persist PROMPTOWL_KEY alongside any
@@ -52,6 +66,25 @@ var config = {
52
66
  get TELEMETRY_INTERVAL_MS() {
53
67
  return parseInt(process.env.TELEMETRY_INTERVAL_MS || "3600000", 10);
54
68
  },
69
+ /**
70
+ * Optional custom logo URL shown in UI header + login screen.
71
+ * Must be an absolute https://, http://, or data:image/… URL. Other
72
+ * schemes (file://, javascript:, relative paths) are rejected with a
73
+ * warning so an operator typo doesn't silently break the favicon.
74
+ * When unset or invalid, the UI falls back to the bundled icon.
75
+ */
76
+ get LOGO_URL() {
77
+ const raw = process.env.LOGO_URL?.trim();
78
+ if (!raw) return null;
79
+ const ok = /^(https?:\/\/|data:image\/)/i.test(raw);
80
+ if (!ok) {
81
+ console.warn(
82
+ `[config] LOGO_URL rejected: must start with https://, http://, or data:image/ (got "${raw}"). Falling back to default logo.`
83
+ );
84
+ return null;
85
+ }
86
+ return raw;
87
+ },
55
88
  get AUTH_MODE() {
56
89
  return process.env.AUTH_MODE || "key";
57
90
  },
@@ -229,6 +262,12 @@ function runMigrations(db2) {
229
262
  if (!nestCols.includes("stewardship_enabled")) {
230
263
  db2.exec("ALTER TABLE nests ADD COLUMN stewardship_enabled INTEGER NOT NULL DEFAULT 0");
231
264
  }
265
+ if (!nestCols.includes("is_imported")) {
266
+ db2.exec("ALTER TABLE nests ADD COLUMN is_imported INTEGER NOT NULL DEFAULT 0");
267
+ }
268
+ if (!nestCols.includes("allow_self_approve")) {
269
+ db2.exec("ALTER TABLE nests ADD COLUMN allow_self_approve INTEGER NOT NULL DEFAULT 0");
270
+ }
232
271
  const userCols = db2.prepare("PRAGMA table_info(users)").all().map((c) => c.name);
233
272
  if (!userCols.includes("is_admin")) {
234
273
  db2.exec("ALTER TABLE users ADD COLUMN is_admin INTEGER NOT NULL DEFAULT 0");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDb
3
- } from "./chunk-KQCWNHDM.js";
3
+ } from "./chunk-G62P54ET.js";
4
4
 
5
5
  // src/governance/version-service.ts
6
6
  import { createHash } from "crypto";
@@ -2,7 +2,7 @@
2
2
  import { randomBytes, createHash, timingSafeEqual } from "crypto";
3
3
  import bcrypt from "bcryptjs";
4
4
  var KEY_PREFIX = "cnst_";
5
- var BCRYPT_ROUNDS = 12;
5
+ var BCRYPT_ROUNDS = process.env.VITEST ? 4 : 12;
6
6
  function generateApiKey() {
7
7
  return KEY_PREFIX + randomBytes(32).toString("hex");
8
8
  }