omnikey-cli 1.0.7 → 1.0.9
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 +7 -1
- package/dist/daemon.js +14 -2
- package/dist/index.js +16 -0
- package/dist/showLogs.js +48 -0
- package/dist/status.js +39 -0
- package/package.json +1 -1
- package/src/daemon.ts +13 -2
- package/src/index.ts +18 -0
- package/src/showLogs.ts +49 -0
- package/src/status.ts +31 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A command-line tool for onboarding users to the Omnikey open-source app and conf
|
|
|
4
4
|
|
|
5
5
|
## About OmnikeyAI (macOS)
|
|
6
6
|
|
|
7
|
-
OmnikeyAI is a productivity tool for macOS that helps you quickly rewrite selected text using OpenAI.
|
|
7
|
+
OmnikeyAI is a productivity tool for macOS that helps you quickly rewrite selected text using OpenAI. The CLI allows you to configure and run the backend daemon on your local macOS and manage your OpenAI API key with ease. Once set up, you can select any text on your Mac in any app and trigger rewrite commands directly from your desktop.
|
|
8
8
|
|
|
9
9
|
- For more details about the app and its features, see the [main README](https://github.com/GurinderRawala/OmniKey-AI).
|
|
10
10
|
- Download the latest macOS app here: [Download OmniKeyAI for macOS](https://omnikeyai-saas-fmytqc3dra-uc.a.run.app/macos/download)
|
|
@@ -35,6 +35,12 @@ omnikey kill-daemon --port 7071
|
|
|
35
35
|
|
|
36
36
|
# Remove the config directory and SQLite database (and launchd agent)
|
|
37
37
|
omnikey remove-config
|
|
38
|
+
|
|
39
|
+
# check daemon status if it is running
|
|
40
|
+
omnikey status
|
|
41
|
+
|
|
42
|
+
# check daemon logs
|
|
43
|
+
omnikey logs --lines 100
|
|
38
44
|
```
|
|
39
45
|
|
|
40
46
|
## Development
|
package/dist/daemon.js
CHANGED
|
@@ -91,10 +91,22 @@ function startDaemon(port = 7071) {
|
|
|
91
91
|
console.error('Failed to create or load launch agent:', e);
|
|
92
92
|
}
|
|
93
93
|
// Also start the backend immediately for current session
|
|
94
|
+
const logPath = path_1.default.join(configDir, 'daemon.log');
|
|
95
|
+
const errorLogPath = path_1.default.join(configDir, 'daemon-error.log');
|
|
96
|
+
// Clean (truncate) log files before starting new session
|
|
97
|
+
try {
|
|
98
|
+
fs_1.default.writeFileSync(logPath, '');
|
|
99
|
+
fs_1.default.writeFileSync(errorLogPath, '');
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
// Ignore errors if files don't exist yet
|
|
103
|
+
}
|
|
104
|
+
const out = fs_1.default.openSync(logPath, 'a');
|
|
105
|
+
const err = fs_1.default.openSync(errorLogPath, 'a');
|
|
94
106
|
const child = (0, child_process_1.spawn)('node', [backendPath], {
|
|
95
|
-
env: { ...
|
|
107
|
+
env: { ...configVars, OMNIKEY_PORT: String(port) },
|
|
96
108
|
detached: true,
|
|
97
|
-
stdio: 'ignore',
|
|
109
|
+
stdio: ['ignore', out, err],
|
|
98
110
|
});
|
|
99
111
|
child.unref();
|
|
100
112
|
console.log(`Omnikey API backend started as a daemon on port ${port}. PID: ${child.pid}`);
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ const onboard_1 = require("./onboard");
|
|
|
6
6
|
const daemon_1 = require("./daemon");
|
|
7
7
|
const killDaemon_1 = require("./killDaemon");
|
|
8
8
|
const removeConfig_1 = require("./removeConfig");
|
|
9
|
+
const status_1 = require("./status");
|
|
10
|
+
const showLogs_1 = require("./showLogs");
|
|
9
11
|
const program = new commander_1.Command();
|
|
10
12
|
program
|
|
11
13
|
.name('omnikey')
|
|
@@ -40,4 +42,18 @@ program
|
|
|
40
42
|
.action(() => {
|
|
41
43
|
(0, removeConfig_1.removeConfigAndDb)();
|
|
42
44
|
});
|
|
45
|
+
// Add status command
|
|
46
|
+
program
|
|
47
|
+
.command('status')
|
|
48
|
+
.description('Show status of Omnikey daemon (lsof on configured port)')
|
|
49
|
+
.action(status_1.statusCmd);
|
|
50
|
+
// Add logs command
|
|
51
|
+
program
|
|
52
|
+
.command('logs')
|
|
53
|
+
.description('Show logs of the running Omnikey daemon')
|
|
54
|
+
.option('--lines <lines>', 'Number of log lines to show', '50')
|
|
55
|
+
.action((options) => {
|
|
56
|
+
const lines = Number(options.lines) || 50;
|
|
57
|
+
(0, showLogs_1.showLogs)(lines);
|
|
58
|
+
});
|
|
43
59
|
program.parseAsync(process.argv);
|
package/dist/showLogs.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.showLogs = showLogs;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
/**
|
|
10
|
+
* Show the logs of the running Omnikey daemon by printing the contents of the daemon log file.
|
|
11
|
+
* Prints the last N lines (default 50) for convenience.
|
|
12
|
+
*/
|
|
13
|
+
function showLogs(lines = 50) {
|
|
14
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '.';
|
|
15
|
+
const configDir = path_1.default.join(homeDir, '.omnikey');
|
|
16
|
+
const logPath = path_1.default.join(configDir, 'daemon.log');
|
|
17
|
+
const errorLogPath = path_1.default.join(configDir, 'daemon-error.log');
|
|
18
|
+
let logLines = [];
|
|
19
|
+
let errorLines = [];
|
|
20
|
+
if (fs_1.default.existsSync(logPath)) {
|
|
21
|
+
const logContent = fs_1.default.readFileSync(logPath, 'utf-8');
|
|
22
|
+
logLines = logContent.split('\n');
|
|
23
|
+
}
|
|
24
|
+
if (fs_1.default.existsSync(errorLogPath)) {
|
|
25
|
+
const errorContent = fs_1.default.readFileSync(errorLogPath, 'utf-8');
|
|
26
|
+
errorLines = errorContent.split('\n');
|
|
27
|
+
}
|
|
28
|
+
if (logLines.length === 0 && errorLines.length === 0) {
|
|
29
|
+
console.log('No daemon.log or daemon-error.log file found.');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const left = logLines.slice(-lines);
|
|
33
|
+
const right = errorLines.slice(-lines);
|
|
34
|
+
// Calculate column widths
|
|
35
|
+
const leftWidth = Math.max(40, ...left.map((l) => l.length));
|
|
36
|
+
const rightWidth = Math.max(40, ...right.map((l) => l.length));
|
|
37
|
+
// Print header
|
|
38
|
+
const leftHeader = 'Other Logs'.padEnd(leftWidth);
|
|
39
|
+
const rightHeader = 'Errors'.padEnd(rightWidth);
|
|
40
|
+
console.log(`${leftHeader} | ${rightHeader}`);
|
|
41
|
+
console.log('-'.repeat(leftWidth) + '-+-' + '-'.repeat(rightWidth));
|
|
42
|
+
// Print lines side by side
|
|
43
|
+
for (let i = 0; i < lines; i++) {
|
|
44
|
+
const l = left[i] !== undefined ? left[i] : '';
|
|
45
|
+
const r = right[i] !== undefined ? right[i] : '';
|
|
46
|
+
console.log(l.padEnd(leftWidth) + ' | ' + r.padEnd(rightWidth));
|
|
47
|
+
}
|
|
48
|
+
}
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.statusCmd = statusCmd;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
function statusCmd() {
|
|
11
|
+
// Read port from ~/.omnikey/config.json
|
|
12
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '.';
|
|
13
|
+
const configDir = path_1.default.join(homeDir, '.omnikey');
|
|
14
|
+
const configPath = path_1.default.join(configDir, 'config.json');
|
|
15
|
+
let port = 7071;
|
|
16
|
+
if (fs_1.default.existsSync(configPath)) {
|
|
17
|
+
try {
|
|
18
|
+
const configVars = JSON.parse(fs_1.default.readFileSync(configPath, 'utf-8'));
|
|
19
|
+
if (configVars.OMNIKEY_PORT) {
|
|
20
|
+
port = Number(configVars.OMNIKEY_PORT);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
console.error('Failed to read config.json:', e);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const output = (0, child_process_1.execSync)(`lsof -i :${port}`).toString();
|
|
29
|
+
if (output.trim()) {
|
|
30
|
+
console.log(`Processes using port ${port}:\n${output}`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.log(`No process is using port ${port}.`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
console.log(`No process is using port ${port}.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"registry": "https://registry.npmjs.org/"
|
|
6
6
|
},
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.9",
|
|
8
8
|
"description": "CLI for onboarding users to Omnikey AI and configuring OPENAI_API_KEY. Use Yarn for install/build.",
|
|
9
9
|
"engines": {
|
|
10
10
|
"node": ">=14.0.0",
|
package/src/daemon.ts
CHANGED
|
@@ -87,10 +87,21 @@ export function startDaemon(port: number = 7071) {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// Also start the backend immediately for current session
|
|
90
|
+
const logPath = path.join(configDir, 'daemon.log');
|
|
91
|
+
const errorLogPath = path.join(configDir, 'daemon-error.log');
|
|
92
|
+
// Clean (truncate) log files before starting new session
|
|
93
|
+
try {
|
|
94
|
+
fs.writeFileSync(logPath, '');
|
|
95
|
+
fs.writeFileSync(errorLogPath, '');
|
|
96
|
+
} catch (e) {
|
|
97
|
+
// Ignore errors if files don't exist yet
|
|
98
|
+
}
|
|
99
|
+
const out = fs.openSync(logPath, 'a');
|
|
100
|
+
const err = fs.openSync(errorLogPath, 'a');
|
|
90
101
|
const child = spawn('node', [backendPath], {
|
|
91
|
-
env: { ...
|
|
102
|
+
env: { ...configVars, OMNIKEY_PORT: String(port) },
|
|
92
103
|
detached: true,
|
|
93
|
-
stdio: 'ignore',
|
|
104
|
+
stdio: ['ignore', out, err],
|
|
94
105
|
});
|
|
95
106
|
child.unref();
|
|
96
107
|
console.log(`Omnikey API backend started as a daemon on port ${port}. PID: ${child.pid}`);
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { onboard } from './onboard';
|
|
|
5
5
|
import { startDaemon } from './daemon';
|
|
6
6
|
import { killDaemon } from './killDaemon';
|
|
7
7
|
import { removeConfigAndDb } from './removeConfig';
|
|
8
|
+
import { statusCmd } from './status';
|
|
9
|
+
import { showLogs } from './showLogs';
|
|
8
10
|
|
|
9
11
|
const program = new Command();
|
|
10
12
|
|
|
@@ -48,4 +50,20 @@ program
|
|
|
48
50
|
removeConfigAndDb();
|
|
49
51
|
});
|
|
50
52
|
|
|
53
|
+
// Add status command
|
|
54
|
+
program
|
|
55
|
+
.command('status')
|
|
56
|
+
.description('Show status of Omnikey daemon (lsof on configured port)')
|
|
57
|
+
.action(statusCmd);
|
|
58
|
+
|
|
59
|
+
// Add logs command
|
|
60
|
+
program
|
|
61
|
+
.command('logs')
|
|
62
|
+
.description('Show logs of the running Omnikey daemon')
|
|
63
|
+
.option('--lines <lines>', 'Number of log lines to show', '50')
|
|
64
|
+
.action((options) => {
|
|
65
|
+
const lines = Number(options.lines) || 50;
|
|
66
|
+
showLogs(lines);
|
|
67
|
+
});
|
|
68
|
+
|
|
51
69
|
program.parseAsync(process.argv);
|
package/src/showLogs.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Show the logs of the running Omnikey daemon by printing the contents of the daemon log file.
|
|
6
|
+
* Prints the last N lines (default 50) for convenience.
|
|
7
|
+
*/
|
|
8
|
+
export function showLogs(lines: number = 50) {
|
|
9
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '.';
|
|
10
|
+
const configDir = path.join(homeDir, '.omnikey');
|
|
11
|
+
const logPath = path.join(configDir, 'daemon.log');
|
|
12
|
+
const errorLogPath = path.join(configDir, 'daemon-error.log');
|
|
13
|
+
|
|
14
|
+
let logLines: string[] = [];
|
|
15
|
+
let errorLines: string[] = [];
|
|
16
|
+
if (fs.existsSync(logPath)) {
|
|
17
|
+
const logContent = fs.readFileSync(logPath, 'utf-8');
|
|
18
|
+
logLines = logContent.split('\n');
|
|
19
|
+
}
|
|
20
|
+
if (fs.existsSync(errorLogPath)) {
|
|
21
|
+
const errorContent = fs.readFileSync(errorLogPath, 'utf-8');
|
|
22
|
+
errorLines = errorContent.split('\n');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (logLines.length === 0 && errorLines.length === 0) {
|
|
26
|
+
console.log('No daemon.log or daemon-error.log file found.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const left = logLines.slice(-lines);
|
|
31
|
+
const right = errorLines.slice(-lines);
|
|
32
|
+
|
|
33
|
+
// Calculate column widths
|
|
34
|
+
const leftWidth = Math.max(40, ...left.map((l) => l.length));
|
|
35
|
+
const rightWidth = Math.max(40, ...right.map((l) => l.length));
|
|
36
|
+
|
|
37
|
+
// Print header
|
|
38
|
+
const leftHeader = 'Other Logs'.padEnd(leftWidth);
|
|
39
|
+
const rightHeader = 'Errors'.padEnd(rightWidth);
|
|
40
|
+
console.log(`${leftHeader} | ${rightHeader}`);
|
|
41
|
+
console.log('-'.repeat(leftWidth) + '-+-' + '-'.repeat(rightWidth));
|
|
42
|
+
|
|
43
|
+
// Print lines side by side
|
|
44
|
+
for (let i = 0; i < lines; i++) {
|
|
45
|
+
const l = left[i] !== undefined ? left[i] : '';
|
|
46
|
+
const r = right[i] !== undefined ? right[i] : '';
|
|
47
|
+
console.log(l.padEnd(leftWidth) + ' | ' + r.padEnd(rightWidth));
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/status.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
|
|
5
|
+
export function statusCmd() {
|
|
6
|
+
// Read port from ~/.omnikey/config.json
|
|
7
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '.';
|
|
8
|
+
const configDir = path.join(homeDir, '.omnikey');
|
|
9
|
+
const configPath = path.join(configDir, 'config.json');
|
|
10
|
+
let port = 7071;
|
|
11
|
+
if (fs.existsSync(configPath)) {
|
|
12
|
+
try {
|
|
13
|
+
const configVars = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
14
|
+
if (configVars.OMNIKEY_PORT) {
|
|
15
|
+
port = Number(configVars.OMNIKEY_PORT);
|
|
16
|
+
}
|
|
17
|
+
} catch (e) {
|
|
18
|
+
console.error('Failed to read config.json:', e);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const output = execSync(`lsof -i :${port}`).toString();
|
|
23
|
+
if (output.trim()) {
|
|
24
|
+
console.log(`Processes using port ${port}:\n${output}`);
|
|
25
|
+
} else {
|
|
26
|
+
console.log(`No process is using port ${port}.`);
|
|
27
|
+
}
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.log(`No process is using port ${port}.`);
|
|
30
|
+
}
|
|
31
|
+
}
|