sticky-note-cli 3.1.6 → 3.1.8

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/bin/cli.js CHANGED
@@ -14,6 +14,7 @@
14
14
 
15
15
  const fs = require("fs");
16
16
  const path = require("path");
17
+ const os = require("os");
17
18
  const readline = require("readline");
18
19
  const { execSync, execFileSync } = require("child_process");
19
20
 
@@ -551,6 +552,11 @@ async function cmdInit() {
551
552
  print(" [OK] Git repository detected");
552
553
  print("");
553
554
 
555
+ // Read existing sticky-note-config.json for teammate flow (cloud URL pre-set via git)
556
+ const existingConfigPath = path.join(process.cwd(), ".sticky-note", "sticky-note-config.json");
557
+ const existingConfig = readJsonSafe(existingConfigPath, {});
558
+ const configStickyUrl = existingConfig.sticky_url || "";
559
+
554
560
  // Auto-detect MCP servers and skills
555
561
  print(" Scanning for existing configuration...");
556
562
  const detectedMcp = detectMcpServers();
@@ -575,6 +581,7 @@ async function cmdInit() {
575
581
 
576
582
  let mcpServers, skills, conventions, staleDaysResolved, injectTokenBudgetResolved;
577
583
  let wantsCloud = false;
584
+ let cloudProvisionedUrl = null; // set after successful provisioning, written to config
578
585
 
579
586
  if (ciMode) {
580
587
  // CI mode: no prompts, use env vars
@@ -597,7 +604,7 @@ async function cmdInit() {
597
604
  conventions = convRaw ? convRaw.split(",").map(s => s.trim()).filter(Boolean) : [];
598
605
  staleDaysResolved = parseIntOr(staleDaysRaw, 14);
599
606
  injectTokenBudgetResolved = 1000;
600
- wantsCloud = v3Mode; // --v3 in CI mode implies cloud
607
+ wantsCloud = v3Mode && !configStickyUrl; // --v3 implies cloud, but not if URL already in config
601
608
  } else {
602
609
  // Interactive prompts
603
610
  const rl = readline.createInterface({
@@ -625,12 +632,25 @@ async function cmdInit() {
625
632
  // Sync MCP servers from teammate's sticky-note config
626
633
  await syncMcpFromStickyNote(rl);
627
634
 
628
- const cloudAnswer = await ask(
629
- rl,
630
- "Set up Cloudflare cloud backend for real-time team sync? (y/N)",
631
- v3Mode ? "y" : "N"
632
- );
633
- wantsCloud = cloudAnswer.toLowerCase() === "y" || cloudAnswer.toLowerCase() === "yes";
635
+ if (configStickyUrl) {
636
+ // Teammate flow: URL already in committed config — just need their API key
637
+ print(`\n Cloud backend detected: ${configStickyUrl}`);
638
+ const keyAnswer = await ask(rl, "Enter your STICKY_API_KEY (get it from your team lead)", "");
639
+ if (keyAnswer.trim()) {
640
+ const envPath = path.join(process.cwd(), ".env.sticky");
641
+ fs.writeFileSync(envPath, `STICKY_URL=${configStickyUrl}\nSTICKY_API_KEY=${keyAnswer.trim()}\n`, "utf-8");
642
+ print(" [OK] .env.sticky written");
643
+ } else {
644
+ print(" ⏭️ No API key entered — skipping .env.sticky (local-only mode)");
645
+ }
646
+ } else {
647
+ const cloudAnswer = await ask(
648
+ rl,
649
+ "Set up Cloudflare cloud backend for real-time team sync? (y/N)",
650
+ v3Mode ? "y" : "N"
651
+ );
652
+ wantsCloud = cloudAnswer.toLowerCase() === "y" || cloudAnswer.toLowerCase() === "yes";
653
+ }
634
654
 
635
655
  rl.close();
636
656
 
@@ -707,13 +727,13 @@ async function cmdInit() {
707
727
  print(" [WARN] Cloud setup failed: " + cloudResult.error);
708
728
  print(" Run `npx sticky-note deploy-backend` to retry.\n");
709
729
  } else if (cloudResult && !cloudResult.error) {
710
- if (cloudResult.secretSet) {
711
- print("\n Share STICKY_URL and STICKY_API_KEY with teammates securely.");
712
- print(" (e.g. org secrets, 1Password — do not commit .env.sticky)\n");
713
- } else {
714
- print("\n [!] API key written to .env.sticky but NOT yet set on the Worker.");
715
- print(" Run the manual command shown above, then share with your team.\n");
716
- }
730
+ cloudProvisionedUrl = cloudResult.workerUrl;
731
+ print("\n ┌─────────────────────────────────────────────────────────────┐");
732
+ print(" │ Share this with teammates (once, via DM or 1Password): │");
733
+ print(` │ STICKY_API_KEY=${cloudResult.apiKey.padEnd(43)}│`);
734
+ print(" │ │");
735
+ print(" │ STICKY_URL is committed to git — teammates get it on pull. │");
736
+ print(" └─────────────────────────────────────────────────────────────┘\n");
717
737
  }
718
738
  } else if (wantsCloud && ciMode) {
719
739
  // CI mode: can't pause for wrangler install, just try and warn on failure
@@ -845,6 +865,7 @@ async function cmdInit() {
845
865
  existing.inject_token_budget = injectTokenBudgetResolved;
846
866
  existing.hook_version = VERSION;
847
867
  existing.min_version = bumpMinVersion(existing.min_version, VERSION);
868
+ if (cloudProvisionedUrl) existing.sticky_url = cloudProvisionedUrl;
848
869
  fs.writeFileSync(configDest, JSON.stringify(existing, null, 2) + "\n");
849
870
  }
850
871
  print(" [OK] .sticky-note/sticky-note-config.json");
@@ -1072,16 +1093,43 @@ async function cmdInit() {
1072
1093
  }
1073
1094
  }
1074
1095
 
1096
+ // Register sticky-note MCP server in Claude Code's global settings (~/.claude/settings.json)
1097
+ const claudeGlobalSettingsPath = path.join(os.homedir(), ".claude", "settings.json");
1098
+ try {
1099
+ const claudeGlobal = readJsonSafe(claudeGlobalSettingsPath, {});
1100
+ if (!claudeGlobal.mcpServers) claudeGlobal.mcpServers = {};
1101
+ if (!claudeGlobal.mcpServers["sticky-note"]) {
1102
+ claudeGlobal.mcpServers["sticky-note"] = {
1103
+ type: "stdio",
1104
+ command: "npx",
1105
+ args: ["-y", "-p", "sticky-note-cli", "sticky-note", "mcp-server"],
1106
+ };
1107
+ fs.writeFileSync(claudeGlobalSettingsPath, JSON.stringify(claudeGlobal, null, 2) + "\n");
1108
+ print(" [OK] Registered sticky-note MCP server in ~/.claude/settings.json (Claude Code)");
1109
+ } else {
1110
+ print(" ⏭️ sticky-note already registered in ~/.claude/settings.json");
1111
+ }
1112
+ } catch (err) {
1113
+ print(" ⏭️ Could not update ~/.claude/settings.json: " + (err.message || err));
1114
+ }
1115
+
1075
1116
  // Done!
1076
- print("\n ✨ Sticky Note V2 initialized!\n");
1117
+ print("\n ✨ Sticky Note initialized!\n");
1077
1118
  print(" Next steps:");
1078
1119
  print(" ┌──────────────────────────────────────────────────────────────┐");
1079
1120
  print(" │ git add .claude .github .sticky-note .gitignore .gitattributes CLAUDE.md │");
1080
- print(" │ git commit -m \"feat: add sticky-note v2 hooks\" │");
1121
+ print(" │ git commit -m \"feat: add sticky-note hooks\" │");
1081
1122
  print(" │ git push │");
1082
1123
  print(" └──────────────────────────────────────────────────────────────┘");
1083
1124
  print("");
1084
- print(" Teammates just need to `git pull` — no extra setup.");
1125
+ if (cloudProvisionedUrl) {
1126
+ print(" Teammates: git pull → run `npx sticky-note init` → enter API key when prompted.");
1127
+ print(" Restart Claude Code to activate the sticky-note MCP server.");
1128
+ } else if (configStickyUrl) {
1129
+ print(" Restart Claude Code to activate the sticky-note MCP server.");
1130
+ } else {
1131
+ print(" Teammates just need to `git pull` — no extra setup.");
1132
+ }
1085
1133
  print("");
1086
1134
  }
1087
1135
 
@@ -3038,6 +3086,17 @@ function provisionCloudBackend() {
3038
3086
  const envPath = path.join(process.cwd(), ".env.sticky");
3039
3087
  fs.writeFileSync(envPath, `STICKY_URL=${workerUrl}\nSTICKY_API_KEY=${apiKey}\n`, "utf-8");
3040
3088
  print(" [OK] .env.sticky written with STICKY_URL and STICKY_API_KEY");
3089
+
3090
+ // Write sticky_url to committed config so teammates get it on git pull
3091
+ const configPath = path.join(process.cwd(), ".sticky-note", "sticky-note-config.json");
3092
+ if (fs.existsSync(configPath)) {
3093
+ try {
3094
+ const cfg = readJsonSafe(configPath, {});
3095
+ cfg.sticky_url = workerUrl;
3096
+ fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2) + "\n");
3097
+ print(" [OK] sticky_url written to .sticky-note/sticky-note-config.json (commit this!)");
3098
+ } catch (_) {}
3099
+ }
3041
3100
  }
3042
3101
 
3043
3102
  return { workerUrl, apiKey, secretSet };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sticky-note-cli",
3
- "version": "3.1.6",
3
+ "version": "3.1.8",
4
4
  "description": "Human-to-human handoff for AI coding assistants. Git-backed shared memory for Claude Code and Copilot CLI.",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -1,7 +1,4 @@
1
- # Sticky Note - data moved to sticky-note/data branch (.git/sticky-note/ cache)
2
- .sticky-note/
3
-
4
- # Sticky Note - local overrides
1
+ # Sticky Note - local overrides (never commit these)
5
2
  .claude/settings.local.json
6
3
  .env.sticky
7
4