@promptowl/contextnest-community 1.16.1 → 1.17.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 +415 -415
- package/LICENSE.md +142 -142
- package/README.md +164 -169
- package/dist/{chunk-QJVRZT6M.js → chunk-4YGJSUJC.js} +35 -5
- package/dist/{chunk-OTGZQZKK.js → chunk-HWDPCPYT.js} +10 -9
- package/dist/{chunk-L7UCMGWZ.js → chunk-SNFGU5Q7.js} +166 -81
- package/dist/{chunk-D6HICFVW.js → chunk-UXJSO54R.js} +1 -1
- package/dist/{chunk-CLKZZZS2.js → chunk-YF4OFT2V.js} +1 -1
- package/dist/{grants-service-I535QVTW.js → grants-service-4NXPBYWD.js} +3 -3
- package/dist/index.js +213 -65
- package/dist/{review-service-V2GR6VM3.js → review-service-3CCKDO5N.js} +9 -7
- package/dist/{stewardship-service-LTREGVSJ.js → stewardship-service-OHTTZFND.js} +2 -2
- package/dist/{version-service-V6K5SZ3P.js → version-service-EFZGGL3Y.js} +2 -2
- package/dist/web3/assets/{hootie-C2ocYkn4.svg → hootie-_U3ECslt.svg} +8 -8
- package/dist/web3/assets/index-D1299AIf.css +1 -0
- package/dist/web3/assets/index-W6tEA3RK.js +1046 -0
- package/dist/web3/index.html +14 -14
- package/package.json +165 -165
- package/dist/web3/assets/index-DnQARUL3.css +0 -1
- package/dist/web3/assets/index-_m7WyozM.js +0 -1051
|
@@ -993,7 +993,8 @@ import { v4 as uuid } from "uuid";
|
|
|
993
993
|
import {
|
|
994
994
|
NestStorage as NestStorage2,
|
|
995
995
|
GraphQueryEngine,
|
|
996
|
-
VersionManager
|
|
996
|
+
VersionManager,
|
|
997
|
+
DocumentNotFoundError
|
|
997
998
|
} from "@promptowl/contextnest-engine";
|
|
998
999
|
import { createEngineApi } from "@promptowl/contextnest-engine/api";
|
|
999
1000
|
|
|
@@ -1060,39 +1061,88 @@ var FlatNestStorage = class extends NestStorage {
|
|
|
1060
1061
|
|
|
1061
1062
|
// src/nodes/engine.ts
|
|
1062
1063
|
var DISCOVERY_TTL_MS = 3e4;
|
|
1063
|
-
var
|
|
1064
|
-
|
|
1065
|
-
"
|
|
1066
|
-
"
|
|
1067
|
-
"
|
|
1068
|
-
|
|
1064
|
+
var isLive = (node) => node.frontmatter.status !== "rejected";
|
|
1065
|
+
var DERIVED_VAULT_FILES = /* @__PURE__ */ new Set([
|
|
1066
|
+
"INDEX.md",
|
|
1067
|
+
"CONTEXT.md",
|
|
1068
|
+
"CLAUDE.md",
|
|
1069
|
+
"GEMINI.md",
|
|
1070
|
+
"AGENTS.md",
|
|
1071
|
+
"README.md"
|
|
1072
|
+
]);
|
|
1069
1073
|
function withDiscoveryCache(storage) {
|
|
1070
1074
|
const entries = /* @__PURE__ */ new Map();
|
|
1071
1075
|
const discover = storage.discoverDocuments.bind(storage);
|
|
1076
|
+
const readDoc = storage.readDocument.bind(storage);
|
|
1077
|
+
const filtersRetired = !(storage instanceof FlatNestStorage);
|
|
1072
1078
|
let generation = 0;
|
|
1073
1079
|
storage.discoverDocuments = async (options = {}) => {
|
|
1074
1080
|
const key = options.includeRetired || options.includeSuperseded ? "all" : "live";
|
|
1075
1081
|
const hit = entries.get(key);
|
|
1076
1082
|
if (hit && Date.now() - hit.ts < DISCOVERY_TTL_MS) return hit.docs;
|
|
1083
|
+
const all = entries.get("all");
|
|
1084
|
+
if (all && Date.now() - all.ts < DISCOVERY_TTL_MS) {
|
|
1085
|
+
const docs2 = filtersRetired ? all.docs.filter(isLive) : all.docs;
|
|
1086
|
+
entries.set("live", { docs: docs2, ts: all.ts });
|
|
1087
|
+
return docs2;
|
|
1088
|
+
}
|
|
1077
1089
|
const startedAt = generation;
|
|
1078
|
-
const
|
|
1079
|
-
|
|
1090
|
+
const crawled = await discover({ ...options, includeRetired: true });
|
|
1091
|
+
const docs = key === "all" || !filtersRetired ? crawled : crawled.filter(isLive);
|
|
1092
|
+
if (generation === startedAt) {
|
|
1093
|
+
const ts = Date.now();
|
|
1094
|
+
entries.set("all", { docs: crawled, ts });
|
|
1095
|
+
entries.set(key, { docs, ts });
|
|
1096
|
+
}
|
|
1080
1097
|
return docs;
|
|
1081
1098
|
};
|
|
1082
1099
|
const invalidate = () => {
|
|
1083
1100
|
generation++;
|
|
1084
1101
|
entries.clear();
|
|
1085
1102
|
};
|
|
1086
|
-
|
|
1103
|
+
const patch = async (id) => {
|
|
1104
|
+
generation++;
|
|
1105
|
+
let node = null;
|
|
1106
|
+
try {
|
|
1107
|
+
node = await readDoc(id);
|
|
1108
|
+
} catch (err) {
|
|
1109
|
+
if (!(err instanceof DocumentNotFoundError)) {
|
|
1110
|
+
invalidate();
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
node = null;
|
|
1114
|
+
}
|
|
1115
|
+
for (const [key, entry] of entries) {
|
|
1116
|
+
const docs = entry.docs.filter((d) => d.id !== id);
|
|
1117
|
+
if (node && (key === "all" || isLive(node))) {
|
|
1118
|
+
const at = docs.findIndex((d) => d.id > id);
|
|
1119
|
+
docs.splice(at === -1 ? docs.length : at, 0, node);
|
|
1120
|
+
}
|
|
1121
|
+
entry.docs = docs;
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
const wrap = (name, after) => {
|
|
1087
1125
|
const write = storage[name].bind(storage);
|
|
1088
1126
|
storage[name] = async (...args) => {
|
|
1089
1127
|
try {
|
|
1090
1128
|
return await write(...args);
|
|
1091
1129
|
} finally {
|
|
1092
|
-
|
|
1130
|
+
try {
|
|
1131
|
+
await after(args);
|
|
1132
|
+
} catch {
|
|
1133
|
+
invalidate();
|
|
1134
|
+
}
|
|
1093
1135
|
}
|
|
1094
1136
|
};
|
|
1095
|
-
}
|
|
1137
|
+
};
|
|
1138
|
+
wrap("writeDocument", (args) => patch(String(args[0])));
|
|
1139
|
+
wrap("deleteDocument", (args) => patch(String(args[0])));
|
|
1140
|
+
wrap("init", () => invalidate());
|
|
1141
|
+
wrap("writeVaultFile", (args) => {
|
|
1142
|
+
const rel = String(args[0] ?? "");
|
|
1143
|
+
const base = rel.split(/[/\\]/).pop() || "";
|
|
1144
|
+
if (rel.endsWith(".md") && !DERIVED_VAULT_FILES.has(base)) invalidate();
|
|
1145
|
+
});
|
|
1096
1146
|
return { storage, invalidate };
|
|
1097
1147
|
}
|
|
1098
1148
|
var NestEngineCache = class {
|
|
@@ -1606,14 +1656,18 @@ async function removeTeamRefs(tx, teamId) {
|
|
|
1606
1656
|
}
|
|
1607
1657
|
async function resolveTeamRolesForUser(nestId, userId) {
|
|
1608
1658
|
const refs = await listNestTeams(nestId).catch(() => []);
|
|
1659
|
+
return resolveTeamRolesFromShared(refs, userId);
|
|
1660
|
+
}
|
|
1661
|
+
async function resolveTeamRolesFromShared(refs, userId) {
|
|
1609
1662
|
if (refs.length === 0) return [];
|
|
1610
|
-
const
|
|
1663
|
+
const ids = [...new Set(refs.map((r) => r.teamId).filter(Boolean))];
|
|
1664
|
+
if (ids.length === 0) return [];
|
|
1665
|
+
const rows = await getDb().all(
|
|
1666
|
+
`SELECT members FROM teams WHERE id IN (${ids.map(() => "?").join(",")})`,
|
|
1667
|
+
ids
|
|
1668
|
+
);
|
|
1611
1669
|
const roles = /* @__PURE__ */ new Set();
|
|
1612
|
-
for (const
|
|
1613
|
-
const row = await db.get("SELECT members FROM teams WHERE id = ?", [
|
|
1614
|
-
ref.teamId
|
|
1615
|
-
]);
|
|
1616
|
-
if (!row) continue;
|
|
1670
|
+
for (const row of rows) {
|
|
1617
1671
|
const member = parseMembers(row.members).find((m) => m.userId === userId);
|
|
1618
1672
|
if (member) roles.add(member.role);
|
|
1619
1673
|
}
|
|
@@ -1679,71 +1733,91 @@ var PERMISSION_LEVELS = {
|
|
|
1679
1733
|
admin: 3,
|
|
1680
1734
|
owner: 4
|
|
1681
1735
|
};
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
const
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
for (const role of await resolveTeamRolesForUser(nestId, userId)) {
|
|
1704
|
-
best = higher(best, teamRoleToPermission(role));
|
|
1705
|
-
}
|
|
1706
|
-
if (best === "admin") return best;
|
|
1707
|
-
const stewardGrant = await db.get(
|
|
1708
|
-
`SELECT 1 FROM stewards s
|
|
1709
|
-
JOIN users u ON u.id = ?
|
|
1710
|
-
WHERE s.nest_id = ? AND s.is_active = 1
|
|
1711
|
-
AND LOWER(s.user_email) = LOWER(u.email)
|
|
1712
|
-
LIMIT 1`,
|
|
1713
|
-
[userId, nestId]
|
|
1736
|
+
var higher = (a, b) => b && PERMISSION_LEVELS[b] > PERMISSION_LEVELS[a] ? b : a;
|
|
1737
|
+
async function resolveNestAccess(nestId, userId) {
|
|
1738
|
+
const row = await getDb().get(
|
|
1739
|
+
`SELECT n.user_id AS owner_id,
|
|
1740
|
+
n.visibility AS visibility,
|
|
1741
|
+
n.shared_teams AS shared_teams,
|
|
1742
|
+
u.email AS caller_email,
|
|
1743
|
+
nc.permission AS collab_permission,
|
|
1744
|
+
(SELECT 1 FROM stewards s
|
|
1745
|
+
WHERE s.nest_id = n.id AND s.is_active = 1
|
|
1746
|
+
AND LOWER(s.user_email) = LOWER(u.email)
|
|
1747
|
+
LIMIT 1) AS steward_hit,
|
|
1748
|
+
(SELECT 1 FROM grants g
|
|
1749
|
+
WHERE g.nest_id = n.id AND g.user_id = ?
|
|
1750
|
+
LIMIT 1) AS grant_hit
|
|
1751
|
+
FROM nests n
|
|
1752
|
+
LEFT JOIN users u ON u.id = ?
|
|
1753
|
+
LEFT JOIN nest_collaborators nc
|
|
1754
|
+
ON nc.nest_id = n.id AND nc.user_id = ?
|
|
1755
|
+
WHERE n.id = ?`,
|
|
1756
|
+
[userId, userId, userId, nestId]
|
|
1714
1757
|
);
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1758
|
+
const absent = {
|
|
1759
|
+
exists: false,
|
|
1760
|
+
ownerId: null,
|
|
1761
|
+
visibility: null,
|
|
1762
|
+
callerEmail: null,
|
|
1763
|
+
collaboratorPermission: null,
|
|
1764
|
+
isSteward: false,
|
|
1765
|
+
hasGrant: false,
|
|
1766
|
+
permission: "none",
|
|
1767
|
+
isPublicReader: false
|
|
1768
|
+
};
|
|
1769
|
+
if (!row) return absent;
|
|
1770
|
+
const base = {
|
|
1771
|
+
exists: true,
|
|
1772
|
+
ownerId: row.owner_id,
|
|
1773
|
+
visibility: row.visibility,
|
|
1774
|
+
callerEmail: row.caller_email ?? null,
|
|
1775
|
+
collaboratorPermission: row.collab_permission ?? null,
|
|
1776
|
+
// Postgres returns integer 1, SQLite returns 1 — both truthy, neither a
|
|
1777
|
+
// boolean, so normalize rather than leaking the driver's shape.
|
|
1778
|
+
isSteward: !!row.steward_hit,
|
|
1779
|
+
hasGrant: !!row.grant_hit
|
|
1780
|
+
};
|
|
1781
|
+
if (row.owner_id === userId) {
|
|
1782
|
+
return { ...base, permission: "owner", isPublicReader: false };
|
|
1783
|
+
}
|
|
1784
|
+
const email = row.caller_email ?? null;
|
|
1785
|
+
const licenseAdmin = isLicenseAdminEmail(email);
|
|
1786
|
+
if (row.owner_id === ANON_USER_ID && licenseAdmin) {
|
|
1787
|
+
return { ...base, permission: "owner", isPublicReader: false };
|
|
1788
|
+
}
|
|
1789
|
+
if (licenseAdmin || email && isSuperAdmin(email)) {
|
|
1790
|
+
return { ...base, permission: "admin", isPublicReader: false };
|
|
1791
|
+
}
|
|
1792
|
+
let best = higher("none", row.collab_permission);
|
|
1793
|
+
if (best !== "admin") {
|
|
1794
|
+
const teamRoles = await resolveTeamRolesFromShared(
|
|
1795
|
+
parseSharedTeams(row.shared_teams),
|
|
1796
|
+
userId
|
|
1797
|
+
);
|
|
1798
|
+
for (const role of teamRoles) {
|
|
1799
|
+
best = higher(best, teamRoleToPermission(role));
|
|
1800
|
+
}
|
|
1801
|
+
if (teamRoles.length > 0) {
|
|
1802
|
+
return { ...base, permission: best, isPublicReader: false };
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
if (best === "admin") {
|
|
1806
|
+
return { ...base, permission: best, isPublicReader: false };
|
|
1807
|
+
}
|
|
1808
|
+
if (base.isSteward) best = higher(best, "read");
|
|
1809
|
+
if (row.visibility === "public") best = higher(best, "read");
|
|
1810
|
+
const isPublicReader2 = row.visibility === "public" && !row.collab_permission && !base.isSteward;
|
|
1811
|
+
return { ...base, permission: best, isPublicReader: isPublicReader2 };
|
|
1812
|
+
}
|
|
1813
|
+
async function resolveNestPermission(nestId, userId) {
|
|
1814
|
+
return (await resolveNestAccess(nestId, userId)).permission;
|
|
1718
1815
|
}
|
|
1719
1816
|
function permissionLevel(p) {
|
|
1720
1817
|
return PERMISSION_LEVELS[p] ?? 0;
|
|
1721
1818
|
}
|
|
1722
1819
|
async function isPublicReader(nestId, userId) {
|
|
1723
|
-
|
|
1724
|
-
const nest = await db.get("SELECT user_id, visibility FROM nests WHERE id = ?", [nestId]);
|
|
1725
|
-
if (!nest) return false;
|
|
1726
|
-
if (nest.visibility !== "public") return false;
|
|
1727
|
-
if (nest.user_id === userId) return false;
|
|
1728
|
-
const directGrant = await db.get(
|
|
1729
|
-
"SELECT 1 FROM nest_collaborators WHERE nest_id = ? AND user_id = ?",
|
|
1730
|
-
[nestId, userId]
|
|
1731
|
-
);
|
|
1732
|
-
if (directGrant) return false;
|
|
1733
|
-
if (await isLicenseAdminUserId(userId)) return false;
|
|
1734
|
-
const caller = await db.get("SELECT email FROM users WHERE id = ?", [userId]);
|
|
1735
|
-
if (caller?.email && isSuperAdmin(caller.email)) return false;
|
|
1736
|
-
const stewardGrant = await db.get(
|
|
1737
|
-
`SELECT 1 FROM stewards s
|
|
1738
|
-
JOIN users u ON u.id = ?
|
|
1739
|
-
WHERE s.nest_id = ? AND s.is_active = 1
|
|
1740
|
-
AND LOWER(s.user_email) = LOWER(u.email)
|
|
1741
|
-
LIMIT 1`,
|
|
1742
|
-
[userId, nestId]
|
|
1743
|
-
);
|
|
1744
|
-
if (stewardGrant) return false;
|
|
1745
|
-
if ((await resolveTeamRolesForUser(nestId, userId)).length > 0) return false;
|
|
1746
|
-
return true;
|
|
1820
|
+
return (await resolveNestAccess(nestId, userId)).isPublicReader;
|
|
1747
1821
|
}
|
|
1748
1822
|
|
|
1749
1823
|
// src/governance/tag-index-service.ts
|
|
@@ -2040,10 +2114,12 @@ async function listSharedNests(userId) {
|
|
|
2040
2114
|
LEFT JOIN stewards s
|
|
2041
2115
|
ON s.nest_id = n.id AND s.is_active = 1
|
|
2042
2116
|
AND LOWER(s.user_email) = LOWER(u.email)
|
|
2117
|
+
LEFT JOIN grants g
|
|
2118
|
+
ON g.nest_id = n.id AND g.user_id = ?
|
|
2043
2119
|
WHERE n.user_id != ?
|
|
2044
|
-
AND (nc.user_id IS NOT NULL OR s.id IS NOT NULL)
|
|
2120
|
+
AND (nc.user_id IS NOT NULL OR s.id IS NOT NULL OR g.id IS NOT NULL)
|
|
2045
2121
|
ORDER BY n.created_at DESC`,
|
|
2046
|
-
[userId, userId, userId]
|
|
2122
|
+
[userId, userId, userId, userId]
|
|
2047
2123
|
);
|
|
2048
2124
|
const seen = new Set(direct.map((n) => n.id));
|
|
2049
2125
|
for (const n of await nestsSharedViaTeams(userId)) {
|
|
@@ -2069,10 +2145,16 @@ async function listSharedNests(userId) {
|
|
|
2069
2145
|
);
|
|
2070
2146
|
return direct;
|
|
2071
2147
|
}
|
|
2072
|
-
async function listVisibleNests(userId) {
|
|
2148
|
+
async function listVisibleNests(userId, opts = {}) {
|
|
2073
2149
|
const db = getDb();
|
|
2074
2150
|
const includeAnon = config.AUTH_MODE === "open" || await isServerAdminUserId(userId);
|
|
2075
|
-
const params =
|
|
2151
|
+
const params = [
|
|
2152
|
+
userId,
|
|
2153
|
+
userId,
|
|
2154
|
+
...opts.readable ? [userId] : [],
|
|
2155
|
+
userId,
|
|
2156
|
+
...includeAnon ? [ANON_USER_ID] : []
|
|
2157
|
+
];
|
|
2076
2158
|
const rows = await db.all(
|
|
2077
2159
|
`SELECT DISTINCT n.* FROM nests n
|
|
2078
2160
|
LEFT JOIN nest_collaborators nc
|
|
@@ -2081,9 +2163,11 @@ async function listVisibleNests(userId) {
|
|
|
2081
2163
|
LEFT JOIN stewards s
|
|
2082
2164
|
ON s.nest_id = n.id AND s.is_active = 1
|
|
2083
2165
|
AND LOWER(s.user_email) = LOWER(u.email)
|
|
2166
|
+
${opts.readable ? "LEFT JOIN grants g ON g.nest_id = n.id AND g.user_id = ?" : ""}
|
|
2084
2167
|
WHERE n.user_id = ?
|
|
2085
2168
|
OR nc.user_id IS NOT NULL
|
|
2086
2169
|
OR s.id IS NOT NULL
|
|
2170
|
+
${opts.readable ? "OR g.id IS NOT NULL OR n.visibility = 'public'" : ""}
|
|
2087
2171
|
${includeAnon ? "OR n.user_id = ?" : ""}
|
|
2088
2172
|
ORDER BY n.created_at DESC`,
|
|
2089
2173
|
params
|
|
@@ -2220,6 +2304,7 @@ export {
|
|
|
2220
2304
|
canApproveWith,
|
|
2221
2305
|
primaryRole,
|
|
2222
2306
|
isServerAdminUserId,
|
|
2307
|
+
resolveNestAccess,
|
|
2223
2308
|
resolveNestPermission,
|
|
2224
2309
|
permissionLevel,
|
|
2225
2310
|
isPublicReader
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
createGrant,
|
|
3
3
|
deleteGrant,
|
|
4
4
|
grantCoversNode,
|
|
5
|
-
|
|
5
|
+
grantRoleForNode,
|
|
6
6
|
listGrants,
|
|
7
7
|
listUserGrants,
|
|
8
8
|
resolveNodeGrant
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HWDPCPYT.js";
|
|
10
10
|
import "./chunk-GUNJTORH.js";
|
|
11
11
|
import "./chunk-JMJLNEXE.js";
|
|
12
12
|
import "./chunk-SLTQACJW.js";
|
|
@@ -14,7 +14,7 @@ export {
|
|
|
14
14
|
createGrant,
|
|
15
15
|
deleteGrant,
|
|
16
16
|
grantCoversNode,
|
|
17
|
-
|
|
17
|
+
grantRoleForNode,
|
|
18
18
|
listGrants,
|
|
19
19
|
listUserGrants,
|
|
20
20
|
resolveNodeGrant
|