sticky-note-cli 3.1.13 → 3.1.15
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 +77 -0
- package/bin/cli.js +68 -0
- package/bin/mcp-server.js +51 -9
- package/package.json +1 -1
- package/sticky-server/.wrangler/cache/cf.json +1 -0
- package/sticky-server/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
- package/sticky-server/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
- package/sticky-server/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
- package/sticky-server/.wrangler/state/v3/do/sticky-note-server-StickyThread/metadata.sqlite +0 -0
- package/sticky-server/.wrangler/state/v3/do/sticky-note-server-StickyThread/metadata.sqlite-shm +0 -0
- package/sticky-server/.wrangler/state/v3/do/sticky-note-server-StickyThread/metadata.sqlite-wal +0 -0
- package/sticky-server/.wrangler/state/v3/kv/PLACEHOLDER_KV_NAMESPACE_ID/blobs/24473f36cce8fd4dcc0287333b336236fef2ffd176b20d9f9861257480f2d2f0000001a0272e56bb +1 -0
- package/sticky-server/.wrangler/state/v3/kv/PLACEHOLDER_KV_NAMESPACE_ID/blobs/896e937930a2be286388f1ae1003af2a41171bcdb97993b90e66a5836c4bce88000001a0272e57be +1 -0
- package/sticky-server/.wrangler/state/v3/kv/PLACEHOLDER_KV_NAMESPACE_ID/blobs/cb1dad011015782163f59d1e79653f10a354fc026eea8e482fe7417f4c4d7426000001a0272e57b2 +1 -0
- package/sticky-server/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/d561fc7d90f13b8d408360f0c2d3dad0579c60d59ea97622cecfbe29274283cd.sqlite +0 -0
- package/sticky-server/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite +0 -0
- package/sticky-server/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-shm +0 -0
- package/sticky-server/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-wal +0 -0
- package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite +0 -0
- package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-shm +0 -0
- package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-wal +0 -0
- package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite +0 -0
- package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-shm +0 -0
- package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-wal +0 -0
- package/sticky-server/.wrangler/tmp/bundle-BhcBKo/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-BhcBKo/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-BhcBKo/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/bundle-EyT3Z4/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-EyT3Z4/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-EyT3Z4/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/bundle-Fenl4S/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-Fenl4S/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-Fenl4S/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/bundle-GEjBtr/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-GEjBtr/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-GEjBtr/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/bundle-QVovzR/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-QVovzR/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-QVovzR/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/bundle-cuweP4/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-cuweP4/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-cuweP4/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/bundle-jSM6YE/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-jSM6YE/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-jSM6YE/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/bundle-skMxAR/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-skMxAR/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-skMxAR/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/bundle-ufHiFB/checked-fetch.js +28 -0
- package/sticky-server/.wrangler/tmp/bundle-ufHiFB/middleware-insertion-facade.js +11 -0
- package/sticky-server/.wrangler/tmp/bundle-ufHiFB/middleware-loader.entry.ts +134 -0
- package/sticky-server/.wrangler/tmp/dev-7URP42/worker.js +1006 -0
- package/sticky-server/.wrangler/tmp/dev-7URP42/worker.js.map +8 -0
- package/sticky-server/.wrangler/tmp/dev-J7vWKa/worker.js +1006 -0
- package/sticky-server/.wrangler/tmp/dev-J7vWKa/worker.js.map +8 -0
- package/sticky-server/.wrangler/tmp/dev-QZJJpV/worker.js +579 -0
- package/sticky-server/.wrangler/tmp/dev-QZJJpV/worker.js.map +8 -0
- package/sticky-server/.wrangler/tmp/dev-ZhpGzw/worker.js +1006 -0
- package/sticky-server/.wrangler/tmp/dev-ZhpGzw/worker.js.map +8 -0
- package/sticky-server/.wrangler/tmp/dev-Zj4Um8/worker.js +1006 -0
- package/sticky-server/.wrangler/tmp/dev-Zj4Um8/worker.js.map +8 -0
- package/sticky-server/.wrangler/tmp/dev-cV8SnT/worker.js +1006 -0
- package/sticky-server/.wrangler/tmp/dev-cV8SnT/worker.js.map +8 -0
- package/sticky-server/.wrangler/tmp/dev-dVJlR1/worker.js +1006 -0
- package/sticky-server/.wrangler/tmp/dev-dVJlR1/worker.js.map +8 -0
- package/sticky-server/.wrangler/tmp/dev-gZFGI3/worker.js +1006 -0
- package/sticky-server/.wrangler/tmp/dev-gZFGI3/worker.js.map +8 -0
- package/sticky-server/.wrangler/tmp/dev-rZTsQz/worker.js +1006 -0
- package/sticky-server/.wrangler/tmp/dev-rZTsQz/worker.js.map +8 -0
- package/sticky-server/adapters/cf-kv.js +60 -0
- package/sticky-server/mcp-tools.js +249 -0
- package/sticky-server/sticky-thread-do.js +134 -0
- package/sticky-server/worker.js +122 -1
- package/sticky-server/wrangler.toml +17 -0
- package/templates/gitignore-additions.txt +9 -0
- package/templates/hooks/event-writer.js +104 -0
- package/templates/hooks/inject-context.js +17 -12
- package/templates/hooks/on-error.js +46 -2
- package/templates/hooks/session-end.js +187 -22
- package/templates/hooks/session-start.js +27 -0
- package/templates/hooks/sticky-utils.js +12 -3
- package/templates/hooks/track-work.js +54 -14
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// .wrangler/tmp/bundle-jSM6YE/checked-fetch.js
|
|
5
|
+
var urls = /* @__PURE__ */ new Set();
|
|
6
|
+
function checkURL(request, init) {
|
|
7
|
+
const url = request instanceof URL ? request : new URL(
|
|
8
|
+
(typeof request === "string" ? new Request(request, init) : request).url
|
|
9
|
+
);
|
|
10
|
+
if (url.port && url.port !== "443" && url.protocol === "https:") {
|
|
11
|
+
if (!urls.has(url.toString())) {
|
|
12
|
+
urls.add(url.toString());
|
|
13
|
+
console.warn(
|
|
14
|
+
`WARNING: known issue with \`fetch()\` requests to custom HTTPS ports in published Workers:
|
|
15
|
+
- ${url.toString()} - the custom port will be ignored when the Worker is published using the \`wrangler deploy\` command.
|
|
16
|
+
`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
__name(checkURL, "checkURL");
|
|
22
|
+
globalThis.fetch = new Proxy(globalThis.fetch, {
|
|
23
|
+
apply(target, thisArg, argArray) {
|
|
24
|
+
const [request, init] = argArray;
|
|
25
|
+
checkURL(request, init);
|
|
26
|
+
return Reflect.apply(target, thisArg, argArray);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// adapters/cf-kv.js
|
|
31
|
+
async function getThreads(kv, project, filters = {}) {
|
|
32
|
+
const indexKey = `${project}:thread-index`;
|
|
33
|
+
const index = JSON.parse(await kv.get(indexKey) || "[]");
|
|
34
|
+
if (index.length === 0) return [];
|
|
35
|
+
const threads = await Promise.all(
|
|
36
|
+
index.map(async (id) => {
|
|
37
|
+
const raw = await kv.get(`${project}:thread:${id}`);
|
|
38
|
+
return raw ? JSON.parse(raw) : null;
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
let result = threads.filter(Boolean);
|
|
42
|
+
if (filters.status) {
|
|
43
|
+
result = result.filter((t) => t.status === filters.status);
|
|
44
|
+
}
|
|
45
|
+
if (filters.q) {
|
|
46
|
+
const q = filters.q.toLowerCase();
|
|
47
|
+
result = result.filter(
|
|
48
|
+
(t) => (t.narrative || "").toLowerCase().includes(q) || (t.handoff_summary || "").toLowerCase().includes(q) || (t.last_note || "").toLowerCase().includes(q) || (t.files_touched || []).some((f) => f.toLowerCase().includes(q))
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
__name(getThreads, "getThreads");
|
|
54
|
+
async function getThread(kv, project, id) {
|
|
55
|
+
const raw = await kv.get(`${project}:thread:${id}`);
|
|
56
|
+
return raw ? JSON.parse(raw) : null;
|
|
57
|
+
}
|
|
58
|
+
__name(getThread, "getThread");
|
|
59
|
+
async function putThread(kv, project, thread) {
|
|
60
|
+
const id = thread.id;
|
|
61
|
+
await kv.put(`${project}:thread:${id}`, JSON.stringify(thread));
|
|
62
|
+
const indexKey = `${project}:thread-index`;
|
|
63
|
+
const index = JSON.parse(await kv.get(indexKey) || "[]");
|
|
64
|
+
if (!index.includes(id)) {
|
|
65
|
+
index.push(id);
|
|
66
|
+
await kv.put(indexKey, JSON.stringify(index));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
__name(putThread, "putThread");
|
|
70
|
+
async function deleteThread(kv, project, id) {
|
|
71
|
+
const existing = await getThread(kv, project, id);
|
|
72
|
+
if (existing) {
|
|
73
|
+
const tombstone = {
|
|
74
|
+
id: existing.id,
|
|
75
|
+
user: existing.user,
|
|
76
|
+
status: "expired",
|
|
77
|
+
closed_at: existing.closed_at || (/* @__PURE__ */ new Date()).toISOString(),
|
|
78
|
+
created_at: existing.created_at
|
|
79
|
+
};
|
|
80
|
+
await kv.put(`${project}:thread:${id}`, JSON.stringify(tombstone));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
__name(deleteThread, "deleteThread");
|
|
84
|
+
async function appendAudit(kv, project, record) {
|
|
85
|
+
const ts = record.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
86
|
+
const uid = crypto.randomUUID();
|
|
87
|
+
const key = `${project}:audit:${ts}:${uid}`;
|
|
88
|
+
await kv.put(key, JSON.stringify(record));
|
|
89
|
+
const indexKey = `${project}:audit-index`;
|
|
90
|
+
const index = JSON.parse(await kv.get(indexKey) || "[]");
|
|
91
|
+
index.push(key);
|
|
92
|
+
if (index.length > 1e4) {
|
|
93
|
+
const removed = index.splice(0, index.length - 1e4);
|
|
94
|
+
await Promise.all(removed.map((k) => kv.delete(k)));
|
|
95
|
+
}
|
|
96
|
+
await kv.put(indexKey, JSON.stringify(index));
|
|
97
|
+
}
|
|
98
|
+
__name(appendAudit, "appendAudit");
|
|
99
|
+
async function queryAudit(kv, project, filters = {}) {
|
|
100
|
+
const indexKey = `${project}:audit-index`;
|
|
101
|
+
const index = JSON.parse(await kv.get(indexKey) || "[]");
|
|
102
|
+
if (index.length === 0) return [];
|
|
103
|
+
const records = await Promise.all(
|
|
104
|
+
index.map(async (key) => {
|
|
105
|
+
const raw = await kv.get(key);
|
|
106
|
+
return raw ? JSON.parse(raw) : null;
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
let result = records.filter(Boolean);
|
|
110
|
+
if (filters.user) {
|
|
111
|
+
result = result.filter((r) => r.user === filters.user);
|
|
112
|
+
}
|
|
113
|
+
if (filters.file) {
|
|
114
|
+
result = result.filter((r) => (r.file || "").includes(filters.file));
|
|
115
|
+
}
|
|
116
|
+
if (filters.tool) {
|
|
117
|
+
result = result.filter((r) => r.tool === filters.tool);
|
|
118
|
+
}
|
|
119
|
+
if (filters.since) {
|
|
120
|
+
const since = new Date(filters.since).getTime();
|
|
121
|
+
result = result.filter(
|
|
122
|
+
(r) => new Date(r.timestamp || 0).getTime() >= since
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
__name(queryAudit, "queryAudit");
|
|
128
|
+
var PRESENCE_TTL_SECONDS = 15 * 60;
|
|
129
|
+
async function getPresence(kv, project) {
|
|
130
|
+
const indexKey = `${project}:presence-index`;
|
|
131
|
+
const index = JSON.parse(await kv.get(indexKey) || "[]");
|
|
132
|
+
if (index.length === 0) return [];
|
|
133
|
+
const records = await Promise.all(
|
|
134
|
+
index.map(async (user) => {
|
|
135
|
+
const raw = await kv.get(`${project}:presence:${user}`);
|
|
136
|
+
return raw ? JSON.parse(raw) : null;
|
|
137
|
+
})
|
|
138
|
+
);
|
|
139
|
+
return records.filter(Boolean);
|
|
140
|
+
}
|
|
141
|
+
__name(getPresence, "getPresence");
|
|
142
|
+
async function upsertPresence(kv, project, record) {
|
|
143
|
+
const user = record.user;
|
|
144
|
+
await kv.put(`${project}:presence:${user}`, JSON.stringify(record), {
|
|
145
|
+
expirationTtl: PRESENCE_TTL_SECONDS
|
|
146
|
+
});
|
|
147
|
+
const indexKey = `${project}:presence-index`;
|
|
148
|
+
const index = JSON.parse(await kv.get(indexKey) || "[]");
|
|
149
|
+
if (!index.includes(user)) {
|
|
150
|
+
index.push(user);
|
|
151
|
+
await kv.put(indexKey, JSON.stringify(index));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
__name(upsertPresence, "upsertPresence");
|
|
155
|
+
async function deletePresence(kv, project, user) {
|
|
156
|
+
await kv.delete(`${project}:presence:${user}`);
|
|
157
|
+
const indexKey = `${project}:presence-index`;
|
|
158
|
+
const index = JSON.parse(await kv.get(indexKey) || "[]");
|
|
159
|
+
const filtered = index.filter((u) => u !== user);
|
|
160
|
+
await kv.put(indexKey, JSON.stringify(filtered));
|
|
161
|
+
}
|
|
162
|
+
__name(deletePresence, "deletePresence");
|
|
163
|
+
var MAX_CHUNK_BYTES = 2 * 1024 * 1024;
|
|
164
|
+
async function getEvents(kv, project, threadId) {
|
|
165
|
+
const metaKey = `${project}:thread:${threadId}`;
|
|
166
|
+
const meta = await kv.get(metaKey, { type: "json" }).catch(() => null);
|
|
167
|
+
const chunkCount = meta && meta._event_chunks || 0;
|
|
168
|
+
if (chunkCount === 0) {
|
|
169
|
+
const single = await kv.get(`${metaKey}:events`, { type: "json" }).catch(() => null);
|
|
170
|
+
return Array.isArray(single) ? single : [];
|
|
171
|
+
}
|
|
172
|
+
const chunks = await Promise.all(
|
|
173
|
+
Array.from(
|
|
174
|
+
{ length: chunkCount },
|
|
175
|
+
(_, i) => kv.get(`${metaKey}:events:${i}`, { type: "json" }).catch(() => [])
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
return chunks.flat().filter(Boolean);
|
|
179
|
+
}
|
|
180
|
+
__name(getEvents, "getEvents");
|
|
181
|
+
async function appendEvents(kv, project, threadId, newEvents) {
|
|
182
|
+
if (!newEvents || newEvents.length === 0) return;
|
|
183
|
+
const metaKey = `${project}:thread:${threadId}`;
|
|
184
|
+
const meta = await kv.get(metaKey, { type: "json" }).catch(() => ({}));
|
|
185
|
+
const chunkCount = meta && meta._event_chunks || 0;
|
|
186
|
+
let currentChunkIdx = chunkCount === 0 ? 0 : chunkCount - 1;
|
|
187
|
+
let currentChunk = [];
|
|
188
|
+
if (chunkCount > 0) {
|
|
189
|
+
currentChunk = await kv.get(`${metaKey}:events:${currentChunkIdx}`, { type: "json" }).catch(() => []) || [];
|
|
190
|
+
}
|
|
191
|
+
for (const event of newEvents) {
|
|
192
|
+
const eventBytes = new TextEncoder().encode(JSON.stringify(event)).length;
|
|
193
|
+
const chunkBytes = new TextEncoder().encode(JSON.stringify(currentChunk)).length;
|
|
194
|
+
if (chunkBytes + eventBytes > MAX_CHUNK_BYTES && currentChunk.length > 0) {
|
|
195
|
+
await kv.put(`${metaKey}:events:${currentChunkIdx}`, JSON.stringify(currentChunk));
|
|
196
|
+
currentChunkIdx++;
|
|
197
|
+
currentChunk = [];
|
|
198
|
+
}
|
|
199
|
+
currentChunk.push(event);
|
|
200
|
+
}
|
|
201
|
+
await kv.put(`${metaKey}:events:${currentChunkIdx}`, JSON.stringify(currentChunk));
|
|
202
|
+
const newMeta = { ...meta || {}, _event_chunks: currentChunkIdx + 1 };
|
|
203
|
+
await kv.put(metaKey, JSON.stringify(newMeta));
|
|
204
|
+
}
|
|
205
|
+
__name(appendEvents, "appendEvents");
|
|
206
|
+
async function getConfig(kv, project) {
|
|
207
|
+
const raw = await kv.get(`${project}:config`);
|
|
208
|
+
return raw ? JSON.parse(raw) : null;
|
|
209
|
+
}
|
|
210
|
+
__name(getConfig, "getConfig");
|
|
211
|
+
async function putConfig(kv, project, config) {
|
|
212
|
+
await kv.put(`${project}:config`, JSON.stringify(config));
|
|
213
|
+
}
|
|
214
|
+
__name(putConfig, "putConfig");
|
|
215
|
+
|
|
216
|
+
// worker.js
|
|
217
|
+
function json(data, status = 200) {
|
|
218
|
+
return new Response(JSON.stringify(data), {
|
|
219
|
+
status,
|
|
220
|
+
headers: { "Content-Type": "application/json" }
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
__name(json, "json");
|
|
224
|
+
function error(message, status = 400) {
|
|
225
|
+
return json({ error: message }, status);
|
|
226
|
+
}
|
|
227
|
+
__name(error, "error");
|
|
228
|
+
function authenticate(request, env) {
|
|
229
|
+
const key = request.headers.get("X-Sticky-API-Key");
|
|
230
|
+
if (!env.STICKY_API_KEY) return true;
|
|
231
|
+
return key === env.STICKY_API_KEY;
|
|
232
|
+
}
|
|
233
|
+
__name(authenticate, "authenticate");
|
|
234
|
+
function getProject(request) {
|
|
235
|
+
return request.headers.get("X-Sticky-Project") || "default";
|
|
236
|
+
}
|
|
237
|
+
__name(getProject, "getProject");
|
|
238
|
+
function matchRoute(method, pathname) {
|
|
239
|
+
if (method === "POST" && pathname === "/threads") return { handler: "createThread" };
|
|
240
|
+
if (method === "GET" && pathname === "/threads") return { handler: "listThreads" };
|
|
241
|
+
if (method === "POST" && pathname.match(/^\/threads\/[^/]+\/events$/)) {
|
|
242
|
+
const id = pathname.split("/")[2];
|
|
243
|
+
return { handler: "appendThreadEvents", id };
|
|
244
|
+
}
|
|
245
|
+
if (method === "GET" && pathname.match(/^\/threads\/[^/]+\/events$/)) {
|
|
246
|
+
const id = pathname.split("/")[2];
|
|
247
|
+
return { handler: "getThreadEvents", id };
|
|
248
|
+
}
|
|
249
|
+
if (method === "GET" && pathname.startsWith("/threads/")) {
|
|
250
|
+
return { handler: "getThread", id: pathname.slice("/threads/".length) };
|
|
251
|
+
}
|
|
252
|
+
if (method === "PUT" && pathname.startsWith("/threads/")) {
|
|
253
|
+
return { handler: "updateThread", id: pathname.slice("/threads/".length) };
|
|
254
|
+
}
|
|
255
|
+
if (method === "DELETE" && pathname.startsWith("/threads/")) {
|
|
256
|
+
return { handler: "deleteThread", id: pathname.slice("/threads/".length) };
|
|
257
|
+
}
|
|
258
|
+
if (method === "GET" && pathname === "/audit") return { handler: "queryAudit" };
|
|
259
|
+
if (method === "POST" && pathname === "/audit") return { handler: "appendAudit" };
|
|
260
|
+
if (method === "GET" && pathname === "/presence") return { handler: "getPresence" };
|
|
261
|
+
if (method === "POST" && pathname === "/presence") return { handler: "upsertPresence" };
|
|
262
|
+
if (method === "DELETE" && pathname.startsWith("/presence/")) {
|
|
263
|
+
return { handler: "deletePresence", user: decodeURIComponent(pathname.slice("/presence/".length)) };
|
|
264
|
+
}
|
|
265
|
+
if (method === "GET" && pathname === "/config") return { handler: "getConfig" };
|
|
266
|
+
if (method === "PUT" && pathname === "/config") return { handler: "putConfig" };
|
|
267
|
+
if (method === "GET" && pathname === "/health") return { handler: "health" };
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
__name(matchRoute, "matchRoute");
|
|
271
|
+
var handlers = {
|
|
272
|
+
async health() {
|
|
273
|
+
return json({ status: "ok", version: "3.0.0" });
|
|
274
|
+
},
|
|
275
|
+
// ── Threads ──
|
|
276
|
+
async createThread(request, kv, project) {
|
|
277
|
+
const thread = await request.json();
|
|
278
|
+
if (!thread.id) return error("thread.id is required");
|
|
279
|
+
await putThread(kv, project, thread);
|
|
280
|
+
return json(thread, 201);
|
|
281
|
+
},
|
|
282
|
+
async listThreads(request, kv, project) {
|
|
283
|
+
const url = new URL(request.url);
|
|
284
|
+
const filters = {
|
|
285
|
+
status: url.searchParams.get("status") || void 0,
|
|
286
|
+
q: url.searchParams.get("q") || void 0
|
|
287
|
+
};
|
|
288
|
+
const threads = await getThreads(kv, project, filters);
|
|
289
|
+
return json({ threads });
|
|
290
|
+
},
|
|
291
|
+
async getThread(_request, kv, project, { id }) {
|
|
292
|
+
const thread = await getThread(kv, project, id);
|
|
293
|
+
if (!thread) return error("Thread not found", 404);
|
|
294
|
+
return json(thread);
|
|
295
|
+
},
|
|
296
|
+
async updateThread(request, kv, project, { id }) {
|
|
297
|
+
const thread = await request.json();
|
|
298
|
+
thread.id = id;
|
|
299
|
+
await putThread(kv, project, thread);
|
|
300
|
+
return json(thread);
|
|
301
|
+
},
|
|
302
|
+
async deleteThread(_request, kv, project, { id }) {
|
|
303
|
+
await deleteThread(kv, project, id);
|
|
304
|
+
return json({ deleted: id });
|
|
305
|
+
},
|
|
306
|
+
// ── Thread Events ──
|
|
307
|
+
async appendThreadEvents(request, kv, project, { id }) {
|
|
308
|
+
const body = await request.json().catch(() => ({}));
|
|
309
|
+
const events = Array.isArray(body.events) ? body.events : [];
|
|
310
|
+
await appendEvents(kv, project, id, events);
|
|
311
|
+
return json({ ok: true, appended: events.length });
|
|
312
|
+
},
|
|
313
|
+
async getThreadEvents(_request, kv, project, { id }) {
|
|
314
|
+
const events = await getEvents(kv, project, id);
|
|
315
|
+
return json({ events });
|
|
316
|
+
},
|
|
317
|
+
// ── Audit ──
|
|
318
|
+
async queryAudit(request, kv, project) {
|
|
319
|
+
const url = new URL(request.url);
|
|
320
|
+
const filters = {
|
|
321
|
+
user: url.searchParams.get("user") || void 0,
|
|
322
|
+
file: url.searchParams.get("file") || void 0,
|
|
323
|
+
tool: url.searchParams.get("tool") || void 0,
|
|
324
|
+
since: url.searchParams.get("since") || void 0
|
|
325
|
+
};
|
|
326
|
+
const records = await queryAudit(kv, project, filters);
|
|
327
|
+
return json({ audit: records });
|
|
328
|
+
},
|
|
329
|
+
async appendAudit(request, kv, project) {
|
|
330
|
+
const record = await request.json();
|
|
331
|
+
await appendAudit(kv, project, record);
|
|
332
|
+
return json({ ok: true }, 201);
|
|
333
|
+
},
|
|
334
|
+
// ── Presence ──
|
|
335
|
+
async getPresence(_request, kv, project) {
|
|
336
|
+
const records = await getPresence(kv, project);
|
|
337
|
+
return json({ presence: records });
|
|
338
|
+
},
|
|
339
|
+
async upsertPresence(request, kv, project) {
|
|
340
|
+
const record = await request.json();
|
|
341
|
+
if (!record.user) return error("record.user is required");
|
|
342
|
+
await upsertPresence(kv, project, record);
|
|
343
|
+
return json({ ok: true });
|
|
344
|
+
},
|
|
345
|
+
async deletePresence(_request, kv, project, { user }) {
|
|
346
|
+
await deletePresence(kv, project, user);
|
|
347
|
+
return json({ deleted: user });
|
|
348
|
+
},
|
|
349
|
+
// ── Config ──
|
|
350
|
+
async getConfig(_request, kv, project) {
|
|
351
|
+
const config = await getConfig(kv, project);
|
|
352
|
+
if (!config) return json({});
|
|
353
|
+
return json(config);
|
|
354
|
+
},
|
|
355
|
+
async putConfig(request, kv, project) {
|
|
356
|
+
const config = await request.json();
|
|
357
|
+
await putConfig(kv, project, config);
|
|
358
|
+
return json(config);
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
var worker_default = {
|
|
362
|
+
async fetch(request, env) {
|
|
363
|
+
if (request.method === "OPTIONS") {
|
|
364
|
+
return new Response(null, {
|
|
365
|
+
status: 204,
|
|
366
|
+
headers: {
|
|
367
|
+
"Access-Control-Allow-Origin": "*",
|
|
368
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
369
|
+
"Access-Control-Allow-Headers": "Content-Type, X-Sticky-API-Key, X-Sticky-Project"
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
if (!authenticate(request, env)) {
|
|
374
|
+
return error("Unauthorized", 401);
|
|
375
|
+
}
|
|
376
|
+
const url = new URL(request.url);
|
|
377
|
+
const route = matchRoute(request.method, url.pathname);
|
|
378
|
+
if (!route) {
|
|
379
|
+
return error("Not found", 404);
|
|
380
|
+
}
|
|
381
|
+
const project = getProject(request);
|
|
382
|
+
const kv = env.STICKY_KV;
|
|
383
|
+
try {
|
|
384
|
+
const handler = handlers[route.handler];
|
|
385
|
+
const response = await handler(request, kv, project, route);
|
|
386
|
+
const headers = new Headers(response.headers);
|
|
387
|
+
headers.set("Access-Control-Allow-Origin", "*");
|
|
388
|
+
return new Response(response.body, {
|
|
389
|
+
status: response.status,
|
|
390
|
+
headers
|
|
391
|
+
});
|
|
392
|
+
} catch (err) {
|
|
393
|
+
return error(`Internal error: ${err.message}`, 500);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// ../../../../../AppData/Roaming/npm/node_modules/wrangler/templates/middleware/middleware-ensure-req-body-drained.ts
|
|
399
|
+
var drainBody = /* @__PURE__ */ __name(async (request, env, _ctx, middlewareCtx) => {
|
|
400
|
+
try {
|
|
401
|
+
return await middlewareCtx.next(request, env);
|
|
402
|
+
} finally {
|
|
403
|
+
try {
|
|
404
|
+
if (request.body !== null && !request.bodyUsed) {
|
|
405
|
+
const reader = request.body.getReader();
|
|
406
|
+
while (!(await reader.read()).done) {
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
} catch (e) {
|
|
410
|
+
console.error("Failed to drain the unused request body.", e);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}, "drainBody");
|
|
414
|
+
var middleware_ensure_req_body_drained_default = drainBody;
|
|
415
|
+
|
|
416
|
+
// ../../../../../AppData/Roaming/npm/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts
|
|
417
|
+
function reduceError(e) {
|
|
418
|
+
return {
|
|
419
|
+
name: e?.name,
|
|
420
|
+
message: e?.message ?? String(e),
|
|
421
|
+
stack: e?.stack,
|
|
422
|
+
cause: e?.cause === void 0 ? void 0 : reduceError(e.cause)
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
__name(reduceError, "reduceError");
|
|
426
|
+
var jsonError = /* @__PURE__ */ __name(async (request, env, _ctx, middlewareCtx) => {
|
|
427
|
+
try {
|
|
428
|
+
return await middlewareCtx.next(request, env);
|
|
429
|
+
} catch (e) {
|
|
430
|
+
const error2 = reduceError(e);
|
|
431
|
+
const body = JSON.stringify(error2);
|
|
432
|
+
const headers = {
|
|
433
|
+
"Content-Type": "application/json",
|
|
434
|
+
"MF-Experimental-Error-Stack": "true"
|
|
435
|
+
};
|
|
436
|
+
const encoded = encodeURIComponent(body);
|
|
437
|
+
if (encoded.length <= 8192) {
|
|
438
|
+
headers["MF-Experimental-Error-Stack-Payload"] = encoded;
|
|
439
|
+
}
|
|
440
|
+
return new Response(body, { status: 500, headers });
|
|
441
|
+
}
|
|
442
|
+
}, "jsonError");
|
|
443
|
+
var middleware_miniflare3_json_error_default = jsonError;
|
|
444
|
+
|
|
445
|
+
// .wrangler/tmp/bundle-jSM6YE/middleware-insertion-facade.js
|
|
446
|
+
var __INTERNAL_WRANGLER_MIDDLEWARE__ = [
|
|
447
|
+
middleware_ensure_req_body_drained_default,
|
|
448
|
+
middleware_miniflare3_json_error_default
|
|
449
|
+
];
|
|
450
|
+
var middleware_insertion_facade_default = worker_default;
|
|
451
|
+
|
|
452
|
+
// ../../../../../AppData/Roaming/npm/node_modules/wrangler/templates/middleware/common.ts
|
|
453
|
+
var __facade_middleware__ = [];
|
|
454
|
+
function __facade_register__(...args) {
|
|
455
|
+
__facade_middleware__.push(...args.flat());
|
|
456
|
+
}
|
|
457
|
+
__name(__facade_register__, "__facade_register__");
|
|
458
|
+
function __facade_invokeChain__(request, env, ctx, dispatch, middlewareChain) {
|
|
459
|
+
const [head, ...tail] = middlewareChain;
|
|
460
|
+
const middlewareCtx = {
|
|
461
|
+
dispatch,
|
|
462
|
+
next(newRequest, newEnv) {
|
|
463
|
+
return __facade_invokeChain__(newRequest, newEnv, ctx, dispatch, tail);
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
return head(request, env, ctx, middlewareCtx);
|
|
467
|
+
}
|
|
468
|
+
__name(__facade_invokeChain__, "__facade_invokeChain__");
|
|
469
|
+
function __facade_invoke__(request, env, ctx, dispatch, finalMiddleware) {
|
|
470
|
+
return __facade_invokeChain__(request, env, ctx, dispatch, [
|
|
471
|
+
...__facade_middleware__,
|
|
472
|
+
finalMiddleware
|
|
473
|
+
]);
|
|
474
|
+
}
|
|
475
|
+
__name(__facade_invoke__, "__facade_invoke__");
|
|
476
|
+
|
|
477
|
+
// .wrangler/tmp/bundle-jSM6YE/middleware-loader.entry.ts
|
|
478
|
+
var __Facade_ScheduledController__ = class ___Facade_ScheduledController__ {
|
|
479
|
+
constructor(scheduledTime, cron, noRetry) {
|
|
480
|
+
this.scheduledTime = scheduledTime;
|
|
481
|
+
this.cron = cron;
|
|
482
|
+
this.#noRetry = noRetry;
|
|
483
|
+
}
|
|
484
|
+
scheduledTime;
|
|
485
|
+
cron;
|
|
486
|
+
static {
|
|
487
|
+
__name(this, "__Facade_ScheduledController__");
|
|
488
|
+
}
|
|
489
|
+
#noRetry;
|
|
490
|
+
noRetry() {
|
|
491
|
+
if (!(this instanceof ___Facade_ScheduledController__)) {
|
|
492
|
+
throw new TypeError("Illegal invocation");
|
|
493
|
+
}
|
|
494
|
+
this.#noRetry();
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
function wrapExportedHandler(worker) {
|
|
498
|
+
if (__INTERNAL_WRANGLER_MIDDLEWARE__ === void 0 || __INTERNAL_WRANGLER_MIDDLEWARE__.length === 0) {
|
|
499
|
+
return worker;
|
|
500
|
+
}
|
|
501
|
+
for (const middleware of __INTERNAL_WRANGLER_MIDDLEWARE__) {
|
|
502
|
+
__facade_register__(middleware);
|
|
503
|
+
}
|
|
504
|
+
const fetchDispatcher = /* @__PURE__ */ __name(function(request, env, ctx) {
|
|
505
|
+
if (worker.fetch === void 0) {
|
|
506
|
+
throw new Error("Handler does not export a fetch() function.");
|
|
507
|
+
}
|
|
508
|
+
return worker.fetch(request, env, ctx);
|
|
509
|
+
}, "fetchDispatcher");
|
|
510
|
+
return {
|
|
511
|
+
...worker,
|
|
512
|
+
fetch(request, env, ctx) {
|
|
513
|
+
const dispatcher = /* @__PURE__ */ __name(function(type, init) {
|
|
514
|
+
if (type === "scheduled" && worker.scheduled !== void 0) {
|
|
515
|
+
const controller = new __Facade_ScheduledController__(
|
|
516
|
+
Date.now(),
|
|
517
|
+
init.cron ?? "",
|
|
518
|
+
() => {
|
|
519
|
+
}
|
|
520
|
+
);
|
|
521
|
+
return worker.scheduled(controller, env, ctx);
|
|
522
|
+
}
|
|
523
|
+
}, "dispatcher");
|
|
524
|
+
return __facade_invoke__(request, env, ctx, dispatcher, fetchDispatcher);
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
__name(wrapExportedHandler, "wrapExportedHandler");
|
|
529
|
+
function wrapWorkerEntrypoint(klass) {
|
|
530
|
+
if (__INTERNAL_WRANGLER_MIDDLEWARE__ === void 0 || __INTERNAL_WRANGLER_MIDDLEWARE__.length === 0) {
|
|
531
|
+
return klass;
|
|
532
|
+
}
|
|
533
|
+
for (const middleware of __INTERNAL_WRANGLER_MIDDLEWARE__) {
|
|
534
|
+
__facade_register__(middleware);
|
|
535
|
+
}
|
|
536
|
+
return class extends klass {
|
|
537
|
+
#fetchDispatcher = /* @__PURE__ */ __name((request, env, ctx) => {
|
|
538
|
+
this.env = env;
|
|
539
|
+
this.ctx = ctx;
|
|
540
|
+
if (super.fetch === void 0) {
|
|
541
|
+
throw new Error("Entrypoint class does not define a fetch() function.");
|
|
542
|
+
}
|
|
543
|
+
return super.fetch(request);
|
|
544
|
+
}, "#fetchDispatcher");
|
|
545
|
+
#dispatcher = /* @__PURE__ */ __name((type, init) => {
|
|
546
|
+
if (type === "scheduled" && super.scheduled !== void 0) {
|
|
547
|
+
const controller = new __Facade_ScheduledController__(
|
|
548
|
+
Date.now(),
|
|
549
|
+
init.cron ?? "",
|
|
550
|
+
() => {
|
|
551
|
+
}
|
|
552
|
+
);
|
|
553
|
+
return super.scheduled(controller);
|
|
554
|
+
}
|
|
555
|
+
}, "#dispatcher");
|
|
556
|
+
fetch(request) {
|
|
557
|
+
return __facade_invoke__(
|
|
558
|
+
request,
|
|
559
|
+
this.env,
|
|
560
|
+
this.ctx,
|
|
561
|
+
this.#dispatcher,
|
|
562
|
+
this.#fetchDispatcher
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
__name(wrapWorkerEntrypoint, "wrapWorkerEntrypoint");
|
|
568
|
+
var WRAPPED_ENTRY;
|
|
569
|
+
if (typeof middleware_insertion_facade_default === "object") {
|
|
570
|
+
WRAPPED_ENTRY = wrapExportedHandler(middleware_insertion_facade_default);
|
|
571
|
+
} else if (typeof middleware_insertion_facade_default === "function") {
|
|
572
|
+
WRAPPED_ENTRY = wrapWorkerEntrypoint(middleware_insertion_facade_default);
|
|
573
|
+
}
|
|
574
|
+
var middleware_loader_entry_default = WRAPPED_ENTRY;
|
|
575
|
+
export {
|
|
576
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__,
|
|
577
|
+
middleware_loader_entry_default as default
|
|
578
|
+
};
|
|
579
|
+
//# sourceMappingURL=worker.js.map
|