puter-cli 1.8.5 → 2.0.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.
@@ -1,7 +1,7 @@
1
- # This workflow will run tests using node on every push
1
+ # This workflow will run tests using node on every push and pull request
2
2
  name: Build package
3
3
 
4
- on: push
4
+ on: [push, pull_request]
5
5
 
6
6
  jobs:
7
7
  build:
@@ -9,7 +9,7 @@ jobs:
9
9
 
10
10
  strategy:
11
11
  matrix:
12
- node-version: ['18.x', '20.x', '23.x']
12
+ node-version: ['20.x', '22.x', '24.x']
13
13
  steps:
14
14
  - uses: actions/checkout@v4
15
15
  - name: Install pnpm
@@ -26,6 +26,7 @@ jobs:
26
26
  - name: Run tests & coverage
27
27
  run: pnpm run coverage
28
28
  - name: Upload coverage reports to Codecov
29
+ if: github.event_name != 'pull_request'
29
30
  uses: codecov/codecov-action@v5
30
31
  with:
31
32
  token: ${{ secrets.CODECOV_TOKEN }}
package/CHANGELOG.md CHANGED
@@ -4,8 +4,46 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [v2.0.0](https://github.com/HeyPuter/puter-cli/compare/v1.8.6...v2.0.0)
8
+
9
+ - Add browser based login [`#75`](https://github.com/HeyPuter/puter-cli/pull/75)
10
+ - Adjust actions for PR test [`#73`](https://github.com/HeyPuter/puter-cli/pull/73)
11
+ - Add test for file commands [`#69`](https://github.com/HeyPuter/puter-cli/pull/69)
12
+ - Add deploy test [`#68`](https://github.com/HeyPuter/puter-cli/pull/68)
13
+ - Add executor test [`#67`](https://github.com/HeyPuter/puter-cli/pull/67)
14
+ - Add ProfileModule test [`#66`](https://github.com/HeyPuter/puter-cli/pull/66)
15
+ - Add commons.test.js [`#64`](https://github.com/HeyPuter/puter-cli/pull/64)
16
+ - Add test shell [`#65`](https://github.com/HeyPuter/puter-cli/pull/65)
17
+ - Add PuterModule test [`#63`](https://github.com/HeyPuter/puter-cli/pull/63)
18
+ - Add test error module [`#62`](https://github.com/HeyPuter/puter-cli/pull/62)
19
+ - Add subdomains test [`#61`](https://github.com/HeyPuter/puter-cli/pull/61)
20
+ - Add sites test [`#60`](https://github.com/HeyPuter/puter-cli/pull/60)
21
+ - Fix first init puter module [`#59`](https://github.com/HeyPuter/puter-cli/pull/59)
22
+ - Fix puter module causing unref error [`#52`](https://github.com/HeyPuter/puter-cli/pull/52)
23
+ - Migrate drivers call to Puter.js NPM [`#33`](https://github.com/HeyPuter/puter-cli/pull/33)
24
+ - Add non interactive puter site deploy [`#30`](https://github.com/HeyPuter/puter-cli/pull/30)
25
+ - Set program name to be hardcoded puter string [`#32`](https://github.com/HeyPuter/puter-cli/pull/32)
26
+ - Enable site:deploy redeploy under same subdomain [`#26`](https://github.com/HeyPuter/puter-cli/pull/26)
27
+ - Fix CLI close unexpectedly when first login [`#29`](https://github.com/HeyPuter/puter-cli/pull/29)
28
+ - Fix logout [`#28`](https://github.com/HeyPuter/puter-cli/pull/28)
29
+ - Site deploy from local dir [`#25`](https://github.com/HeyPuter/puter-cli/pull/25)
30
+ - Fix CI [`0b189de`](https://github.com/HeyPuter/puter-cli/commit/0b189dede790280bdf6e2a4691843970eb7ea83f)
31
+ - Init puter js npm [`b1bd5e7`](https://github.com/HeyPuter/puter-cli/commit/b1bd5e78a232391a2102e85e3ee0c0665ed1a00b)
32
+ - Update pnpm-lock.yaml [`9f7f8fc`](https://github.com/HeyPuter/puter-cli/commit/9f7f8fc7921427a580fe0bb8ca0dd10fe5db8b6b)
33
+
34
+ #### [v1.8.6](https://github.com/HeyPuter/puter-cli/compare/v1.8.5...v1.8.6)
35
+
36
+ > 8 October 2025
37
+
38
+ - Use random name if not specified for `site:deploy` [`#24`](https://github.com/HeyPuter/puter-cli/pull/24)
39
+ - Use random name if not specified [`48ae3f0`](https://github.com/HeyPuter/puter-cli/commit/48ae3f04325f27b654e00050c7ec514bee72535e)
40
+ - docs(readme): update site command [`aa4ba6e`](https://github.com/HeyPuter/puter-cli/commit/aa4ba6e1ee52e1c6e2c0cb5fb74c120fb1b5c0c3)
41
+ - refactor(site): remove name argument from site:deploy [`1ffaacb`](https://github.com/HeyPuter/puter-cli/commit/1ffaacbd3e00dff4f75af66bd1d4b9aee1daf9c6)
42
+
7
43
  #### [v1.8.5](https://github.com/HeyPuter/puter-cli/compare/v1.8.4...v1.8.5)
8
44
 
45
+ > 5 October 2025
46
+
9
47
  - feat(site): add site:deploy command for one-step project deployment [`94210ed`](https://github.com/HeyPuter/puter-cli/commit/94210ed796e7564647f4cd177a1b0bef72e66ef2)
10
48
  - Fix and add some details to the README file [`8acb6ea`](https://github.com/HeyPuter/puter-cli/commit/8acb6ea753b4f83c146f26473f61756e613a4953)
11
49
  - fix(files): touch command to creation a new file [`d30a067`](https://github.com/HeyPuter/puter-cli/commit/d30a0673e9aa5fb5b5d6b037a6a134a196a27529)
package/README.md CHANGED
@@ -36,7 +36,7 @@ The **Puter CLI** is a command-line interface tool designed to interact with the
36
36
  ## Installation
37
37
 
38
38
  ### Prerequisites
39
- - Node.js (v18 or higher)
39
+ - Node.js (v20 or higher)
40
40
  - npm (v7 or higher)
41
41
 
42
42
  Run the following command to install puter-cli globally in your system:
@@ -197,12 +197,18 @@ P.S. This command will look for the allocated `subdomain` and attempt to delete
197
197
 
198
198
  The static sites are served from the selected directory (or the current directory if none is specified).
199
199
 
200
- - **Deploy Site**: Deploy a static website from a directory.
200
+ - **Create Site**: Create a static website from a directory.
201
201
  ```bash
202
- puter> site:create <app_name> [<dir>] [--subdomain=<name>]
202
+ puter> site:create <app_name> [<dir>] [--subdomain=<name>]
203
203
  ```
204
204
  P.S. If the subdomain already exists, it will generate a new random one. You can set your own subdomain using `--subdomain` argument.
205
205
 
206
+ - **Deploy Site**: Deploy a static website from the current local directory to a remote directory. If no remote directory is specified, it deploys to the current directory on the remote instance.
207
+ ```bash
208
+ puter> site:deploy [<remote_dir>] [--subdomain=<name>]
209
+ ```
210
+ P.S. If the subdomain is not provided, it will be generated from the app name. The `--subdomain` argument allows you to specify a custom subdomain. All files in the remote directory will overwritten.
211
+
206
212
  - **List Sites**: List all hosted sites.
207
213
  ```bash
208
214
  puter> sites
@@ -252,10 +258,18 @@ or just type (you'll need to login):
252
258
 
253
259
  ## Examples
254
260
 
255
- 1. **Log in and List Files**:
261
+ In order to execute any command you'll need to authenticate first, this is a one time action:
256
262
  ```bash
263
+ # This will open the browser to authenticate you for the first time.
257
264
  puter login
265
+ # or (if you want to authenticate using your username/password)
266
+ #puter login --with-credentials
267
+ ```
268
+ 1. **Log in and List Files**:
269
+ ```bash
258
270
  puter> ls
271
+ # or list files in a specific directory:
272
+ puter> ls /
259
273
  ```
260
274
 
261
275
  2. **Create and Deploy a Static Site**:
package/bin/index.js CHANGED
@@ -5,30 +5,43 @@ import { login, logout } from '../src/commands/auth.js';
5
5
  import { init } from '../src/commands/init.js';
6
6
  import { startShell } from '../src/commands/shell.js';
7
7
  import { PROJECT_NAME, getLatestVersion } from '../src/commons.js';
8
- import { createApp } from '../src/commands/apps.js';
9
- import { deploy } from '../src/commands/deploy.js';
8
+ import { appInfo, createApp, listApps, deleteApp, updateApp } from '../src/commands/apps.js';
9
+ import inquirer from 'inquirer';
10
+ import { initProfileModule } from '../src/modules/ProfileModule.js';
11
+ import { initPuterModule } from '../src/modules/PuterModule.js';
12
+ import { createSite, infoSite, listSites, deleteSite } from '../src/commands/sites.js';
10
13
 
11
14
  async function main() {
15
+ initProfileModule();
16
+ initPuterModule();
17
+
12
18
  const version = await getLatestVersion(PROJECT_NAME);
13
19
 
14
20
  const program = new Command();
15
21
  program
16
- .name(PROJECT_NAME)
22
+ .name('puter')
17
23
  .description('CLI tool for Puter cloud platform')
18
24
  .version(version);
19
25
 
20
26
  program
21
27
  .command('login')
22
28
  .description('Login to Puter account')
23
- .option('-s, --save', 'Save authentication token in .env file', '')
24
- .action(() => {
25
- startShell('login');
29
+ .option('-s, --save', 'Save authentication token in .env file')
30
+ .option('--web', 'Use browser-based login (default)')
31
+ .option('--with-credentials', 'Use username/password login')
32
+ .option('--host <url>', 'Puter host URL', 'https://puter.com')
33
+ .action(async (options) => {
34
+ await login(options);
35
+ process.exit(0);
26
36
  });
27
37
 
28
38
  program
29
39
  .command('logout')
30
40
  .description('Logout from Puter account')
31
- .action(logout);
41
+ .action(async () => {
42
+ await logout();
43
+ process.exit(0);
44
+ });
32
45
 
33
46
  program
34
47
  .command('init')
@@ -38,24 +51,46 @@ async function main() {
38
51
  program
39
52
  .command('shell')
40
53
  .description('Start interactive shell')
41
- .action(startShell);
54
+ .action(() => startShell());
42
55
 
43
56
 
44
57
  // App commands
45
58
  program
46
- .command('app:create')
47
- .description('Create a new Puter application')
59
+ .command('apps')
60
+ .description('List all your apps')
61
+ .argument('[period]', 'period: today, yesterday, 7d, 30d, this_month, last_month')
62
+ .action(async (period) => {
63
+ await listApps({
64
+ statsPeriod: period || 'all'
65
+ });
66
+ process.exit(0);
67
+ });
68
+
69
+ const app = program
70
+ .command('app')
71
+ .description('App management commands');
72
+
73
+ app
74
+ .command('info')
75
+ .description('Get application information')
76
+ .argument('<app_name>', 'Name of the application')
77
+ .action(async (app_name) => {
78
+ await appInfo([app_name]);
79
+ process.exit(0);
80
+ });
81
+
82
+ app
83
+ .command('create')
84
+ .description('Create a new app')
48
85
  .argument('<name>', 'Name of the application')
49
- .argument('[remoteDir]', 'Remote directory path')
50
- .option('-d, --description [description]', 'Application description', '')
51
- .option('-u, --url <url>', 'Application URL', 'https://dev-center.puter.com/coming-soon.html')
52
- .action(async (name, remoteDir, options) => {
86
+ .argument('<remote_dir>', 'Remote directory URL')
87
+ .action(async (name, remote_dir) => {
53
88
  try {
54
89
  await createApp({
55
- name,
56
- directory: remoteDir || '',
57
- description: options.description || '',
58
- url: options.url
90
+ name: name,
91
+ directory: remote_dir || '',
92
+ description: '',
93
+ url: 'https://dev-center.puter.com/coming-soon.html'
59
94
  });
60
95
  } catch (error) {
61
96
  console.error(chalk.red(error.message));
@@ -63,22 +98,140 @@ async function main() {
63
98
  process.exit(0);
64
99
  });
65
100
 
66
- /*/ Deploy command
101
+ app
102
+ .command('update')
103
+ .description('Update an app')
104
+ .argument('<name>', 'Name of the application')
105
+ .argument('[dir]', 'Directory path', '.')
106
+ .action(async (name, dir) => {
107
+ await updateApp([name, dir]);
108
+ process.exit(0);
109
+ });
110
+
111
+ app
112
+ .command('delete')
113
+ .description('Delete an app')
114
+ .argument('<name>', 'Name of the application')
115
+ .option('-f, --force', 'Force deletion without confirmation')
116
+ .action(async (name, options) => {
117
+ let shouldDelete = options.force;
118
+
119
+ if (!shouldDelete) {
120
+ const answer = await inquirer.prompt([
121
+ {
122
+ type: 'confirm',
123
+ name: 'confirm',
124
+ message: `Are you sure you want to delete the app "${name}"?`,
125
+ default: false
126
+ }
127
+ ]);
128
+ shouldDelete = answer.confirm;
129
+ }
130
+
131
+ if (shouldDelete) {
132
+ await deleteApp(name);
133
+ } else {
134
+ console.log(chalk.yellow('App deletion cancelled.'));
135
+ }
136
+ process.exit(0);
137
+ });
138
+
67
139
  program
68
- .command('site:deploy')
140
+ .command('sites')
141
+ .description('List sites and subdomains')
142
+ .action(async () => {
143
+ await listSites();
144
+ process.exit(0);
145
+ });
146
+
147
+ const site = program
148
+ .command('site')
149
+ .description('Site management commands');
150
+
151
+ site
152
+ .command('info')
153
+ .description('Get site information by UID')
154
+ .argument('<site_uid>', 'Site UID')
155
+ .action(async (site_uid) => {
156
+ await infoSite([site_uid]);
157
+ process.exit(0);
158
+ });
159
+
160
+ site
161
+ .command('create')
162
+ .description('Create a static website from directory')
163
+ .argument('<app_name>', 'Application name')
164
+ .argument('[dir]', 'Directory path')
165
+ .option('--subdomain <name>', 'Subdomain name')
166
+ .action(async (app_name, dir, options) => {
167
+ const args = [app_name];
168
+ if (dir) args.push(dir);
169
+ if (options.subdomain) args.push(`--subdomain=${options.subdomain}`)
170
+
171
+ await createSite(args)
172
+ process.exit(0);
173
+ });
174
+
175
+ site
176
+ .command('deploy')
69
177
  .description('Deploy a local web project to Puter')
70
- .argument('[name]', 'Name of the site')
71
- .argument('[remoteDir]', 'Remote directory path')
72
- .option('--subdomain <subdomain>', 'Subdomain for the site')
73
- .action(async (name, remoteDir, options) => {
74
- try {
75
- await deploy([name, remoteDir, `--subdomain=${options.subdomain}`].filter(Boolean));
76
- } catch (error) {
77
- console.error(chalk.red(error.message));
78
- }
79
- process.exit(0);
178
+ .argument('[local_dir]', 'Local directory path')
179
+ .argument('[subdomain]', 'Deployment subdomain (<subdomain>.puter.site)')
180
+ .action(async (local_dir, subdomain) => {
181
+ if (!local_dir) {
182
+ const answer = await inquirer.prompt([
183
+ {
184
+ type: 'input',
185
+ name: 'local_dir',
186
+ message: 'Local directory path:',
187
+ default: '.'
188
+ }
189
+ ]);
190
+ local_dir = answer.local_dir;
191
+ }
192
+
193
+ if (!subdomain) {
194
+ const answer = await inquirer.prompt([
195
+ {
196
+ type: 'input',
197
+ name: 'subdomain',
198
+ message: 'Deployment subdomain (leave empty for random):',
199
+ }
200
+ ]);
201
+ subdomain = answer.subdomain;
202
+ }
203
+
204
+ await startShell(`site:deploy ${local_dir}${subdomain ? ` --subdomain=${subdomain}` : ''}`)
205
+ process.exit(0);
206
+ });
207
+
208
+ site
209
+ .command('delete')
210
+ .description('Delete a site by UID')
211
+ .argument('<uid>', 'Site UID')
212
+ .option('-f, --force', 'Force deletion without confirmation')
213
+ .action(async (uid, options) => {
214
+ let shouldDelete = options.force;
215
+
216
+ if (!shouldDelete) {
217
+ const answer = await inquirer.prompt([
218
+ {
219
+ type: 'confirm',
220
+ name: 'confirm',
221
+ message: `Are you sure you want to delete the site with UID "${uid}"?`,
222
+ default: false
223
+ }
224
+ ]);
225
+ shouldDelete = answer.confirm;
226
+ }
227
+
228
+ if (shouldDelete) {
229
+ await deleteSite([uid]);
230
+ } else {
231
+ console.log(chalk.yellow('Site deletion cancelled.'));
232
+ }
233
+ process.exit(0);
80
234
  });
81
- */
82
235
 
83
236
  if (process.argv.length === 2) {
84
237
  startShell();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "puter-cli",
3
- "version": "1.8.5",
3
+ "version": "2.0.0",
4
4
  "description": "Command line interface for Puter cloud platform",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -8,8 +8,15 @@
8
8
  },
9
9
  "preferGlobal": true,
10
10
  "type": "module",
11
+ "scripts": {
12
+ "start": "node bin/index.js",
13
+ "test": "TZ=UTC vitest run tests/*",
14
+ "test:watch": "TZ=UTC vitest --watch tests/*",
15
+ "version": "auto-changelog -p && git add CHANGELOG.md",
16
+ "coverage": "TZ=UTC vitest run --coverage"
17
+ },
11
18
  "engines": {
12
- "node": ">=18.0.0"
19
+ "node": ">=20.0.0"
13
20
  },
14
21
  "keywords": [
15
22
  "puter",
@@ -19,7 +26,7 @@
19
26
  "author": "Ibrahim.H",
20
27
  "license": "MIT",
21
28
  "dependencies": {
22
- "@heyputer/putility": "^1.0.2",
29
+ "@heyputer/puter.js": "^2.2.8",
23
30
  "chalk": "^5.3.0",
24
31
  "cli-table3": "^0.6.5",
25
32
  "commander": "^13.0.0",
@@ -46,12 +53,5 @@
46
53
  "bugs": {
47
54
  "url": "https://github.com/HeyPuter/puter-cli/issues"
48
55
  },
49
- "homepage": "https://github.com/HeyPuter/puter-cli",
50
- "scripts": {
51
- "start": "node bin/index.js",
52
- "test": "TZ=UTC vitest run tests/*",
53
- "test:watch": "TZ=UTC vitest --watch tests/*",
54
- "version": "auto-changelog -p && git add CHANGELOG.md",
55
- "coverage": "TZ=UTC vitest run --coverage"
56
- }
57
- }
56
+ "homepage": "https://github.com/HeyPuter/puter-cli"
57
+ }