@mcp-s/skills 1.0.2 → 1.3.1
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 +399 -96
- package/ThirdPartyNoticeText.txt +171 -0
- package/bin/cli.mjs +14 -0
- package/dist/_chunks/libs/@clack/core.mjs +767 -0
- package/dist/_chunks/libs/@clack/prompts.mjs +275 -0
- package/dist/_chunks/libs/@kwsites/file-exists.mjs +562 -0
- package/dist/_chunks/libs/@kwsites/promise-deferred.mjs +37 -0
- package/dist/_chunks/libs/bluebird.mjs +4141 -0
- package/dist/_chunks/libs/core-util-is.mjs +65 -0
- package/dist/_chunks/libs/duplexer2.mjs +1726 -0
- package/dist/_chunks/libs/esprima.mjs +5338 -0
- package/dist/_chunks/libs/extend-shallow.mjs +31 -0
- package/dist/_chunks/libs/fs-extra.mjs +1801 -0
- package/dist/_chunks/libs/gray-matter.mjs +2596 -0
- package/dist/_chunks/libs/node-int64.mjs +103 -0
- package/dist/_chunks/libs/simple-git.mjs +3584 -0
- package/dist/_chunks/libs/unzipper.mjs +945 -0
- package/dist/_chunks/libs/xdg-basedir.mjs +14 -0
- package/dist/_chunks/rolldown-runtime.mjs +24 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +4258 -0
- package/package.json +85 -27
- package/dist/agents.js +0 -246
- package/dist/api.js +0 -45
- package/dist/auth.js +0 -98
- package/dist/index.js +0 -482
- package/dist/installer.js +0 -188
- package/dist/types.js +0 -1
package/package.json
CHANGED
|
@@ -1,53 +1,111 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-s/skills",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.3.1",
|
|
4
|
+
"description": "The open agent skills ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"files": [
|
|
7
|
-
"dist"
|
|
8
|
-
],
|
|
9
|
-
"main": "dist/index.js",
|
|
10
6
|
"bin": {
|
|
11
|
-
"skills": "
|
|
7
|
+
"skills": "./bin/cli.mjs",
|
|
8
|
+
"add-skill": "./bin/cli.mjs"
|
|
12
9
|
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"bin",
|
|
13
|
+
"README.md",
|
|
14
|
+
"ThirdPartyNoticeText.txt"
|
|
15
|
+
],
|
|
13
16
|
"scripts": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
17
|
+
"build": "node scripts/generate-licenses.ts && obuild",
|
|
18
|
+
"generate-licenses": "node scripts/generate-licenses.ts",
|
|
19
|
+
"dev": "node src/cli.ts",
|
|
20
|
+
"exec:test": "node scripts/execute-tests.ts",
|
|
21
|
+
"prepublishOnly": "npm run build",
|
|
22
|
+
"format": "prettier --write 'src/**/*.ts' 'scripts/**/*.ts'",
|
|
23
|
+
"format:check": "prettier --check 'src/**/*.ts' 'scripts/**/*.ts'",
|
|
24
|
+
"prepare": "husky",
|
|
25
|
+
"test": "vitest",
|
|
26
|
+
"type-check": "tsc --noEmit",
|
|
27
|
+
"publish:snapshot": "npm version prerelease --preid=snapshot --no-git-tag-version && npm publish --tag snapshot"
|
|
28
|
+
},
|
|
29
|
+
"lint-staged": {
|
|
30
|
+
"src/**/*.ts": "prettier --write",
|
|
31
|
+
"scripts/**/*.ts": "prettier --write",
|
|
32
|
+
"tests/**/*.ts": "prettier --write"
|
|
19
33
|
},
|
|
20
|
-
"author": "MCP-S",
|
|
21
|
-
"license": "ISC",
|
|
22
34
|
"keywords": [
|
|
23
35
|
"cli",
|
|
24
36
|
"agent-skills",
|
|
25
37
|
"skills",
|
|
26
38
|
"ai-agents",
|
|
27
|
-
"
|
|
39
|
+
"amp",
|
|
40
|
+
"antigravity",
|
|
41
|
+
"augment",
|
|
28
42
|
"claude-code",
|
|
43
|
+
"openclaw",
|
|
29
44
|
"cline",
|
|
45
|
+
"codebuddy",
|
|
30
46
|
"codex",
|
|
47
|
+
"command-code",
|
|
48
|
+
"continue",
|
|
49
|
+
"crush",
|
|
31
50
|
"cursor",
|
|
51
|
+
"droid",
|
|
52
|
+
"gemini-cli",
|
|
53
|
+
"github-copilot",
|
|
54
|
+
"goose",
|
|
55
|
+
"junie",
|
|
56
|
+
"iflow-cli",
|
|
57
|
+
"kilo",
|
|
58
|
+
"kimi-cli",
|
|
59
|
+
"kiro-cli",
|
|
60
|
+
"kode",
|
|
61
|
+
"mcpjam",
|
|
62
|
+
"mistral-vibe",
|
|
63
|
+
"mux",
|
|
32
64
|
"opencode",
|
|
65
|
+
"openclaude",
|
|
33
66
|
"openhands",
|
|
34
|
-
"
|
|
67
|
+
"pi",
|
|
68
|
+
"qoder",
|
|
69
|
+
"qwen-code",
|
|
70
|
+
"replit",
|
|
71
|
+
"roo",
|
|
72
|
+
"trae",
|
|
73
|
+
"trae-cn",
|
|
74
|
+
"windsurf",
|
|
75
|
+
"zencoder",
|
|
76
|
+
"neovate",
|
|
77
|
+
"pochi",
|
|
78
|
+
"adal"
|
|
35
79
|
],
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"commander": "^13.1.0",
|
|
40
|
-
"open": "^10.1.1"
|
|
80
|
+
"repository": {
|
|
81
|
+
"type": "git",
|
|
82
|
+
"url": "git+https://github.com/vercel-labs/skills.git"
|
|
41
83
|
},
|
|
42
|
-
"
|
|
43
|
-
|
|
84
|
+
"homepage": "https://github.com/vercel-labs/skills#readme",
|
|
85
|
+
"bugs": {
|
|
86
|
+
"url": "https://github.com/vercel-labs/skills/issues"
|
|
44
87
|
},
|
|
88
|
+
"author": "",
|
|
89
|
+
"license": "MIT",
|
|
45
90
|
"devDependencies": {
|
|
46
|
-
"@
|
|
47
|
-
"
|
|
48
|
-
"
|
|
91
|
+
"@clack/prompts": "^0.11.0",
|
|
92
|
+
"@types/bun": "latest",
|
|
93
|
+
"@types/node": "^22.10.0",
|
|
94
|
+
"@types/unzipper": "^0.10.11",
|
|
95
|
+
"gray-matter": "^4.0.3",
|
|
96
|
+
"husky": "^9.1.7",
|
|
97
|
+
"lint-staged": "^16.2.7",
|
|
98
|
+
"obuild": "^0.4.22",
|
|
99
|
+
"picocolors": "^1.1.1",
|
|
100
|
+
"prettier": "^3.8.1",
|
|
101
|
+
"simple-git": "^3.27.0",
|
|
102
|
+
"typescript": "^5.9.3",
|
|
103
|
+
"unzipper": "^0.12.3",
|
|
104
|
+
"vitest": "^4.0.17",
|
|
105
|
+
"xdg-basedir": "^5.1.0"
|
|
49
106
|
},
|
|
50
107
|
"engines": {
|
|
51
108
|
"node": ">=18"
|
|
52
|
-
}
|
|
109
|
+
},
|
|
110
|
+
"packageManager": "pnpm@10.17.1"
|
|
53
111
|
}
|
package/dist/agents.js
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import { homedir } from "os";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { existsSync } from "fs";
|
|
4
|
-
const home = homedir();
|
|
5
|
-
export const agents = {
|
|
6
|
-
amp: {
|
|
7
|
-
name: "amp",
|
|
8
|
-
displayName: "Amp",
|
|
9
|
-
skillsDir: ".agents/skills",
|
|
10
|
-
globalSkillsDir: join(home, ".config/agents/skills"),
|
|
11
|
-
detectInstalled: async () => {
|
|
12
|
-
return existsSync(join(home, ".config/amp"));
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
antigravity: {
|
|
16
|
-
name: "antigravity",
|
|
17
|
-
displayName: "Antigravity",
|
|
18
|
-
skillsDir: ".agent/skills",
|
|
19
|
-
globalSkillsDir: join(home, ".gemini/antigravity/skills"),
|
|
20
|
-
detectInstalled: async () => {
|
|
21
|
-
return (existsSync(join(process.cwd(), ".agent")) ||
|
|
22
|
-
existsSync(join(home, ".gemini/antigravity")));
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
"claude-code": {
|
|
26
|
-
name: "claude-code",
|
|
27
|
-
displayName: "Claude Code",
|
|
28
|
-
skillsDir: ".claude/skills",
|
|
29
|
-
globalSkillsDir: join(home, ".claude/skills"),
|
|
30
|
-
detectInstalled: async () => {
|
|
31
|
-
return existsSync(join(home, ".claude"));
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
clawdbot: {
|
|
35
|
-
name: "clawdbot",
|
|
36
|
-
displayName: "Clawdbot",
|
|
37
|
-
skillsDir: "skills",
|
|
38
|
-
globalSkillsDir: join(home, ".clawdbot/skills"),
|
|
39
|
-
detectInstalled: async () => {
|
|
40
|
-
return existsSync(join(home, ".clawdbot"));
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
cline: {
|
|
44
|
-
name: "cline",
|
|
45
|
-
displayName: "Cline",
|
|
46
|
-
skillsDir: ".cline/skills",
|
|
47
|
-
globalSkillsDir: join(home, ".cline/skills"),
|
|
48
|
-
detectInstalled: async () => {
|
|
49
|
-
return existsSync(join(home, ".cline"));
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
codex: {
|
|
53
|
-
name: "codex",
|
|
54
|
-
displayName: "Codex",
|
|
55
|
-
skillsDir: ".codex/skills",
|
|
56
|
-
globalSkillsDir: join(home, ".codex/skills"),
|
|
57
|
-
detectInstalled: async () => {
|
|
58
|
-
return existsSync(join(home, ".codex"));
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
"command-code": {
|
|
62
|
-
name: "command-code",
|
|
63
|
-
displayName: "Command Code",
|
|
64
|
-
skillsDir: ".commandcode/skills",
|
|
65
|
-
globalSkillsDir: join(home, ".commandcode/skills"),
|
|
66
|
-
detectInstalled: async () => {
|
|
67
|
-
return existsSync(join(home, ".commandcode"));
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
cursor: {
|
|
71
|
-
name: "cursor",
|
|
72
|
-
displayName: "Cursor",
|
|
73
|
-
skillsDir: ".cursor/skills",
|
|
74
|
-
globalSkillsDir: join(home, ".cursor/skills"),
|
|
75
|
-
detectInstalled: async () => {
|
|
76
|
-
return existsSync(join(home, ".cursor"));
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
droid: {
|
|
80
|
-
name: "droid",
|
|
81
|
-
displayName: "Droid",
|
|
82
|
-
skillsDir: ".factory/skills",
|
|
83
|
-
globalSkillsDir: join(home, ".factory/skills"),
|
|
84
|
-
detectInstalled: async () => {
|
|
85
|
-
return existsSync(join(home, ".factory/skills"));
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
"gemini-cli": {
|
|
89
|
-
name: "gemini-cli",
|
|
90
|
-
displayName: "Gemini CLI",
|
|
91
|
-
skillsDir: ".gemini/skills",
|
|
92
|
-
globalSkillsDir: join(home, ".gemini/skills"),
|
|
93
|
-
detectInstalled: async () => {
|
|
94
|
-
return existsSync(join(home, ".gemini"));
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
"github-copilot": {
|
|
98
|
-
name: "github-copilot",
|
|
99
|
-
displayName: "GitHub Copilot",
|
|
100
|
-
skillsDir: ".github/skills",
|
|
101
|
-
globalSkillsDir: join(home, ".copilot/skills"),
|
|
102
|
-
detectInstalled: async () => {
|
|
103
|
-
return (existsSync(join(process.cwd(), ".github")) ||
|
|
104
|
-
existsSync(join(home, ".copilot")));
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
goose: {
|
|
108
|
-
name: "goose",
|
|
109
|
-
displayName: "Goose",
|
|
110
|
-
skillsDir: ".goose/skills",
|
|
111
|
-
globalSkillsDir: join(home, ".config/goose/skills"),
|
|
112
|
-
detectInstalled: async () => {
|
|
113
|
-
return existsSync(join(home, ".config/goose"));
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
kilo: {
|
|
117
|
-
name: "kilo",
|
|
118
|
-
displayName: "Kilo Code",
|
|
119
|
-
skillsDir: ".kilocode/skills",
|
|
120
|
-
globalSkillsDir: join(home, ".kilocode/skills"),
|
|
121
|
-
detectInstalled: async () => {
|
|
122
|
-
return existsSync(join(home, ".kilocode"));
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
"kiro-cli": {
|
|
126
|
-
name: "kiro-cli",
|
|
127
|
-
displayName: "Kiro CLI",
|
|
128
|
-
skillsDir: ".kiro/skills",
|
|
129
|
-
globalSkillsDir: join(home, ".kiro/skills"),
|
|
130
|
-
detectInstalled: async () => {
|
|
131
|
-
return existsSync(join(home, ".kiro"));
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
mcpjam: {
|
|
135
|
-
name: "mcpjam",
|
|
136
|
-
displayName: "MCPJam",
|
|
137
|
-
skillsDir: ".mcpjam/skills",
|
|
138
|
-
globalSkillsDir: join(home, ".mcpjam/skills"),
|
|
139
|
-
detectInstalled: async () => {
|
|
140
|
-
return existsSync(join(home, ".mcpjam"));
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
opencode: {
|
|
144
|
-
name: "opencode",
|
|
145
|
-
displayName: "OpenCode",
|
|
146
|
-
skillsDir: ".opencode/skills",
|
|
147
|
-
globalSkillsDir: join(home, ".config/opencode/skills"),
|
|
148
|
-
detectInstalled: async () => {
|
|
149
|
-
return (existsSync(join(home, ".config/opencode")) ||
|
|
150
|
-
existsSync(join(home, ".claude/skills")));
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
openhands: {
|
|
154
|
-
name: "openhands",
|
|
155
|
-
displayName: "OpenHands",
|
|
156
|
-
skillsDir: ".openhands/skills",
|
|
157
|
-
globalSkillsDir: join(home, ".openhands/skills"),
|
|
158
|
-
detectInstalled: async () => {
|
|
159
|
-
return existsSync(join(home, ".openhands"));
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
pi: {
|
|
163
|
-
name: "pi",
|
|
164
|
-
displayName: "Pi",
|
|
165
|
-
skillsDir: ".pi/skills",
|
|
166
|
-
globalSkillsDir: join(home, ".pi/agent/skills"),
|
|
167
|
-
detectInstalled: async () => {
|
|
168
|
-
return existsSync(join(home, ".pi/agent"));
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
qoder: {
|
|
172
|
-
name: "qoder",
|
|
173
|
-
displayName: "Qoder",
|
|
174
|
-
skillsDir: ".qoder/skills",
|
|
175
|
-
globalSkillsDir: join(home, ".qoder/skills"),
|
|
176
|
-
detectInstalled: async () => {
|
|
177
|
-
return existsSync(join(home, ".qoder"));
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
"qwen-code": {
|
|
181
|
-
name: "qwen-code",
|
|
182
|
-
displayName: "Qwen Code",
|
|
183
|
-
skillsDir: ".qwen/skills",
|
|
184
|
-
globalSkillsDir: join(home, ".qwen/skills"),
|
|
185
|
-
detectInstalled: async () => {
|
|
186
|
-
return existsSync(join(home, ".qwen"));
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
roo: {
|
|
190
|
-
name: "roo",
|
|
191
|
-
displayName: "Roo Code",
|
|
192
|
-
skillsDir: ".roo/skills",
|
|
193
|
-
globalSkillsDir: join(home, ".roo/skills"),
|
|
194
|
-
detectInstalled: async () => {
|
|
195
|
-
return existsSync(join(home, ".roo"));
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
trae: {
|
|
199
|
-
name: "trae",
|
|
200
|
-
displayName: "Trae",
|
|
201
|
-
skillsDir: ".trae/skills",
|
|
202
|
-
globalSkillsDir: join(home, ".trae/skills"),
|
|
203
|
-
detectInstalled: async () => {
|
|
204
|
-
return existsSync(join(home, ".trae"));
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
windsurf: {
|
|
208
|
-
name: "windsurf",
|
|
209
|
-
displayName: "Windsurf",
|
|
210
|
-
skillsDir: ".windsurf/skills",
|
|
211
|
-
globalSkillsDir: join(home, ".codeium/windsurf/skills"),
|
|
212
|
-
detectInstalled: async () => {
|
|
213
|
-
return existsSync(join(home, ".codeium/windsurf"));
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
zencoder: {
|
|
217
|
-
name: "zencoder",
|
|
218
|
-
displayName: "Zencoder",
|
|
219
|
-
skillsDir: ".zencoder/skills",
|
|
220
|
-
globalSkillsDir: join(home, ".zencoder/skills"),
|
|
221
|
-
detectInstalled: async () => {
|
|
222
|
-
return existsSync(join(home, ".zencoder"));
|
|
223
|
-
},
|
|
224
|
-
},
|
|
225
|
-
neovate: {
|
|
226
|
-
name: "neovate",
|
|
227
|
-
displayName: "Neovate",
|
|
228
|
-
skillsDir: ".neovate/skills",
|
|
229
|
-
globalSkillsDir: join(home, ".neovate/skills"),
|
|
230
|
-
detectInstalled: async () => {
|
|
231
|
-
return existsSync(join(home, ".neovate"));
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
};
|
|
235
|
-
export async function detectInstalledAgents() {
|
|
236
|
-
const installed = [];
|
|
237
|
-
for (const [type, config] of Object.entries(agents)) {
|
|
238
|
-
if (await config.detectInstalled()) {
|
|
239
|
-
installed.push(type);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return installed;
|
|
243
|
-
}
|
|
244
|
-
export function getAgentConfig(type) {
|
|
245
|
-
return agents[type];
|
|
246
|
-
}
|
package/dist/api.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
export async function fetchSkills(baseUrl, auth) {
|
|
2
|
-
const headers = {
|
|
3
|
-
"Content-Type": "application/json",
|
|
4
|
-
};
|
|
5
|
-
if (auth) {
|
|
6
|
-
headers["Authorization"] = `${auth.userAccessKey}:${auth.userOTT}`;
|
|
7
|
-
}
|
|
8
|
-
const response = await fetch(`${baseUrl}/skills`, {
|
|
9
|
-
headers,
|
|
10
|
-
});
|
|
11
|
-
if (!response.ok) {
|
|
12
|
-
const errorText = await response.text();
|
|
13
|
-
// Check for authentication error
|
|
14
|
-
if (response.status === 401) {
|
|
15
|
-
const error = new Error("Unauthorized");
|
|
16
|
-
error.status = 401;
|
|
17
|
-
throw error;
|
|
18
|
-
}
|
|
19
|
-
throw new Error(`Failed to fetch skills: ${response.status} ${response.statusText}\n${errorText}`);
|
|
20
|
-
}
|
|
21
|
-
const data = await response.json();
|
|
22
|
-
return data.data;
|
|
23
|
-
}
|
|
24
|
-
export async function fetchSkillContent(baseUrl, skillSlug, auth) {
|
|
25
|
-
const headers = {
|
|
26
|
-
"Content-Type": "application/json",
|
|
27
|
-
};
|
|
28
|
-
if (auth) {
|
|
29
|
-
headers["Authorization"] = `${auth.userAccessKey}:${auth.userOTT}`;
|
|
30
|
-
}
|
|
31
|
-
const response = await fetch(`${baseUrl}/skills/${skillSlug}/content`, {
|
|
32
|
-
headers,
|
|
33
|
-
});
|
|
34
|
-
if (!response.ok) {
|
|
35
|
-
const errorText = await response.text();
|
|
36
|
-
if (response.status === 401) {
|
|
37
|
-
const error = new Error("Unauthorized");
|
|
38
|
-
error.status = 401;
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
41
|
-
throw new Error(`Failed to fetch skill content: ${response.status} ${response.statusText}\n${errorText}`);
|
|
42
|
-
}
|
|
43
|
-
const data = await response.json();
|
|
44
|
-
return data.content;
|
|
45
|
-
}
|
package/dist/auth.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { homedir } from "os";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
4
|
-
import { existsSync } from "fs";
|
|
5
|
-
import crypto from "crypto";
|
|
6
|
-
import open from "open";
|
|
7
|
-
const CONFIG_DIR = join(homedir(), ".mcp-s");
|
|
8
|
-
const CONFIG_FILE = join(CONFIG_DIR, "skills-config.json");
|
|
9
|
-
export const generateToken = () => crypto.randomBytes(32).toString("hex");
|
|
10
|
-
export async function loadAuthConfig() {
|
|
11
|
-
try {
|
|
12
|
-
if (!existsSync(CONFIG_FILE)) {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
const content = await readFile(CONFIG_FILE, "utf-8");
|
|
16
|
-
return JSON.parse(content);
|
|
17
|
-
}
|
|
18
|
-
catch (_a) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
export async function saveAuthConfig(config) {
|
|
23
|
-
if (!existsSync(CONFIG_DIR)) {
|
|
24
|
-
await mkdir(CONFIG_DIR, { recursive: true });
|
|
25
|
-
}
|
|
26
|
-
await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
|
|
27
|
-
}
|
|
28
|
-
export async function generateAuthUrl({ baseUrl, userAccessKey, userOTT, }) {
|
|
29
|
-
const response = await fetch(`${baseUrl}/generate-auth-url`, {
|
|
30
|
-
method: "POST",
|
|
31
|
-
headers: {
|
|
32
|
-
Authorization: `${userAccessKey}:${userOTT}`,
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
if (!response.ok) {
|
|
36
|
-
throw new Error(`Failed to generate auth URL: ${response.status}`);
|
|
37
|
-
}
|
|
38
|
-
const { data: { url }, } = await response.json();
|
|
39
|
-
return url;
|
|
40
|
-
}
|
|
41
|
-
export async function authenticate({ baseUrl, userAccessKey, userOTT, openBrowser = true, }) {
|
|
42
|
-
const url = await generateAuthUrl({ baseUrl, userAccessKey, userOTT });
|
|
43
|
-
let opened = false;
|
|
44
|
-
if (openBrowser) {
|
|
45
|
-
try {
|
|
46
|
-
await open(url);
|
|
47
|
-
opened = true;
|
|
48
|
-
}
|
|
49
|
-
catch (_a) {
|
|
50
|
-
// Browser opening failed, user will need to use the URL manually
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return { url, opened };
|
|
54
|
-
}
|
|
55
|
-
export async function getOrCreateAuth(org) {
|
|
56
|
-
const existing = await loadAuthConfig();
|
|
57
|
-
if (existing && existing.userAccessKey && existing.userOTT) {
|
|
58
|
-
// If org changed, generate new OTT
|
|
59
|
-
if (org && existing.org !== org) {
|
|
60
|
-
const newOTT = generateToken();
|
|
61
|
-
await saveAuthConfig(Object.assign(Object.assign({}, existing), { userOTT: newOTT, org }));
|
|
62
|
-
return {
|
|
63
|
-
userAccessKey: existing.userAccessKey,
|
|
64
|
-
userOTT: newOTT,
|
|
65
|
-
isNew: true,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
userAccessKey: existing.userAccessKey,
|
|
70
|
-
userOTT: existing.userOTT,
|
|
71
|
-
isNew: false,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
// Create new auth
|
|
75
|
-
const userAccessKey = generateToken();
|
|
76
|
-
const userOTT = generateToken();
|
|
77
|
-
await saveAuthConfig({
|
|
78
|
-
userAccessKey,
|
|
79
|
-
userOTT,
|
|
80
|
-
org,
|
|
81
|
-
});
|
|
82
|
-
return {
|
|
83
|
-
userAccessKey,
|
|
84
|
-
userOTT,
|
|
85
|
-
isNew: true,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
export async function refreshToken(org) {
|
|
89
|
-
const existing = await loadAuthConfig();
|
|
90
|
-
const userAccessKey = (existing === null || existing === void 0 ? void 0 : existing.userAccessKey) || generateToken();
|
|
91
|
-
const userOTT = generateToken();
|
|
92
|
-
await saveAuthConfig({
|
|
93
|
-
userAccessKey,
|
|
94
|
-
userOTT,
|
|
95
|
-
org,
|
|
96
|
-
});
|
|
97
|
-
return { userAccessKey, userOTT };
|
|
98
|
-
}
|