sticky-note-cli 3.1.14 → 3.1.16

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.
Files changed (82) hide show
  1. package/README.md +77 -0
  2. package/bin/cli.js +61 -0
  3. package/bin/mcp-server.js +51 -9
  4. package/package.json +1 -1
  5. package/sticky-server/.wrangler/cache/cf.json +1 -0
  6. package/sticky-server/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  7. package/sticky-server/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  8. package/sticky-server/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  9. package/sticky-server/.wrangler/state/v3/do/sticky-note-server-StickyThread/metadata.sqlite +0 -0
  10. package/sticky-server/.wrangler/state/v3/do/sticky-note-server-StickyThread/metadata.sqlite-shm +0 -0
  11. package/sticky-server/.wrangler/state/v3/do/sticky-note-server-StickyThread/metadata.sqlite-wal +0 -0
  12. package/sticky-server/.wrangler/state/v3/kv/PLACEHOLDER_KV_NAMESPACE_ID/blobs/24473f36cce8fd4dcc0287333b336236fef2ffd176b20d9f9861257480f2d2f0000001a0272e56bb +1 -0
  13. package/sticky-server/.wrangler/state/v3/kv/PLACEHOLDER_KV_NAMESPACE_ID/blobs/896e937930a2be286388f1ae1003af2a41171bcdb97993b90e66a5836c4bce88000001a0272e57be +1 -0
  14. package/sticky-server/.wrangler/state/v3/kv/PLACEHOLDER_KV_NAMESPACE_ID/blobs/cb1dad011015782163f59d1e79653f10a354fc026eea8e482fe7417f4c4d7426000001a0272e57b2 +1 -0
  15. package/sticky-server/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/d561fc7d90f13b8d408360f0c2d3dad0579c60d59ea97622cecfbe29274283cd.sqlite +0 -0
  16. package/sticky-server/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite +0 -0
  17. package/sticky-server/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-shm +0 -0
  18. package/sticky-server/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-wal +0 -0
  19. package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite +0 -0
  20. package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-shm +0 -0
  21. package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-wal +0 -0
  22. package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite +0 -0
  23. package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-shm +0 -0
  24. package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-wal +0 -0
  25. package/sticky-server/.wrangler/tmp/bundle-BhcBKo/checked-fetch.js +28 -0
  26. package/sticky-server/.wrangler/tmp/bundle-BhcBKo/middleware-insertion-facade.js +11 -0
  27. package/sticky-server/.wrangler/tmp/bundle-BhcBKo/middleware-loader.entry.ts +134 -0
  28. package/sticky-server/.wrangler/tmp/bundle-EyT3Z4/checked-fetch.js +28 -0
  29. package/sticky-server/.wrangler/tmp/bundle-EyT3Z4/middleware-insertion-facade.js +11 -0
  30. package/sticky-server/.wrangler/tmp/bundle-EyT3Z4/middleware-loader.entry.ts +134 -0
  31. package/sticky-server/.wrangler/tmp/bundle-Fenl4S/checked-fetch.js +28 -0
  32. package/sticky-server/.wrangler/tmp/bundle-Fenl4S/middleware-insertion-facade.js +11 -0
  33. package/sticky-server/.wrangler/tmp/bundle-Fenl4S/middleware-loader.entry.ts +134 -0
  34. package/sticky-server/.wrangler/tmp/bundle-GEjBtr/checked-fetch.js +28 -0
  35. package/sticky-server/.wrangler/tmp/bundle-GEjBtr/middleware-insertion-facade.js +11 -0
  36. package/sticky-server/.wrangler/tmp/bundle-GEjBtr/middleware-loader.entry.ts +134 -0
  37. package/sticky-server/.wrangler/tmp/bundle-QVovzR/checked-fetch.js +28 -0
  38. package/sticky-server/.wrangler/tmp/bundle-QVovzR/middleware-insertion-facade.js +11 -0
  39. package/sticky-server/.wrangler/tmp/bundle-QVovzR/middleware-loader.entry.ts +134 -0
  40. package/sticky-server/.wrangler/tmp/bundle-cuweP4/checked-fetch.js +28 -0
  41. package/sticky-server/.wrangler/tmp/bundle-cuweP4/middleware-insertion-facade.js +11 -0
  42. package/sticky-server/.wrangler/tmp/bundle-cuweP4/middleware-loader.entry.ts +134 -0
  43. package/sticky-server/.wrangler/tmp/bundle-jSM6YE/checked-fetch.js +28 -0
  44. package/sticky-server/.wrangler/tmp/bundle-jSM6YE/middleware-insertion-facade.js +11 -0
  45. package/sticky-server/.wrangler/tmp/bundle-jSM6YE/middleware-loader.entry.ts +134 -0
  46. package/sticky-server/.wrangler/tmp/bundle-skMxAR/checked-fetch.js +28 -0
  47. package/sticky-server/.wrangler/tmp/bundle-skMxAR/middleware-insertion-facade.js +11 -0
  48. package/sticky-server/.wrangler/tmp/bundle-skMxAR/middleware-loader.entry.ts +134 -0
  49. package/sticky-server/.wrangler/tmp/bundle-ufHiFB/checked-fetch.js +28 -0
  50. package/sticky-server/.wrangler/tmp/bundle-ufHiFB/middleware-insertion-facade.js +11 -0
  51. package/sticky-server/.wrangler/tmp/bundle-ufHiFB/middleware-loader.entry.ts +134 -0
  52. package/sticky-server/.wrangler/tmp/dev-7URP42/worker.js +1006 -0
  53. package/sticky-server/.wrangler/tmp/dev-7URP42/worker.js.map +8 -0
  54. package/sticky-server/.wrangler/tmp/dev-J7vWKa/worker.js +1006 -0
  55. package/sticky-server/.wrangler/tmp/dev-J7vWKa/worker.js.map +8 -0
  56. package/sticky-server/.wrangler/tmp/dev-QZJJpV/worker.js +579 -0
  57. package/sticky-server/.wrangler/tmp/dev-QZJJpV/worker.js.map +8 -0
  58. package/sticky-server/.wrangler/tmp/dev-ZhpGzw/worker.js +1006 -0
  59. package/sticky-server/.wrangler/tmp/dev-ZhpGzw/worker.js.map +8 -0
  60. package/sticky-server/.wrangler/tmp/dev-Zj4Um8/worker.js +1006 -0
  61. package/sticky-server/.wrangler/tmp/dev-Zj4Um8/worker.js.map +8 -0
  62. package/sticky-server/.wrangler/tmp/dev-cV8SnT/worker.js +1006 -0
  63. package/sticky-server/.wrangler/tmp/dev-cV8SnT/worker.js.map +8 -0
  64. package/sticky-server/.wrangler/tmp/dev-dVJlR1/worker.js +1006 -0
  65. package/sticky-server/.wrangler/tmp/dev-dVJlR1/worker.js.map +8 -0
  66. package/sticky-server/.wrangler/tmp/dev-gZFGI3/worker.js +1006 -0
  67. package/sticky-server/.wrangler/tmp/dev-gZFGI3/worker.js.map +8 -0
  68. package/sticky-server/.wrangler/tmp/dev-rZTsQz/worker.js +1006 -0
  69. package/sticky-server/.wrangler/tmp/dev-rZTsQz/worker.js.map +8 -0
  70. package/sticky-server/adapters/cf-kv.js +60 -0
  71. package/sticky-server/mcp-tools.js +249 -0
  72. package/sticky-server/sticky-thread-do.js +134 -0
  73. package/sticky-server/worker.js +122 -1
  74. package/sticky-server/wrangler.toml +17 -0
  75. package/templates/gitignore-additions.txt +10 -0
  76. package/templates/hooks/event-writer.js +104 -0
  77. package/templates/hooks/inject-context.js +17 -12
  78. package/templates/hooks/on-error.js +46 -2
  79. package/templates/hooks/session-end.js +187 -22
  80. package/templates/hooks/session-start.js +27 -0
  81. package/templates/hooks/sticky-utils.js +12 -3
  82. package/templates/hooks/track-work.js +54 -14
@@ -0,0 +1,1006 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // .wrangler/tmp/bundle-cuweP4/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 metaKey2 = `${project}:thread:${threadId}`;
166
+ const meta = await kv.get(metaKey2, { type: "json" }).catch(() => null);
167
+ const chunkCount = meta && meta._event_chunks || 0;
168
+ if (chunkCount === 0) {
169
+ const single = await kv.get(`${metaKey2}: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(`${metaKey2}: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 metaKey2 = `${project}:thread:${threadId}`;
184
+ const meta = await kv.get(metaKey2, { 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(`${metaKey2}:events:${currentChunkIdx}`, { type: "json" }).catch(() => []) || [];
190
+ }
191
+ const enc = new TextEncoder();
192
+ let chunkBytes = enc.encode(JSON.stringify(currentChunk)).length;
193
+ for (const event of newEvents) {
194
+ const eventBytes = enc.encode(JSON.stringify(event)).length;
195
+ if (chunkBytes + eventBytes > MAX_CHUNK_BYTES && currentChunk.length > 0) {
196
+ await kv.put(`${metaKey2}:events:${currentChunkIdx}`, JSON.stringify(currentChunk));
197
+ currentChunkIdx++;
198
+ currentChunk = [];
199
+ chunkBytes = 0;
200
+ }
201
+ currentChunk.push(event);
202
+ chunkBytes += eventBytes;
203
+ }
204
+ await kv.put(`${metaKey2}:events:${currentChunkIdx}`, JSON.stringify(currentChunk));
205
+ const newMeta = { ...meta || {}, _event_chunks: currentChunkIdx + 1 };
206
+ await kv.put(metaKey2, JSON.stringify(newMeta));
207
+ }
208
+ __name(appendEvents, "appendEvents");
209
+ async function getConfig(kv, project) {
210
+ const raw = await kv.get(`${project}:config`);
211
+ return raw ? JSON.parse(raw) : null;
212
+ }
213
+ __name(getConfig, "getConfig");
214
+ async function putConfig(kv, project, config) {
215
+ await kv.put(`${project}:config`, JSON.stringify(config));
216
+ }
217
+ __name(putConfig, "putConfig");
218
+
219
+ // mcp-tools.js
220
+ var EVENT_TYPES = Object.freeze({
221
+ SESSION_OPEN: "session_open",
222
+ SESSION_CLOSE: "session_close",
223
+ USER_PROMPT: "user_prompt",
224
+ CHECKPOINT: "checkpoint"
225
+ });
226
+ var MCP_TOOL_DEFINITIONS = [
227
+ {
228
+ name: "open_thread",
229
+ description: "Call at session start. Creates a new thread and returns its thread_id for use in subsequent append_event and close_thread calls.",
230
+ inputSchema: {
231
+ type: "object",
232
+ properties: {
233
+ prompt: { type: "string", description: "Verbatim first user prompt" },
234
+ branch: { type: "string", description: "Current git branch" },
235
+ user: { type: "string", description: "Username" },
236
+ model: { type: "string", description: "Model ID (e.g. claude-sonnet-4-6)" },
237
+ mcp_servers: { type: "array", items: { type: "string" }, description: "Connected MCP server names" },
238
+ claude_md_hash: { type: "string", description: "SHA256 of CLAUDE.md content (optional)" }
239
+ },
240
+ required: ["prompt", "user"]
241
+ }
242
+ },
243
+ {
244
+ name: "append_event",
245
+ description: "Call for every action in the session. Records one event (user_prompt, ai_thinking, ai_response, tool_call, tool_result, tool_error, tool_denied, context_compressed, git_commit, subagent_spawn, subagent_result, checkpoint). Do not call for streaming tokens or internal transport retries.",
246
+ inputSchema: {
247
+ type: "object",
248
+ properties: {
249
+ thread_id: { type: "string", description: "thread_id returned by open_thread" },
250
+ type: { type: "string", description: "Event type (see description)" },
251
+ data: { type: "object", description: "Event-specific payload" }
252
+ },
253
+ required: ["thread_id", "type", "data"]
254
+ }
255
+ },
256
+ {
257
+ name: "set_checkpoint",
258
+ description: "Call when the user switches to a different topic mid-session. Marks subsequent events with the new topic for attribution.",
259
+ inputSchema: {
260
+ type: "object",
261
+ properties: {
262
+ thread_id: { type: "string" },
263
+ topic: { type: "string", description: "Short description of new work topic" }
264
+ },
265
+ required: ["thread_id", "topic"]
266
+ }
267
+ },
268
+ {
269
+ name: "close_thread",
270
+ description: "Call at session end. Writes the session_close event, updates thread status to closed, and triggers a git commit of thread metadata.",
271
+ inputSchema: {
272
+ type: "object",
273
+ properties: {
274
+ thread_id: { type: "string" },
275
+ narrative: { type: "string", description: "Summary of what was accomplished" },
276
+ work_type: { type: "string", description: "e.g. bug-fix, feature-development, debugging, refactor, documentation" },
277
+ handoff_summary: { type: "string", description: "Notes for teammates picking this up" },
278
+ failed_approaches: { type: "array", items: { type: "string" }, description: "What was tried and didn't work" },
279
+ files_touched: { type: "array", items: { type: "string" }, description: "Files modified during session" }
280
+ },
281
+ required: ["thread_id", "narrative"]
282
+ }
283
+ }
284
+ ];
285
+ async function handleMcpTool(toolName, input, env, project, getOrCreateDO2) {
286
+ switch (toolName) {
287
+ case "open_thread":
288
+ return handleOpenThread(input, env, project, getOrCreateDO2);
289
+ case "append_event":
290
+ return handleAppendEvent(input, env, project, getOrCreateDO2);
291
+ case "set_checkpoint":
292
+ return handleSetCheckpoint(input, env, project, getOrCreateDO2);
293
+ case "close_thread":
294
+ return handleCloseThread(input, env, project, getOrCreateDO2);
295
+ default:
296
+ throw new Error(`Unknown tool: ${toolName}`);
297
+ }
298
+ }
299
+ __name(handleMcpTool, "handleMcpTool");
300
+ async function handleOpenThread(input, env, project, getOrCreateDO2) {
301
+ const threadId = crypto.randomUUID();
302
+ const now = (/* @__PURE__ */ new Date()).toISOString();
303
+ const threadMeta = {
304
+ id: threadId,
305
+ status: "open",
306
+ user: input.user,
307
+ branch: input.branch || "",
308
+ created_at: now,
309
+ last_activity_at: now,
310
+ files_touched: [],
311
+ narrative: "",
312
+ tool: "claude-code",
313
+ session_id: null,
314
+ // remote sessions don't have a local session_id
315
+ _event_chunks: 0
316
+ };
317
+ const metaKey2 = `${project}:thread:${threadId}`;
318
+ await env.STICKY_KV.put(metaKey2, JSON.stringify(threadMeta));
319
+ const openEvent = {
320
+ ts: now,
321
+ type: EVENT_TYPES.SESSION_OPEN,
322
+ session_id: null,
323
+ data: {
324
+ model: input.model || null,
325
+ branch: input.branch || null,
326
+ user: input.user,
327
+ mcp_servers: input.mcp_servers || [],
328
+ claude_md_hash: input.claude_md_hash || null
329
+ }
330
+ };
331
+ const promptEvent = {
332
+ ts: now,
333
+ type: EVENT_TYPES.USER_PROMPT,
334
+ session_id: null,
335
+ data: { content: input.prompt }
336
+ };
337
+ const do_stub = getOrCreateDO2(env, threadId);
338
+ await do_stub.fetch(new Request("http://do/do/open", {
339
+ method: "POST",
340
+ headers: { "Content-Type": "application/json" },
341
+ body: JSON.stringify({ thread_id: threadId, project, events: [openEvent, promptEvent] })
342
+ }));
343
+ _commitThreadToGit(env, project, threadId, getOrCreateDO2).catch(() => {
344
+ });
345
+ return { thread_id: threadId };
346
+ }
347
+ __name(handleOpenThread, "handleOpenThread");
348
+ async function handleAppendEvent(input, env, project, getOrCreateDO2) {
349
+ const { thread_id, type, data } = input;
350
+ const metaKey2 = `${project}:thread:${thread_id}`;
351
+ const exists = await env.STICKY_KV.get(metaKey2, { type: "text" });
352
+ if (!exists) return { ok: false, error: "unknown thread_id" };
353
+ const event = { ts: (/* @__PURE__ */ new Date()).toISOString(), type, session_id: null, data: data || {} };
354
+ const do_stub = getOrCreateDO2(env, thread_id);
355
+ await do_stub.fetch(new Request("http://do/do/append", {
356
+ method: "POST",
357
+ headers: { "Content-Type": "application/json" },
358
+ body: JSON.stringify({ event })
359
+ }));
360
+ return { ok: true };
361
+ }
362
+ __name(handleAppendEvent, "handleAppendEvent");
363
+ async function handleSetCheckpoint(input, env, project, getOrCreateDO2) {
364
+ return handleAppendEvent(
365
+ { thread_id: input.thread_id, type: EVENT_TYPES.CHECKPOINT, data: { topic: input.topic } },
366
+ env,
367
+ project,
368
+ getOrCreateDO2
369
+ );
370
+ }
371
+ __name(handleSetCheckpoint, "handleSetCheckpoint");
372
+ async function handleCloseThread(input, env, project, getOrCreateDO2) {
373
+ const { thread_id, narrative, work_type, handoff_summary, failed_approaches, files_touched } = input;
374
+ const now = (/* @__PURE__ */ new Date()).toISOString();
375
+ const closeEvent = {
376
+ ts: now,
377
+ type: EVENT_TYPES.SESSION_CLOSE,
378
+ session_id: null,
379
+ data: {
380
+ narrative,
381
+ work_type: work_type || "general",
382
+ handoff_summary: handoff_summary || "",
383
+ failed_approaches: failed_approaches || [],
384
+ files_touched: files_touched || []
385
+ }
386
+ };
387
+ const do_stub = getOrCreateDO2(env, thread_id);
388
+ await do_stub.fetch(new Request("http://do/do/close", {
389
+ method: "POST",
390
+ headers: { "Content-Type": "application/json" },
391
+ body: JSON.stringify({ close_event: closeEvent })
392
+ }));
393
+ const metaKey2 = `${project}:thread:${thread_id}`;
394
+ const meta = await env.STICKY_KV.get(metaKey2, { type: "json" }).catch(() => ({})) || {};
395
+ meta.status = "closed";
396
+ meta.closed_at = now;
397
+ meta.narrative = narrative;
398
+ meta.work_type = work_type || "general";
399
+ meta.handoff_summary = handoff_summary || "";
400
+ meta.failed_approaches = failed_approaches || [];
401
+ if (files_touched) {
402
+ meta.files_touched = [.../* @__PURE__ */ new Set([...meta.files_touched || [], ...files_touched])];
403
+ }
404
+ await env.STICKY_KV.put(metaKey2, JSON.stringify(meta));
405
+ await _commitThreadToGit(env, project, thread_id, getOrCreateDO2);
406
+ return { ok: true };
407
+ }
408
+ __name(handleCloseThread, "handleCloseThread");
409
+ async function _commitThreadToGit(env, project, threadId, getOrCreateDO2) {
410
+ const kv = env.STICKY_KV;
411
+ const threadsListKey = `${project}:threads_index`;
412
+ let threadIds = await kv.get(threadsListKey, { type: "json" }).catch(() => []) || [];
413
+ if (!threadIds.includes(threadId)) {
414
+ threadIds = [threadId, ...threadIds].slice(0, 500);
415
+ await kv.put(threadsListKey, JSON.stringify(threadIds));
416
+ }
417
+ const pat = env.GITHUB_PAT;
418
+ const repoFull = env.GITHUB_REPO;
419
+ if (!pat || !repoFull) return;
420
+ const [owner, repo] = repoFull.split("/");
421
+ if (!owner || !repo) return;
422
+ const allMeta = await Promise.all(
423
+ threadIds.map((id) => kv.get(`${project}:thread:${id}`, { type: "json" }).catch(() => null))
424
+ );
425
+ const threads = allMeta.filter(Boolean).map((m) => {
426
+ const { _event_chunks, _last_recovery_attempt, ...rest } = m;
427
+ return rest;
428
+ });
429
+ const newContent = JSON.stringify({ version: "2", project, threads }, null, 2) + "\n";
430
+ const do_stub = getOrCreateDO2(env, threadId);
431
+ await do_stub.fetch(new Request("http://do/do/github-commit", {
432
+ method: "POST",
433
+ headers: { "Content-Type": "application/json" },
434
+ body: JSON.stringify({
435
+ owner,
436
+ repo,
437
+ path: ".sticky-note/sticky-note.json",
438
+ content: newContent,
439
+ message: `chore(sticky-note): sync thread ${threadId.slice(0, 8)}`,
440
+ pat
441
+ })
442
+ }));
443
+ }
444
+ __name(_commitThreadToGit, "_commitThreadToGit");
445
+
446
+ // sticky-thread-do.js
447
+ var StickyThread = class {
448
+ static {
449
+ __name(this, "StickyThread");
450
+ }
451
+ constructor(state, env) {
452
+ this.state = state;
453
+ this.env = env;
454
+ this.buffer = [];
455
+ this.flushThreshold = 10;
456
+ this.threadId = null;
457
+ this.project = "default";
458
+ }
459
+ async fetch(request) {
460
+ const url = new URL(request.url);
461
+ const body = await request.json().catch(() => ({}));
462
+ if (url.pathname === "/do/open") {
463
+ this.threadId = body.thread_id;
464
+ this.project = body.project || "default";
465
+ for (const ev of body.events || []) this.buffer.push(ev);
466
+ await this._scheduleFlush();
467
+ return new Response(JSON.stringify({ ok: true, thread_id: this.threadId }), {
468
+ headers: { "Content-Type": "application/json" }
469
+ });
470
+ }
471
+ if (url.pathname === "/do/append") {
472
+ const event = body.event;
473
+ if (event) this.buffer.push(event);
474
+ if (this.buffer.length >= this.flushThreshold) {
475
+ await this._flush();
476
+ } else {
477
+ await this._scheduleFlush();
478
+ }
479
+ return new Response(JSON.stringify({ ok: true }), {
480
+ headers: { "Content-Type": "application/json" }
481
+ });
482
+ }
483
+ if (url.pathname === "/do/close") {
484
+ const closeEvent = body.close_event;
485
+ if (closeEvent) this.buffer.push(closeEvent);
486
+ await this._flush();
487
+ try {
488
+ await this.state.storage.deleteAlarm();
489
+ } catch (_) {
490
+ }
491
+ return new Response(JSON.stringify({ ok: true, flushed: true }), {
492
+ headers: { "Content-Type": "application/json" }
493
+ });
494
+ }
495
+ if (url.pathname === "/do/github-commit") {
496
+ const result = await this._githubCommit(body);
497
+ return new Response(JSON.stringify(result), {
498
+ headers: { "Content-Type": "application/json" },
499
+ status: result.ok ? 200 : 500
500
+ });
501
+ }
502
+ return new Response("not found", { status: 404 });
503
+ }
504
+ async alarm() {
505
+ if (this.buffer.length > 0) {
506
+ await this._flush();
507
+ }
508
+ }
509
+ async _scheduleFlush() {
510
+ try {
511
+ const existing = await this.state.storage.getAlarm();
512
+ if (!existing) {
513
+ await this.state.storage.setAlarm(Date.now() + 5e3);
514
+ }
515
+ } catch (_) {
516
+ }
517
+ }
518
+ async _flush() {
519
+ if (this.buffer.length === 0 || !this.threadId) return;
520
+ const toFlush = this.buffer.splice(0);
521
+ try {
522
+ await appendEvents(this.env.STICKY_KV, this.project, this.threadId, toFlush);
523
+ } catch (err) {
524
+ this.buffer.unshift(...toFlush);
525
+ }
526
+ }
527
+ async _githubCommit(body) {
528
+ const { owner, repo, path: filePath, content, message, pat } = body;
529
+ if (!pat) return { ok: false, error: "no PAT" };
530
+ const apiBase = `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`;
531
+ const headers = {
532
+ Authorization: `Bearer ${pat}`,
533
+ Accept: "application/vnd.github+json",
534
+ "Content-Type": "application/json",
535
+ "User-Agent": "sticky-note-worker"
536
+ };
537
+ let sha = null;
538
+ let retries = 3;
539
+ while (retries-- > 0) {
540
+ const getResp = await fetch(apiBase, { headers }).catch(() => null);
541
+ if (getResp && getResp.ok) {
542
+ const data = await getResp.json().catch(() => ({}));
543
+ sha = data.sha || null;
544
+ }
545
+ const putBody = {
546
+ message,
547
+ content: btoa(unescape(encodeURIComponent(content))),
548
+ // base64 encode UTF-8
549
+ ...sha ? { sha } : {}
550
+ };
551
+ const putResp = await fetch(apiBase, {
552
+ method: "PUT",
553
+ headers,
554
+ body: JSON.stringify(putBody)
555
+ }).catch(() => null);
556
+ if (!putResp) return { ok: false, error: "network error" };
557
+ if (putResp.ok) return { ok: true };
558
+ if (putResp.status === 409) {
559
+ await new Promise((r) => setTimeout(r, 200));
560
+ continue;
561
+ }
562
+ const errBody = await putResp.json().catch(() => ({}));
563
+ return { ok: false, error: errBody.message || `HTTP ${putResp.status}` };
564
+ }
565
+ return { ok: false, error: "max retries exceeded (409 conflict)" };
566
+ }
567
+ };
568
+
569
+ // worker.js
570
+ function json(data, status = 200) {
571
+ return new Response(JSON.stringify(data), {
572
+ status,
573
+ headers: { "Content-Type": "application/json" }
574
+ });
575
+ }
576
+ __name(json, "json");
577
+ function error(message, status = 400) {
578
+ return json({ error: message }, status);
579
+ }
580
+ __name(error, "error");
581
+ function authenticate(request, env) {
582
+ const key = request.headers.get("X-Sticky-API-Key");
583
+ if (!env.STICKY_API_KEY) return true;
584
+ return key === env.STICKY_API_KEY;
585
+ }
586
+ __name(authenticate, "authenticate");
587
+ function getProject(request) {
588
+ return request.headers.get("X-Sticky-Project") || "default";
589
+ }
590
+ __name(getProject, "getProject");
591
+ function matchRoute(method, pathname) {
592
+ if (method === "POST" && pathname === "/threads") return { handler: "createThread" };
593
+ if (method === "GET" && pathname === "/threads") return { handler: "listThreads" };
594
+ if (method === "POST" && pathname.match(/^\/threads\/[^/]+\/events$/)) {
595
+ const id = pathname.split("/")[2];
596
+ return { handler: "appendThreadEvents", id };
597
+ }
598
+ if (method === "GET" && pathname.match(/^\/threads\/[^/]+\/events$/)) {
599
+ const id = pathname.split("/")[2];
600
+ return { handler: "getThreadEvents", id };
601
+ }
602
+ if (method === "GET" && pathname.startsWith("/threads/")) {
603
+ return { handler: "getThread", id: pathname.slice("/threads/".length) };
604
+ }
605
+ if (method === "PUT" && pathname.startsWith("/threads/")) {
606
+ return { handler: "updateThread", id: pathname.slice("/threads/".length) };
607
+ }
608
+ if (method === "DELETE" && pathname.startsWith("/threads/")) {
609
+ return { handler: "deleteThread", id: pathname.slice("/threads/".length) };
610
+ }
611
+ if (method === "GET" && pathname === "/audit") return { handler: "queryAudit" };
612
+ if (method === "POST" && pathname === "/audit") return { handler: "appendAudit" };
613
+ if (method === "GET" && pathname === "/presence") return { handler: "getPresence" };
614
+ if (method === "POST" && pathname === "/presence") return { handler: "upsertPresence" };
615
+ if (method === "DELETE" && pathname.startsWith("/presence/")) {
616
+ return { handler: "deletePresence", user: decodeURIComponent(pathname.slice("/presence/".length)) };
617
+ }
618
+ if (method === "GET" && pathname === "/config") return { handler: "getConfig" };
619
+ if (method === "PUT" && pathname === "/config") return { handler: "putConfig" };
620
+ if (method === "GET" && pathname === "/mcp") return { handler: "mcpListTools" };
621
+ if (method === "POST" && pathname === "/mcp") return { handler: "mcpCallTool" };
622
+ if (method === "GET" && pathname === "/health") return { handler: "health" };
623
+ return null;
624
+ }
625
+ __name(matchRoute, "matchRoute");
626
+ var handlers = {
627
+ async health() {
628
+ return json({ status: "ok", version: "3.0.0" });
629
+ },
630
+ // ── Threads ──
631
+ async createThread(request, kv, project) {
632
+ const thread = await request.json();
633
+ if (!thread.id) return error("thread.id is required");
634
+ await putThread(kv, project, thread);
635
+ return json(thread, 201);
636
+ },
637
+ async listThreads(request, kv, project) {
638
+ const url = new URL(request.url);
639
+ const filters = {
640
+ status: url.searchParams.get("status") || void 0,
641
+ q: url.searchParams.get("q") || void 0
642
+ };
643
+ const threads = await getThreads(kv, project, filters);
644
+ return json({ threads });
645
+ },
646
+ async getThread(_request, kv, project, { id }) {
647
+ const thread = await getThread(kv, project, id);
648
+ if (!thread) return error("Thread not found", 404);
649
+ return json(thread);
650
+ },
651
+ async updateThread(request, kv, project, { id }) {
652
+ const thread = await request.json();
653
+ thread.id = id;
654
+ await putThread(kv, project, thread);
655
+ return json(thread);
656
+ },
657
+ async deleteThread(_request, kv, project, { id }) {
658
+ await deleteThread(kv, project, id);
659
+ return json({ deleted: id });
660
+ },
661
+ // ── Thread Events ──
662
+ async appendThreadEvents(request, kv, project, { id }) {
663
+ const body = await request.json().catch(() => ({}));
664
+ const events = Array.isArray(body.events) ? body.events : [];
665
+ await appendEvents(kv, project, id, events);
666
+ return json({ ok: true, appended: events.length });
667
+ },
668
+ async getThreadEvents(_request, kv, project, { id }) {
669
+ const events = await getEvents(kv, project, id);
670
+ return json({ events });
671
+ },
672
+ // ── Audit ──
673
+ async queryAudit(request, kv, project) {
674
+ const url = new URL(request.url);
675
+ const filters = {
676
+ user: url.searchParams.get("user") || void 0,
677
+ file: url.searchParams.get("file") || void 0,
678
+ tool: url.searchParams.get("tool") || void 0,
679
+ since: url.searchParams.get("since") || void 0
680
+ };
681
+ const records = await queryAudit(kv, project, filters);
682
+ return json({ audit: records });
683
+ },
684
+ async appendAudit(request, kv, project) {
685
+ const record = await request.json();
686
+ await appendAudit(kv, project, record);
687
+ return json({ ok: true }, 201);
688
+ },
689
+ // ── Presence ──
690
+ async getPresence(_request, kv, project) {
691
+ const records = await getPresence(kv, project);
692
+ return json({ presence: records });
693
+ },
694
+ async upsertPresence(request, kv, project) {
695
+ const record = await request.json();
696
+ if (!record.user) return error("record.user is required");
697
+ await upsertPresence(kv, project, record);
698
+ return json({ ok: true });
699
+ },
700
+ async deletePresence(_request, kv, project, { user }) {
701
+ await deletePresence(kv, project, user);
702
+ return json({ deleted: user });
703
+ },
704
+ // ── MCP ──
705
+ async mcpListTools() {
706
+ return json({ tools: MCP_TOOL_DEFINITIONS });
707
+ },
708
+ async mcpCallTool(request, _kv, project, _route, env) {
709
+ const body = await request.json().catch(() => ({}));
710
+ const toolName = body.tool || body.name;
711
+ const toolInput = body.input || body.arguments || {};
712
+ if (!toolName) return error("tool name required");
713
+ try {
714
+ const result = await handleMcpTool(toolName, toolInput, env, project, getOrCreateDO);
715
+ return json({ content: [{ type: "text", text: JSON.stringify(result) }] });
716
+ } catch (err) {
717
+ return error(err.message, 400);
718
+ }
719
+ },
720
+ // ── Config ──
721
+ async getConfig(_request, kv, project) {
722
+ const config = await getConfig(kv, project);
723
+ if (!config) return json({});
724
+ return json(config);
725
+ },
726
+ async putConfig(request, kv, project) {
727
+ const config = await request.json();
728
+ await putConfig(kv, project, config);
729
+ return json(config);
730
+ }
731
+ };
732
+ function getOrCreateDO(env, threadId) {
733
+ const id = env.STICKY_THREAD.idFromName(threadId);
734
+ return env.STICKY_THREAD.get(id);
735
+ }
736
+ __name(getOrCreateDO, "getOrCreateDO");
737
+ var worker_default = {
738
+ async fetch(request, env) {
739
+ if (request.method === "OPTIONS") {
740
+ return new Response(null, {
741
+ status: 204,
742
+ headers: {
743
+ "Access-Control-Allow-Origin": "*",
744
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
745
+ "Access-Control-Allow-Headers": "Content-Type, X-Sticky-API-Key, X-Sticky-Project"
746
+ }
747
+ });
748
+ }
749
+ if (!authenticate(request, env)) {
750
+ return error("Unauthorized", 401);
751
+ }
752
+ const url = new URL(request.url);
753
+ const route = matchRoute(request.method, url.pathname);
754
+ if (!route) {
755
+ return error("Not found", 404);
756
+ }
757
+ const project = getProject(request);
758
+ const kv = env.STICKY_KV;
759
+ try {
760
+ const handler = handlers[route.handler];
761
+ const response = await handler(request, kv, project, route, env);
762
+ const headers = new Headers(response.headers);
763
+ headers.set("Access-Control-Allow-Origin", "*");
764
+ return new Response(response.body, {
765
+ status: response.status,
766
+ headers
767
+ });
768
+ } catch (err) {
769
+ return error(`Internal error: ${err.message}`, 500);
770
+ }
771
+ },
772
+ async scheduled(event, env, ctx) {
773
+ ctx.waitUntil(runCrashRecovery(env));
774
+ }
775
+ };
776
+ async function runCrashRecovery(env) {
777
+ const projects = ["default"];
778
+ const staleThresholdMs = 30 * 60 * 1e3;
779
+ const now = Date.now();
780
+ for (const project of projects) {
781
+ const threadsListKey = `${project}:threads_index`;
782
+ const threadIds = await env.STICKY_KV.get(threadsListKey, { type: "json" }).catch(() => []) || [];
783
+ const metas = await Promise.all(
784
+ threadIds.map(
785
+ (id) => env.STICKY_KV.get(`${project}:thread:${id}`, { type: "json" }).catch(() => null)
786
+ )
787
+ );
788
+ for (let i = 0; i < threadIds.length; i++) {
789
+ const meta = metas[i];
790
+ const threadId = threadIds[i];
791
+ if (!meta || meta.status !== "open") continue;
792
+ const lastActivity = new Date(meta.last_activity_at || meta.created_at).getTime();
793
+ if (now - lastActivity < staleThresholdMs) continue;
794
+ const lastAttempt = meta._last_recovery_attempt || 0;
795
+ if (now - lastAttempt < 5 * 60 * 1e3) continue;
796
+ try {
797
+ const do_stub = getOrCreateDO(env, threadId);
798
+ const recovery_event = {
799
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
800
+ type: EVENT_TYPES.SESSION_CLOSE,
801
+ session_id: null,
802
+ data: { narrative: "[recovered by cron]", work_type: "unknown", handoff_summary: "", failed_approaches: [], files_touched: [] }
803
+ };
804
+ meta._last_recovery_attempt = now;
805
+ await env.STICKY_KV.put(metaKey, JSON.stringify(meta));
806
+ await do_stub.fetch(new Request("http://do/do/close", {
807
+ method: "POST",
808
+ headers: { "Content-Type": "application/json" },
809
+ body: JSON.stringify({ close_event: recovery_event })
810
+ }));
811
+ meta.status = "stale";
812
+ meta.last_activity_at = (/* @__PURE__ */ new Date()).toISOString();
813
+ await env.STICKY_KV.put(metaKey, JSON.stringify(meta));
814
+ await _commitThreadToGit(env, project, threadId, getOrCreateDO).catch(() => {
815
+ });
816
+ } catch (_) {
817
+ console.error(`[sticky-note] crash recovery failed for thread ${threadId}`);
818
+ }
819
+ }
820
+ }
821
+ }
822
+ __name(runCrashRecovery, "runCrashRecovery");
823
+
824
+ // ../../../../../AppData/Roaming/npm/node_modules/wrangler/templates/middleware/middleware-ensure-req-body-drained.ts
825
+ var drainBody = /* @__PURE__ */ __name(async (request, env, _ctx, middlewareCtx) => {
826
+ try {
827
+ return await middlewareCtx.next(request, env);
828
+ } finally {
829
+ try {
830
+ if (request.body !== null && !request.bodyUsed) {
831
+ const reader = request.body.getReader();
832
+ while (!(await reader.read()).done) {
833
+ }
834
+ }
835
+ } catch (e) {
836
+ console.error("Failed to drain the unused request body.", e);
837
+ }
838
+ }
839
+ }, "drainBody");
840
+ var middleware_ensure_req_body_drained_default = drainBody;
841
+
842
+ // ../../../../../AppData/Roaming/npm/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts
843
+ function reduceError(e) {
844
+ return {
845
+ name: e?.name,
846
+ message: e?.message ?? String(e),
847
+ stack: e?.stack,
848
+ cause: e?.cause === void 0 ? void 0 : reduceError(e.cause)
849
+ };
850
+ }
851
+ __name(reduceError, "reduceError");
852
+ var jsonError = /* @__PURE__ */ __name(async (request, env, _ctx, middlewareCtx) => {
853
+ try {
854
+ return await middlewareCtx.next(request, env);
855
+ } catch (e) {
856
+ const error2 = reduceError(e);
857
+ const body = JSON.stringify(error2);
858
+ const headers = {
859
+ "Content-Type": "application/json",
860
+ "MF-Experimental-Error-Stack": "true"
861
+ };
862
+ const encoded = encodeURIComponent(body);
863
+ if (encoded.length <= 8192) {
864
+ headers["MF-Experimental-Error-Stack-Payload"] = encoded;
865
+ }
866
+ return new Response(body, { status: 500, headers });
867
+ }
868
+ }, "jsonError");
869
+ var middleware_miniflare3_json_error_default = jsonError;
870
+
871
+ // .wrangler/tmp/bundle-cuweP4/middleware-insertion-facade.js
872
+ var __INTERNAL_WRANGLER_MIDDLEWARE__ = [
873
+ middleware_ensure_req_body_drained_default,
874
+ middleware_miniflare3_json_error_default
875
+ ];
876
+ var middleware_insertion_facade_default = worker_default;
877
+
878
+ // ../../../../../AppData/Roaming/npm/node_modules/wrangler/templates/middleware/common.ts
879
+ var __facade_middleware__ = [];
880
+ function __facade_register__(...args) {
881
+ __facade_middleware__.push(...args.flat());
882
+ }
883
+ __name(__facade_register__, "__facade_register__");
884
+ function __facade_invokeChain__(request, env, ctx, dispatch, middlewareChain) {
885
+ const [head, ...tail] = middlewareChain;
886
+ const middlewareCtx = {
887
+ dispatch,
888
+ next(newRequest, newEnv) {
889
+ return __facade_invokeChain__(newRequest, newEnv, ctx, dispatch, tail);
890
+ }
891
+ };
892
+ return head(request, env, ctx, middlewareCtx);
893
+ }
894
+ __name(__facade_invokeChain__, "__facade_invokeChain__");
895
+ function __facade_invoke__(request, env, ctx, dispatch, finalMiddleware) {
896
+ return __facade_invokeChain__(request, env, ctx, dispatch, [
897
+ ...__facade_middleware__,
898
+ finalMiddleware
899
+ ]);
900
+ }
901
+ __name(__facade_invoke__, "__facade_invoke__");
902
+
903
+ // .wrangler/tmp/bundle-cuweP4/middleware-loader.entry.ts
904
+ var __Facade_ScheduledController__ = class ___Facade_ScheduledController__ {
905
+ constructor(scheduledTime, cron, noRetry) {
906
+ this.scheduledTime = scheduledTime;
907
+ this.cron = cron;
908
+ this.#noRetry = noRetry;
909
+ }
910
+ scheduledTime;
911
+ cron;
912
+ static {
913
+ __name(this, "__Facade_ScheduledController__");
914
+ }
915
+ #noRetry;
916
+ noRetry() {
917
+ if (!(this instanceof ___Facade_ScheduledController__)) {
918
+ throw new TypeError("Illegal invocation");
919
+ }
920
+ this.#noRetry();
921
+ }
922
+ };
923
+ function wrapExportedHandler(worker) {
924
+ if (__INTERNAL_WRANGLER_MIDDLEWARE__ === void 0 || __INTERNAL_WRANGLER_MIDDLEWARE__.length === 0) {
925
+ return worker;
926
+ }
927
+ for (const middleware of __INTERNAL_WRANGLER_MIDDLEWARE__) {
928
+ __facade_register__(middleware);
929
+ }
930
+ const fetchDispatcher = /* @__PURE__ */ __name(function(request, env, ctx) {
931
+ if (worker.fetch === void 0) {
932
+ throw new Error("Handler does not export a fetch() function.");
933
+ }
934
+ return worker.fetch(request, env, ctx);
935
+ }, "fetchDispatcher");
936
+ return {
937
+ ...worker,
938
+ fetch(request, env, ctx) {
939
+ const dispatcher = /* @__PURE__ */ __name(function(type, init) {
940
+ if (type === "scheduled" && worker.scheduled !== void 0) {
941
+ const controller = new __Facade_ScheduledController__(
942
+ Date.now(),
943
+ init.cron ?? "",
944
+ () => {
945
+ }
946
+ );
947
+ return worker.scheduled(controller, env, ctx);
948
+ }
949
+ }, "dispatcher");
950
+ return __facade_invoke__(request, env, ctx, dispatcher, fetchDispatcher);
951
+ }
952
+ };
953
+ }
954
+ __name(wrapExportedHandler, "wrapExportedHandler");
955
+ function wrapWorkerEntrypoint(klass) {
956
+ if (__INTERNAL_WRANGLER_MIDDLEWARE__ === void 0 || __INTERNAL_WRANGLER_MIDDLEWARE__.length === 0) {
957
+ return klass;
958
+ }
959
+ for (const middleware of __INTERNAL_WRANGLER_MIDDLEWARE__) {
960
+ __facade_register__(middleware);
961
+ }
962
+ return class extends klass {
963
+ #fetchDispatcher = /* @__PURE__ */ __name((request, env, ctx) => {
964
+ this.env = env;
965
+ this.ctx = ctx;
966
+ if (super.fetch === void 0) {
967
+ throw new Error("Entrypoint class does not define a fetch() function.");
968
+ }
969
+ return super.fetch(request);
970
+ }, "#fetchDispatcher");
971
+ #dispatcher = /* @__PURE__ */ __name((type, init) => {
972
+ if (type === "scheduled" && super.scheduled !== void 0) {
973
+ const controller = new __Facade_ScheduledController__(
974
+ Date.now(),
975
+ init.cron ?? "",
976
+ () => {
977
+ }
978
+ );
979
+ return super.scheduled(controller);
980
+ }
981
+ }, "#dispatcher");
982
+ fetch(request) {
983
+ return __facade_invoke__(
984
+ request,
985
+ this.env,
986
+ this.ctx,
987
+ this.#dispatcher,
988
+ this.#fetchDispatcher
989
+ );
990
+ }
991
+ };
992
+ }
993
+ __name(wrapWorkerEntrypoint, "wrapWorkerEntrypoint");
994
+ var WRAPPED_ENTRY;
995
+ if (typeof middleware_insertion_facade_default === "object") {
996
+ WRAPPED_ENTRY = wrapExportedHandler(middleware_insertion_facade_default);
997
+ } else if (typeof middleware_insertion_facade_default === "function") {
998
+ WRAPPED_ENTRY = wrapWorkerEntrypoint(middleware_insertion_facade_default);
999
+ }
1000
+ var middleware_loader_entry_default = WRAPPED_ENTRY;
1001
+ export {
1002
+ StickyThread,
1003
+ __INTERNAL_WRANGLER_MIDDLEWARE__,
1004
+ middleware_loader_entry_default as default
1005
+ };
1006
+ //# sourceMappingURL=worker.js.map