@crawlee-cloud/cli 0.1.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.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Crawlee Cloud CLI
2
+
3
+ The official CLI tool for [Crawlee Cloud](https://crawlee.cloud).
4
+
5
+ Manage your Crawlee Cloud resources, deploy Actors, and view logs directly from your terminal.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install -g @crawlee-cloud/cli
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```bash
16
+ crawlee-cloud <command> [options]
17
+ # Alias
18
+ cc <command> [options]
19
+ ```
20
+
21
+ ### Commands
22
+
23
+ - `login` - Login to your Crawlee Cloud account
24
+ - `push` - Deploy an Actor to the cloud
25
+ - `run` - Start an Actor run
26
+ - `call` - Run an Actor and wait for it to finish
27
+ - `logs` - Stream logs from a running Actor
28
+
29
+ ## Example
30
+
31
+ ```bash
32
+ # Login
33
+ cc login
34
+
35
+ # Push the current directory as an Actor
36
+ cc push my-actor
37
+
38
+ # Run the Actor
39
+ cc call my-actor
40
+ ```
41
+
42
+ ## Documentation
43
+
44
+ For full documentation, visit the [Crawlee Cloud Documentation](https://github.com/crawlee-cloud/crawlee-cloud).
package/dist/bin.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;GAEG"}
package/dist/bin.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point
4
+ */
5
+ import { program } from './index.js';
6
+ program.parse();
7
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `crawlee-cloud call` command
3
+ *
4
+ * Calls a remote Actor on the platform.
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare const callCommand: Command;
8
+ //# sourceMappingURL=call.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../src/commands/call.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,WAAW,SAyGpB,CAAC"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * `crawlee-cloud call` command
3
+ *
4
+ * Calls a remote Actor on the platform.
5
+ */
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import fs from 'fs-extra';
10
+ import { getConfig } from '../utils/config.js';
11
+ export const callCommand = new Command('call')
12
+ .description('Call a remote Actor')
13
+ .argument('<actor>', 'Actor name or ID')
14
+ .option('-i, --input <json>', 'Input JSON or path to JSON file')
15
+ .option('-w, --wait', 'Wait for run to finish', false)
16
+ .option('-t, --timeout <seconds>', 'Timeout in seconds', '3600')
17
+ .option('-m, --memory <mb>', 'Memory in MB', '1024')
18
+ .action(async (actor, options) => {
19
+ console.log(chalk.bold(`\n📞 Calling Actor: ${actor}\n`));
20
+ const config = await getConfig();
21
+ if (!config.token) {
22
+ console.log(chalk.red('❌ Not logged in. Run: crawlee-cloud login'));
23
+ process.exit(1);
24
+ }
25
+ // Parse input
26
+ let inputData = {};
27
+ if (options.input) {
28
+ if (options.input.startsWith('{')) {
29
+ inputData = JSON.parse(options.input);
30
+ }
31
+ else if (await fs.pathExists(options.input)) {
32
+ inputData = await fs.readJson(options.input);
33
+ }
34
+ else {
35
+ console.log(chalk.red(`❌ Input file not found: ${options.input}`));
36
+ process.exit(1);
37
+ }
38
+ }
39
+ const spinner = ora('Starting Actor run...').start();
40
+ try {
41
+ // Start the run
42
+ const response = await fetch(`${config.apiBaseUrl}/v2/acts/${actor}/runs`, {
43
+ method: 'POST',
44
+ headers: {
45
+ 'Content-Type': 'application/json',
46
+ 'Authorization': `Bearer ${config.token}`,
47
+ },
48
+ body: JSON.stringify({
49
+ input: inputData,
50
+ timeout: parseInt(options.timeout, 10),
51
+ memory: parseInt(options.memory, 10),
52
+ }),
53
+ });
54
+ if (!response.ok) {
55
+ const errorData = await response.json().catch(() => ({}));
56
+ throw new Error(errorData.error?.message || `API error: ${response.status}`);
57
+ }
58
+ const result = await response.json();
59
+ const runId = result.data.id;
60
+ spinner.succeed(`Run started: ${runId}`);
61
+ if (options.wait) {
62
+ console.log(chalk.dim('\nWaiting for run to complete...'));
63
+ // Poll for completion
64
+ let status = 'RUNNING';
65
+ while (status === 'RUNNING' || status === 'READY') {
66
+ await sleep(2000);
67
+ const statusResponse = await fetch(`${config.apiBaseUrl}/v2/actor-runs/${runId}`, {
68
+ headers: { 'Authorization': `Bearer ${config.token}` },
69
+ });
70
+ const statusResult = await statusResponse.json();
71
+ status = statusResult.data.status;
72
+ process.stdout.write('.');
73
+ }
74
+ console.log();
75
+ if (status === 'SUCCEEDED') {
76
+ console.log(chalk.green(`\n✅ Run completed successfully\n`));
77
+ // Fetch and display output
78
+ const outputResponse = await fetch(`${config.apiBaseUrl}/v2/actor-runs/${runId}/key-value-store/records/OUTPUT`, { headers: { 'Authorization': `Bearer ${config.token}` } });
79
+ if (outputResponse.ok) {
80
+ const output = await outputResponse.json();
81
+ console.log(chalk.dim('Output:'));
82
+ console.log(JSON.stringify(output, null, 2));
83
+ }
84
+ }
85
+ else {
86
+ console.log(chalk.red(`\n❌ Run finished with status: ${status}\n`));
87
+ }
88
+ }
89
+ else {
90
+ console.log(chalk.dim(`\nView logs: crawlee-cloud logs ${runId}`));
91
+ }
92
+ console.log();
93
+ }
94
+ catch (err) {
95
+ spinner.fail('Failed to start run');
96
+ console.error(err.message);
97
+ process.exit(1);
98
+ }
99
+ });
100
+ function sleep(ms) {
101
+ return new Promise(resolve => setTimeout(resolve, ms));
102
+ }
103
+ //# sourceMappingURL=call.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/commands/call.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * `crawlee-cloud create` command
3
+ *
4
+ * Creates a new Actor project using official Apify templates.
5
+ * This ensures 100% compatibility with Apify Cloud for zero-code migration.
6
+ */
7
+ import { Command } from 'commander';
8
+ export declare const createCommand: Command;
9
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SAiEtB,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * `crawlee-cloud create` command
3
+ *
4
+ * Creates a new Actor project using official Apify templates.
5
+ * This ensures 100% compatibility with Apify Cloud for zero-code migration.
6
+ */
7
+ import { Command } from 'commander';
8
+ import chalk from 'chalk';
9
+ import { spawn } from 'child_process';
10
+ import { input } from '@inquirer/prompts';
11
+ export const createCommand = new Command('create')
12
+ .description('Create a new Actor project (uses official Apify templates)')
13
+ .argument('[name]', 'Actor name')
14
+ .option('-t, --template <template>', 'Template to use (passed to apify-cli)')
15
+ .option('--skip-install', 'Skip npm install after creation')
16
+ .action(async (name, options) => {
17
+ console.log(chalk.bold('\n🚀 Create new Crawlee Cloud Actor\n'));
18
+ console.log(chalk.dim('Using official Apify templates for 100% compatibility\n'));
19
+ // Get name if not provided
20
+ const actorName = name || await input({
21
+ message: 'Actor name:',
22
+ default: 'my-actor',
23
+ validate: (value) => {
24
+ if (!/^[a-z0-9-]+$/.test(value)) {
25
+ return 'Name must be lowercase letters, numbers, and hyphens only';
26
+ }
27
+ return true;
28
+ },
29
+ });
30
+ // Build apify-cli create command arguments
31
+ const args = ['apify-cli', 'create', actorName];
32
+ if (options.template) {
33
+ args.push('--template', options.template);
34
+ }
35
+ if (options.skipInstall) {
36
+ args.push('--skip-dependency-install');
37
+ }
38
+ console.log(chalk.dim(`Running: npx ${args.join(' ')}\n`));
39
+ // Run npx apify-cli create
40
+ const child = spawn('npx', args, {
41
+ stdio: 'inherit',
42
+ shell: true,
43
+ });
44
+ child.on('close', (code) => {
45
+ if (code === 0) {
46
+ console.log(chalk.green('\n✅ Actor created successfully!'));
47
+ console.log(chalk.dim('\nYour Actor is 100% compatible with both:'));
48
+ console.log(chalk.cyan(' • Apify Cloud (apify.com)'));
49
+ console.log(chalk.cyan(' • Crawlee Cloud (self-hosted)'));
50
+ console.log();
51
+ console.log(chalk.dim('To run locally:'));
52
+ console.log(chalk.cyan(` cd ${actorName}`));
53
+ console.log(chalk.cyan(' npm start'));
54
+ console.log();
55
+ console.log(chalk.dim('To deploy to Crawlee Cloud:'));
56
+ console.log(chalk.cyan(' crawlee-cloud push'));
57
+ console.log();
58
+ }
59
+ else {
60
+ console.log(chalk.red(`\n❌ Failed to create Actor (exit code: ${code})`));
61
+ process.exit(code ?? 1);
62
+ }
63
+ });
64
+ child.on('error', (err) => {
65
+ console.error(chalk.red('\n❌ Failed to run apify-cli:'), err.message);
66
+ console.log(chalk.dim('\nMake sure you have npx available (comes with npm 5.2+)'));
67
+ process.exit(1);
68
+ });
69
+ });
70
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `crawlee-cloud login` command
3
+ *
4
+ * Authenticate with the platform.
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare const loginCommand: Command;
8
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,YAAY,SAiDrB,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `crawlee-cloud login` command
3
+ *
4
+ * Authenticate with the platform.
5
+ */
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import { password, input } from '@inquirer/prompts';
9
+ import { saveConfig, getConfig } from '../utils/config.js';
10
+ export const loginCommand = new Command('login')
11
+ .description('Authenticate with Crawlee Cloud')
12
+ .option('-t, --token <token>', 'API token')
13
+ .option('-u, --url <url>', 'API base URL')
14
+ .action(async (options) => {
15
+ console.log(chalk.bold('\n🔐 Login to Crawlee Cloud\n'));
16
+ const existingConfig = await getConfig();
17
+ // Get API URL
18
+ const apiBaseUrl = options.url || await input({
19
+ message: 'API URL:',
20
+ default: existingConfig.apiBaseUrl || 'http://localhost:3000',
21
+ });
22
+ // Get token
23
+ const token = options.token || await password({
24
+ message: 'API Token:',
25
+ mask: '*',
26
+ });
27
+ // Test connection
28
+ console.log(chalk.dim('\nTesting connection...'));
29
+ try {
30
+ const response = await fetch(`${apiBaseUrl}/health`);
31
+ if (!response.ok) {
32
+ throw new Error(`Server returned ${response.status}`);
33
+ }
34
+ const health = await response.json();
35
+ console.log(chalk.green(`✅ Connected to Crawlee Cloud v${health.version}`));
36
+ // Save config
37
+ await saveConfig({
38
+ apiBaseUrl,
39
+ token,
40
+ });
41
+ console.log(chalk.dim('\nCredentials saved to ~/.crawlee-cloud/config.json'));
42
+ console.log(chalk.green('\n✅ Login successful!\n'));
43
+ }
44
+ catch (err) {
45
+ console.log(chalk.red(`\n❌ Failed to connect: ${err.message}`));
46
+ console.log(chalk.dim(`\nMake sure the platform is running at ${apiBaseUrl}`));
47
+ process.exit(1);
48
+ }
49
+ });
50
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,qBAAqB,EAAE,WAAW,CAAC;KAC1C,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC;KACzC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC;IAEzD,MAAM,cAAc,GAAG,MAAM,SAAS,EAAE,CAAC;IAEzC,cAAc;IACd,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,IAAI,MAAM,KAAK,CAAC;QAC5C,OAAO,EAAE,UAAU;QACnB,OAAO,EAAE,cAAc,CAAC,UAAU,IAAI,uBAAuB;KAC9D,CAAC,CAAC;IAEH,YAAY;IACZ,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,QAAQ,CAAC;QAC5C,OAAO,EAAE,YAAY;QACrB,IAAI,EAAE,GAAG;KACV,CAAC,CAAC;IAEH,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAElD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,SAAS,CAAC,CAAC;QAErD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAyC,CAAC;QAE5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iCAAiC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAE5E,cAAc;QACd,MAAM,UAAU,CAAC;YACf,UAAU;YACV,KAAK;SACN,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAEtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA2B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0CAA0C,UAAU,EAAE,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `crawlee-cloud logs` command
3
+ *
4
+ * View logs for a run.
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare const logsCommand: Command;
8
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,WAAW,SAoFpB,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * `crawlee-cloud logs` command
3
+ *
4
+ * View logs for a run.
5
+ */
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import { getConfig } from '../utils/config.js';
9
+ export const logsCommand = new Command('logs')
10
+ .description('View logs for a run')
11
+ .argument('<run-id>', 'Run ID')
12
+ .option('-f, --follow', 'Follow logs in real-time', false)
13
+ .action(async (runId, options) => {
14
+ console.log(chalk.bold(`\n📋 Logs for run: ${runId}\n`));
15
+ const config = await getConfig();
16
+ if (!config.token) {
17
+ console.log(chalk.red('❌ Not logged in. Run: crawlee-cloud login'));
18
+ process.exit(1);
19
+ }
20
+ try {
21
+ // Get run info
22
+ const runResponse = await fetch(`${config.apiBaseUrl}/v2/actor-runs/${runId}`, {
23
+ headers: { 'Authorization': `Bearer ${config.token}` },
24
+ });
25
+ if (!runResponse.ok) {
26
+ console.log(chalk.red(`❌ Run not found: ${runId}`));
27
+ process.exit(1);
28
+ }
29
+ const run = (await runResponse.json());
30
+ console.log(chalk.dim(`Actor: ${run.data.actId}`));
31
+ console.log(chalk.dim(`Status: ${run.data.status}`));
32
+ console.log(chalk.dim(`Started: ${run.data.startedAt}`));
33
+ if (run.data.finishedAt) {
34
+ console.log(chalk.dim(`Finished: ${run.data.finishedAt}`));
35
+ }
36
+ console.log(chalk.dim('─'.repeat(60)));
37
+ console.log();
38
+ if (options.follow && (run.data.status === 'RUNNING' || run.data.status === 'READY')) {
39
+ // Follow logs (simplified - in production would use WebSocket or SSE)
40
+ console.log(chalk.dim('Following logs... (Ctrl+C to stop)\n'));
41
+ while (true) {
42
+ await sleep(2000);
43
+ const statusResponse = await fetch(`${config.apiBaseUrl}/v2/actor-runs/${runId}`, {
44
+ headers: { 'Authorization': `Bearer ${config.token}` },
45
+ });
46
+ const statusResult = await statusResponse.json();
47
+ if (statusResult.data.status !== 'RUNNING' && statusResult.data.status !== 'READY') {
48
+ console.log(chalk.dim(`\nRun finished with status: ${statusResult.data.status}`));
49
+ break;
50
+ }
51
+ }
52
+ }
53
+ else {
54
+ // For now, just show run status
55
+ // In production, would fetch actual container logs
56
+ console.log(chalk.dim('(Real-time logs not yet implemented - checking run status)'));
57
+ console.log();
58
+ if (run.data.status === 'SUCCEEDED') {
59
+ console.log(chalk.green('Run completed successfully'));
60
+ }
61
+ else if (run.data.status === 'FAILED') {
62
+ console.log(chalk.red('Run failed'));
63
+ }
64
+ else if (run.data.status === 'RUNNING') {
65
+ console.log(chalk.yellow('Run is still in progress'));
66
+ }
67
+ else {
68
+ console.log(chalk.dim(`Status: ${run.data.status}`));
69
+ }
70
+ }
71
+ console.log();
72
+ }
73
+ catch (err) {
74
+ console.error(chalk.red('Failed to fetch logs:'), err.message);
75
+ process.exit(1);
76
+ }
77
+ });
78
+ function sleep(ms) {
79
+ return new Promise(resolve => setTimeout(resolve, ms));
80
+ }
81
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `crawlee-cloud push` command
3
+ *
4
+ * Builds and pushes Actor to the platform.
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare const pushCommand: Command;
8
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,eAAO,MAAM,WAAW,SA8IpB,CAAC"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * `crawlee-cloud push` command
3
+ *
4
+ * Builds and pushes Actor to the platform.
5
+ */
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import path from 'path';
10
+ import fs from 'fs-extra';
11
+ import { spawn } from 'child_process';
12
+ import { getConfig } from '../utils/config.js';
13
+ function validateActorJson(actorJson) {
14
+ const errors = [];
15
+ if (!actorJson.name) {
16
+ errors.push('Missing required field: "name"');
17
+ }
18
+ else if (!/^[a-z0-9-]+$/.test(actorJson.name)) {
19
+ errors.push('"name" must contain only lowercase letters, numbers, and hyphens');
20
+ }
21
+ if (!actorJson.actorSpecification) {
22
+ errors.push('Missing required field: "actorSpecification"');
23
+ }
24
+ return errors;
25
+ }
26
+ export const pushCommand = new Command('push')
27
+ .description('Push Actor to Crawlee Cloud')
28
+ .option('-t, --tag <tag>', 'Docker image tag', 'latest')
29
+ .option('--no-build', 'Skip Docker build')
30
+ .action(async (options) => {
31
+ console.log(chalk.bold('\n📤 Pushing Actor to Crawlee Cloud\n'));
32
+ const cwd = process.cwd();
33
+ const config = await getConfig();
34
+ // Check if .actor directory exists
35
+ const actorDir = path.join(cwd, '.actor');
36
+ if (!await fs.pathExists(actorDir)) {
37
+ console.log(chalk.red('❌ No .actor directory found.'));
38
+ console.log(chalk.dim('\nTo create an Actor, run:'));
39
+ console.log(chalk.cyan(' npx apify-cli create my-actor'));
40
+ console.log(chalk.dim('\nOr create .actor/actor.json manually with:'));
41
+ console.log(chalk.dim(` {
42
+ "actorSpecification": 1,
43
+ "name": "my-actor",
44
+ "title": "My Actor"
45
+ }`));
46
+ process.exit(1);
47
+ }
48
+ // Check if actor.json exists
49
+ const actorJsonPath = path.join(actorDir, 'actor.json');
50
+ if (!await fs.pathExists(actorJsonPath)) {
51
+ console.log(chalk.red('❌ No .actor/actor.json found.'));
52
+ console.log(chalk.dim('\nCreate .actor/actor.json with at minimum:'));
53
+ console.log(chalk.dim(` {
54
+ "actorSpecification": 1,
55
+ "name": "my-actor",
56
+ "title": "My Actor"
57
+ }`));
58
+ process.exit(1);
59
+ }
60
+ // Parse and validate actor.json
61
+ let actorJson;
62
+ try {
63
+ actorJson = await fs.readJson(actorJsonPath);
64
+ }
65
+ catch (err) {
66
+ console.log(chalk.red('❌ Invalid JSON in .actor/actor.json'));
67
+ console.error(err);
68
+ process.exit(1);
69
+ }
70
+ // Validate required fields
71
+ const validationErrors = validateActorJson(actorJson);
72
+ if (validationErrors.length > 0) {
73
+ console.log(chalk.red('❌ Invalid .actor/actor.json:'));
74
+ validationErrors.forEach(err => console.log(chalk.red(` • ${err}`)));
75
+ process.exit(1);
76
+ }
77
+ const actorName = actorJson.name;
78
+ const imageName = `crawlee-cloud/actor-${actorName}:${options.tag}`;
79
+ console.log(chalk.dim(`Actor: ${actorName}`));
80
+ if (actorJson.title)
81
+ console.log(chalk.dim(`Title: ${actorJson.title}`));
82
+ if (actorJson.version)
83
+ console.log(chalk.dim(`Version: ${actorJson.version}`));
84
+ console.log(chalk.dim(`Image: ${imageName}`));
85
+ console.log();
86
+ // Check Dockerfile exists
87
+ const dockerfilePath = actorJson.dockerfile
88
+ ? path.resolve(cwd, '.actor', actorJson.dockerfile)
89
+ : path.join(cwd, 'Dockerfile');
90
+ if (!await fs.pathExists(dockerfilePath)) {
91
+ console.log(chalk.red(`❌ Dockerfile not found at: ${dockerfilePath}`));
92
+ process.exit(1);
93
+ }
94
+ // Build Docker image
95
+ if (options.build !== false) {
96
+ const buildSpinner = ora('Building Docker image...').start();
97
+ try {
98
+ await runCommand('docker', ['build', '-t', imageName, '.'], cwd);
99
+ buildSpinner.succeed('Docker image built');
100
+ }
101
+ catch (err) {
102
+ buildSpinner.fail('Docker build failed');
103
+ console.error(err);
104
+ process.exit(1);
105
+ }
106
+ }
107
+ // Push to registry (if configured)
108
+ if (config.registryUrl) {
109
+ const pushSpinner = ora('Pushing to registry...').start();
110
+ try {
111
+ const remoteImage = `${config.registryUrl}/actor-${actorName}:${options.tag}`;
112
+ await runCommand('docker', ['tag', imageName, remoteImage], cwd);
113
+ await runCommand('docker', ['push', remoteImage], cwd);
114
+ pushSpinner.succeed('Image pushed to registry');
115
+ }
116
+ catch (err) {
117
+ pushSpinner.fail('Push failed');
118
+ console.error(err);
119
+ process.exit(1);
120
+ }
121
+ }
122
+ // Register with API
123
+ const registerSpinner = ora('Registering with platform...').start();
124
+ try {
125
+ const response = await fetch(`${config.apiBaseUrl}/v2/acts`, {
126
+ method: 'POST',
127
+ headers: {
128
+ 'Content-Type': 'application/json',
129
+ 'Authorization': `Bearer ${config.token}`,
130
+ },
131
+ body: JSON.stringify({
132
+ name: actorName,
133
+ title: actorJson.title,
134
+ description: actorJson.description,
135
+ defaultRunOptions: {
136
+ image: imageName,
137
+ },
138
+ }),
139
+ });
140
+ if (!response.ok) {
141
+ const errorText = await response.text();
142
+ throw new Error(`API error: ${response.status} - ${errorText}`);
143
+ }
144
+ registerSpinner.succeed('Registered with platform');
145
+ console.log(chalk.green(`\n✅ Actor "${actorName}" pushed successfully!\n`));
146
+ console.log(chalk.dim(`Run with: npx crawlee-cloud call ${actorName}`));
147
+ console.log(chalk.dim(`Dashboard: http://localhost:3001/actors/${actorName}`));
148
+ console.log();
149
+ }
150
+ catch (err) {
151
+ registerSpinner.fail('Registration failed');
152
+ console.error(err);
153
+ process.exit(1);
154
+ }
155
+ });
156
+ function runCommand(cmd, args, cwd) {
157
+ return new Promise((resolve, reject) => {
158
+ const child = spawn(cmd, args, { cwd, stdio: 'pipe' });
159
+ let stderr = '';
160
+ child.stderr?.on('data', (data) => {
161
+ stderr += data.toString();
162
+ });
163
+ child.on('exit', (code) => {
164
+ if (code === 0) {
165
+ resolve();
166
+ }
167
+ else {
168
+ reject(new Error(stderr || `Command failed with code ${code}`));
169
+ }
170
+ });
171
+ });
172
+ }
173
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `crawlee-cloud run` command
3
+ *
4
+ * Runs an Actor locally with local storage.
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare const runCommand: Command;
8
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,UAAU,SA4GnB,CAAC"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * `crawlee-cloud run` command
3
+ *
4
+ * Runs an Actor locally with local storage.
5
+ */
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import { spawn } from 'child_process';
9
+ import path from 'path';
10
+ import fs from 'fs-extra';
11
+ import dotenv from 'dotenv';
12
+ export const runCommand = new Command('run')
13
+ .description('Run Actor locally')
14
+ .option('-i, --input <json>', 'Input JSON or path to JSON file')
15
+ .option('--no-purge', 'Do not purge storage before run')
16
+ .action(async (options) => {
17
+ console.log(chalk.bold('\n🏃 Running Actor locally\n'));
18
+ const cwd = process.cwd();
19
+ // Check if we're in an Actor directory
20
+ const packageJsonPath = path.join(cwd, 'package.json');
21
+ if (!await fs.pathExists(packageJsonPath)) {
22
+ console.log(chalk.red('❌ No package.json found. Are you in an Actor directory?'));
23
+ process.exit(1);
24
+ }
25
+ // Load .env if exists
26
+ const envPath = path.join(cwd, '.env');
27
+ if (await fs.pathExists(envPath)) {
28
+ dotenv.config({ path: envPath });
29
+ }
30
+ // Set up storage directory
31
+ const storageDir = path.join(cwd, 'storage');
32
+ // Purge storage if requested
33
+ if (options.purge !== false) {
34
+ console.log(chalk.dim('Purging local storage...'));
35
+ await fs.remove(storageDir);
36
+ }
37
+ await fs.ensureDir(path.join(storageDir, 'key_value_stores', 'default'));
38
+ await fs.ensureDir(path.join(storageDir, 'datasets', 'default'));
39
+ await fs.ensureDir(path.join(storageDir, 'request_queues', 'default'));
40
+ // Handle input
41
+ if (options.input) {
42
+ let inputData;
43
+ if (options.input.startsWith('{')) {
44
+ // JSON string
45
+ inputData = JSON.parse(options.input);
46
+ }
47
+ else if (await fs.pathExists(options.input)) {
48
+ // File path
49
+ inputData = await fs.readJson(options.input);
50
+ }
51
+ else {
52
+ console.log(chalk.red(`❌ Input file not found: ${options.input}`));
53
+ process.exit(1);
54
+ }
55
+ // Write input to storage
56
+ await fs.writeJson(path.join(storageDir, 'key_value_stores', 'default', 'INPUT.json'), inputData, { spaces: 2 });
57
+ console.log(chalk.dim('Input saved to storage'));
58
+ }
59
+ // Set environment variables for local run
60
+ const env = {
61
+ ...process.env,
62
+ APIFY_LOCAL_STORAGE_DIR: storageDir,
63
+ APIFY_HEADLESS: '1',
64
+ CRAWLEE_STORAGE_DIR: storageDir,
65
+ };
66
+ // Determine start command
67
+ const pkg = await fs.readJson(packageJsonPath);
68
+ const startScript = pkg.scripts?.start || pkg.scripts?.['start:dev'];
69
+ if (!startScript) {
70
+ console.log(chalk.red('❌ No start script found in package.json'));
71
+ process.exit(1);
72
+ }
73
+ console.log(chalk.cyan(`Running: npm start\n`));
74
+ console.log(chalk.dim('─'.repeat(60)));
75
+ // Run the Actor
76
+ const child = spawn('npm', ['start'], {
77
+ cwd,
78
+ env,
79
+ stdio: 'inherit',
80
+ shell: true,
81
+ });
82
+ child.on('exit', async (code) => {
83
+ console.log(chalk.dim('─'.repeat(60)));
84
+ if (code === 0) {
85
+ console.log(chalk.green('\n✅ Actor finished successfully\n'));
86
+ // Show dataset summary
87
+ const datasetDir = path.join(storageDir, 'datasets', 'default');
88
+ const files = await fs.readdir(datasetDir).catch(() => []);
89
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
90
+ if (jsonFiles.length > 0) {
91
+ console.log(chalk.dim(`Dataset: ${jsonFiles.length} items saved`));
92
+ console.log(chalk.dim(`Location: ${datasetDir}`));
93
+ }
94
+ }
95
+ else {
96
+ console.log(chalk.red(`\n❌ Actor failed with exit code ${code}\n`));
97
+ }
98
+ process.exit(code || 0);
99
+ });
100
+ });
101
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Crawlee Cloud CLI
3
+ *
4
+ * Commands:
5
+ * run Run Actor locally
6
+ * push Push Actor to platform
7
+ * call <actor> Call a remote Actor
8
+ * logs <run-id> View run logs
9
+ * login Authenticate with platform
10
+ *
11
+ * Note: To create a new Actor, use `apify create` (official Apify CLI)
12
+ * for 100% compatibility with both Apify Cloud and Crawlee Cloud.
13
+ */
14
+ import { Command } from 'commander';
15
+ export declare const program: Command;
16
+ export { program as cli };
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,OAAO,SAAgB,CAAC;AAcrC,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Crawlee Cloud CLI
3
+ *
4
+ * Commands:
5
+ * run Run Actor locally
6
+ * push Push Actor to platform
7
+ * call <actor> Call a remote Actor
8
+ * logs <run-id> View run logs
9
+ * login Authenticate with platform
10
+ *
11
+ * Note: To create a new Actor, use `apify create` (official Apify CLI)
12
+ * for 100% compatibility with both Apify Cloud and Crawlee Cloud.
13
+ */
14
+ import { Command } from 'commander';
15
+ import { runCommand } from './commands/run.js';
16
+ import { pushCommand } from './commands/push.js';
17
+ import { callCommand } from './commands/call.js';
18
+ import { logsCommand } from './commands/logs.js';
19
+ import { loginCommand } from './commands/login.js';
20
+ export const program = new Command();
21
+ program
22
+ .name('crawlee-cloud')
23
+ .description('CLI for Crawlee Cloud - run and deploy Actors (use `apify create` to create new Actors)')
24
+ .version('0.1.0');
25
+ // Register commands
26
+ program.addCommand(runCommand);
27
+ program.addCommand(pushCommand);
28
+ program.addCommand(callCommand);
29
+ program.addCommand(logsCommand);
30
+ program.addCommand(loginCommand);
31
+ export { program as cli };
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAErC,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,yFAAyF,CAAC;KACtG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAEjC,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Configuration utilities for CLI.
3
+ */
4
+ export interface CLIConfig {
5
+ apiBaseUrl: string;
6
+ token: string;
7
+ registryUrl?: string;
8
+ }
9
+ /**
10
+ * Get CLI configuration.
11
+ */
12
+ export declare function getConfig(): Promise<CLIConfig>;
13
+ /**
14
+ * Save CLI configuration.
15
+ */
16
+ export declare function saveConfig(config: Partial<CLIConfig>): Promise<void>;
17
+ /**
18
+ * Clear CLI configuration.
19
+ */
20
+ export declare function clearConfig(): Promise<void>;
21
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,CAkBpD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Configuration utilities for CLI.
3
+ */
4
+ import fs from 'fs-extra';
5
+ import path from 'path';
6
+ import os from 'os';
7
+ const CONFIG_DIR = path.join(os.homedir(), '.crawlee-cloud');
8
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
9
+ /**
10
+ * Get CLI configuration.
11
+ */
12
+ export async function getConfig() {
13
+ // Check environment variables first
14
+ const envConfig = {
15
+ apiBaseUrl: process.env.CRAWLEE_CLOUD_API_URL || process.env.APIFY_API_BASE_URL?.replace('/v2', '') || 'http://localhost:3000',
16
+ token: process.env.CRAWLEE_CLOUD_TOKEN || process.env.APIFY_TOKEN || '',
17
+ registryUrl: process.env.CRAWLEE_CLOUD_REGISTRY_URL,
18
+ };
19
+ // Load from file if exists
20
+ if (await fs.pathExists(CONFIG_FILE)) {
21
+ const fileConfig = await fs.readJson(CONFIG_FILE);
22
+ return {
23
+ ...envConfig,
24
+ ...fileConfig,
25
+ };
26
+ }
27
+ return envConfig;
28
+ }
29
+ /**
30
+ * Save CLI configuration.
31
+ */
32
+ export async function saveConfig(config) {
33
+ await fs.ensureDir(CONFIG_DIR);
34
+ const existing = await getConfig();
35
+ const merged = { ...existing, ...config };
36
+ await fs.writeJson(CONFIG_FILE, merged, { spaces: 2, mode: 0o600 });
37
+ }
38
+ /**
39
+ * Clear CLI configuration.
40
+ */
41
+ export async function clearConfig() {
42
+ if (await fs.pathExists(CONFIG_FILE)) {
43
+ await fs.remove(CONFIG_FILE);
44
+ }
45
+ }
46
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAQpB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,oCAAoC;IACpC,MAAM,SAAS,GAAc;QAC3B,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,uBAAuB;QAC9H,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE;QACvE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;KACpD,CAAC;IAEF,2BAA2B;IAC3B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAClD,OAAO;YACL,GAAG,SAAS;YACZ,GAAG,UAAU;SACd,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAA0B;IACzD,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAE/B,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IAE1C,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@crawlee-cloud/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for Crawlee Cloud - run and deploy Actors",
5
+ "type": "module",
6
+ "bin": {
7
+ "crawlee-cloud": "./dist/bin.js",
8
+ "cc": "./dist/bin.js"
9
+ },
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "dev": "tsx src/bin.ts",
15
+ "clean": "rm -rf dist",
16
+ "typecheck": "tsc --noEmit"
17
+ },
18
+ "keywords": [
19
+ "crawlee",
20
+ "cli",
21
+ "apify",
22
+ "scraper"
23
+ ],
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "commander": "^12.1.0",
27
+ "chalk": "^5.3.0",
28
+ "ora": "^8.1.1",
29
+ "inquirer": "^12.1.0",
30
+ "fs-extra": "^11.2.0",
31
+ "dotenv": "^16.4.7"
32
+ },
33
+ "devDependencies": {
34
+ "@types/fs-extra": "^11.0.4",
35
+ "@types/node": "^20.10.0",
36
+ "tsx": "^4.7.0",
37
+ "typescript": "^5.7.2"
38
+ },
39
+ "files": [
40
+ "dist"
41
+ ],
42
+ "preferGlobal": true,
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/crawlee-cloud/crawlee-cloud.git"
49
+ },
50
+ "bugs": {
51
+ "url": "https://github.com/crawlee-cloud/crawlee-cloud/issues"
52
+ },
53
+ "homepage": "https://crawlee.cloud"
54
+ }