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
package/README.md
CHANGED
|
@@ -50,6 +50,23 @@ their next session by relevance.
|
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
53
|
+
## What's New in V3.2
|
|
54
|
+
|
|
55
|
+
- **claude.ai cowork session tracking**: Sessions in claude.ai (cowork, projects) are now
|
|
56
|
+
captured with full fidelity — every tool call, AI response, thinking block, and user
|
|
57
|
+
prompt — matching the richness of local Claude Code sessions. Connect the remote MCP
|
|
58
|
+
endpoint once in your claude.ai project settings and capture happens automatically.
|
|
59
|
+
- **AI blame**: Trace any line of code back to the prompt, reasoning chain, and tool calls
|
|
60
|
+
that produced it. Every session event is stored in KV keyed by thread ID. `get-line-attribution`
|
|
61
|
+
maps file lines to thread IDs; from there you can fetch the full event stream and walk back
|
|
62
|
+
to the `user_prompt` → `ai_thinking` → `tool_call` → `tool_result` chain.
|
|
63
|
+
- **Enriched local event stream**: Claude Code hook sessions now emit structured events
|
|
64
|
+
(not just audit entries) — full tool args, results capped at 10 KB, AI thinking and
|
|
65
|
+
response blocks extracted from transcript at session end, all pushed to KV for team access.
|
|
66
|
+
- **Init wizard cowork setup**: After cloud backend provisioning, `npx sticky-note init`
|
|
67
|
+
now prompts for a GitHub PAT (for Worker→git commits) and prints the remote MCP connector
|
|
68
|
+
URL + project system prompt to paste into claude.ai. See [Setup: claude.ai Cowork](#setup-claudeai-cowork).
|
|
69
|
+
|
|
53
70
|
## What's New in V3.1
|
|
54
71
|
|
|
55
72
|
- **Full transcript capture**: Every session's complete verbatim transcript
|
|
@@ -160,6 +177,66 @@ in the background via hooks — capturing threads and surfacing context.
|
|
|
160
177
|
|
|
161
178
|
---
|
|
162
179
|
|
|
180
|
+
## Setup: claude.ai Cowork
|
|
181
|
+
|
|
182
|
+
To capture sessions from claude.ai (cowork, projects), you need the cloud backend running
|
|
183
|
+
and a remote MCP connector configured in your claude.ai project settings.
|
|
184
|
+
|
|
185
|
+
### Prerequisites
|
|
186
|
+
|
|
187
|
+
Cloud backend must be set up first (`npx sticky-note init` → answer **y** to cloud backend).
|
|
188
|
+
|
|
189
|
+
### Step 1: Run init with GitHub PAT (optional but recommended)
|
|
190
|
+
|
|
191
|
+
After cloud provisioning, `npx sticky-note init` prompts:
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
Optional: GitHub PAT for Worker → git commits (enables remote cowork session tracking).
|
|
195
|
+
Create at https://github.com/settings/tokens/new (fine-grained, Contents read+write).
|
|
196
|
+
PAT (leave blank to skip):
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Enter a PAT to enable the Worker to commit thread metadata to `sticky-note.json` after each session.
|
|
200
|
+
Leave blank if you only want KV event storage (metadata won't appear in git history).
|
|
201
|
+
|
|
202
|
+
The wizard then prints your connector details:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
── claude.ai Cowork MCP Connector ──────────────────────────
|
|
206
|
+
To track cowork sessions, add this connector in claude.ai project settings:
|
|
207
|
+
URL: https://sticky-{owner}-{repo}.workers.dev/mcp
|
|
208
|
+
Header: X-Sticky-API-Key: <your-key>
|
|
209
|
+
|
|
210
|
+
The CLAUDE.md project system prompt (paste into claude.ai project instructions):
|
|
211
|
+
1. Call open_thread at session start with the verbatim first user prompt
|
|
212
|
+
2. Call append_event for every action: ai_thinking, ai_response, tool_call,
|
|
213
|
+
tool_result, tool_error, tool_denied, context_compressed, git_commit,
|
|
214
|
+
subagent_spawn, subagent_result, checkpoint
|
|
215
|
+
3. Call set_checkpoint when the user switches topics
|
|
216
|
+
4. Call close_thread at session end with narrative and work_type
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Step 2: Configure claude.ai project
|
|
220
|
+
|
|
221
|
+
1. Open your claude.ai project → **Settings** → **Integrations** → **Add MCP Server**
|
|
222
|
+
2. Enter the URL and header from the wizard output
|
|
223
|
+
3. Paste the system prompt block into your project instructions
|
|
224
|
+
|
|
225
|
+
That's it. The next cowork session in that project will open a thread, stream events live,
|
|
226
|
+
and commit thread metadata to git when the session ends.
|
|
227
|
+
|
|
228
|
+
### Worker secrets (manual / CI)
|
|
229
|
+
|
|
230
|
+
If you need to set secrets without the wizard:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
cd sticky-server
|
|
234
|
+
wrangler secret put GITHUB_PAT # fine-grained PAT, Contents read+write
|
|
235
|
+
wrangler secret put GITHUB_REPO # value: owner/repo (e.g. acme/frontend)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
163
240
|
## How Context Gets Injected
|
|
164
241
|
|
|
165
242
|
Sticky Note injects context through **four mechanisms**: two that run
|
package/bin/cli.js
CHANGED
|
@@ -198,6 +198,14 @@ function makeExecutable(filePath) {
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
// Markers used by older sticky-note versions to wrap blocks in .git/hooks/pre-commit
|
|
202
|
+
// and .git/hooks/post-commit. These were removed in V3 (data branch handles persistence),
|
|
203
|
+
// but cmdUpdate() and cmdMigrateDataBranch() still need to strip them from old repos.
|
|
204
|
+
const STICKY_PRE_COMMIT_MARKER = "# [sticky-note:auto-stage]";
|
|
205
|
+
const STICKY_PRE_COMMIT_END = "# [/sticky-note:auto-stage]";
|
|
206
|
+
const STICKY_POST_COMMIT_MARKER = "# [sticky-note:auto-sync]";
|
|
207
|
+
const STICKY_POST_COMMIT_END = "# [/sticky-note:auto-sync]";
|
|
208
|
+
|
|
201
209
|
function installGitHook(hookName) {
|
|
202
210
|
try {
|
|
203
211
|
const gitDir = path.join(process.cwd(), ".git");
|
|
@@ -748,6 +756,59 @@ async function cmdInit() {
|
|
|
748
756
|
print(" [OK] .env.sticky (cloud backend configured)");
|
|
749
757
|
}
|
|
750
758
|
|
|
759
|
+
// GitHub PAT collection + MCP connector URL output (cloud backend only, interactive only)
|
|
760
|
+
const workerUrl = cloudProvisionedUrl || configStickyUrl;
|
|
761
|
+
if (workerUrl && !ciMode) {
|
|
762
|
+
const rl2 = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
763
|
+
const ask2 = (q) => new Promise((res) => rl2.question(q, res));
|
|
764
|
+
|
|
765
|
+
const pat = await ask2(
|
|
766
|
+
"\nOptional: GitHub PAT for Worker → git commits (enables remote cowork session tracking).\n" +
|
|
767
|
+
"Create at https://github.com/settings/tokens/new (fine-grained, Contents read+write).\n" +
|
|
768
|
+
"PAT (leave blank to skip): "
|
|
769
|
+
);
|
|
770
|
+
|
|
771
|
+
if (pat && pat.trim()) {
|
|
772
|
+
const repo = await ask2("GitHub repo in owner/repo format (e.g. acme/frontend): ");
|
|
773
|
+
if (repo && repo.trim().includes("/")) {
|
|
774
|
+
try {
|
|
775
|
+
execSync(`wrangler secret put GITHUB_PAT`, { input: pat.trim(), stdio: ["pipe", "inherit", "inherit"] });
|
|
776
|
+
execSync(`wrangler secret put GITHUB_REPO`, { input: repo.trim(), stdio: ["pipe", "inherit", "inherit"] });
|
|
777
|
+
print(" ✓ GitHub PAT and repo stored as Worker secrets");
|
|
778
|
+
} catch (_) {
|
|
779
|
+
print(" ⚠ Could not store secrets via wrangler — set manually:");
|
|
780
|
+
print(` wrangler secret put GITHUB_PAT`);
|
|
781
|
+
print(` wrangler secret put GITHUB_REPO # value: ${repo.trim()}`);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
rl2.close();
|
|
786
|
+
|
|
787
|
+
// Always print connector instructions if Worker URL is configured
|
|
788
|
+
let envStickyApiKey = "";
|
|
789
|
+
try {
|
|
790
|
+
const envStickyPath = path.join(process.cwd(), ".env.sticky");
|
|
791
|
+
const envContent = fs.readFileSync(envStickyPath, "utf-8");
|
|
792
|
+
const m = envContent.match(/^STICKY_API_KEY=(.+)$/m);
|
|
793
|
+
if (m && m[1].trim()) envStickyApiKey = m[1].trim();
|
|
794
|
+
} catch (_) { /* no .env.sticky yet */ }
|
|
795
|
+
|
|
796
|
+
print("\n── claude.ai Cowork MCP Connector ──────────────────────────");
|
|
797
|
+
print("To track cowork sessions, add this connector in claude.ai project settings:");
|
|
798
|
+
print(` URL: ${workerUrl}/mcp`);
|
|
799
|
+
if (envStickyApiKey) {
|
|
800
|
+
print(` Header: X-Sticky-API-Key: ${envStickyApiKey}`);
|
|
801
|
+
}
|
|
802
|
+
print("\nThe CLAUDE.md project system prompt (paste into claude.ai project instructions):");
|
|
803
|
+
print(" 1. Call open_thread at session start with the verbatim first user prompt");
|
|
804
|
+
print(" 2. Call append_event for every action: ai_thinking, ai_response, tool_call,");
|
|
805
|
+
print(" tool_result, tool_error, tool_denied, context_compressed, git_commit,");
|
|
806
|
+
print(" subagent_spawn, subagent_result, checkpoint");
|
|
807
|
+
print(" 3. Call set_checkpoint when the user switches topics");
|
|
808
|
+
print(" 4. Call close_thread at session end with narrative and work_type");
|
|
809
|
+
print("────────────────────────────────────────────────────────────\n");
|
|
810
|
+
}
|
|
811
|
+
|
|
751
812
|
print("\n 📁 Creating files...\n");
|
|
752
813
|
|
|
753
814
|
// Create directories
|
|
@@ -847,6 +908,9 @@ async function cmdInit() {
|
|
|
847
908
|
configTemplate.inject_token_budget = injectTokenBudgetResolved;
|
|
848
909
|
configTemplate.hook_version = VERSION;
|
|
849
910
|
configTemplate.min_version = VERSION;
|
|
911
|
+
// When cloud is configured, default auto_push to true so threads reach
|
|
912
|
+
// GitHub even when Cloudflare KV hits its daily write limit.
|
|
913
|
+
if (cloudProvisionedUrl || configStickyUrl) configTemplate.auto_push = true;
|
|
850
914
|
fs.writeFileSync(configDest, JSON.stringify(configTemplate, null, 2) + "\n");
|
|
851
915
|
} else {
|
|
852
916
|
// Update existing config with new settings
|
|
@@ -859,6 +923,10 @@ async function cmdInit() {
|
|
|
859
923
|
existing.hook_version = VERSION;
|
|
860
924
|
existing.min_version = bumpMinVersion(existing.min_version, VERSION);
|
|
861
925
|
if (cloudProvisionedUrl) existing.sticky_url = cloudProvisionedUrl;
|
|
926
|
+
// Enable auto_push when cloud is configured (if not already explicitly set)
|
|
927
|
+
if ((cloudProvisionedUrl || configStickyUrl) && existing.auto_push === false) {
|
|
928
|
+
existing.auto_push = true;
|
|
929
|
+
}
|
|
862
930
|
fs.writeFileSync(configDest, JSON.stringify(existing, null, 2) + "\n");
|
|
863
931
|
}
|
|
864
932
|
print(" [OK] .sticky-note/sticky-note-config.json");
|
package/bin/mcp-server.js
CHANGED
|
@@ -508,17 +508,19 @@ function toolCheckOverlaps(params) {
|
|
|
508
508
|
};
|
|
509
509
|
}
|
|
510
510
|
|
|
511
|
-
function toolGetEnvironmentStatus() {
|
|
511
|
+
async function toolGetEnvironmentStatus() {
|
|
512
512
|
const envDir = path.join(stickyDir(), "environment");
|
|
513
513
|
const mcpPath = path.join(PROJECT_ROOT, ".mcp.json");
|
|
514
514
|
|
|
515
|
-
// No environment directory — feature not set up
|
|
515
|
+
// No environment directory — feature not set up, but still check cloud health
|
|
516
516
|
if (!fs.existsSync(envDir)) {
|
|
517
|
-
|
|
517
|
+
const result = {
|
|
518
518
|
status: "not_configured",
|
|
519
519
|
message: "No .sticky-note/environment/ directory found. Environment sync is not set up for this repo.",
|
|
520
520
|
action: "none",
|
|
521
521
|
};
|
|
522
|
+
result.cloud = await _checkCloudHealth();
|
|
523
|
+
return result;
|
|
522
524
|
}
|
|
523
525
|
|
|
524
526
|
const manifest = readJsonSafe(path.join(envDir, "manifest.json"), {});
|
|
@@ -604,9 +606,42 @@ function toolGetEnvironmentStatus() {
|
|
|
604
606
|
}
|
|
605
607
|
}
|
|
606
608
|
|
|
609
|
+
result.cloud = await _checkCloudHealth();
|
|
610
|
+
if (result.cloud.status === "auth_error" && result.status === "complete") {
|
|
611
|
+
result.status = "incomplete";
|
|
612
|
+
}
|
|
613
|
+
|
|
607
614
|
return result;
|
|
608
615
|
}
|
|
609
616
|
|
|
617
|
+
async function _checkCloudHealth() {
|
|
618
|
+
const { url: cloudUrl, apiKey } = getCloudConfig();
|
|
619
|
+
if (!cloudUrl) return { status: "not_configured" };
|
|
620
|
+
try {
|
|
621
|
+
const headers = {};
|
|
622
|
+
if (apiKey) headers["X-Sticky-API-Key"] = apiKey;
|
|
623
|
+
const resp = await fetch(`${cloudUrl}/health`, { method: "GET", headers, signal: AbortSignal.timeout(5000) });
|
|
624
|
+
if (resp.ok) {
|
|
625
|
+
const body = await resp.json().catch(() => ({}));
|
|
626
|
+
return { status: "ok", url: cloudUrl, version: body.version || null };
|
|
627
|
+
} else if (resp.status === 401) {
|
|
628
|
+
return {
|
|
629
|
+
status: "auth_error",
|
|
630
|
+
url: cloudUrl,
|
|
631
|
+
message: "Cloud reachable but API key rejected — check STICKY_API_KEY in .env.sticky",
|
|
632
|
+
action: "fix_api_key",
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
return { status: "error", url: cloudUrl, message: `HTTP ${resp.status}` };
|
|
636
|
+
} catch (err) {
|
|
637
|
+
return {
|
|
638
|
+
status: "unreachable",
|
|
639
|
+
url: cloudUrl,
|
|
640
|
+
message: err.name === "TimeoutError" ? "Cloud timed out (5s)" : err.message,
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
610
645
|
function toolGetThreadContextForFiles(params) {
|
|
611
646
|
const { files } = params;
|
|
612
647
|
if (!files || !Array.isArray(files) || files.length === 0) {
|
|
@@ -819,7 +854,7 @@ const CAPABILITIES = {
|
|
|
819
854
|
tools: {},
|
|
820
855
|
};
|
|
821
856
|
|
|
822
|
-
function handleRequest(msg) {
|
|
857
|
+
async function handleRequest(msg) {
|
|
823
858
|
const { method, params, id } = msg;
|
|
824
859
|
|
|
825
860
|
switch (method) {
|
|
@@ -872,7 +907,7 @@ function handleRequest(msg) {
|
|
|
872
907
|
}
|
|
873
908
|
|
|
874
909
|
try {
|
|
875
|
-
const result = tool.handler(toolArgs);
|
|
910
|
+
const result = await tool.handler(toolArgs);
|
|
876
911
|
return {
|
|
877
912
|
jsonrpc: "2.0",
|
|
878
913
|
id,
|
|
@@ -953,10 +988,17 @@ function handleRequest(msg) {
|
|
|
953
988
|
continue;
|
|
954
989
|
}
|
|
955
990
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
991
|
+
handleRequest(msg).then((response) => {
|
|
992
|
+
if (response) {
|
|
993
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
994
|
+
}
|
|
995
|
+
}).catch((err) => {
|
|
996
|
+
process.stdout.write(JSON.stringify({
|
|
997
|
+
jsonrpc: "2.0",
|
|
998
|
+
id: msg.id,
|
|
999
|
+
error: { code: -32603, message: `Internal error: ${err.message}` },
|
|
1000
|
+
}) + "\n");
|
|
1001
|
+
});
|
|
960
1002
|
}
|
|
961
1003
|
});
|
|
962
1004
|
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"httpProtocol":"HTTP/1.1","clientAcceptEncoding":"gzip, deflate, br","requestPriority":"","edgeRequestKeepAliveStatus":1,"requestHeaderNames":{},"clientTcpRtt":7,"clientQuicRtt":0,"colo":"SEA","asn":209,"asOrganization":"CenturyLink Communications, LLC","country":"US","isEUCountry":false,"city":"Seattle","continent":"NA","region":"Washington","regionCode":"WA","timezone":"America/Los_Angeles","longitude":"-122.33207","latitude":"47.60621","postalCode":"98101","metroCode":"819","tlsVersion":"TLSv1.3","tlsCipher":"AEAD-AES256-GCM-SHA384","tlsClientRandom":"XQNGM/m2YSoD+2/DfSjDYbB2Sp72SCXcbv9uvodPXVE=","tlsClientCiphersSha1":"kXrN3VEKDdzz2cPKTQaKzpxVTxQ=","tlsClientExtensionsSha1":"1eY97BUYYO8vDaTfHQywB1pcNdM=","tlsClientExtensionsSha1Le":"u4wtEMFQBY18l3BzHAvORm+KGRw=","tlsExportedAuthenticator":{"clientHandshake":"f0ba9bf76868d7072bc036be30b47e1e52b95cb14ad9335c8ced6c6111a717f35199ac65e82d44e7e40953dfbe17ece3","serverHandshake":"eee30a00abc412c4338e37496a61e82a6a645fdbcd5c143c9e0ce63eac2a96313112bc19879848ea58d8133239726287","clientFinished":"926eadd8221a92f6e9f21352b1857815711f83deea9c9960be964e3d9eca3a9311620fec3037ff128e697b449aa2ca37","serverFinished":"93f0c496a5a2e85128652abdb1e9e2155f7202217144390b29b544e0a7a228190c0a4e4ec7e85ab4342c63f377a1edcd"},"tlsClientHelloLength":"1605","tlsClientAuth":{"certPresented":"0","certVerified":"NONE","certRevoked":"0","certIssuerDN":"","certSubjectDN":"","certIssuerDNRFC2253":"","certSubjectDNRFC2253":"","certIssuerDNLegacy":"","certSubjectDNLegacy":"","certSerial":"","certIssuerSerial":"","certSKI":"","certIssuerSKI":"","certFingerprintSHA1":"","certFingerprintSHA256":"","certNotBefore":"","certNotAfter":"","certRFC9440":"","certRFC9440TooLarge":false,"certChainRFC9440":"","certChainRFC9440TooLarge":false},"verifiedBotCategory":"","edgeL4":{"deliveryRate":460059},"botManagement":{"corporateProxy":false,"verifiedBot":false,"jsDetection":{"passed":false},"staticResource":false,"detectionIds":{},"score":99}}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/sticky-server/.wrangler/state/v3/do/sticky-note-server-StickyThread/metadata.sqlite-shm
ADDED
|
Binary file
|
package/sticky-server/.wrangler/state/v3/do/sticky-note-server-StickyThread/metadata.sqlite-wal
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
["test-thread-1"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"test-thread-1","status":"open","user":"dheer","_event_chunks":1}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"type":"tool_call","ts":"2026-08-21T10:00:00Z","data":{"tool":"Read"}}]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/sticky-server/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const urls = new Set();
|
|
2
|
+
|
|
3
|
+
function checkURL(request, init) {
|
|
4
|
+
const url =
|
|
5
|
+
request instanceof URL
|
|
6
|
+
? request
|
|
7
|
+
: new URL(
|
|
8
|
+
(typeof request === "string" ? new Request(request, init) : request)
|
|
9
|
+
.url
|
|
10
|
+
);
|
|
11
|
+
if (url.port && url.port !== "443" && url.protocol === "https:") {
|
|
12
|
+
if (!urls.has(url.toString())) {
|
|
13
|
+
urls.add(url.toString());
|
|
14
|
+
console.warn(
|
|
15
|
+
`WARNING: known issue with \`fetch()\` requests to custom HTTPS ports in published Workers:\n` +
|
|
16
|
+
` - ${url.toString()} - the custom port will be ignored when the Worker is published using the \`wrangler deploy\` command.\n`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
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
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import worker, * as OTHER_EXPORTS from "C:\\Users\\dheer\\OneDrive\\Desktop\\Projects\\sticky-note\\sticky-server\\worker.js";
|
|
2
|
+
import * as __MIDDLEWARE_0__ from "C:\\Users\\dheer\\AppData\\Roaming\\npm\\node_modules\\wrangler\\templates\\middleware\\middleware-ensure-req-body-drained.ts";
|
|
3
|
+
import * as __MIDDLEWARE_1__ from "C:\\Users\\dheer\\AppData\\Roaming\\npm\\node_modules\\wrangler\\templates\\middleware\\middleware-miniflare3-json-error.ts";
|
|
4
|
+
|
|
5
|
+
export * from "C:\\Users\\dheer\\OneDrive\\Desktop\\Projects\\sticky-note\\sticky-server\\worker.js";
|
|
6
|
+
const MIDDLEWARE_TEST_INJECT = "__INJECT_FOR_TESTING_WRANGLER_MIDDLEWARE__";
|
|
7
|
+
export const __INTERNAL_WRANGLER_MIDDLEWARE__ = [
|
|
8
|
+
|
|
9
|
+
__MIDDLEWARE_0__.default,__MIDDLEWARE_1__.default
|
|
10
|
+
]
|
|
11
|
+
export default worker;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// This loads all middlewares exposed on the middleware object and then starts
|
|
2
|
+
// the invocation chain. The big idea is that we can add these to the middleware
|
|
3
|
+
// export dynamically through wrangler, or we can potentially let users directly
|
|
4
|
+
// add them as a sort of "plugin" system.
|
|
5
|
+
|
|
6
|
+
import ENTRY, { __INTERNAL_WRANGLER_MIDDLEWARE__ } from "C:\\Users\\dheer\\OneDrive\\Desktop\\Projects\\sticky-note\\sticky-server\\.wrangler\\tmp\\bundle-BhcBKo\\middleware-insertion-facade.js";
|
|
7
|
+
import { __facade_invoke__, __facade_register__, Dispatcher } from "C:\\Users\\dheer\\AppData\\Roaming\\npm\\node_modules\\wrangler\\templates\\middleware\\common.ts";
|
|
8
|
+
import type { WorkerEntrypointConstructor } from "C:\\Users\\dheer\\OneDrive\\Desktop\\Projects\\sticky-note\\sticky-server\\.wrangler\\tmp\\bundle-BhcBKo\\middleware-insertion-facade.js";
|
|
9
|
+
|
|
10
|
+
// Preserve all the exports from the worker
|
|
11
|
+
export * from "C:\\Users\\dheer\\OneDrive\\Desktop\\Projects\\sticky-note\\sticky-server\\.wrangler\\tmp\\bundle-BhcBKo\\middleware-insertion-facade.js";
|
|
12
|
+
|
|
13
|
+
class __Facade_ScheduledController__ implements ScheduledController {
|
|
14
|
+
readonly #noRetry: ScheduledController["noRetry"];
|
|
15
|
+
|
|
16
|
+
constructor(
|
|
17
|
+
readonly scheduledTime: number,
|
|
18
|
+
readonly cron: string,
|
|
19
|
+
noRetry: ScheduledController["noRetry"]
|
|
20
|
+
) {
|
|
21
|
+
this.#noRetry = noRetry;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
noRetry() {
|
|
25
|
+
if (!(this instanceof __Facade_ScheduledController__)) {
|
|
26
|
+
throw new TypeError("Illegal invocation");
|
|
27
|
+
}
|
|
28
|
+
// Need to call native method immediately in case uncaught error thrown
|
|
29
|
+
this.#noRetry();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function wrapExportedHandler(worker: ExportedHandler): ExportedHandler {
|
|
34
|
+
// If we don't have any middleware defined, just return the handler as is
|
|
35
|
+
if (
|
|
36
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__ === undefined ||
|
|
37
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__.length === 0
|
|
38
|
+
) {
|
|
39
|
+
return worker;
|
|
40
|
+
}
|
|
41
|
+
// Otherwise, register all middleware once
|
|
42
|
+
for (const middleware of __INTERNAL_WRANGLER_MIDDLEWARE__) {
|
|
43
|
+
__facade_register__(middleware);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const fetchDispatcher: ExportedHandlerFetchHandler = function (
|
|
47
|
+
request,
|
|
48
|
+
env,
|
|
49
|
+
ctx
|
|
50
|
+
) {
|
|
51
|
+
if (worker.fetch === undefined) {
|
|
52
|
+
throw new Error("Handler does not export a fetch() function.");
|
|
53
|
+
}
|
|
54
|
+
return worker.fetch(request, env, ctx);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
...worker,
|
|
59
|
+
fetch(request, env, ctx) {
|
|
60
|
+
const dispatcher: Dispatcher = function (type, init) {
|
|
61
|
+
if (type === "scheduled" && worker.scheduled !== undefined) {
|
|
62
|
+
const controller = new __Facade_ScheduledController__(
|
|
63
|
+
Date.now(),
|
|
64
|
+
init.cron ?? "",
|
|
65
|
+
() => {}
|
|
66
|
+
);
|
|
67
|
+
return worker.scheduled(controller, env, ctx);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
return __facade_invoke__(request, env, ctx, dispatcher, fetchDispatcher);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function wrapWorkerEntrypoint(
|
|
76
|
+
klass: WorkerEntrypointConstructor
|
|
77
|
+
): WorkerEntrypointConstructor {
|
|
78
|
+
// If we don't have any middleware defined, just return the handler as is
|
|
79
|
+
if (
|
|
80
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__ === undefined ||
|
|
81
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__.length === 0
|
|
82
|
+
) {
|
|
83
|
+
return klass;
|
|
84
|
+
}
|
|
85
|
+
// Otherwise, register all middleware once
|
|
86
|
+
for (const middleware of __INTERNAL_WRANGLER_MIDDLEWARE__) {
|
|
87
|
+
__facade_register__(middleware);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// `extend`ing `klass` here so other RPC methods remain callable
|
|
91
|
+
return class extends klass {
|
|
92
|
+
#fetchDispatcher: ExportedHandlerFetchHandler<Record<string, unknown>> = (
|
|
93
|
+
request,
|
|
94
|
+
env,
|
|
95
|
+
ctx
|
|
96
|
+
) => {
|
|
97
|
+
this.env = env;
|
|
98
|
+
this.ctx = ctx;
|
|
99
|
+
if (super.fetch === undefined) {
|
|
100
|
+
throw new Error("Entrypoint class does not define a fetch() function.");
|
|
101
|
+
}
|
|
102
|
+
return super.fetch(request);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
#dispatcher: Dispatcher = (type, init) => {
|
|
106
|
+
if (type === "scheduled" && super.scheduled !== undefined) {
|
|
107
|
+
const controller = new __Facade_ScheduledController__(
|
|
108
|
+
Date.now(),
|
|
109
|
+
init.cron ?? "",
|
|
110
|
+
() => {}
|
|
111
|
+
);
|
|
112
|
+
return super.scheduled(controller);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
fetch(request: Request<unknown, IncomingRequestCfProperties>) {
|
|
117
|
+
return __facade_invoke__(
|
|
118
|
+
request,
|
|
119
|
+
this.env,
|
|
120
|
+
this.ctx,
|
|
121
|
+
this.#dispatcher,
|
|
122
|
+
this.#fetchDispatcher
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let WRAPPED_ENTRY: ExportedHandler | WorkerEntrypointConstructor | undefined;
|
|
129
|
+
if (typeof ENTRY === "object") {
|
|
130
|
+
WRAPPED_ENTRY = wrapExportedHandler(ENTRY);
|
|
131
|
+
} else if (typeof ENTRY === "function") {
|
|
132
|
+
WRAPPED_ENTRY = wrapWorkerEntrypoint(ENTRY);
|
|
133
|
+
}
|
|
134
|
+
export default WRAPPED_ENTRY;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const urls = new Set();
|
|
2
|
+
|
|
3
|
+
function checkURL(request, init) {
|
|
4
|
+
const url =
|
|
5
|
+
request instanceof URL
|
|
6
|
+
? request
|
|
7
|
+
: new URL(
|
|
8
|
+
(typeof request === "string" ? new Request(request, init) : request)
|
|
9
|
+
.url
|
|
10
|
+
);
|
|
11
|
+
if (url.port && url.port !== "443" && url.protocol === "https:") {
|
|
12
|
+
if (!urls.has(url.toString())) {
|
|
13
|
+
urls.add(url.toString());
|
|
14
|
+
console.warn(
|
|
15
|
+
`WARNING: known issue with \`fetch()\` requests to custom HTTPS ports in published Workers:\n` +
|
|
16
|
+
` - ${url.toString()} - the custom port will be ignored when the Worker is published using the \`wrangler deploy\` command.\n`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
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
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import worker, * as OTHER_EXPORTS from "C:\\Users\\dheer\\OneDrive\\Desktop\\Projects\\sticky-note\\sticky-server\\worker.js";
|
|
2
|
+
import * as __MIDDLEWARE_0__ from "C:\\Users\\dheer\\AppData\\Roaming\\npm\\node_modules\\wrangler\\templates\\middleware\\middleware-ensure-req-body-drained.ts";
|
|
3
|
+
import * as __MIDDLEWARE_1__ from "C:\\Users\\dheer\\AppData\\Roaming\\npm\\node_modules\\wrangler\\templates\\middleware\\middleware-miniflare3-json-error.ts";
|
|
4
|
+
|
|
5
|
+
export * from "C:\\Users\\dheer\\OneDrive\\Desktop\\Projects\\sticky-note\\sticky-server\\worker.js";
|
|
6
|
+
const MIDDLEWARE_TEST_INJECT = "__INJECT_FOR_TESTING_WRANGLER_MIDDLEWARE__";
|
|
7
|
+
export const __INTERNAL_WRANGLER_MIDDLEWARE__ = [
|
|
8
|
+
|
|
9
|
+
__MIDDLEWARE_0__.default,__MIDDLEWARE_1__.default
|
|
10
|
+
]
|
|
11
|
+
export default worker;
|