sticky-note-cli 3.1.6 → 3.1.7
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 +76 -17
- package/package.json +1 -1
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
|
|
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
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
|
|
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
|
|
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
|
|
1121
|
+
print(" │ git commit -m \"feat: add sticky-note hooks\" │");
|
|
1081
1122
|
print(" │ git push │");
|
|
1082
1123
|
print(" └──────────────────────────────────────────────────────────────┘");
|
|
1083
1124
|
print("");
|
|
1084
|
-
|
|
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 };
|