@tonk/cli 0.0.1
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 +16 -0
- package/bin/tonk.js +3 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +292 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/create.d.ts +3 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +33 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/deploy.d.ts +3 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +113 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +3 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +71 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/serve.d.ts +3 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +53 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/tonk.d.ts +2 -0
- package/dist/tonk.d.ts.map +1 -0
- package/dist/tonk.js +27 -0
- package/dist/tonk.js.map +1 -0
- package/package.json +84 -0
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Tonk CLI
|
|
2
|
+
|
|
3
|
+
Command line utilities for your Tonk network
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
1. Clone the repository
|
|
8
|
+
2. Install dependencies: `pnpm install`
|
|
9
|
+
3. Link for local testing: `npm link`
|
|
10
|
+
4. Run the dev mode: `pnpm run dev`
|
|
11
|
+
|
|
12
|
+
## License
|
|
13
|
+
|
|
14
|
+
Simplicity and freedom.
|
|
15
|
+
|
|
16
|
+
MIT © Tonk
|
package/bin/tonk.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAOlC,eAAO,MAAM,aAAa,SAiXtB,CAAC"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
export const configCommand = new Command('config')
|
|
8
|
+
.description('Configure EC2 server and create a config file for your Tonk app')
|
|
9
|
+
.option('-i, --instance <address>', 'EC2 instance address')
|
|
10
|
+
.option('-k, --key <path>', 'Path to SSH key file')
|
|
11
|
+
.option('-u, --user <name>', 'SSH username', 'ec2-user')
|
|
12
|
+
.option('-p, --provision', 'Provision a new EC2 instance')
|
|
13
|
+
.option('-n, --key-name <name>', 'AWS key pair name (for provisioning)')
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
const currentFileUrl = import.meta.url;
|
|
16
|
+
const currentFilePath = new URL(currentFileUrl).pathname;
|
|
17
|
+
const cliPath = path.dirname(path.dirname(currentFilePath));
|
|
18
|
+
const awsScriptsPath = path.join(cliPath, 'scripts', 'aws');
|
|
19
|
+
// Check if AWS CLI is installed
|
|
20
|
+
const checkAwsInstalled = () => {
|
|
21
|
+
try {
|
|
22
|
+
execSync('aws --version', { stdio: 'ignore' });
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
// If provisioning or any AWS operation is needed, check for AWS CLI first
|
|
31
|
+
if (options.provision) {
|
|
32
|
+
if (!checkAwsInstalled()) {
|
|
33
|
+
console.log(chalk.yellow('AWS CLI is not installed or not in your PATH.'));
|
|
34
|
+
const { installAws } = await inquirer.prompt([
|
|
35
|
+
{
|
|
36
|
+
type: 'confirm',
|
|
37
|
+
name: 'installAws',
|
|
38
|
+
message: 'AWS CLI is required for provisioning. Would you like instructions to install it?',
|
|
39
|
+
default: true,
|
|
40
|
+
},
|
|
41
|
+
]);
|
|
42
|
+
if (installAws) {
|
|
43
|
+
console.log(chalk.blue('\nAWS CLI Installation Instructions:'));
|
|
44
|
+
console.log(chalk.white('\nFor macOS:'));
|
|
45
|
+
console.log(' brew install awscli');
|
|
46
|
+
console.log('\nFor Linux:');
|
|
47
|
+
console.log(' sudo apt-get install awscli # Debian/Ubuntu');
|
|
48
|
+
console.log(' sudo yum install awscli # Amazon Linux/RHEL/CentOS');
|
|
49
|
+
console.log('\nFor Windows:');
|
|
50
|
+
console.log(' Download and run the installer from: https://aws.amazon.com/cli/');
|
|
51
|
+
console.log('\nAfter installation, configure AWS CLI by running:');
|
|
52
|
+
console.log(' aws configure\n');
|
|
53
|
+
throw new Error('Please install AWS CLI and run this command again.');
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
throw new Error('AWS CLI is required for provisioning. Exiting.');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Check if AWS credentials are configured (account for SSO)
|
|
60
|
+
try {
|
|
61
|
+
// First check if any profile is available - handles both standard and SSO profiles
|
|
62
|
+
const { profileName } = await inquirer.prompt([
|
|
63
|
+
{
|
|
64
|
+
type: 'input',
|
|
65
|
+
name: 'profileName',
|
|
66
|
+
message: 'Enter your AWS profile name (leave empty for default):',
|
|
67
|
+
default: '',
|
|
68
|
+
},
|
|
69
|
+
]);
|
|
70
|
+
// Store the profile for later use
|
|
71
|
+
options.awsProfile = profileName;
|
|
72
|
+
const profileOption = profileName ? `--profile ${profileName}` : '';
|
|
73
|
+
// Prompt for AWS region
|
|
74
|
+
let region;
|
|
75
|
+
try {
|
|
76
|
+
// Try to get the region from the profile
|
|
77
|
+
const getRegionCommand = `aws configure get region ${profileOption}`;
|
|
78
|
+
region = execSync(getRegionCommand, { encoding: 'utf8' }).trim();
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
region = ''; // Region not found in profile
|
|
82
|
+
}
|
|
83
|
+
// If region is not set in the profile, prompt for it
|
|
84
|
+
if (!region) {
|
|
85
|
+
const { selectedRegion } = await inquirer.prompt([
|
|
86
|
+
{
|
|
87
|
+
type: 'list',
|
|
88
|
+
name: 'selectedRegion',
|
|
89
|
+
message: 'Select your AWS region:',
|
|
90
|
+
choices: [
|
|
91
|
+
'us-east-1',
|
|
92
|
+
'us-east-2',
|
|
93
|
+
'us-west-1',
|
|
94
|
+
'us-west-2',
|
|
95
|
+
'eu-west-1',
|
|
96
|
+
'eu-west-2',
|
|
97
|
+
'eu-central-1',
|
|
98
|
+
'ap-northeast-1',
|
|
99
|
+
'ap-northeast-2',
|
|
100
|
+
'ap-southeast-1',
|
|
101
|
+
'ap-southeast-2',
|
|
102
|
+
'sa-east-1',
|
|
103
|
+
],
|
|
104
|
+
default: 'us-east-1',
|
|
105
|
+
},
|
|
106
|
+
]);
|
|
107
|
+
region = selectedRegion;
|
|
108
|
+
}
|
|
109
|
+
console.log(chalk.blue(`Using AWS region: ${region}`));
|
|
110
|
+
options.awsRegion = region;
|
|
111
|
+
try {
|
|
112
|
+
// Try to execute an AWS command with the provided profile and region
|
|
113
|
+
execSync(`aws sts get-caller-identity ${profileOption} --region ${region}`, { stdio: 'ignore' });
|
|
114
|
+
console.log(chalk.green('AWS credentials verified successfully.'));
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
// If SSO authentication is needed
|
|
118
|
+
const { useSso } = await inquirer.prompt([
|
|
119
|
+
{
|
|
120
|
+
type: 'confirm',
|
|
121
|
+
name: 'useSso',
|
|
122
|
+
message: 'Are you using AWS SSO for authentication?',
|
|
123
|
+
default: false,
|
|
124
|
+
},
|
|
125
|
+
]);
|
|
126
|
+
if (useSso) {
|
|
127
|
+
console.log(chalk.blue('\nPlease login to AWS SSO:'));
|
|
128
|
+
try {
|
|
129
|
+
execSync(`aws sso login ${profileOption}`, { stdio: 'inherit' });
|
|
130
|
+
// Verify the login worked
|
|
131
|
+
execSync(`aws sts get-caller-identity ${profileOption} --region ${region}`, { stdio: 'ignore' });
|
|
132
|
+
console.log(chalk.green('AWS SSO login successful.'));
|
|
133
|
+
}
|
|
134
|
+
catch (ssoError) {
|
|
135
|
+
console.log(chalk.red('AWS SSO login failed.'));
|
|
136
|
+
throw new Error('Please set up your AWS SSO profile and try again.');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.log(chalk.yellow('AWS CLI is not configured with valid credentials.'));
|
|
141
|
+
console.log(chalk.blue('\nPlease run the following command to configure AWS CLI:'));
|
|
142
|
+
console.log(' aws configure\n');
|
|
143
|
+
throw new Error('Please configure AWS CLI and run this command again.');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
if (!options.keyName) {
|
|
151
|
+
const answers = await inquirer.prompt([
|
|
152
|
+
{
|
|
153
|
+
type: 'input',
|
|
154
|
+
name: 'keyName',
|
|
155
|
+
message: 'Enter a name for the AWS key pair:',
|
|
156
|
+
default: 'tonk-key',
|
|
157
|
+
validate: input => input.length > 0 || 'Key pair name is required',
|
|
158
|
+
},
|
|
159
|
+
]);
|
|
160
|
+
options.keyName = answers.keyName;
|
|
161
|
+
}
|
|
162
|
+
console.log(chalk.blue(`Creating key pair ${options.keyName}...`));
|
|
163
|
+
const keyPath = path.join(process.cwd(), `${options.keyName}.pem`);
|
|
164
|
+
const profileOption = options.awsProfile
|
|
165
|
+
? `--profile ${options.awsProfile}`
|
|
166
|
+
: '';
|
|
167
|
+
const regionOption = options.awsRegion
|
|
168
|
+
? `--region ${options.awsRegion}`
|
|
169
|
+
: '';
|
|
170
|
+
// Modify the create-key.sh script call to pass region
|
|
171
|
+
execSync(`${path.join(awsScriptsPath, 'create-key.sh')} ${options.keyName} "${profileOption}" "${regionOption}"`, {
|
|
172
|
+
stdio: 'inherit',
|
|
173
|
+
});
|
|
174
|
+
console.log(chalk.blue(`Provisioning EC2 instance with key ${options.keyName}...`));
|
|
175
|
+
// Modify the provision.sh script call to pass region
|
|
176
|
+
const provisionOutput = execSync(`${path.join(awsScriptsPath, 'provision.sh')} ${options.keyName} "${profileOption}" "${regionOption}"`, { encoding: 'utf8' });
|
|
177
|
+
// Extract instance ID from provision output
|
|
178
|
+
const instanceIdMatch = provisionOutput.match(/Instance launched with ID: (i-[a-z0-9]+)/);
|
|
179
|
+
if (!instanceIdMatch) {
|
|
180
|
+
throw new Error('Failed to extract instance ID from provisioning output');
|
|
181
|
+
}
|
|
182
|
+
const instanceId = instanceIdMatch[1];
|
|
183
|
+
console.log(chalk.blue(`Waiting for instance ${instanceId} to initialize...`));
|
|
184
|
+
// Wait for instance to be running and pass status checks
|
|
185
|
+
execSync(`aws ec2 wait instance-status-ok --instance-ids ${instanceId} ${profileOption} ${regionOption}`, {
|
|
186
|
+
stdio: 'inherit',
|
|
187
|
+
});
|
|
188
|
+
// Get the public DNS name
|
|
189
|
+
const publicDns = execSync(`${path.join(awsScriptsPath, 'ec2-dns.sh')} ${instanceId} "${profileOption}" "${regionOption}"`, { encoding: 'utf8' }).trim();
|
|
190
|
+
if (!publicDns) {
|
|
191
|
+
throw new Error('Failed to get public DNS for the instance');
|
|
192
|
+
}
|
|
193
|
+
options.instance = publicDns;
|
|
194
|
+
options.key = keyPath;
|
|
195
|
+
console.log(chalk.green(`EC2 instance provisioned successfully: ${publicDns}`));
|
|
196
|
+
}
|
|
197
|
+
// If options are not provided, prompt for them
|
|
198
|
+
if (!options.instance) {
|
|
199
|
+
const answers = await inquirer.prompt([
|
|
200
|
+
{
|
|
201
|
+
type: 'input',
|
|
202
|
+
name: 'instance',
|
|
203
|
+
message: 'Enter your EC2 instance address:',
|
|
204
|
+
validate: input => input.length > 0 || 'EC2 instance address is required',
|
|
205
|
+
},
|
|
206
|
+
]);
|
|
207
|
+
options.instance = answers.instance;
|
|
208
|
+
}
|
|
209
|
+
if (!options.key) {
|
|
210
|
+
const answers = await inquirer.prompt([
|
|
211
|
+
{
|
|
212
|
+
type: 'input',
|
|
213
|
+
name: 'key',
|
|
214
|
+
message: 'Enter the path to your SSH key file:',
|
|
215
|
+
validate: input => {
|
|
216
|
+
if (!input.length)
|
|
217
|
+
return 'SSH key file path is required';
|
|
218
|
+
if (!fs.existsSync(input))
|
|
219
|
+
return 'SSH key file does not exist';
|
|
220
|
+
return true;
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
]);
|
|
224
|
+
options.key = answers.key;
|
|
225
|
+
}
|
|
226
|
+
// Create config file with EC2 instance URL
|
|
227
|
+
const projectRoot = process.cwd();
|
|
228
|
+
const configFilePath = path.join(projectRoot, 'tonk.config.json');
|
|
229
|
+
const wsProtocol = 'ws';
|
|
230
|
+
const wsUrl = `${wsProtocol}://${options.instance}`;
|
|
231
|
+
const configData = {
|
|
232
|
+
ec2: {
|
|
233
|
+
instance: options.instance,
|
|
234
|
+
user: options.user,
|
|
235
|
+
keyPath: options.key,
|
|
236
|
+
},
|
|
237
|
+
websocket: {
|
|
238
|
+
url: wsUrl,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
fs.writeFileSync(configFilePath, JSON.stringify(configData, null, 2));
|
|
242
|
+
console.log(chalk.green(`Created config file at ${configFilePath}`));
|
|
243
|
+
// Provision the EC2 server with basic requirements
|
|
244
|
+
console.log(chalk.blue(`Setting up EC2 instance ${options.instance}...`));
|
|
245
|
+
// Create a shell script with the commands to run on the EC2 instance
|
|
246
|
+
const setupScript = `
|
|
247
|
+
# Update system packages
|
|
248
|
+
sudo yum update -y
|
|
249
|
+
|
|
250
|
+
# Install Docker if not already installed
|
|
251
|
+
if ! command -v docker &> /dev/null; then
|
|
252
|
+
sudo yum install -y docker
|
|
253
|
+
sudo systemctl enable docker
|
|
254
|
+
sudo systemctl start docker
|
|
255
|
+
sudo usermod -aG docker ${options.user}
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
# Create directory for Tonk app if it doesn't exist
|
|
259
|
+
mkdir -p ~/tonk-app
|
|
260
|
+
`;
|
|
261
|
+
// Create a temporary script and execute it
|
|
262
|
+
const tempScriptPath = path.join(process.cwd(), 'tonk-setup-temp.sh');
|
|
263
|
+
fs.writeFileSync(tempScriptPath, setupScript);
|
|
264
|
+
try {
|
|
265
|
+
// Make the script executable
|
|
266
|
+
fs.chmodSync(tempScriptPath, '755');
|
|
267
|
+
// Copy the script to the EC2 instance and execute it
|
|
268
|
+
execSync(`scp -i "${options.key}" ${tempScriptPath} ${options.user}@${options.instance}:~/tonk-setup.sh && ` +
|
|
269
|
+
`ssh -i "${options.key}" ${options.user}@${options.instance} "chmod +x ~/tonk-setup.sh && ~/tonk-setup.sh"`, { stdio: 'inherit' });
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
// Clean up the temporary script
|
|
273
|
+
if (fs.existsSync(tempScriptPath)) {
|
|
274
|
+
fs.unlinkSync(tempScriptPath);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
console.log(chalk.green(`
|
|
278
|
+
✅ Configuration successful!
|
|
279
|
+
|
|
280
|
+
Your EC2 instance has been provisioned with Docker.
|
|
281
|
+
Config file created at: ${configFilePath}
|
|
282
|
+
WebSocket URL: ${wsUrl}
|
|
283
|
+
|
|
284
|
+
You can now use 'tonk deploy' to deploy your app to this instance.
|
|
285
|
+
`));
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
console.error(chalk.red('Configuration failed:'), error);
|
|
289
|
+
process.exit(1);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAGlC,eAAO,MAAM,aAAa,SA4BtB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import child_process from 'child_process';
|
|
3
|
+
export const createCommand = new Command('create')
|
|
4
|
+
.description('Create a new tonk application or component')
|
|
5
|
+
.argument('<type>', 'Type of creation (app)')
|
|
6
|
+
.action((type) => {
|
|
7
|
+
if (type === 'app') {
|
|
8
|
+
console.log('Creating a new tonk app...');
|
|
9
|
+
// TODO: Implement app creation logic
|
|
10
|
+
let binaryPath = null;
|
|
11
|
+
try {
|
|
12
|
+
binaryPath = child_process
|
|
13
|
+
.execSync('which tonk-create', { encoding: 'utf-8' })
|
|
14
|
+
.toString()
|
|
15
|
+
.trim();
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
if (!binaryPath) {
|
|
19
|
+
// use the command from npm registry
|
|
20
|
+
child_process.execSync('npx @tonk/create', { stdio: 'inherit' });
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
child_process.execSync(binaryPath, { stdio: 'inherit' });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.error('Invalid creation type. Currently only "app" is supported.');
|
|
29
|
+
/* eslint-disable-next-line */
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,aAAa,MAAM,eAAe,CAAC;AAE1C,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,4CAA4C,CAAC;KACzD,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;KAC5C,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;IACvB,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,qCAAqC;QACrC,IAAI,UAAU,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC;YACH,UAAU,GAAG,aAAa;iBACvB,QAAQ,CAAC,mBAAmB,EAAE,EAAC,QAAQ,EAAE,OAAO,EAAC,CAAC;iBAClD,QAAQ,EAAE;iBACV,IAAI,EAAE,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,oCAAoC;gBACpC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAC,KAAK,EAAE,SAAS,EAAC,CAAC,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAC,KAAK,EAAE,SAAS,EAAC,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CACX,2DAA2D,CAC5D,CAAC;QACF,8BAA8B;QAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAOlC,eAAO,MAAM,aAAa,SAoJtB,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { createRequire } from 'module';
|
|
7
|
+
export const deployCommand = new Command('deploy')
|
|
8
|
+
.description('Deploy a Tonk app to EC2')
|
|
9
|
+
.option('-i, --instance <address>', 'EC2 instance address')
|
|
10
|
+
.option('-k, --key <path>', 'Path to SSH key file')
|
|
11
|
+
.option('-u, --user <name>', 'SSH username', 'ec2-user')
|
|
12
|
+
.option('-p, --port <port>', 'Port to run the app on', '8080')
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
const projectRoot = process.cwd();
|
|
15
|
+
const configFilePath = path.join(projectRoot, 'tonk.config.json');
|
|
16
|
+
// Check if config file exists
|
|
17
|
+
if (!fs.existsSync(configFilePath)) {
|
|
18
|
+
console.error(chalk.red(`
|
|
19
|
+
Error: No configuration file found at ${configFilePath}
|
|
20
|
+
|
|
21
|
+
Please run 'tonk config' first to set up your EC2 instance and create a configuration file.
|
|
22
|
+
You can provision a new EC2 instance with 'tonk config --provision' or configure an existing one.
|
|
23
|
+
`));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
// Load settings from config file
|
|
27
|
+
try {
|
|
28
|
+
const configData = JSON.parse(fs.readFileSync(configFilePath, 'utf8'));
|
|
29
|
+
// Use config values as defaults if not provided in command options
|
|
30
|
+
if (!options.instance && configData.ec2 && configData.ec2.instance) {
|
|
31
|
+
options.instance = configData.ec2.instance;
|
|
32
|
+
console.log(chalk.blue(`Using EC2 instance from config: ${options.instance}`));
|
|
33
|
+
}
|
|
34
|
+
if (!options.key && configData.ec2 && configData.ec2.keyPath) {
|
|
35
|
+
options.key = configData.ec2.keyPath;
|
|
36
|
+
console.log(chalk.blue(`Using SSH key from config: ${options.key}`));
|
|
37
|
+
}
|
|
38
|
+
if (!options.user && configData.ec2 && configData.ec2.user) {
|
|
39
|
+
options.user = configData.ec2.user;
|
|
40
|
+
console.log(chalk.blue(`Using SSH user from config: ${options.user}`));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error(chalk.red(`Error: Could not parse config file at ${configFilePath}. Please run 'tonk config' again.`));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
// Verify required options are present after loading from config
|
|
48
|
+
if (!options.instance) {
|
|
49
|
+
console.error(chalk.red('Error: EC2 instance address not found in config file and not provided as an option.'));
|
|
50
|
+
console.error(chalk.yellow("Please run 'tonk config' again."));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
if (!options.key || !fs.existsSync(options.key)) {
|
|
54
|
+
console.error(chalk.red('Error: Valid SSH key file path not found in config file and not provided as an option.'));
|
|
55
|
+
console.error(chalk.yellow("Please run 'tonk config' again."));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
// 1. Build the application
|
|
60
|
+
console.log(chalk.blue('Building application...'));
|
|
61
|
+
execSync('npm run build', { cwd: projectRoot, stdio: 'inherit' });
|
|
62
|
+
// 2. Copy Dockerfile if it doesn't exist
|
|
63
|
+
const dockerfilePath = path.join(projectRoot, 'Dockerfile');
|
|
64
|
+
if (!fs.existsSync(dockerfilePath)) {
|
|
65
|
+
const require = createRequire(import.meta.url);
|
|
66
|
+
const templatePath = path.join(require.resolve('@tonk/server/package.json'), '..', 'templates', 'Dockerfile');
|
|
67
|
+
fs.copyFileSync(templatePath, dockerfilePath);
|
|
68
|
+
console.log(chalk.green('Created Dockerfile from template'));
|
|
69
|
+
}
|
|
70
|
+
// 3. Package the application
|
|
71
|
+
console.log(chalk.blue('Packaging application...'));
|
|
72
|
+
// Create a tarball
|
|
73
|
+
const packOutput = execSync('npm pack', {
|
|
74
|
+
cwd: projectRoot,
|
|
75
|
+
encoding: 'utf8',
|
|
76
|
+
}).trim();
|
|
77
|
+
// npm pack creates a file with a name like: package-name-version.tgz
|
|
78
|
+
const npmPackageFile = path.join(projectRoot, packOutput);
|
|
79
|
+
const tarFileName = 'tonk-app.tgz';
|
|
80
|
+
const tarFilePath = path.join(projectRoot, tarFileName);
|
|
81
|
+
// Rename the npm package to our standard name
|
|
82
|
+
if (fs.existsSync(tarFilePath)) {
|
|
83
|
+
fs.unlinkSync(tarFilePath);
|
|
84
|
+
}
|
|
85
|
+
fs.renameSync(npmPackageFile, tarFilePath);
|
|
86
|
+
// 4. Copy to EC2
|
|
87
|
+
console.log(chalk.blue(`Copying to EC2 instance ${options.instance}...`));
|
|
88
|
+
execSync(`scp -i "${options.key}" "${tarFileName}" ${options.user}@${options.instance}:~/`, { cwd: projectRoot, stdio: 'inherit' });
|
|
89
|
+
// 5. SSH into EC2 and deploy with Docker
|
|
90
|
+
console.log(chalk.blue('Deploying on EC2...'));
|
|
91
|
+
const sshCommand = `ssh -i "${options.key}" ${options.user}@${options.instance} '
|
|
92
|
+
mkdir -p tonk-app &&
|
|
93
|
+
tar -xzf ${tarFileName} -C tonk-app --strip-components=1 &&
|
|
94
|
+
cd tonk-app &&
|
|
95
|
+
docker build -t tonk-app . &&
|
|
96
|
+
docker stop tonk-app-container || true &&
|
|
97
|
+
docker rm tonk-app-container || true &&
|
|
98
|
+
docker run -d --name tonk-app-container -p ${options.port}:8080 -e PORT=8080 tonk-app
|
|
99
|
+
'`;
|
|
100
|
+
execSync(sshCommand, { cwd: projectRoot, stdio: 'inherit' });
|
|
101
|
+
// 6. Clean up
|
|
102
|
+
fs.unlinkSync(tarFilePath);
|
|
103
|
+
console.log(chalk.green(`
|
|
104
|
+
✅ Deployment successful!
|
|
105
|
+
Your app is now running at http://${options.instance}:${options.port}
|
|
106
|
+
`));
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error(chalk.red('Deployment failed:'), error);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAOlC,eAAO,MAAM,UAAU,SAmFnB,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import { createServer } from '@tonk/server';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
export const devCommand = new Command('dev')
|
|
8
|
+
.description('Start a Tonk app in development mode')
|
|
9
|
+
.option('-p, --port <port>', 'Port to run the sync server on', '4080')
|
|
10
|
+
.option('-f, --frontend-port <port>', 'Port to run the frontend dev server on', '3000')
|
|
11
|
+
.option('--no-open', 'Disable auto-opening the browser')
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
const projectRoot = process.cwd();
|
|
14
|
+
const port = parseInt(options.port, 10);
|
|
15
|
+
const frontendPort = parseInt(options.frontendPort, 10);
|
|
16
|
+
// Ensure we have a package.json
|
|
17
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
18
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
19
|
+
console.error(chalk.red('Error: package.json not found. Make sure you are in a Tonk project directory.'));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
console.log(chalk.blue('Starting Tonk development environment...'));
|
|
23
|
+
// Start the sync server
|
|
24
|
+
const server = await createServer({
|
|
25
|
+
port,
|
|
26
|
+
mode: 'development',
|
|
27
|
+
verbose: true,
|
|
28
|
+
distPath: undefined,
|
|
29
|
+
});
|
|
30
|
+
// Start webpack dev server
|
|
31
|
+
const webpackArgs = [
|
|
32
|
+
'webpack',
|
|
33
|
+
'serve',
|
|
34
|
+
'--mode',
|
|
35
|
+
'development',
|
|
36
|
+
'--port',
|
|
37
|
+
frontendPort.toString(),
|
|
38
|
+
];
|
|
39
|
+
// Add --open flag if needed
|
|
40
|
+
if (options.open) {
|
|
41
|
+
webpackArgs.push('--open');
|
|
42
|
+
}
|
|
43
|
+
console.log(chalk.blue(`Starting webpack dev server on port ${frontendPort}...`));
|
|
44
|
+
console.log(chalk.blue(`Sync server running on port ${port}`));
|
|
45
|
+
const webpackProcess = spawn('npx', webpackArgs, {
|
|
46
|
+
cwd: projectRoot,
|
|
47
|
+
stdio: 'inherit',
|
|
48
|
+
shell: true,
|
|
49
|
+
env: {
|
|
50
|
+
...process.env,
|
|
51
|
+
PORT: frontendPort.toString(),
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
// Handle process termination
|
|
55
|
+
const cleanup = () => {
|
|
56
|
+
console.log(chalk.yellow('\nShutting down servers...'));
|
|
57
|
+
webpackProcess.kill();
|
|
58
|
+
server.stop().catch(console.error);
|
|
59
|
+
};
|
|
60
|
+
process.on('SIGINT', cleanup);
|
|
61
|
+
process.on('SIGTERM', cleanup);
|
|
62
|
+
// Handle webpack process exit
|
|
63
|
+
webpackProcess.on('exit', code => {
|
|
64
|
+
if (code !== 0 && code !== null) {
|
|
65
|
+
console.error(chalk.red(`Webpack process exited with code ${code}`));
|
|
66
|
+
}
|
|
67
|
+
server.stop().catch(console.error);
|
|
68
|
+
process.exit(code || 0);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AACpC,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACzC,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,mBAAmB,EAAE,gCAAgC,EAAE,MAAM,CAAC;KACrE,MAAM,CACL,4BAA4B,EAC5B,wCAAwC,EACxC,MAAM,CACP;KACA,MAAM,CAAC,WAAW,EAAE,kCAAkC,CAAC;KACvD,MAAM,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;IACtB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAExD,gCAAgC;IAChC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC/D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CACP,+EAA+E,CAChF,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;IAEpE,wBAAwB;IACxB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QAChC,IAAI;QACJ,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,SAAS;KACpB,CAAC,CAAC;IAEH,2BAA2B;IAC3B,MAAM,WAAW,GAAG;QAClB,SAAS;QACT,OAAO;QACP,QAAQ;QACR,aAAa;QACb,QAAQ;QACR,YAAY,CAAC,QAAQ,EAAE;KACxB,CAAC;IAEF,4BAA4B;IAC5B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,uCAAuC,YAAY,KAAK,CAAC,CACrE,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC,CAAC;IAE/D,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE;QAC/C,GAAG,EAAE,WAAW;QAChB,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,IAAI;QACX,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,IAAI,EAAE,YAAY,CAAC,QAAQ,EAAE;SAC9B;KACF,CAAC,CAAC;IAEH,6BAA6B;IAC7B,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACxD,cAAc,CAAC,IAAI,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE/B,8BAA8B;IAC9B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;QAC/B,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAMlC,eAAO,MAAM,YAAY,SAgErB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { createServer } from '@tonk/server';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
export const serveCommand = new Command('serve')
|
|
7
|
+
.description('Start a Tonk app in production mode')
|
|
8
|
+
.option('-p, --port <port>', 'Port to run the server on', '8080')
|
|
9
|
+
.option('-d, --dist <path>', 'Path to the dist directory', 'dist')
|
|
10
|
+
.action(async (options) => {
|
|
11
|
+
const projectRoot = process.cwd();
|
|
12
|
+
const port = parseInt(options.port, 10);
|
|
13
|
+
const distPath = path.isAbsolute(options.dist)
|
|
14
|
+
? options.dist
|
|
15
|
+
: path.join(projectRoot, options.dist);
|
|
16
|
+
// Check if the dist directory exists
|
|
17
|
+
if (!fs.existsSync(distPath)) {
|
|
18
|
+
console.error(chalk.red(`Error: Dist directory not found at ${distPath}. Make sure you've built the project first.`));
|
|
19
|
+
console.log(chalk.yellow(`Tip: Run 'npm run build' or 'yarn build' before serving.`));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
// Check if dist/index.html exists
|
|
23
|
+
const indexPath = path.join(distPath, 'index.html');
|
|
24
|
+
if (!fs.existsSync(indexPath)) {
|
|
25
|
+
console.error(chalk.red(`Error: index.html not found in ${distPath}. The build output may be incomplete.`));
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
console.log(chalk.blue('Starting Tonk production server...'));
|
|
29
|
+
try {
|
|
30
|
+
// Start the production server
|
|
31
|
+
const server = await createServer({
|
|
32
|
+
port,
|
|
33
|
+
mode: 'production',
|
|
34
|
+
distPath,
|
|
35
|
+
verbose: true,
|
|
36
|
+
});
|
|
37
|
+
// Log success info
|
|
38
|
+
console.log(chalk.green(`Server running at http://localhost:${port}`));
|
|
39
|
+
console.log(chalk.blue('Press Ctrl+C to stop the server'));
|
|
40
|
+
// Handle process termination
|
|
41
|
+
const cleanup = () => {
|
|
42
|
+
console.log(chalk.yellow('\nShutting down server...'));
|
|
43
|
+
server.stop().catch(console.error);
|
|
44
|
+
};
|
|
45
|
+
process.on('SIGINT', cleanup);
|
|
46
|
+
process.on('SIGTERM', cleanup);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error(chalk.red('Failed to start server:'), error);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,YAAY"}
|
package/dist/tonk.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tonk.d.ts","sourceRoot":"","sources":["../src/tonk.ts"],"names":[],"mappings":""}
|
package/dist/tonk.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { createCommand } from './commands/create.js';
|
|
3
|
+
import { devCommand } from './commands/dev.js';
|
|
4
|
+
import { serveCommand } from './commands/serve.js';
|
|
5
|
+
import { deployCommand } from './commands/deploy.js';
|
|
6
|
+
import { configCommand } from './commands/config.js';
|
|
7
|
+
const program = new Command();
|
|
8
|
+
// Main program setup
|
|
9
|
+
program
|
|
10
|
+
.name('tonk')
|
|
11
|
+
.description('The tonk cli helps you to manage your tonk stack and apps.')
|
|
12
|
+
.version('0.1.0')
|
|
13
|
+
.on('--help', () => {
|
|
14
|
+
console.log('\nWork in progress!');
|
|
15
|
+
});
|
|
16
|
+
program.addCommand(createCommand);
|
|
17
|
+
program.addCommand(devCommand);
|
|
18
|
+
program.addCommand(serveCommand);
|
|
19
|
+
program.addCommand(deployCommand);
|
|
20
|
+
program.addCommand(configCommand);
|
|
21
|
+
// Parse arguments
|
|
22
|
+
program.parse();
|
|
23
|
+
// Show help if no arguments provided
|
|
24
|
+
if (!process.argv.slice(2).length) {
|
|
25
|
+
program.outputHelp();
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=tonk.js.map
|
package/dist/tonk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tonk.js","sourceRoot":"","sources":["../src/tonk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,qBAAqB;AACrB,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,OAAO,CAAC;KAChB,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACjB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,kBAAkB;AAClB,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,qCAAqC;AACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tonk/cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "The Tonk stack command line utility",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"tonk": "./bin/tonk.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"typesVersions": {
|
|
13
|
+
"*": {
|
|
14
|
+
"index": [
|
|
15
|
+
"./dist/index.d.ts"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"bin",
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup && chmod +x ./dist/tonk.js",
|
|
25
|
+
"dev": "tsup --watch",
|
|
26
|
+
"clean": "gts clean",
|
|
27
|
+
"lint": "gts lint",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"prepublishOnly": "npm run build",
|
|
30
|
+
"compile": "tsc",
|
|
31
|
+
"fix": "gts fix",
|
|
32
|
+
"prepare": "npm run compile",
|
|
33
|
+
"pretest": "npm run compile",
|
|
34
|
+
"posttest": "npm run lint"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.6.1",
|
|
38
|
+
"@tonk/tinyfoot-mcp-server": "^0.1.2",
|
|
39
|
+
"@tonk/server": "file:../server",
|
|
40
|
+
"chalk": "^5.3.0",
|
|
41
|
+
"commander": "^11.1.0",
|
|
42
|
+
"dotenv": "^16.4.7",
|
|
43
|
+
"execa": "^8.0.1",
|
|
44
|
+
"fastmcp": "^1.20.2",
|
|
45
|
+
"fs-extra": "^11.2.0",
|
|
46
|
+
"gradient-string": "^2.0.2",
|
|
47
|
+
"inquirer": "^9.2.12",
|
|
48
|
+
"listr2": "^8.2.5",
|
|
49
|
+
"open": "^10.1.0",
|
|
50
|
+
"ora": "^7.0.1",
|
|
51
|
+
"zod": "^3.24.2"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/fs-extra": "^11.0.4",
|
|
55
|
+
"@types/gradient-string": "^1.1.5",
|
|
56
|
+
"@types/inquirer": "^9.0.7",
|
|
57
|
+
"@types/node": "^22.7.5",
|
|
58
|
+
"gts": "^6.0.2",
|
|
59
|
+
"rimraf": "^5.0.5",
|
|
60
|
+
"tsup": "^8.0.1",
|
|
61
|
+
"typescript": "^5.6.3",
|
|
62
|
+
"vitest": "^1.0.4"
|
|
63
|
+
},
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=18"
|
|
66
|
+
},
|
|
67
|
+
"keywords": [
|
|
68
|
+
"cli",
|
|
69
|
+
"ai",
|
|
70
|
+
"crdt",
|
|
71
|
+
"local-first"
|
|
72
|
+
],
|
|
73
|
+
"author": "tonk-labs",
|
|
74
|
+
"license": "MIT",
|
|
75
|
+
"repository": {
|
|
76
|
+
"type": "git",
|
|
77
|
+
"url": "https://github.com/tonk-labs/ipn.git",
|
|
78
|
+
"directory": "packages/cli"
|
|
79
|
+
},
|
|
80
|
+
"bugs": {
|
|
81
|
+
"url": "https://github.com/tonk-labs/ipn/issues"
|
|
82
|
+
},
|
|
83
|
+
"homepage": "https://github.com/tonk-labs/ipn#readme"
|
|
84
|
+
}
|