@chakresh/kresh 0.1.4 → 0.1.7

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@chakresh/kresh",
3
- "version": "0.1.4",
3
+ "version": "0.1.7",
4
4
  "bin": {
5
5
  "kresh": "./src/index.js"
6
6
  },
@@ -1,22 +1,66 @@
1
1
  import ora from 'ora';
2
2
  import os from 'os';
3
3
  import path from 'path';
4
+ import fs from 'fs/promises';
5
+ import inquirer from 'inquirer';
4
6
  import { api } from '../services/api.js';
5
- import { writeLocalSkill } from '../services/filesystem.js';
7
+ import { writeLocalSkill, getWorkspaceRoot } from '../services/filesystem.js';
6
8
  import { logger } from '../utils/logger.js';
9
+ import { cliAuthFlow, getToken } from '../services/auth.js';
7
10
 
8
11
  /**
9
12
  * Installs a skill from the registry locally.
10
13
  */
11
- import { cliAuthFlow, getToken } from '../services/auth.js';
12
-
13
14
  export async function installSkill(skillSlug, isRetry = false) {
14
15
  const spinner = ora(`Fetching skill "${skillSlug}"...`).start();
15
16
  try {
16
17
  const response = await api.get(`/api/skills/${skillSlug}`);
17
18
  const { skillContent, ...metadata } = response.data;
19
+ spinner.stop();
20
+
21
+ if (metadata.category === 'Agents') {
22
+ const { fileName } = await inquirer.prompt([
23
+ {
24
+ type: 'list',
25
+ name: 'fileName',
26
+ message: 'This is an Agent. Where would you like to save it?',
27
+ choices: ['AGENT.md', 'CLAUDE.md', 'Standard skills folder']
28
+ }
29
+ ]);
30
+
31
+ if (fileName !== 'Standard skills folder') {
32
+ const rootDir = await getWorkspaceRoot();
33
+ const targetPath = path.join(rootDir, fileName);
34
+
35
+ let shouldWrite = true;
36
+ try {
37
+ await fs.access(targetPath);
38
+ const { overwrite } = await inquirer.prompt([
39
+ {
40
+ type: 'confirm',
41
+ name: 'overwrite',
42
+ message: `${fileName} already exists. Do you want to replace it?`,
43
+ default: false
44
+ }
45
+ ]);
46
+ shouldWrite = overwrite;
47
+ } catch (e) {
48
+ // File doesn't exist, proceed
49
+ }
50
+
51
+ if (shouldWrite) {
52
+ spinner.start(`Writing ${fileName} to root directory...`);
53
+ await fs.writeFile(targetPath, skillContent, 'utf8');
54
+ spinner.succeed(`Successfully installed ${logger.bold(metadata.name)} (v${metadata.currentVersion}) by @${metadata.ownerUsername}`);
55
+ logger.info(`Saved to: ${logger.bold(targetPath)}`);
56
+ } else {
57
+ logger.info('Installation cancelled.');
58
+ }
59
+ return;
60
+ }
61
+ }
18
62
 
19
- spinner.text = 'Writing skill files locally...';
63
+ spinner.start('Writing skill files locally...');
20
64
  const savedDir = await writeLocalSkill(skillSlug, skillContent, metadata);
21
65
 
22
66
  spinner.succeed(`Successfully installed ${logger.bold(metadata.name)} (v${metadata.currentVersion}) by @${metadata.ownerUsername}`);
@@ -0,0 +1,24 @@
1
+ import { cliAuthFlow, clearToken, getToken } from '../services/auth.js';
2
+ import { logger } from '../utils/logger.js';
3
+
4
+ export async function loginCommand(options) {
5
+ if (options.flush) {
6
+ clearToken();
7
+ logger.info('Authentication token has been flushed. You are now logged out of the CLI.');
8
+ return;
9
+ }
10
+
11
+ const existingToken = getToken();
12
+ if (existingToken) {
13
+ logger.info('You are already authenticated. To log in as someone else, run: kresh login --flush');
14
+ return;
15
+ }
16
+
17
+ try {
18
+ logger.info('Starting browser authentication...');
19
+ await cliAuthFlow();
20
+ // cliAuthFlow already prints success and saves the token
21
+ } catch (error) {
22
+ logger.error('Authentication failed: ' + error.message);
23
+ }
24
+ }
package/src/index.js CHANGED
@@ -6,6 +6,7 @@ import { searchSkills } from './commands/search.js';
6
6
  import { listInstalledSkills } from './commands/ls.js';
7
7
  import { removeSkill } from './commands/remove.js';
8
8
  import { publishSkill } from './commands/publish.js';
9
+ import { loginCommand } from './commands/login.js';
9
10
 
10
11
  const program = new Command();
11
12
 
@@ -53,4 +54,11 @@ program
53
54
  await publishSkill();
54
55
  });
55
56
 
57
+ program
58
+ .command('login [action]')
59
+ .description('Authenticate with the Kresh registry. Use "kresh login flush" to clear your session.')
60
+ .action(async (action) => {
61
+ await loginCommand({ flush: action === 'flush' });
62
+ });
63
+
56
64
  program.parse();
@@ -34,6 +34,18 @@ export function setToken(token) {
34
34
  }
35
35
  }
36
36
 
37
+ export function clearToken() {
38
+ try {
39
+ if (fs.existsSync(CONFIG_FILE)) {
40
+ const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
41
+ delete config.token;
42
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
43
+ }
44
+ } catch (err) {
45
+ logger.error('Failed to clear config: ' + err.message);
46
+ }
47
+ }
48
+
37
49
  function openBrowser(url) {
38
50
  const startCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
39
51
  exec(`${startCmd} "${url}"`, (err) => {
@@ -4,7 +4,7 @@ import path from 'path';
4
4
  /**
5
5
  * Helper to find the workspace or project root directory by scanning up.
6
6
  */
7
- async function getWorkspaceRoot(startDir = process.cwd()) {
7
+ export async function getWorkspaceRoot(startDir = process.cwd()) {
8
8
  let currentDir = startDir;
9
9
  while (true) {
10
10
  try {