@mihari/logger-tool 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/LICENSE +21 -0
- package/README.md +49 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +197 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
- package/src/index.ts +190 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mihari Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# @mihari/logger-tool
|
|
2
|
+
|
|
3
|
+
CLI tool for the mihari log collection library.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @mihari/logger-tool
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
Set the following environment variables:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
export MIHARI_TOKEN="your-api-token"
|
|
17
|
+
export MIHARI_ENDPOINT="https://logs.example.com"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Send a single message
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
mihari send "Deployment completed" --level info
|
|
26
|
+
mihari send "Error detected" --level error
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Stream logs from stdin
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Pipe from a file
|
|
33
|
+
tail -f /var/log/app.log | mihari tail
|
|
34
|
+
|
|
35
|
+
# Pipe from another command
|
|
36
|
+
my-app 2>&1 | mihari tail --level warn
|
|
37
|
+
|
|
38
|
+
# Pipe from echo
|
|
39
|
+
echo "Quick log message" | mihari tail
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Options
|
|
43
|
+
|
|
44
|
+
- `--level <level>` - Log level: debug, info, warn, error, fatal (default: info)
|
|
45
|
+
- `--help` - Show help message
|
|
46
|
+
|
|
47
|
+
## License
|
|
48
|
+
|
|
49
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -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,197 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const readline = __importStar(require("readline"));
|
|
38
|
+
const logger_core_1 = require("@mihari/logger-core");
|
|
39
|
+
const logger_types_1 = require("@mihari/logger-types");
|
|
40
|
+
const USAGE = `
|
|
41
|
+
mihari - CLI tool for mihari log collection
|
|
42
|
+
|
|
43
|
+
Usage:
|
|
44
|
+
mihari send <message> [--level <level>] Send a single log message
|
|
45
|
+
mihari tail Read stdin line by line and send each as a log
|
|
46
|
+
|
|
47
|
+
Environment variables:
|
|
48
|
+
MIHARI_TOKEN Authentication token (required)
|
|
49
|
+
MIHARI_ENDPOINT API endpoint URL (required)
|
|
50
|
+
|
|
51
|
+
Options:
|
|
52
|
+
--level <level> Log level: debug, info, warn, error, fatal (default: info)
|
|
53
|
+
--help Show this help message
|
|
54
|
+
|
|
55
|
+
Examples:
|
|
56
|
+
mihari send "Deployment completed" --level info
|
|
57
|
+
echo "Error occurred" | mihari tail
|
|
58
|
+
tail -f /var/log/app.log | mihari tail --level warn
|
|
59
|
+
`.trim();
|
|
60
|
+
function getConfig() {
|
|
61
|
+
const token = process.env.MIHARI_TOKEN;
|
|
62
|
+
const endpoint = process.env.MIHARI_ENDPOINT;
|
|
63
|
+
if (!token) {
|
|
64
|
+
console.error("Error: MIHARI_TOKEN environment variable is required");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
if (!endpoint) {
|
|
68
|
+
console.error("Error: MIHARI_ENDPOINT environment variable is required");
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
return { token, endpoint };
|
|
72
|
+
}
|
|
73
|
+
function parseLevel(levelStr) {
|
|
74
|
+
const normalized = levelStr.toLowerCase();
|
|
75
|
+
const levelMap = {
|
|
76
|
+
debug: logger_types_1.LogLevel.Debug,
|
|
77
|
+
info: logger_types_1.LogLevel.Info,
|
|
78
|
+
warn: logger_types_1.LogLevel.Warn,
|
|
79
|
+
error: logger_types_1.LogLevel.Error,
|
|
80
|
+
fatal: logger_types_1.LogLevel.Fatal,
|
|
81
|
+
};
|
|
82
|
+
const level = levelMap[normalized];
|
|
83
|
+
if (!level) {
|
|
84
|
+
console.error(`Error: Invalid log level "${levelStr}". Valid levels: debug, info, warn, error, fatal`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
return level;
|
|
88
|
+
}
|
|
89
|
+
async function sendCommand(args) {
|
|
90
|
+
const config = getConfig();
|
|
91
|
+
const client = new logger_core_1.MihariClient(config);
|
|
92
|
+
let message = "";
|
|
93
|
+
let level = logger_types_1.LogLevel.Info;
|
|
94
|
+
const mutableArgs = [...args];
|
|
95
|
+
while (mutableArgs.length > 0) {
|
|
96
|
+
const arg = mutableArgs.shift();
|
|
97
|
+
if (arg === "--level" && mutableArgs.length > 0) {
|
|
98
|
+
level = parseLevel(mutableArgs.shift());
|
|
99
|
+
}
|
|
100
|
+
else if (!message) {
|
|
101
|
+
message = arg;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!message) {
|
|
105
|
+
console.error("Error: Message is required for send command");
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
switch (level) {
|
|
109
|
+
case logger_types_1.LogLevel.Debug:
|
|
110
|
+
client.debug(message);
|
|
111
|
+
break;
|
|
112
|
+
case logger_types_1.LogLevel.Info:
|
|
113
|
+
client.info(message);
|
|
114
|
+
break;
|
|
115
|
+
case logger_types_1.LogLevel.Warn:
|
|
116
|
+
client.warn(message);
|
|
117
|
+
break;
|
|
118
|
+
case logger_types_1.LogLevel.Error:
|
|
119
|
+
client.error(message);
|
|
120
|
+
break;
|
|
121
|
+
case logger_types_1.LogLevel.Fatal:
|
|
122
|
+
client.fatal(message);
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
await client.flush();
|
|
126
|
+
console.log(`Sent: [${level}] ${message}`);
|
|
127
|
+
}
|
|
128
|
+
async function tailCommand(args) {
|
|
129
|
+
const config = getConfig();
|
|
130
|
+
const client = new logger_core_1.MihariClient(config);
|
|
131
|
+
let level = logger_types_1.LogLevel.Info;
|
|
132
|
+
const mutableArgs = [...args];
|
|
133
|
+
while (mutableArgs.length > 0) {
|
|
134
|
+
const arg = mutableArgs.shift();
|
|
135
|
+
if (arg === "--level" && mutableArgs.length > 0) {
|
|
136
|
+
level = parseLevel(mutableArgs.shift());
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const rl = readline.createInterface({
|
|
140
|
+
input: process.stdin,
|
|
141
|
+
terminal: false,
|
|
142
|
+
});
|
|
143
|
+
let lineCount = 0;
|
|
144
|
+
rl.on("line", (line) => {
|
|
145
|
+
const trimmed = line.trim();
|
|
146
|
+
if (!trimmed)
|
|
147
|
+
return;
|
|
148
|
+
switch (level) {
|
|
149
|
+
case logger_types_1.LogLevel.Debug:
|
|
150
|
+
client.debug(trimmed);
|
|
151
|
+
break;
|
|
152
|
+
case logger_types_1.LogLevel.Info:
|
|
153
|
+
client.info(trimmed);
|
|
154
|
+
break;
|
|
155
|
+
case logger_types_1.LogLevel.Warn:
|
|
156
|
+
client.warn(trimmed);
|
|
157
|
+
break;
|
|
158
|
+
case logger_types_1.LogLevel.Error:
|
|
159
|
+
client.error(trimmed);
|
|
160
|
+
break;
|
|
161
|
+
case logger_types_1.LogLevel.Fatal:
|
|
162
|
+
client.fatal(trimmed);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
lineCount++;
|
|
166
|
+
});
|
|
167
|
+
rl.on("close", async () => {
|
|
168
|
+
await client.shutdown();
|
|
169
|
+
console.log(`Sent ${lineCount} log entries`);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
async function main() {
|
|
173
|
+
const args = process.argv.slice(2);
|
|
174
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
175
|
+
console.log(USAGE);
|
|
176
|
+
process.exit(0);
|
|
177
|
+
}
|
|
178
|
+
const command = args[0];
|
|
179
|
+
const commandArgs = args.slice(1);
|
|
180
|
+
switch (command) {
|
|
181
|
+
case "send":
|
|
182
|
+
await sendCommand(commandArgs);
|
|
183
|
+
break;
|
|
184
|
+
case "tail":
|
|
185
|
+
await tailCommand(commandArgs);
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
console.error(`Unknown command: ${command}`);
|
|
189
|
+
console.log(USAGE);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
main().catch((err) => {
|
|
194
|
+
console.error("Fatal error:", err);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
});
|
|
197
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mihari/logger-tool",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI tool for mihari log collection",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"types": "src/index.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mihari": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"clean": "rm -rf dist",
|
|
16
|
+
"test": "cd ../.. && npx vitest run --config vitest.config.ts packages/tool"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"vitest": "^3.0.0"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@mihari/logger-core": "^0.1.0",
|
|
23
|
+
"@mihari/logger-types": "^0.1.0"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/mihari/mihari-js",
|
|
32
|
+
"directory": "packages/tool"
|
|
33
|
+
},
|
|
34
|
+
"gitHead": "dc10a3217caa819965eb3a1e2ff3901a16e510aa"
|
|
35
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import * as readline from "readline";
|
|
4
|
+
import { MihariClient } from "@mihari/logger-core";
|
|
5
|
+
import { LogLevel, MihariConfig } from "@mihari/logger-types";
|
|
6
|
+
|
|
7
|
+
const USAGE = `
|
|
8
|
+
mihari - CLI tool for mihari log collection
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
mihari send <message> [--level <level>] Send a single log message
|
|
12
|
+
mihari tail Read stdin line by line and send each as a log
|
|
13
|
+
|
|
14
|
+
Environment variables:
|
|
15
|
+
MIHARI_TOKEN Authentication token (required)
|
|
16
|
+
MIHARI_ENDPOINT API endpoint URL (required)
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
--level <level> Log level: debug, info, warn, error, fatal (default: info)
|
|
20
|
+
--help Show this help message
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
mihari send "Deployment completed" --level info
|
|
24
|
+
echo "Error occurred" | mihari tail
|
|
25
|
+
tail -f /var/log/app.log | mihari tail --level warn
|
|
26
|
+
`.trim();
|
|
27
|
+
|
|
28
|
+
function getConfig(): MihariConfig {
|
|
29
|
+
const token = process.env.MIHARI_TOKEN;
|
|
30
|
+
const endpoint = process.env.MIHARI_ENDPOINT;
|
|
31
|
+
|
|
32
|
+
if (!token) {
|
|
33
|
+
console.error("Error: MIHARI_TOKEN environment variable is required");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!endpoint) {
|
|
38
|
+
console.error("Error: MIHARI_ENDPOINT environment variable is required");
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return { token, endpoint };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function parseLevel(levelStr: string): LogLevel {
|
|
46
|
+
const normalized = levelStr.toLowerCase();
|
|
47
|
+
const levelMap: Record<string, LogLevel> = {
|
|
48
|
+
debug: LogLevel.Debug,
|
|
49
|
+
info: LogLevel.Info,
|
|
50
|
+
warn: LogLevel.Warn,
|
|
51
|
+
error: LogLevel.Error,
|
|
52
|
+
fatal: LogLevel.Fatal,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const level = levelMap[normalized];
|
|
56
|
+
if (!level) {
|
|
57
|
+
console.error(
|
|
58
|
+
`Error: Invalid log level "${levelStr}". Valid levels: debug, info, warn, error, fatal`
|
|
59
|
+
);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return level;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function sendCommand(args: readonly string[]): Promise<void> {
|
|
67
|
+
const config = getConfig();
|
|
68
|
+
const client = new MihariClient(config);
|
|
69
|
+
|
|
70
|
+
let message = "";
|
|
71
|
+
let level = LogLevel.Info;
|
|
72
|
+
|
|
73
|
+
const mutableArgs = [...args];
|
|
74
|
+
while (mutableArgs.length > 0) {
|
|
75
|
+
const arg = mutableArgs.shift()!;
|
|
76
|
+
if (arg === "--level" && mutableArgs.length > 0) {
|
|
77
|
+
level = parseLevel(mutableArgs.shift()!);
|
|
78
|
+
} else if (!message) {
|
|
79
|
+
message = arg;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!message) {
|
|
84
|
+
console.error("Error: Message is required for send command");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
switch (level) {
|
|
89
|
+
case LogLevel.Debug:
|
|
90
|
+
client.debug(message);
|
|
91
|
+
break;
|
|
92
|
+
case LogLevel.Info:
|
|
93
|
+
client.info(message);
|
|
94
|
+
break;
|
|
95
|
+
case LogLevel.Warn:
|
|
96
|
+
client.warn(message);
|
|
97
|
+
break;
|
|
98
|
+
case LogLevel.Error:
|
|
99
|
+
client.error(message);
|
|
100
|
+
break;
|
|
101
|
+
case LogLevel.Fatal:
|
|
102
|
+
client.fatal(message);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
await client.flush();
|
|
107
|
+
console.log(`Sent: [${level}] ${message}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function tailCommand(args: readonly string[]): Promise<void> {
|
|
111
|
+
const config = getConfig();
|
|
112
|
+
const client = new MihariClient(config);
|
|
113
|
+
|
|
114
|
+
let level = LogLevel.Info;
|
|
115
|
+
|
|
116
|
+
const mutableArgs = [...args];
|
|
117
|
+
while (mutableArgs.length > 0) {
|
|
118
|
+
const arg = mutableArgs.shift()!;
|
|
119
|
+
if (arg === "--level" && mutableArgs.length > 0) {
|
|
120
|
+
level = parseLevel(mutableArgs.shift()!);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const rl = readline.createInterface({
|
|
125
|
+
input: process.stdin,
|
|
126
|
+
terminal: false,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
let lineCount = 0;
|
|
130
|
+
|
|
131
|
+
rl.on("line", (line: string) => {
|
|
132
|
+
const trimmed = line.trim();
|
|
133
|
+
if (!trimmed) return;
|
|
134
|
+
|
|
135
|
+
switch (level) {
|
|
136
|
+
case LogLevel.Debug:
|
|
137
|
+
client.debug(trimmed);
|
|
138
|
+
break;
|
|
139
|
+
case LogLevel.Info:
|
|
140
|
+
client.info(trimmed);
|
|
141
|
+
break;
|
|
142
|
+
case LogLevel.Warn:
|
|
143
|
+
client.warn(trimmed);
|
|
144
|
+
break;
|
|
145
|
+
case LogLevel.Error:
|
|
146
|
+
client.error(trimmed);
|
|
147
|
+
break;
|
|
148
|
+
case LogLevel.Fatal:
|
|
149
|
+
client.fatal(trimmed);
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
lineCount++;
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
rl.on("close", async () => {
|
|
157
|
+
await client.shutdown();
|
|
158
|
+
console.log(`Sent ${lineCount} log entries`);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function main(): Promise<void> {
|
|
163
|
+
const args = process.argv.slice(2);
|
|
164
|
+
|
|
165
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
166
|
+
console.log(USAGE);
|
|
167
|
+
process.exit(0);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const command = args[0];
|
|
171
|
+
const commandArgs = args.slice(1);
|
|
172
|
+
|
|
173
|
+
switch (command) {
|
|
174
|
+
case "send":
|
|
175
|
+
await sendCommand(commandArgs);
|
|
176
|
+
break;
|
|
177
|
+
case "tail":
|
|
178
|
+
await tailCommand(commandArgs);
|
|
179
|
+
break;
|
|
180
|
+
default:
|
|
181
|
+
console.error(`Unknown command: ${command}`);
|
|
182
|
+
console.log(USAGE);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
main().catch((err) => {
|
|
188
|
+
console.error("Fatal error:", err);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
});
|