puter-cli 1.1.4 → 1.2.0

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.
@@ -0,0 +1,21 @@
1
+ # This workflow will run tests using node on every push
2
+
3
+ name: Build package
4
+
5
+ on: push
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+
11
+ strategy:
12
+ matrix:
13
+ node-version: ['18.x', '20.x', '23.x']
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: ${{ matrix.node-version }}
20
+ - run: npm ci
21
+ - run: npm test
@@ -1,11 +1,9 @@
1
1
  # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
2
  # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
3
 
4
- name: Node.js Package
4
+ name: Publish package
5
5
 
6
- on:
7
- release:
8
- types: [created]
6
+ on: push
9
7
 
10
8
  jobs:
11
9
  build:
@@ -18,19 +16,16 @@ jobs:
18
16
  - run: npm ci
19
17
  - run: npm test
20
18
 
21
- publish-gpr:
19
+ publish-npm:
22
20
  needs: build
23
21
  runs-on: ubuntu-latest
24
- permissions:
25
- contents: read
26
- packages: write
27
22
  steps:
28
23
  - uses: actions/checkout@v4
29
24
  - uses: actions/setup-node@v4
30
25
  with:
31
26
  node-version: 20
32
- registry-url: https://npm.pkg.github.com/
27
+ registry-url: https://registry.npmjs.org/
33
28
  - run: npm ci
34
29
  - run: npm publish
35
30
  env:
36
- NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
31
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Puter-CLI
2
2
 
3
3
  <p align="center">
4
- <img alt="test" src="https://github.com/bitsnaps/puter-cli/actions/workflows/npm-publish-github-packages.yml/badge.svg">
4
+ <img alt="test" src="https://github.com/bitsnaps/puter-cli/actions/workflows/npm-build.yml/badge.svg">
5
5
  <img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/bitsnaps/puter-cli">
6
6
  </p>
7
7
 
@@ -123,17 +123,17 @@ P.S. These commands consider the current directory as the base path for every op
123
123
  #### User Information
124
124
  - **Get User Info**: Display user information.
125
125
  ```bash
126
- puter whoami
126
+ puter> whoami
127
127
  ```
128
128
 
129
129
  #### Disk Usage
130
130
  - **Check Disk Usage**: Display disk usage information.
131
131
  ```bash
132
- puter df
132
+ puter> df
133
133
  ```
134
134
  - **Get Usage Info**: Fetch usage information for services.
135
135
  ```bash
136
- puter usage
136
+ puter> usage
137
137
  ```
138
138
 
139
139
  #### Application Management
@@ -142,25 +142,25 @@ The **Application** are sepcial type of hosted web app, they're served from the
142
142
 
143
143
  - **List Applications**: List all applications.
144
144
  ```bash
145
- puter apps [period]
145
+ puter> apps [period]
146
146
  ```
147
147
  P.S. Please check the help command `help apps` for more details about any argument.
148
148
 
149
149
  - **Create Application**: Create a new application.
150
150
  ```bash
151
- puter app:create <name> [<remote_dir>] [--url=<url>]
151
+ puter> app:create <name> [<directory>] [--description="My App Description"] [--url=<url>]
152
152
  ```
153
153
  P.S. By default a new `index.html` with basic content will be created, but you can set a directory when you create a new application as follows: `app:create nameOfApp ./appDir`, so all files will be copied to the `AppData` directoy, you can then update your app using `app:update <name> <remote_dir>`. This command will attempt to create a subdomain with a random `uid` prefixed with the name of the app.
154
154
 
155
155
  - **Update Application**: Update an application.
156
156
  ```bash
157
- puter app:update <name> <remote_dir>
157
+ puter> app:update <name> <remote_dir>
158
158
  ```
159
159
  **IMPORTANT** All existing files will be overwritten, new files are copied, other files are just ignored.
160
160
 
161
161
  - **Delete Application**: Delete an application.
162
162
  ```bash
163
- puter app:delete [-f] <name>
163
+ puter> app:delete [-f] <name>
164
164
  ```
165
165
  P.S. This command will lookup for the allocated `subdomain` and attempt to delete it if it exists.
166
166
 
@@ -170,20 +170,31 @@ The static sites are served from the selected directory (or the current director
170
170
 
171
171
  - **Deploy Site**: Deploy a static website from a directory.
172
172
  ```bash
173
- puter site:create <app_name> [<dir>] [--subdomain=<name>]
173
+ puter> site:create <app_name> [<dir>] [--subdomain=<name>]
174
174
  ```
175
175
  P.S. If the subdomain already exists, it will generate a new random one can set your own subdomain using `--subdomain` argument.
176
176
 
177
177
  - **List Sites**: List all hosted sites.
178
178
  ```bash
179
- puter sites
179
+ puter> sites
180
180
  ```
181
181
  - **Delete Site**: Delete a hosted site.
182
182
  ```bash
183
- puter site:delete <uid>
183
+ puter> site:delete <uid>
184
184
  ```
185
185
  P.S. You can find the `<uid>` in the list of `sites`.
186
186
 
187
+ #### Commands history
188
+
189
+ - **Display history**: Display the history executed commands
190
+ ```bash
191
+ puter> history
192
+ ```
193
+ - **Copy command from history**: Copy a previous command from history by line number
194
+ ```bash
195
+ puter> history <line_number>
196
+ ```
197
+
187
198
  #### Interactive Shell
188
199
  - **Start Shell**: Launch an interactive shell.
189
200
  ```bash
@@ -198,10 +209,14 @@ or just type (you'll need to login):
198
209
  - **General Help**: Display a list of available commands.
199
210
  ```bash
200
211
  puter help
212
+ # or inside the interactive shell:
213
+ puter> help
201
214
  ```
202
215
  - **Command Help**: Display detailed help for a specific command.
203
216
  ```bash
204
217
  puter help <command>
218
+ # or inside the interactive shell:
219
+ puter> help <command>
205
220
  ```
206
221
 
207
222
  ---
package/bin/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import { login, logout } from '../commands/auth.js';
4
- import { init } from '../commands/init.js';
5
- import { startShell } from '../commands/shell.js';
6
- import { PROJECT_NAME, getLatestVersion } from '../commands/commons.js';
3
+ import { login, logout } from '../src/commands/auth.js';
4
+ import { init } from '../src/commands/init.js';
5
+ import { startShell } from '../src/commands/shell.js';
6
+ import { PROJECT_NAME, getLatestVersion } from '../src/commons.js';
7
7
 
8
8
  async function main() {
9
9
  const { version } = await getLatestVersion(PROJECT_NAME);
@@ -34,10 +34,32 @@ async function main() {
34
34
  .description('Start interactive shell')
35
35
  .action(startShell);
36
36
 
37
+
38
+ // App commands
39
+ program
40
+ .command('app:create <name>')
41
+ .description('Create a new Puter application')
42
+ .argument('<name>', 'Name of the application')
43
+ .argument('[directory]', 'Local directory path')
44
+ .option('-d, --description <description>', 'Application description')
45
+ .option('-u, --url <url>', 'Application URL', 'https://dev-center.puter.com/coming-soon.html')
46
+ .action(async (name, directory, options) => {
47
+ try {
48
+ await createApp({
49
+ name,
50
+ directory: directory || '',
51
+ description: options.description || '',
52
+ url: options.url
53
+ });
54
+ } catch (error) {
55
+ console.error(chalk.red(error.message));
56
+ }
57
+ });
58
+
37
59
  if (process.argv.length === 2) {
38
60
  startShell();
39
61
  } else {
40
- program.parse();
62
+ program.parse(process.argv);
41
63
  }
42
64
  }
43
65
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "puter-cli",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "Command line interface for Puter cloud platform",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -26,7 +26,7 @@
26
26
  "dependencies": {
27
27
  "chalk": "^5.3.0",
28
28
  "cli-table3": "^0.6.5",
29
- "commander": "^11.1.0",
29
+ "commander": "^13.0.0",
30
30
  "conf": "^12.0.0",
31
31
  "cross-spawn": "^7.0.3",
32
32
  "glob": "^11.0.0",
@@ -34,7 +34,8 @@
34
34
  "minimatch": "^10.0.1",
35
35
  "node-fetch": "^3.3.2",
36
36
  "ora": "^8.0.1",
37
- "uuid": "^11.0.5"
37
+ "uuid": "^11.0.5",
38
+ "yargs-parser": "^21.1.1"
38
39
  },
39
40
  "devDependencies": {
40
41
  "vitest": "^2.1.8"
@@ -2,13 +2,13 @@ import path from 'path';
2
2
  import chalk from 'chalk';
3
3
  import fetch from 'node-fetch';
4
4
  import Table from 'cli-table3';
5
- import { displayNonNullValues, formatDate } from './utils.js';
6
- import { API_BASE, getHeaders, getDefaultHomePage, isValidAppName, resolvePath } from './commons.js';
5
+ import { displayNonNullValues, formatDate } from '../utils.js';
6
+ import { API_BASE, getHeaders, getDefaultHomePage, isValidAppName, resolvePath } from '../commons.js';
7
7
  import { createSubdomain, getSubdomains } from './subdomains.js';
8
8
  import { deleteSite } from './sites.js';
9
9
  import { copyFile, createFile, listRemoteFiles, pathExists, removeFileOrDirectory } from './files.js';
10
10
  import { getCurrentDirectory } from './auth.js';
11
- import crypto from './crypto.js';
11
+ import crypto from '../crypto.js';
12
12
 
13
13
  /**
14
14
  * List all apps
@@ -126,25 +126,28 @@ export async function appInfo(args = []) {
126
126
  /**
127
127
  * Create a new web application
128
128
  * @param {string} name The name of the App
129
+ * @param {string} directory Optional directory path
129
130
  * @param {string} description A description of the App
130
131
  * @param {string} url A default coming-soon URL
131
- * @returns Output JSON data
132
+ * @returns {Promise<Object>} Output JSON data
132
133
  */
133
- export async function createApp(args = []) {
134
- if (args.length < 1 || !isValidAppName(args[0])) {
135
- console.log(chalk.red('Usage: app:create <valid_name_app> [<remote_dir>] [--url=<url>]'));
136
- console.log(chalk.yellow('Example: app:create myapp'));
137
- console.log(chalk.yellow('Example: app:create myapp ./myapp'));
138
- return;
134
+ export async function createApp(args) {
135
+ const name = args.name; // App name (required)
136
+ console.log(args);
137
+ if (!isValidAppName(name)) {
138
+ throw new Error('Invalid application name');
139
139
  }
140
- const name = args[0]; // App name (required)
141
140
  // Use the default home page if the root directory if none specified
142
- const localDir = (args[1] && !args[1].startsWith('--'))? resolvePath(getCurrentDirectory(), args[1]):'';
143
- // Optional description (disabled at the moment)
144
- const description = ''; // (args.find(arg => arg.toLocaleLowerCase().startsWith('--description='))?.split('=')[1]) || '';
145
- const url = (args.find(arg => arg.toLocaleLowerCase().startsWith('--url='))?.split('=')[1]) || 'https://dev-center.puter.com/coming-soon.html'; // Optional url
141
+ const localDir = args.directory ? resolvePath(getCurrentDirectory(), args.directory) : '';
142
+ // Optional description
143
+ const description = args.description || '';
144
+ const url = args.url || '';
145
+
146
+ console.log(chalk.green(`Creating app "${name}"...`));
147
+ console.log(chalk.dim(`Directory: ${localDir || '[default]'}`));
148
+ console.log(chalk.dim(`Description: ${description}`));
149
+ console.log(chalk.dim(`URL: ${url}`));
146
150
 
147
- console.log(chalk.dim(`Creating app: ${chalk.green(name)}...\n`));
148
151
  try {
149
152
  // Step 1: Create the app
150
153
  const createAppResponse = await fetch(`${API_BASE}/drivers/call`, {
@@ -3,7 +3,7 @@ import chalk from 'chalk';
3
3
  import Conf from 'conf';
4
4
  import ora from 'ora';
5
5
  import fetch from 'node-fetch';
6
- import { PROJECT_NAME, API_BASE, getHeaders, BASE_URL } from './commons.js'
6
+ import { PROJECT_NAME, API_BASE, getHeaders, BASE_URL } from '../commons.js'
7
7
  const config = new Conf({ projectName: PROJECT_NAME });
8
8
 
9
9
  /**
@@ -6,12 +6,12 @@ import chalk from 'chalk';
6
6
  import ora from 'ora';
7
7
  import Conf from 'conf';
8
8
  import fetch from 'node-fetch';
9
- import { API_BASE, BASE_URL, PROJECT_NAME, getHeaders, showDiskSpaceUsage, resolvePath } from './commons.js';
10
- import { formatDate, formatDateTime, formatSize } from './utils.js';
9
+ import { API_BASE, BASE_URL, PROJECT_NAME, getHeaders, showDiskSpaceUsage, resolvePath } from '../commons.js';
10
+ import { formatDate, formatDateTime, formatSize } from '../utils.js';
11
11
  import inquirer from 'inquirer';
12
12
  import { getAuthToken, getCurrentDirectory, getCurrentUserName } from './auth.js';
13
13
  import { updatePrompt } from './shell.js';
14
- import crypto from './crypto.js';
14
+ import crypto from '../crypto.js';
15
15
 
16
16
  const config = new Conf({ projectName: PROJECT_NAME });
17
17
 
@@ -3,7 +3,7 @@ import chalk from 'chalk';
3
3
  import ora from 'ora';
4
4
  import { promises as fs } from 'fs';
5
5
  import path from 'path';
6
- import { generateAppName } from './commons.js';
6
+ import { generateAppName } from '../commons.js';
7
7
 
8
8
  export async function init() {
9
9
  const answers = await inquirer.prompt([
@@ -1,13 +1,13 @@
1
1
  import readline from 'node:readline';
2
2
  import chalk from 'chalk';
3
3
  import Conf from 'conf';
4
- import { execCommand, getPrompt } from './executor.js';
4
+ import { execCommand, getPrompt } from '../executor.js';
5
5
  import { getAuthToken } from './auth.js';
6
- import { PROJECT_NAME } from './commons.js';
6
+ import { PROJECT_NAME } from '../commons.js';
7
7
 
8
8
  const config = new Conf({ projectName: PROJECT_NAME });
9
9
 
10
- const rl = readline.createInterface({
10
+ export const rl = readline.createInterface({
11
11
  input: process.stdin,
12
12
  output: process.stdout,
13
13
  prompt: null
@@ -2,8 +2,8 @@ import chalk from 'chalk';
2
2
  import fetch from 'node-fetch';
3
3
  import Table from 'cli-table3';
4
4
  import { getCurrentUserName, getCurrentDirectory } from './auth.js';
5
- import { API_BASE, getHeaders, generateAppName, resolvePath, isValidAppName } from './commons.js';
6
- import { displayNonNullValues, formatDate, formatDateTime } from './utils.js';
5
+ import { API_BASE, getHeaders, generateAppName, resolvePath, isValidAppName } from '../commons.js';
6
+ import { displayNonNullValues, formatDate, formatDateTime } from '../utils.js';
7
7
  import { getSubdomains, createSubdomain, deleteSubdomain } from './subdomains.js';
8
8
 
9
9
 
@@ -1,6 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import fetch from 'node-fetch';
3
- import { API_BASE, getHeaders } from './commons.js';
3
+ import { API_BASE, getHeaders } from '../commons.js';
4
4
 
5
5
  /**
6
6
  * Get list of subdomains.
@@ -1,5 +1,5 @@
1
1
  import chalk from 'chalk';
2
- import { getAuthToken } from './auth.js';
2
+ import { getAuthToken } from './commands/auth.js';
3
3
 
4
4
  export const PROJECT_NAME = 'puter-cli';
5
5
  export const API_BASE = 'https://api.puter.com';
@@ -1,19 +1,23 @@
1
1
  import chalk from 'chalk';
2
- import ora from 'ora';
3
2
  import Conf from 'conf';
4
- import { listApps, appInfo, createApp, updateApp, deleteApp } from './apps.js';
5
- import { listSites, createSite, deleteSite, infoSite } from './sites.js';
3
+ import { listApps, appInfo, createApp, updateApp, deleteApp } from './commands/apps.js';
4
+ import { listSites, createSite, deleteSite, infoSite } from './commands/sites.js';
6
5
  import { listFiles, makeDirectory, renameFileOrDirectory,
7
6
  removeFileOrDirectory, emptyTrash, changeDirectory, showCwd,
8
7
  getInfo, getDiskUsage, createFile, readFile, uploadFile,
9
- downloadFile, copyFile, syncDirectory } from './files.js';
10
- import { getUserInfo, getUsageInfo } from './auth.js';
8
+ downloadFile, copyFile, syncDirectory } from './commands/files.js';
9
+ import { getUserInfo, getUsageInfo } from './commands/auth.js';
11
10
  import { PROJECT_NAME, API_BASE, getHeaders } from './commons.js';
12
11
  import inquirer from 'inquirer';
13
12
  import { exec } from 'node:child_process';
13
+ import { parseArgs } from './utils.js';
14
+ import { rl } from './commands/shell.js';
14
15
 
15
16
  const config = new Conf({ projectName: PROJECT_NAME });
16
17
 
18
+ // History of commands
19
+ const commandHistory = [];
20
+
17
21
  /**
18
22
  * Update the prompt function
19
23
  * @returns The current prompt
@@ -26,7 +30,7 @@ const commands = {
26
30
  help: showHelp,
27
31
  exit: () => process.exit(0),
28
32
  logout: async () => {
29
- await import('./auth.js').then(m => m.logout());
33
+ await import('./commands/auth.js').then(m => m.logout());
30
34
  process.exit(0);
31
35
  },
32
36
  whoami: getUserInfo,
@@ -37,12 +41,48 @@ const commands = {
37
41
  });
38
42
  },
39
43
  app: appInfo,
40
- 'app:create': async (args) => {
41
- if (args.length < 1) {
42
- console.log(chalk.red('Usage: app:create <name> [<remote_dir>] [--description=<description>] [--url=<url>]'));
44
+ history: async (args) => {
45
+ const lineNumber = parseInt(args[0]);
46
+
47
+ if (isNaN(lineNumber)) {
48
+ // Display full history
49
+ commandHistory.forEach((command, index) => {
50
+ console.log(chalk.cyan(`${index + 1}: ${command}`));
51
+ });
52
+ } else {
53
+ // Copy the command at the specified line number
54
+ if (lineNumber < 1 || lineNumber > commandHistory.length) {
55
+ console.error(chalk.red(`Invalid line number. History has ${commandHistory.length} entries.`));
56
+ return;
57
+ }
58
+
59
+ const commandToCopy = commandHistory[lineNumber - 1];
60
+ // Simulate typing the command in the shell
61
+ rl.write(commandToCopy);
62
+ }
63
+ },
64
+ 'app:create': async (rawArgs) => {
65
+ try {
66
+ const args = parseArgs(rawArgs.join(' '));
67
+ // Consider using explicit argument definition if necessary
68
+ // const args = parseArgs(rawArgs.join(' '), {string: ['description', 'url'],
69
+ // alias: { d: 'description', u: 'url', },
70
+ // });
71
+
72
+ if (!args.length < 1) {
73
+ console.log(chalk.red('Usage: app:create <name> [directory] [--description="My App Description"] [--url=app-url]'));
43
74
  return;
75
+ }
76
+
77
+ await createApp({
78
+ name: args._[0],
79
+ directory: args._[1] || '',
80
+ description: args.description || '',
81
+ url: args.url || 'https://dev-center.puter.com/coming-soon.html'
82
+ });
83
+ } catch (error) {
84
+ console.error(chalk.red(error.message));
44
85
  }
45
- await createApp(args);
46
86
  },
47
87
  'app:update': async (args) => {
48
88
  if (args.length < 1) {
@@ -51,13 +91,20 @@ const commands = {
51
91
  }
52
92
  await updateApp(args);
53
93
  },
54
- 'app:delete': async (args) => {
94
+ 'app:delete': async (rawArgs) => {
95
+ const args = parseArgs(rawArgs.join(' '), {
96
+ string: ['_'],
97
+ boolean: ['f'],
98
+ configuration: {
99
+ 'populate--': true
100
+ }
101
+ });
55
102
  if (args.length < 1) {
56
103
  console.log(chalk.red('Usage: app:delete <name>'));
57
104
  return;
58
105
  }
59
- const name = args.find(arg => arg !=='-f')
60
- const force = args.some(arg => arg =='-f')? true: false;
106
+ const name = args._[0];
107
+ const force = !!args.f;
61
108
 
62
109
  if (!force){
63
110
  const { confirm } = await inquirer.prompt([
@@ -96,7 +143,7 @@ const commands = {
96
143
  sites: listSites,
97
144
  site: infoSite,
98
145
  'site:delete': deleteSite,
99
- 'site:create': createSite
146
+ 'site:create': createSite,
100
147
  };
101
148
 
102
149
  /**
@@ -106,6 +153,12 @@ const commands = {
106
153
  export async function execCommand(input) {
107
154
  const [cmd, ...args] = input.split(' ');
108
155
 
156
+
157
+ // Add the command to history (skip the "history" command itself)
158
+ if (cmd !== 'history') {
159
+ commandHistory.push(input);
160
+ }
161
+
109
162
  if (cmd === 'help') {
110
163
  // Handle help command
111
164
  const command = args[0];
@@ -144,6 +197,7 @@ export async function execCommand(input) {
144
197
  * @param {string} [command] - The command to display help for.
145
198
  */
146
199
  function showHelp(command) {
200
+ // Consider using `program.helpInformation()` function for global "help" command...
147
201
  const commandHelp = {
148
202
  help: `
149
203
  ${chalk.cyan('help [command]')}
@@ -187,9 +241,9 @@ function showHelp(command) {
187
241
  Example: app myapp
188
242
  `,
189
243
  'app:create': `
190
- ${chalk.cyan('app:create <name> [<remote_dir>] [--url=<url>]')}
244
+ ${chalk.cyan('app:create <name> [<remote_dir>] [--description="<description>"] [--url=<url>]')}
191
245
  Create a new app.
192
- Example: app:create myapp https://example.com
246
+ Example: app:create myapp https://myapp.puter.site
193
247
  `,
194
248
  'app:update': `
195
249
  ${chalk.cyan('app:update <name> [dir]')}
@@ -288,6 +342,11 @@ function showHelp(command) {
288
342
  Execute a command on the host machine.
289
343
  Example: !ls -la
290
344
  `,
345
+ 'history [line]': `
346
+ ${chalk.cyan('history [line]')}
347
+ Display history of commands or copy command by line number
348
+ Example: history 2
349
+ `,
291
350
  };
292
351
 
293
352
  if (command && commandHelp[command]) {
@@ -1,4 +1,5 @@
1
1
  import chalk from 'chalk';
2
+ import yargsParser from 'yargs-parser';
2
3
 
3
4
  /**
4
5
  * Convert "2024-10-07T15:03:53.000Z" to "10/7/2024, 15:03:53"
@@ -89,4 +90,14 @@ export function displayNonNullValues(data) {
89
90
  });
90
91
  console.log(chalk.cyan('-'.repeat(maxKeyLength*3)));
91
92
  console.log(chalk.cyan(`You have ${chalk.green(tableData.length)} key/value pair(s).`));
92
- }
93
+ }
94
+
95
+ /**
96
+ * Parse command line arguments including quoted strings
97
+ * @param {string} input Raw command line input
98
+ * @returns {Object} Parsed arguments
99
+ */
100
+ export function parseArgs(input, options = {}) {
101
+ const result = yargsParser(input, options);
102
+ return result;
103
+ }
@@ -1,12 +1,12 @@
1
1
  import { describe, it, expect, vi, beforeEach } from 'vitest';
2
2
  import { login, logout, getUserInfo, isAuthenticated, getAuthToken, getCurrentUserName,
3
- getCurrentDirectory, getUsageInfo } from './commands/auth.js';
3
+ getCurrentDirectory, getUsageInfo } from '../src/commands/auth.js';
4
4
  import inquirer from 'inquirer';
5
5
  import ora from 'ora';
6
6
  import chalk from 'chalk';
7
7
  import fetch from 'node-fetch';
8
8
  import Conf from 'conf';
9
- import { BASE_URL } from '../commands/commons.js';
9
+ import { BASE_URL } from '../src/commons.js';
10
10
 
11
11
  // Mock console to prevent actual logging
12
12
  vi.spyOn(console, 'log').mockImplementation(() => {});
File without changes