@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.
Files changed (2) hide show
  1. package/dist/index.mjs +87 -141
  2. 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 = axios.create({
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(teamId, id, prompt) {
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(teamId, args.id, args.prompt)).prompt
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
- const credentials = await getCredentials();
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 as ${credentials.email}`
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.25";
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.25",
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; npx jive",
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",