bitcompass 0.2.2 → 0.2.4
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/dist/mcp/server.js +19 -0
- package/package.json +22 -7
- package/scripts/postinstall.js +107 -0
package/dist/mcp/server.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { AUTH_REQUIRED_MSG, insertRule, searchRules } from '../api/client.js';
|
|
2
2
|
import { loadCredentials } from '../auth/config.js';
|
|
3
|
+
/** When token is missing, we fail initialize so Cursor shows "Needs authentication" (yellow) instead of success (green). */
|
|
4
|
+
const NEEDS_AUTH_ERROR_MESSAGE = 'Needs authentication';
|
|
5
|
+
const NEEDS_AUTH_ERROR_CODE = -32001; // Server error: auth required
|
|
3
6
|
function createStdioServer() {
|
|
4
7
|
const handlers = new Map();
|
|
5
8
|
let requestId = 0;
|
|
@@ -16,6 +19,22 @@ function createStdioServer() {
|
|
|
16
19
|
if (isNotification)
|
|
17
20
|
return;
|
|
18
21
|
if (msg.method === 'initialize') {
|
|
22
|
+
const hasToken = Boolean(loadCredentials()?.access_token);
|
|
23
|
+
if (!hasToken) {
|
|
24
|
+
send({
|
|
25
|
+
jsonrpc: '2.0',
|
|
26
|
+
id,
|
|
27
|
+
error: {
|
|
28
|
+
code: NEEDS_AUTH_ERROR_CODE,
|
|
29
|
+
message: NEEDS_AUTH_ERROR_MESSAGE,
|
|
30
|
+
data: {
|
|
31
|
+
action: 'Login',
|
|
32
|
+
instructions: "Run `bitcompass login` in a terminal, then restart the MCP server in Cursor.",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
19
38
|
send({
|
|
20
39
|
jsonrpc: '2.0',
|
|
21
40
|
id,
|
package/package.json
CHANGED
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bitcompass",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "BitCompass CLI - rules, solutions, and MCP server",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"bin": {
|
|
6
|
+
"bin": {
|
|
7
|
+
"bitcompass": "./dist/index.js"
|
|
8
|
+
},
|
|
7
9
|
"scripts": {
|
|
8
10
|
"build": "tsc",
|
|
9
11
|
"dev": "tsc --watch",
|
|
10
12
|
"start": "node dist/index.js",
|
|
11
|
-
"prepare": "npm run build"
|
|
13
|
+
"prepare": "npm run build",
|
|
14
|
+
"postinstall": "node scripts/postinstall.js"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
12
18
|
},
|
|
13
|
-
"engines": { "node": ">=18" },
|
|
14
19
|
"repository": {
|
|
15
20
|
"type": "git",
|
|
16
21
|
"url": "https://github.com/company-compass/company-compass.git",
|
|
17
22
|
"directory": "packages/bitcompass-cli"
|
|
18
23
|
},
|
|
19
24
|
"license": "MIT",
|
|
20
|
-
"keywords": [
|
|
25
|
+
"keywords": [
|
|
26
|
+
"mcp",
|
|
27
|
+
"cursor",
|
|
28
|
+
"rules",
|
|
29
|
+
"bitcompass",
|
|
30
|
+
"cli",
|
|
31
|
+
"supabase"
|
|
32
|
+
],
|
|
21
33
|
"dependencies": {
|
|
22
34
|
"dotenv": "^16.4.5",
|
|
23
35
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
@@ -35,5 +47,8 @@
|
|
|
35
47
|
"@types/node": "^22.0.0",
|
|
36
48
|
"typescript": "^5.8.0"
|
|
37
49
|
},
|
|
38
|
-
"files": [
|
|
39
|
-
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"scripts"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
|
+
import { dirname, join } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const pkgPath = join(__dirname, "..", "package.json");
|
|
10
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
11
|
+
const version = pkg.version;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Renders text with a gradient between two RGB colors.
|
|
15
|
+
* @param {string} text
|
|
16
|
+
* @param {[number, number, number]} start - [r, g, b] 0-255
|
|
17
|
+
* @param {[number, number, number]} end - [r, g, b] 0-255
|
|
18
|
+
* @returns {string}
|
|
19
|
+
*/
|
|
20
|
+
const gradient = (text, [r1, g1, b1], [r2, g2, b2]) =>
|
|
21
|
+
[...text]
|
|
22
|
+
.map((char, i) => {
|
|
23
|
+
const t = text.length > 1 ? i / (text.length - 1) : 1;
|
|
24
|
+
const r = Math.round(r1 + (r2 - r1) * t);
|
|
25
|
+
const g = Math.round(g1 + (g2 - g1) * t);
|
|
26
|
+
const b = Math.round(b1 + (b2 - b1) * t);
|
|
27
|
+
return chalk.rgb(r, g, b)(char);
|
|
28
|
+
})
|
|
29
|
+
.join("");
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Glow effect: gradient that peaks in the middle (bright center, dimmer edges).
|
|
33
|
+
* @param {string} text
|
|
34
|
+
* @param {[number, number, number]} baseColor - [r, g, b] for the glow color
|
|
35
|
+
* @returns {string}
|
|
36
|
+
*/
|
|
37
|
+
const glow = (text, [r, g, b]) =>
|
|
38
|
+
[...text]
|
|
39
|
+
.map((char, i) => {
|
|
40
|
+
const t = text.length > 1 ? i / (text.length - 1) : 1;
|
|
41
|
+
const peak = 1 - 4 * (t - 0.5) * (t - 0.5);
|
|
42
|
+
const mult = 0.4 + 0.6 * Math.max(0, peak);
|
|
43
|
+
const R = Math.round(r * mult);
|
|
44
|
+
const G = Math.round(g * mult);
|
|
45
|
+
const B = Math.round(b * mult);
|
|
46
|
+
return chalk.rgb(R, G, B)(char);
|
|
47
|
+
})
|
|
48
|
+
.join("");
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Same as glow but with a brightness multiplier for animation (0–1).
|
|
52
|
+
*/
|
|
53
|
+
const glowWithBrightness = (text, [r, g, b], brightness) =>
|
|
54
|
+
[...text]
|
|
55
|
+
.map((char, i) => {
|
|
56
|
+
const t = text.length > 1 ? i / (text.length - 1) : 1;
|
|
57
|
+
const peak = 1 - 4 * (t - 0.5) * (t - 0.5);
|
|
58
|
+
const mult = (0.4 + 0.6 * Math.max(0, peak)) * brightness;
|
|
59
|
+
const R = Math.round(r * Math.min(1, mult));
|
|
60
|
+
const G = Math.round(g * Math.min(1, mult));
|
|
61
|
+
const B = Math.round(b * Math.min(1, mult));
|
|
62
|
+
return chalk.rgb(R, G, B)(char);
|
|
63
|
+
})
|
|
64
|
+
.join("");
|
|
65
|
+
|
|
66
|
+
const cyan = [0, 212, 255];
|
|
67
|
+
const magenta = [255, 64, 200];
|
|
68
|
+
const amber = [255, 190, 50];
|
|
69
|
+
const glowColor = [255, 120, 255];
|
|
70
|
+
|
|
71
|
+
const PREFIX = "made by ";
|
|
72
|
+
const AUTHOR = "davide97g";
|
|
73
|
+
const GITHUB_URL = "https://github.com/davide97g/";
|
|
74
|
+
|
|
75
|
+
/** Wraps text in OSC 8 hyperlink so it's clickable in supported terminals (VS Code, iTerm2, Windows Terminal). */
|
|
76
|
+
const link = (url, text) => `\x1b]8;;${url}\x1b\\${text}\x1b]8;;\x1b\\`;
|
|
77
|
+
|
|
78
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
79
|
+
|
|
80
|
+
const animateAuthorLine = async () => {
|
|
81
|
+
const isTty = process.stdout.isTTY;
|
|
82
|
+
const frames = 6;
|
|
83
|
+
const frameMs = 80;
|
|
84
|
+
|
|
85
|
+
if (!isTty) {
|
|
86
|
+
console.log(PREFIX + link(GITHUB_URL, glow(AUTHOR, glowColor)));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (let f = 0; f < frames; f++) {
|
|
91
|
+
const t = f / (frames - 1);
|
|
92
|
+
const brightness = 0.3 + 0.7 * (1 - Math.cos(t * Math.PI));
|
|
93
|
+
const styledAuthor = glowWithBrightness(AUTHOR, glowColor, brightness);
|
|
94
|
+
const line = PREFIX + link(GITHUB_URL, styledAuthor);
|
|
95
|
+
process.stdout.write("\r\x1b[K" + line);
|
|
96
|
+
await sleep(frameMs);
|
|
97
|
+
}
|
|
98
|
+
const finalLine = PREFIX + link(GITHUB_URL, glow(AUTHOR, glowColor));
|
|
99
|
+
process.stdout.write("\r\x1b[K" + finalLine + "\n");
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
(async () => {
|
|
103
|
+
console.log("");
|
|
104
|
+
console.log(gradient(`version ${version}`, cyan, magenta));
|
|
105
|
+
await animateAuthorLine();
|
|
106
|
+
console.log("");
|
|
107
|
+
})();
|