@chakresh/kresh 0.1.3 → 0.1.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/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@chakresh/kresh",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "bin": {
5
5
  "kresh": "./src/index.js"
6
6
  },
7
7
  "type": "module",
8
8
  "dependencies": {
9
- "@chakresh/kresh": "^0.1.2",
10
9
  "axios": "^1.6.8",
11
10
  "chalk": "^5.3.0",
12
11
  "commander": "^11.1.0",
@@ -8,7 +8,9 @@ import { logger } from '../utils/logger.js';
8
8
  /**
9
9
  * Installs a skill from the registry locally.
10
10
  */
11
- export async function installSkill(skillSlug) {
11
+ import { cliAuthFlow, getToken } from '../services/auth.js';
12
+
13
+ export async function installSkill(skillSlug, isRetry = false) {
12
14
  const spinner = ora(`Fetching skill "${skillSlug}"...`).start();
13
15
  try {
14
16
  const response = await api.get(`/api/skills/${skillSlug}`);
@@ -20,15 +22,32 @@ export async function installSkill(skillSlug) {
20
22
  spinner.succeed(`Successfully installed ${logger.bold(metadata.name)} (v${metadata.currentVersion}) by @${metadata.ownerUsername}`);
21
23
  logger.info(`Saved to: ${logger.bold(savedDir)}`);
22
24
  } catch (error) {
23
- spinner.fail(`Installation failed for "${skillSlug}"`);
24
- if (error.response) {
25
- if (error.response.status === 404) {
26
- logger.error(`Skill "${skillSlug}" was not found in the registry.`);
25
+ spinner.stop();
26
+ if (error.response && error.response.status === 404 && !isRetry) {
27
+ // It might be a private skill, let's try authenticating
28
+ logger.info(`Skill "${skillSlug}" not found publicly. This might be a private skill.`);
29
+
30
+ const hasToken = getToken();
31
+ if (!hasToken) {
32
+ logger.info('Attempting to authenticate via browser to access private skills...');
33
+ try {
34
+ await cliAuthFlow();
35
+ // Retry the installation now that we have a token
36
+ logger.info('Authentication successful. Retrying download...');
37
+ return await installSkill(skillSlug, true);
38
+ } catch (authErr) {
39
+ logger.error('Authentication failed: ' + authErr.message);
40
+ }
27
41
  } else {
28
- logger.error(`Registry error: ${error.response.data?.error || error.response.statusText}`);
42
+ logger.error(`Skill "${skillSlug}" was not found in the registry, even with your authenticated session.`);
29
43
  }
30
44
  } else {
31
- logger.error(`Connection error: ${error.message}`);
45
+ spinner.fail(`Installation failed for "${skillSlug}"`);
46
+ if (error.response) {
47
+ logger.error(`Registry error: ${error.response.data?.error || error.response.statusText}`);
48
+ } else {
49
+ logger.error(`Connection error: ${error.message}`);
50
+ }
32
51
  }
33
52
  }
34
53
  }
@@ -1,6 +1,7 @@
1
1
  import axios from 'axios';
2
+ import { getToken } from './auth.js';
2
3
 
3
- const baseURL = process.env.KRESH_API_URL || 'https://kresh.vercel.app';
4
+ const baseURL = process.env.KRESH_API_URL || 'http://localhost:3000'; // Assume localhost for local testing
4
5
 
5
6
  export const api = axios.create({
6
7
  baseURL,
@@ -10,3 +11,12 @@ export const api = axios.create({
10
11
  'Content-Type': 'application/json'
11
12
  }
12
13
  });
14
+
15
+ api.interceptors.request.use((config) => {
16
+ const token = getToken();
17
+ if (token) {
18
+ config.headers.Authorization = `Bearer ${token}`;
19
+ }
20
+ return config;
21
+ });
22
+
@@ -0,0 +1,96 @@
1
+ import http from 'http';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { exec } from 'child_process';
6
+ import { logger } from '../utils/logger.js';
7
+ import ora from 'ora';
8
+
9
+ const KRESH_DIR = path.join(os.homedir(), '.kresh');
10
+ const CONFIG_FILE = path.join(KRESH_DIR, 'config.json');
11
+
12
+ export function getToken() {
13
+ try {
14
+ if (fs.existsSync(CONFIG_FILE)) {
15
+ const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
16
+ return config.token || null;
17
+ }
18
+ } catch (err) {
19
+ // ignore
20
+ }
21
+ return null;
22
+ }
23
+
24
+ export function setToken(token) {
25
+ try {
26
+ if (!fs.existsSync(KRESH_DIR)) {
27
+ fs.mkdirSync(KRESH_DIR, { recursive: true });
28
+ }
29
+ const config = fs.existsSync(CONFIG_FILE) ? JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8')) : {};
30
+ config.token = token;
31
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
32
+ } catch (err) {
33
+ logger.error('Failed to save config: ' + err.message);
34
+ }
35
+ }
36
+
37
+ function openBrowser(url) {
38
+ const startCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
39
+ exec(`${startCmd} "${url}"`, (err) => {
40
+ if (err) {
41
+ logger.warn(`Could not open browser automatically. Please visit: ${url}`);
42
+ }
43
+ });
44
+ }
45
+
46
+ export async function cliAuthFlow() {
47
+ return new Promise((resolve, reject) => {
48
+ const server = http.createServer((req, res) => {
49
+ const url = new URL(req.url, `http://${req.headers.host}`);
50
+ if (url.pathname === '/callback') {
51
+ const token = url.searchParams.get('token');
52
+ if (token) {
53
+ res.writeHead(200, { 'Content-Type': 'text/html' });
54
+ res.end(`
55
+ <html>
56
+ <head><title>Kresh CLI Authenticated</title></head>
57
+ <body style="font-family: monospace; padding: 2rem; text-align: center; background: #000; color: #fff;">
58
+ <h2 style="color: #4ade80;">Success!</h2>
59
+ <p>The Kresh CLI has been authenticated. You can close this window and return to your terminal.</p>
60
+ </body>
61
+ </html>
62
+ `);
63
+
64
+ setToken(token);
65
+
66
+ setTimeout(() => {
67
+ server.close();
68
+ resolve(token);
69
+ }, 500);
70
+ } else {
71
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
72
+ res.end('Missing token in callback.');
73
+ server.close();
74
+ reject(new Error('Missing token'));
75
+ }
76
+ } else {
77
+ res.writeHead(404);
78
+ res.end();
79
+ }
80
+ });
81
+
82
+ server.listen(0, '127.0.0.1', () => {
83
+ const port = server.address().port;
84
+ const baseUrl = process.env.KRESH_API_URL || 'https://kresh.vercel.app';
85
+ const authUrl = `${baseUrl}/cli/auth?port=${port}`;
86
+
87
+ const spinner = ora('Opening browser for authentication...').start();
88
+ openBrowser(authUrl);
89
+ spinner.succeed(`Waiting for authentication... (if browser doesn't open, visit ${authUrl})`);
90
+ });
91
+
92
+ server.on('error', (err) => {
93
+ reject(err);
94
+ });
95
+ });
96
+ }