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 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. It consists of a macOS menu bar app and a TypeScript backend daemon. The CLI allows you to configure and run the backend daemon, onboard users, and manage your OpenAI API key with ease. Once set up, you can select any text on your Mac and trigger rewrite commands directly from your desktop.
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: { ...process.env, ...configVars, OMNIKEY_PORT: String(port) },
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);
@@ -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",
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: { ...process.env, ...configVars, OMNIKEY_PORT: String(port) },
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);
@@ -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
+ }