@jive-ai/cli 0.0.25 → 0.0.26
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/index.mjs +87 -141
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -3,10 +3,12 @@ import { Command } from "commander";
|
|
|
3
3
|
import prompts from "prompts";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import ora from "ora";
|
|
6
|
-
import axios from "axios";
|
|
7
6
|
import fs from "fs/promises";
|
|
8
7
|
import path from "path";
|
|
9
8
|
import os from "os";
|
|
9
|
+
import { exec } from "child_process";
|
|
10
|
+
import { promisify } from "util";
|
|
11
|
+
import AxiosClient from "axios";
|
|
10
12
|
import "crypto";
|
|
11
13
|
import matter from "gray-matter";
|
|
12
14
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -114,6 +116,84 @@ async function isProjectInitialized() {
|
|
|
114
116
|
//#region src/constants.ts
|
|
115
117
|
const API_URL = process.env.JIVE_API_URL || "https://next.getjive.app";
|
|
116
118
|
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/commands/auth.ts
|
|
121
|
+
const execAsync = promisify(exec);
|
|
122
|
+
async function openBrowser(url) {
|
|
123
|
+
const commands = {
|
|
124
|
+
darwin: "open",
|
|
125
|
+
win32: "start",
|
|
126
|
+
linux: "xdg-open"
|
|
127
|
+
};
|
|
128
|
+
const platform = process.platform;
|
|
129
|
+
const command = commands[platform];
|
|
130
|
+
if (!command) {
|
|
131
|
+
console.log(chalk.yellow(`\n⚠️ Unable to open browser automatically on ${platform}`));
|
|
132
|
+
console.log(chalk.white(`Please open this URL manually: ${chalk.cyan(url)}\n`));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
await execAsync(`${command} "${url}"`);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.log(chalk.yellow("\n⚠️ Failed to open browser automatically"));
|
|
139
|
+
console.log(chalk.white(`Please open this URL manually: ${chalk.cyan(url)}\n`));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async function loginCommand() {
|
|
143
|
+
console.log(chalk.bold("\n👋 Login to Jive\n"));
|
|
144
|
+
console.log(chalk.white("Opening browser for authentication...\n"));
|
|
145
|
+
await openBrowser(`${API_URL}/cli-auth`);
|
|
146
|
+
console.log(chalk.gray("If the browser did not open, visit:"));
|
|
147
|
+
console.log(chalk.cyan(`${API_URL}/cli-auth\n`));
|
|
148
|
+
const response = await prompts({
|
|
149
|
+
type: "password",
|
|
150
|
+
name: "apiKey",
|
|
151
|
+
message: "Paste your API key from the browser:",
|
|
152
|
+
validate: (value) => {
|
|
153
|
+
if (!value) return "API key is required";
|
|
154
|
+
if (!value.startsWith("jive_")) return "Invalid API key format (must start with \"jive_\")";
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
if (!response.apiKey) {
|
|
159
|
+
console.log(chalk.yellow("\n❌ Login cancelled"));
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const spinner = ora("Validating API key...").start();
|
|
163
|
+
try {
|
|
164
|
+
await AxiosClient.get(`${API_URL}/api/teams`, { headers: { "X-API-Key": response.apiKey } });
|
|
165
|
+
spinner.succeed(chalk.green("Logged in successfully!"));
|
|
166
|
+
await saveCredentials({ token: response.apiKey });
|
|
167
|
+
console.log(chalk.green("\n✓ API key configured\n"));
|
|
168
|
+
console.log(chalk.white("Next steps:"));
|
|
169
|
+
console.log(chalk.white(" • Run"), chalk.cyan("jive team create"), chalk.white("to create a team"));
|
|
170
|
+
console.log(chalk.white(" • Run"), chalk.cyan("jive init"), chalk.white("to initialize your project with an existing team\n"));
|
|
171
|
+
} catch (error) {
|
|
172
|
+
spinner.fail(chalk.red("Login failed"));
|
|
173
|
+
if (error.response?.status === 401) console.error(chalk.red("\n❌ Invalid API key. Please try again.\n"));
|
|
174
|
+
else console.error(chalk.red(`\n❌ ${error.message || "Unable to validate API key"}`));
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async function logoutCommand() {
|
|
179
|
+
if (!await getCredentials()) {
|
|
180
|
+
console.log(chalk.yellow("\n⚠️ You are not logged in"));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (!(await prompts({
|
|
184
|
+
type: "confirm",
|
|
185
|
+
name: "confirm",
|
|
186
|
+
message: `Are you sure you want to logout?`,
|
|
187
|
+
initial: true
|
|
188
|
+
})).confirm) {
|
|
189
|
+
console.log(chalk.yellow("\n❌ Logout cancelled"));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
await clearCredentials();
|
|
193
|
+
console.log(chalk.green("\n✅ Logged out successfully"));
|
|
194
|
+
console.log(chalk.gray(`Run ${chalk.cyan("jive login")} to login again\n`));
|
|
195
|
+
}
|
|
196
|
+
|
|
117
197
|
//#endregion
|
|
118
198
|
//#region src/lib/api-client.ts
|
|
119
199
|
var ApiClient = class {
|
|
@@ -121,7 +201,7 @@ var ApiClient = class {
|
|
|
121
201
|
baseURL;
|
|
122
202
|
constructor(baseURL = API_URL) {
|
|
123
203
|
this.baseURL = baseURL;
|
|
124
|
-
this.client =
|
|
204
|
+
this.client = AxiosClient.create({
|
|
125
205
|
baseURL: this.baseURL,
|
|
126
206
|
timeout: 3e4,
|
|
127
207
|
headers: { "Content-Type": "application/json" }
|
|
@@ -148,21 +228,6 @@ var ApiClient = class {
|
|
|
148
228
|
else if (error.request) return { message: `Unable to connect to ${this.baseURL}. Please check your internet connection.` };
|
|
149
229
|
else return { message: error.message };
|
|
150
230
|
}
|
|
151
|
-
async signup(email, password) {
|
|
152
|
-
return (await this.client.post("/api/auth/signup", {
|
|
153
|
-
email,
|
|
154
|
-
password
|
|
155
|
-
})).data;
|
|
156
|
-
}
|
|
157
|
-
async login(email, password) {
|
|
158
|
-
return (await this.client.post("/api/auth/login", {
|
|
159
|
-
email,
|
|
160
|
-
password
|
|
161
|
-
})).data;
|
|
162
|
-
}
|
|
163
|
-
async logout() {
|
|
164
|
-
await this.client.post("/api/auth/logout");
|
|
165
|
-
}
|
|
166
231
|
async getTeams() {
|
|
167
232
|
return (await this.client.get("/api/teams")).data;
|
|
168
233
|
}
|
|
@@ -190,7 +255,7 @@ var ApiClient = class {
|
|
|
190
255
|
async getMcpServers(teamId) {
|
|
191
256
|
return (await this.client.get(`/api/teams/${teamId}/mcp-servers`)).data;
|
|
192
257
|
}
|
|
193
|
-
async callSubagent(
|
|
258
|
+
async callSubagent(id, prompt) {
|
|
194
259
|
return (await this.client.post(`/api/subagents/${id}/call`, { prompt })).data;
|
|
195
260
|
}
|
|
196
261
|
async createMcpServer(teamId, data) {
|
|
@@ -209,65 +274,6 @@ function getApiClient() {
|
|
|
209
274
|
return apiClient;
|
|
210
275
|
}
|
|
211
276
|
|
|
212
|
-
//#endregion
|
|
213
|
-
//#region src/commands/auth.ts
|
|
214
|
-
async function loginCommand() {
|
|
215
|
-
console.log(chalk.bold("\n👋 Login to Jive\n"));
|
|
216
|
-
const response = await prompts([{
|
|
217
|
-
type: "text",
|
|
218
|
-
name: "email",
|
|
219
|
-
message: "Email address:",
|
|
220
|
-
validate: (value) => value ? true : "Email is required"
|
|
221
|
-
}, {
|
|
222
|
-
type: "password",
|
|
223
|
-
name: "password",
|
|
224
|
-
message: "Password:",
|
|
225
|
-
validate: (value) => value ? true : "Password is required"
|
|
226
|
-
}]);
|
|
227
|
-
if (!response.email || !response.password) {
|
|
228
|
-
console.log(chalk.yellow("\n❌ Login cancelled"));
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
const spinner = ora("Logging in...").start();
|
|
232
|
-
try {
|
|
233
|
-
const result = await getApiClient().login(response.email, response.password);
|
|
234
|
-
spinner.succeed(chalk.green("Logged in successfully!"));
|
|
235
|
-
console.log(chalk.cyan(`\n📧 ${result.email}`));
|
|
236
|
-
console.log(chalk.green("✓ API key configured\n"));
|
|
237
|
-
await saveCredentials({
|
|
238
|
-
token: result.token,
|
|
239
|
-
userId: result.userId,
|
|
240
|
-
email: result.email
|
|
241
|
-
});
|
|
242
|
-
console.log(chalk.white("Next steps:"));
|
|
243
|
-
console.log(chalk.white(" • Run"), chalk.cyan("jive team create"), chalk.white("to create a team"));
|
|
244
|
-
console.log(chalk.white(" • Run"), chalk.cyan("jive init"), chalk.white("to initialize your project with an existing team\n"));
|
|
245
|
-
} catch (error) {
|
|
246
|
-
spinner.fail(chalk.red("Login failed"));
|
|
247
|
-
console.error(chalk.red(`\n❌ ${error.message || "Invalid email or password"}`));
|
|
248
|
-
process.exit(1);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
async function logoutCommand() {
|
|
252
|
-
const credentials = await getCredentials();
|
|
253
|
-
if (!credentials) {
|
|
254
|
-
console.log(chalk.yellow("\n⚠️ You are not logged in"));
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
if (!(await prompts({
|
|
258
|
-
type: "confirm",
|
|
259
|
-
name: "confirm",
|
|
260
|
-
message: `Logout from ${credentials.email}?`,
|
|
261
|
-
initial: true
|
|
262
|
-
})).confirm) {
|
|
263
|
-
console.log(chalk.yellow("\n❌ Logout cancelled"));
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
await clearCredentials();
|
|
267
|
-
console.log(chalk.green("\n✅ Logged out successfully"));
|
|
268
|
-
console.log(chalk.gray(`Run ${chalk.cyan("jive login")} to login again\n`));
|
|
269
|
-
}
|
|
270
|
-
|
|
271
277
|
//#endregion
|
|
272
278
|
//#region src/commands/team.ts
|
|
273
279
|
const teamCommands = {
|
|
@@ -526,30 +532,6 @@ async function addToGitignore(pattern) {
|
|
|
526
532
|
const CLAUDE_PLUGINS_DIR = path.join(process.cwd(), ".claude", "plugins");
|
|
527
533
|
const JIVE_CONFIG_DIR = path.join(process.cwd(), ".jive");
|
|
528
534
|
const JIVE_CONFIG_PATH = path.join(JIVE_CONFIG_DIR, "config.json");
|
|
529
|
-
async function getPluginStatus() {
|
|
530
|
-
const pluginPath = path.join(CLAUDE_PLUGINS_DIR, "jive-mcp-telemetry");
|
|
531
|
-
const configPath = JIVE_CONFIG_PATH;
|
|
532
|
-
let installed = false;
|
|
533
|
-
let configured = false;
|
|
534
|
-
try {
|
|
535
|
-
await fs.access(pluginPath);
|
|
536
|
-
installed = true;
|
|
537
|
-
} catch {
|
|
538
|
-
installed = false;
|
|
539
|
-
}
|
|
540
|
-
try {
|
|
541
|
-
await fs.access(configPath);
|
|
542
|
-
configured = true;
|
|
543
|
-
} catch {
|
|
544
|
-
configured = false;
|
|
545
|
-
}
|
|
546
|
-
return {
|
|
547
|
-
installed,
|
|
548
|
-
configured,
|
|
549
|
-
pluginPath: installed ? pluginPath : void 0,
|
|
550
|
-
configPath: configured ? configPath : void 0
|
|
551
|
-
};
|
|
552
|
-
}
|
|
553
535
|
|
|
554
536
|
//#endregion
|
|
555
537
|
//#region src/commands/init.ts
|
|
@@ -1471,7 +1453,7 @@ async function startMcpServer() {
|
|
|
1471
1453
|
}
|
|
1472
1454
|
case "call_subagent": return { content: [{
|
|
1473
1455
|
type: "text",
|
|
1474
|
-
text: (await apiClient$1.callSubagent(
|
|
1456
|
+
text: (await apiClient$1.callSubagent(args.id, args.prompt)).prompt
|
|
1475
1457
|
}] };
|
|
1476
1458
|
case "list_mcp_servers": {
|
|
1477
1459
|
const results = mcpServers.filter((server$1) => connectionManager.serverIsActive(server$1.name)).map((server$1) => ({
|
|
@@ -1839,10 +1821,6 @@ async function doctorCommand() {
|
|
|
1839
1821
|
name: "Subagent Runner",
|
|
1840
1822
|
result: await checkSubagentRunner()
|
|
1841
1823
|
});
|
|
1842
|
-
results.push({
|
|
1843
|
-
name: "Plugin Config",
|
|
1844
|
-
result: await checkPluginConfig()
|
|
1845
|
-
});
|
|
1846
1824
|
results.push({
|
|
1847
1825
|
name: "API Connectivity",
|
|
1848
1826
|
result: await checkApiConnectivity()
|
|
@@ -1879,8 +1857,7 @@ async function doctorCommand() {
|
|
|
1879
1857
|
}
|
|
1880
1858
|
}
|
|
1881
1859
|
async function checkAuthentication() {
|
|
1882
|
-
|
|
1883
|
-
if (!credentials) return {
|
|
1860
|
+
if (!await getCredentials()) return {
|
|
1884
1861
|
status: "fail",
|
|
1885
1862
|
message: "Not authenticated",
|
|
1886
1863
|
fix: "Run \"jive login\" to authenticate"
|
|
@@ -1888,7 +1865,7 @@ async function checkAuthentication() {
|
|
|
1888
1865
|
return {
|
|
1889
1866
|
status: "pass",
|
|
1890
1867
|
message: "Authenticated",
|
|
1891
|
-
details: `Logged in
|
|
1868
|
+
details: `Logged in via API key`
|
|
1892
1869
|
};
|
|
1893
1870
|
}
|
|
1894
1871
|
async function checkProjectInit() {
|
|
@@ -1960,37 +1937,6 @@ async function checkSubagentRunner() {
|
|
|
1960
1937
|
};
|
|
1961
1938
|
}
|
|
1962
1939
|
}
|
|
1963
|
-
async function checkPluginConfig() {
|
|
1964
|
-
const pluginStatus = await getPluginStatus();
|
|
1965
|
-
if (!pluginStatus.configured) return {
|
|
1966
|
-
status: "warn",
|
|
1967
|
-
message: "Plugin not configured",
|
|
1968
|
-
details: "Missing .jive/config.json",
|
|
1969
|
-
fix: "Run \"jive init\" to create plugin configuration"
|
|
1970
|
-
};
|
|
1971
|
-
try {
|
|
1972
|
-
const configContent = await fs.readFile(pluginStatus.configPath, "utf-8");
|
|
1973
|
-
const config = JSON.parse(configContent);
|
|
1974
|
-
if (!config.apiUrl || !config.apiKey) return {
|
|
1975
|
-
status: "warn",
|
|
1976
|
-
message: "Plugin config incomplete",
|
|
1977
|
-
details: "Missing apiUrl or apiKey",
|
|
1978
|
-
fix: "Run \"jive init\" to recreate plugin configuration"
|
|
1979
|
-
};
|
|
1980
|
-
return {
|
|
1981
|
-
status: "pass",
|
|
1982
|
-
message: "Plugin configured",
|
|
1983
|
-
details: `API: ${config.apiUrl}`
|
|
1984
|
-
};
|
|
1985
|
-
} catch (error) {
|
|
1986
|
-
return {
|
|
1987
|
-
status: "warn",
|
|
1988
|
-
message: "Invalid plugin config",
|
|
1989
|
-
details: error.message,
|
|
1990
|
-
fix: "Run \"jive init\" to recreate plugin configuration"
|
|
1991
|
-
};
|
|
1992
|
-
}
|
|
1993
|
-
}
|
|
1994
1940
|
async function checkApiConnectivity() {
|
|
1995
1941
|
if (!await getCredentials()) return {
|
|
1996
1942
|
status: "fail",
|
|
@@ -2043,7 +1989,7 @@ async function checkTeamMembership() {
|
|
|
2043
1989
|
|
|
2044
1990
|
//#endregion
|
|
2045
1991
|
//#region package.json
|
|
2046
|
-
var version = "0.0.
|
|
1992
|
+
var version = "0.0.26";
|
|
2047
1993
|
|
|
2048
1994
|
//#endregion
|
|
2049
1995
|
//#region src/index.ts
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@jive-ai/cli",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.26",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"jive": "dist/index.mjs"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
-
"dev": "npm run build
|
|
14
|
+
"dev": "npm run build && JIVE_API_URL=http://localhost:5173 npx jive",
|
|
15
15
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
17
|
"build": "tsdown",
|