@observeone/cli 1.0.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.
Files changed (84) hide show
  1. package/README.md +214 -0
  2. package/dist/README.md +214 -0
  3. package/dist/commands/ai-check.d.ts +9 -0
  4. package/dist/commands/ai-check.d.ts.map +1 -0
  5. package/dist/commands/ai-check.js +492 -0
  6. package/dist/commands/ai-check.js.map +1 -0
  7. package/dist/commands/apply.d.ts +6 -0
  8. package/dist/commands/apply.d.ts.map +1 -0
  9. package/dist/commands/apply.js +290 -0
  10. package/dist/commands/apply.js.map +1 -0
  11. package/dist/commands/check.d.ts +9 -0
  12. package/dist/commands/check.d.ts.map +1 -0
  13. package/dist/commands/check.js +267 -0
  14. package/dist/commands/check.js.map +1 -0
  15. package/dist/commands/export.d.ts +6 -0
  16. package/dist/commands/export.d.ts.map +1 -0
  17. package/dist/commands/export.js +95 -0
  18. package/dist/commands/export.js.map +1 -0
  19. package/dist/commands/heartbeat.d.ts +9 -0
  20. package/dist/commands/heartbeat.d.ts.map +1 -0
  21. package/dist/commands/heartbeat.js +264 -0
  22. package/dist/commands/heartbeat.js.map +1 -0
  23. package/dist/commands/list.d.ts +9 -0
  24. package/dist/commands/list.d.ts.map +1 -0
  25. package/dist/commands/list.js +42 -0
  26. package/dist/commands/list.js.map +1 -0
  27. package/dist/commands/login.d.ts +9 -0
  28. package/dist/commands/login.d.ts.map +1 -0
  29. package/dist/commands/login.js +192 -0
  30. package/dist/commands/login.js.map +1 -0
  31. package/dist/commands/monitor.d.ts +9 -0
  32. package/dist/commands/monitor.d.ts.map +1 -0
  33. package/dist/commands/monitor.js +292 -0
  34. package/dist/commands/monitor.js.map +1 -0
  35. package/dist/index.d.ts +5 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +125 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/interfaces/api-client.interface.d.ts +76 -0
  40. package/dist/interfaces/api-client.interface.d.ts.map +1 -0
  41. package/dist/interfaces/api-client.interface.js +2 -0
  42. package/dist/interfaces/api-client.interface.js.map +1 -0
  43. package/dist/interfaces/config.interface.d.ts +26 -0
  44. package/dist/interfaces/config.interface.d.ts.map +1 -0
  45. package/dist/interfaces/config.interface.js +2 -0
  46. package/dist/interfaces/config.interface.js.map +1 -0
  47. package/dist/interfaces/output.interface.d.ts +22 -0
  48. package/dist/interfaces/output.interface.d.ts.map +1 -0
  49. package/dist/interfaces/output.interface.js +2 -0
  50. package/dist/interfaces/output.interface.js.map +1 -0
  51. package/dist/interfaces/sse-client.interface.d.ts +18 -0
  52. package/dist/interfaces/sse-client.interface.d.ts.map +1 -0
  53. package/dist/interfaces/sse-client.interface.js +6 -0
  54. package/dist/interfaces/sse-client.interface.js.map +1 -0
  55. package/dist/package.json +42 -0
  56. package/dist/services/api-client.service.d.ts +82 -0
  57. package/dist/services/api-client.service.d.ts.map +1 -0
  58. package/dist/services/api-client.service.js +262 -0
  59. package/dist/services/api-client.service.js.map +1 -0
  60. package/dist/services/config.service.d.ts +32 -0
  61. package/dist/services/config.service.d.ts.map +1 -0
  62. package/dist/services/config.service.js +104 -0
  63. package/dist/services/config.service.js.map +1 -0
  64. package/dist/services/output.service.d.ts +28 -0
  65. package/dist/services/output.service.d.ts.map +1 -0
  66. package/dist/services/output.service.js +258 -0
  67. package/dist/services/output.service.js.map +1 -0
  68. package/dist/services/sse-client.service.d.ts +16 -0
  69. package/dist/services/sse-client.service.d.ts.map +1 -0
  70. package/dist/services/sse-client.service.js +80 -0
  71. package/dist/services/sse-client.service.js.map +1 -0
  72. package/dist/types/index.d.ts +106 -0
  73. package/dist/types/index.d.ts.map +1 -0
  74. package/dist/types/index.js +2 -0
  75. package/dist/types/index.js.map +1 -0
  76. package/dist/utils/live-progress.d.ts +23 -0
  77. package/dist/utils/live-progress.d.ts.map +1 -0
  78. package/dist/utils/live-progress.js +116 -0
  79. package/dist/utils/live-progress.js.map +1 -0
  80. package/dist/utils/log-writer.d.ts +13 -0
  81. package/dist/utils/log-writer.d.ts.map +1 -0
  82. package/dist/utils/log-writer.js +97 -0
  83. package/dist/utils/log-writer.js.map +1 -0
  84. package/package.json +66 -0
@@ -0,0 +1,192 @@
1
+ import { Command } from 'commander';
2
+ import inquirer from 'inquirer';
3
+ import chalk from 'chalk';
4
+ import { existsSync, writeFileSync } from 'fs';
5
+ import open from 'open';
6
+ /**
7
+ * Factory function to create login command with direct service injection
8
+ */
9
+ export function createLoginCommand(configService, apiClient, outputService) {
10
+ return new Command('login')
11
+ .description('Authenticate with ObserveOne platform')
12
+ .option('-k, --api-key <key>', 'API key to use for authentication')
13
+ .option('--api-url <url>', 'Override API URL')
14
+ .option('--skip-setup', 'Skip project configuration setup')
15
+ .option('--headless', 'Authenticate headlessly using OBS_EMAIL and OBS_PASSWORD environment variables')
16
+ .action(async (options) => {
17
+ try {
18
+ // Handle API URL override first, before other operations
19
+ if (options.apiUrl) {
20
+ configService.setCommandLineApiUrl(options.apiUrl);
21
+ }
22
+ // Headless Auth Flow (Agent / CI)
23
+ if (options.headless) {
24
+ const email = process.env.OBS_EMAIL;
25
+ const password = process.env.OBS_PASSWORD;
26
+ if (!email || !password) {
27
+ outputService.error('Headless authentication requires OBS_EMAIL and OBS_PASSWORD environment variables.');
28
+ process.exit(1);
29
+ }
30
+ outputService.progress('Provisioning headless M2M API key...');
31
+ try {
32
+ const { api_key } = await apiClient.provisionHeadlessAuth(email, password);
33
+ configService.setApiKey(api_key);
34
+ configService.setApiUrl(configService.getApiUrl());
35
+ apiClient.setApiKey(api_key);
36
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.json) {
37
+ outputService.formatJsonOutput({ authenticated: true });
38
+ }
39
+ else {
40
+ outputService.success('Successfully authenticated headlessly!');
41
+ if (!options.skipSetup) {
42
+ outputService.warning('Skipping interactive project setup in headless mode.');
43
+ }
44
+ }
45
+ process.exit(0);
46
+ }
47
+ catch (error) {
48
+ outputService.error(`Headless authentication failed: ${error.message}`);
49
+ process.exit(1);
50
+ }
51
+ return;
52
+ }
53
+ // Handle API key override
54
+ if (options.apiKey) {
55
+ configService.setApiKey(options.apiKey);
56
+ }
57
+ const apiKey = configService.getApiKey();
58
+ if (!apiKey) {
59
+ outputService.error('Not authenticated. Please run "obs login" first.');
60
+ process.exit(1);
61
+ }
62
+ // Check for API key in command option first (highest priority)
63
+ let apiKeyToUse = options.apiKey;
64
+ // If no explicit command option but global option was set, use that
65
+ if (!apiKeyToUse) {
66
+ apiKeyToUse = configService.getApiKey();
67
+ }
68
+ // If an API key is available (from either source), try to authenticate
69
+ if (apiKeyToUse) {
70
+ // Use the API key that was provided
71
+ configService.setApiKey(apiKeyToUse);
72
+ apiClient.setApiKey(apiKeyToUse);
73
+ // Validate the API key
74
+ const isValid = await apiClient.validateToken();
75
+ if (isValid) {
76
+ outputService.success('Successfully authenticated with provided API key');
77
+ // Setup project config if needed (skip in test mode)
78
+ if (!options.skipSetup) {
79
+ await setupProjectConfig(configService, outputService);
80
+ }
81
+ process.exit(0);
82
+ return;
83
+ }
84
+ else {
85
+ outputService.error('Invalid API key provided. Please check your key and try again.');
86
+ process.exit(1);
87
+ }
88
+ }
89
+ // Browser-based authentication flow
90
+ console.log(chalk.bold('\n🔐 ObserveOne Authentication'));
91
+ // Request auth session
92
+ outputService.progress('Requesting authentication session...');
93
+ const { request_id, auth_url } = await apiClient.requestCliAuth();
94
+ outputService.success('Successfully requested authentication session. Auth URL: ' + auth_url);
95
+ console.log(chalk.gray("We'll open your browser to authenticate with ObserveOne"));
96
+ console.log('');
97
+ console.log(chalk.blue('Opening browser for authentication...'));
98
+ console.log(chalk.gray(`Auth URL: ${auth_url}`));
99
+ console.log(chalk.gray("If the browser doesn't open automatically, visit the URL above."));
100
+ console.log('');
101
+ console.log(chalk.yellow('⏳ Waiting for authentication...'));
102
+ try {
103
+ await open(auth_url);
104
+ }
105
+ catch (error) {
106
+ // Ignore open errors, user can copy link
107
+ }
108
+ // Poll for status
109
+ const maxAttempts = 60; // 5 minutes (5s interval)
110
+ const intervalMs = 5000;
111
+ let attempts = 0;
112
+ while (attempts < maxAttempts) {
113
+ try {
114
+ const status = await apiClient.checkCliAuthStatus(request_id);
115
+ if (status.status === 'approved' && status.api_key) {
116
+ configService.setApiKey(status.api_key);
117
+ configService.setApiUrl(configService.getApiUrl());
118
+ apiClient.setApiKey(status.api_key);
119
+ outputService.success('Successfully authenticated!');
120
+ // Setup project config if needed
121
+ await setupProjectConfig(configService, outputService);
122
+ console.log('');
123
+ console.log(chalk.bold('Next steps:'));
124
+ console.log(chalk.gray('1. Run "obs list" to see available tests'));
125
+ console.log(chalk.gray('2. Run "obs ai-check <test-name>" to execute tests'));
126
+ process.exit(0);
127
+ }
128
+ else if (status.status === 'denied') {
129
+ outputService.error('Authentication denied by user.');
130
+ process.exit(1);
131
+ }
132
+ // Wait before next poll
133
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
134
+ attempts++;
135
+ }
136
+ catch (error) {
137
+ // If 404 or other error, might be expired or invalid
138
+ attempts++;
139
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
140
+ }
141
+ }
142
+ outputService.error('Authentication timed out.');
143
+ process.exit(1);
144
+ }
145
+ catch (error) {
146
+ outputService.error(outputService.formatError(error));
147
+ process.exit(1);
148
+ }
149
+ });
150
+ }
151
+ /**
152
+ * Helper function for project configuration setup
153
+ */
154
+ async function setupProjectConfig(configService, outputService) {
155
+ const configPath = '.obs.config.json';
156
+ if (!existsSync(configPath)) {
157
+ console.log(chalk.bold('\n🚀 Setting up project configuration...'));
158
+ const projectAnswers = await inquirer.prompt([
159
+ {
160
+ type: 'input',
161
+ name: 'projectName',
162
+ message: 'Project name:',
163
+ default: process.cwd().split(/[/\\]/).pop() || 'My Project',
164
+ validate: (input) => (input.trim() ? true : 'Project name is required'),
165
+ },
166
+ {
167
+ type: 'input',
168
+ name: 'projectDescription',
169
+ message: 'Project description:',
170
+ default: 'AI-powered test automation project',
171
+ },
172
+ ]);
173
+ const projectConfig = {
174
+ project: {
175
+ name: projectAnswers.projectName,
176
+ description: projectAnswers.projectDescription,
177
+ },
178
+ defaultOptions: {
179
+ timeout: 600000,
180
+ retries: 3,
181
+ verbose: false,
182
+ pollIntervalMs: 2000,
183
+ maxAttempts: 300,
184
+ },
185
+ };
186
+ writeFileSync(configPath, JSON.stringify(projectConfig, null, 2));
187
+ configService.setProjectConfig(projectConfig.project);
188
+ configService.setDefaultOptions(projectConfig.defaultOptions);
189
+ outputService.success('Project configuration created!');
190
+ }
191
+ }
192
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Command } from 'commander';
2
+ import { IConfigService } from '../interfaces/config.interface.js';
3
+ import { IApiClient } from '../interfaces/api-client.interface.js';
4
+ import { IOutputService } from '../interfaces/output.interface.js';
5
+ /**
6
+ * Factory function to create monitor command
7
+ */
8
+ export declare function createMonitorCommand(configService: IConfigService, apiClient: IApiClient, outputService: IOutputService): Command;
9
+ //# sourceMappingURL=monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../src/commands/monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAmTT"}
@@ -0,0 +1,292 @@
1
+ import { Command } from 'commander';
2
+ import inquirer from 'inquirer';
3
+ /**
4
+ * Factory function to create monitor command
5
+ */
6
+ export function createMonitorCommand(configService, apiClient, outputService) {
7
+ const monitor = new Command('monitor').description('Manage URL monitors');
8
+ // LIST
9
+ monitor
10
+ .command('list')
11
+ .description('List all URL monitors')
12
+ .option('-f, --format <format>', 'Output format (table, json)', 'table')
13
+ .action(async (options) => {
14
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.format === 'json') {
15
+ outputService.enableJsonMode();
16
+ }
17
+ try {
18
+ const apiKey = configService.getApiKey();
19
+ if (!apiKey) {
20
+ outputService.error('Not authenticated. Please run "obs login" first.');
21
+ process.exit(1);
22
+ }
23
+ outputService.progress('Fetching URL monitors...');
24
+ const monitors = await apiClient.getUrlMonitors();
25
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.format === 'json') {
26
+ outputService.formatJsonOutput(monitors);
27
+ }
28
+ else {
29
+ outputService.formatMonitorList(monitors, process.env.OBS_VERBOSE === 'true');
30
+ }
31
+ }
32
+ catch (error) {
33
+ outputService.error(outputService.formatError(error));
34
+ process.exit(1);
35
+ }
36
+ });
37
+ // GET
38
+ monitor
39
+ .command('get <id>')
40
+ .description('Get details of a URL monitor')
41
+ .option('-j, --json', 'Output in JSON format')
42
+ .action(async (id, options) => {
43
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.json) {
44
+ outputService.enableJsonMode();
45
+ }
46
+ try {
47
+ const apiKey = configService.getApiKey();
48
+ if (!apiKey) {
49
+ outputService.error('Not authenticated. Please run "obs login" first.');
50
+ process.exit(1);
51
+ }
52
+ const monitorId = parseInt(id);
53
+ if (isNaN(monitorId)) {
54
+ outputService.error('Invalid monitor ID.');
55
+ process.exit(1);
56
+ }
57
+ if (process.env.OBS_JSON_OUTPUT === 'true') {
58
+ outputService.enableJsonMode();
59
+ }
60
+ outputService.progress(`Fetching monitor ${monitorId}...`);
61
+ const monitorData = await apiClient.getUrlMonitor(monitorId);
62
+ if (process.env.OBS_JSON_OUTPUT === 'true') {
63
+ outputService.formatJsonOutput(monitorData);
64
+ }
65
+ else {
66
+ outputService.formatMonitorList([monitorData], true);
67
+ }
68
+ }
69
+ catch (error) {
70
+ outputService.error(outputService.formatError(error));
71
+ process.exit(1);
72
+ }
73
+ });
74
+ // CREATE
75
+ monitor
76
+ .command('create')
77
+ .description('Create a new URL monitor')
78
+ .option('-n, --name <name>', 'Monitor name')
79
+ .option('-u, --url <url>', 'URL to monitor')
80
+ .option('-i, --interval <cron>', "Cron expression for interval (e.g. '*/5 * * * *')")
81
+ .option('--no-alerts', 'Disable alerts on failure')
82
+ .option('-j, --json', 'Output in JSON format')
83
+ .action(async (options) => {
84
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.json) {
85
+ outputService.enableJsonMode();
86
+ }
87
+ try {
88
+ const apiKey = configService.getApiKey();
89
+ if (!apiKey) {
90
+ outputService.error('Not authenticated. Please run "obs login" first.');
91
+ process.exit(1);
92
+ }
93
+ let { name, url, interval, alerts } = options;
94
+ // Interactive prompts if missing critical fields
95
+ if (!name || !url) {
96
+ const answers = await inquirer.prompt([
97
+ {
98
+ type: 'input',
99
+ name: 'name',
100
+ message: 'Monitor name:',
101
+ when: !name,
102
+ validate: (val) => (val.trim() ? true : 'Name is required'),
103
+ },
104
+ {
105
+ type: 'input',
106
+ name: 'url',
107
+ message: 'URL to monitor:',
108
+ when: !url,
109
+ validate: (val) => {
110
+ try {
111
+ new URL(val);
112
+ return true;
113
+ }
114
+ catch {
115
+ return 'Please enter a valid URL (e.g. https://example.com)';
116
+ }
117
+ },
118
+ },
119
+ {
120
+ type: 'input',
121
+ name: 'interval',
122
+ message: 'Cron interval (default: Every 5 mins):',
123
+ when: !interval,
124
+ default: '*/5 * * * *',
125
+ },
126
+ ]);
127
+ name = name || answers.name;
128
+ url = url || answers.url;
129
+ interval = interval || answers.interval;
130
+ }
131
+ outputService.progress('Creating URL monitor...');
132
+ const newMonitor = await apiClient.createUrlMonitor({
133
+ name,
134
+ url,
135
+ cron_expression: interval || '*/5 * * * *',
136
+ alert_on_failure: alerts !== false,
137
+ timeout_ms: 30000,
138
+ });
139
+ if (process.env.OBS_JSON_OUTPUT === 'true') {
140
+ outputService.formatJsonOutput(newMonitor);
141
+ }
142
+ else {
143
+ outputService.success(`Monitor "${newMonitor.name}" created successfully (ID: ${newMonitor.id})`);
144
+ }
145
+ }
146
+ catch (error) {
147
+ outputService.error(outputService.formatError(error));
148
+ process.exit(1);
149
+ }
150
+ });
151
+ // DELETE
152
+ monitor
153
+ .command('delete <id>')
154
+ .description('Delete a URL monitor')
155
+ .option('-y, --yes', 'Skip confirmation prompt')
156
+ .option('-j, --json', 'Output in JSON format')
157
+ .action(async (id, options) => {
158
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.json) {
159
+ outputService.enableJsonMode();
160
+ }
161
+ try {
162
+ const apiKey = configService.getApiKey();
163
+ if (!apiKey) {
164
+ outputService.error('Not authenticated. Please run "obs login" first.');
165
+ process.exit(1);
166
+ }
167
+ const monitorId = parseInt(id);
168
+ if (isNaN(monitorId)) {
169
+ outputService.error('Invalid monitor ID.');
170
+ process.exit(1);
171
+ }
172
+ if (!options.yes) {
173
+ const { confirm } = await inquirer.prompt([
174
+ {
175
+ type: 'confirm',
176
+ name: 'confirm',
177
+ message: `Are you sure you want to delete monitor ${monitorId}?`,
178
+ default: false,
179
+ },
180
+ ]);
181
+ if (!confirm) {
182
+ outputService.info('Deletion cancelled.');
183
+ return;
184
+ }
185
+ }
186
+ outputService.progress(`Deleting monitor ${monitorId}...`);
187
+ await apiClient.deleteUrlMonitor(monitorId);
188
+ if (process.env.OBS_JSON_OUTPUT === 'true') {
189
+ outputService.formatJsonOutput({ success: true, id: monitorId });
190
+ }
191
+ else {
192
+ outputService.success(`Monitor ${monitorId} deleted successfully.`);
193
+ }
194
+ }
195
+ catch (error) {
196
+ outputService.error(outputService.formatError(error));
197
+ process.exit(1);
198
+ }
199
+ });
200
+ // UPDATE
201
+ monitor
202
+ .command('update <id>')
203
+ .description('Update a URL monitor')
204
+ .option('-n, --name <name>', 'New monitor name')
205
+ .option('-u, --url <url>', 'New URL')
206
+ .option('-i, --interval <cron>', 'New cron interval')
207
+ .option('-j, --json', 'Output in JSON format')
208
+ .action(async (id, options) => {
209
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.json) {
210
+ outputService.enableJsonMode();
211
+ }
212
+ try {
213
+ const apiKey = configService.getApiKey();
214
+ if (!apiKey) {
215
+ outputService.error('Not authenticated. Please run "obs login" first.');
216
+ process.exit(1);
217
+ }
218
+ const monitorId = parseInt(id);
219
+ if (isNaN(monitorId)) {
220
+ outputService.error('Invalid monitor ID.');
221
+ process.exit(1);
222
+ }
223
+ const { name, url, interval } = options;
224
+ if (!name && !url && !interval) {
225
+ outputService.error('Please provide at least one field to update (--name, --url, or --interval).');
226
+ process.exit(1);
227
+ }
228
+ outputService.progress(`Updating monitor ${monitorId}...`);
229
+ const existing = await apiClient.getUrlMonitor(monitorId);
230
+ const payload = {
231
+ name: name || existing.name,
232
+ url: url || existing.url,
233
+ timeout_ms: existing.timeout_ms || 30000,
234
+ cron_expression: interval || existing.interval || existing.cron_expression,
235
+ alert_on_failure: existing.alert_on_failure ?? true,
236
+ };
237
+ const updatedMonitor = await apiClient.updateUrlMonitor(monitorId, payload);
238
+ if (process.env.OBS_JSON_OUTPUT === 'true') {
239
+ outputService.formatJsonOutput(updatedMonitor);
240
+ }
241
+ else {
242
+ outputService.success(`Monitor ${monitorId} updated successfully.`);
243
+ }
244
+ }
245
+ catch (error) {
246
+ outputService.error(outputService.formatError(error));
247
+ process.exit(1);
248
+ }
249
+ });
250
+ // TOGGLE
251
+ monitor
252
+ .command('toggle <id>')
253
+ .description('Pause or resume a URL monitor')
254
+ .option('-j, --json', 'Output in JSON format')
255
+ .action(async (id, options) => {
256
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.json) {
257
+ outputService.enableJsonMode();
258
+ }
259
+ try {
260
+ const apiKey = configService.getApiKey();
261
+ if (!apiKey) {
262
+ outputService.error('Not authenticated. Please run "obs login" first.');
263
+ process.exit(1);
264
+ }
265
+ const monitorId = parseInt(id);
266
+ if (isNaN(monitorId)) {
267
+ outputService.error('Invalid monitor ID.');
268
+ process.exit(1);
269
+ }
270
+ if (process.env.OBS_JSON_OUTPUT === 'true') {
271
+ outputService.enableJsonMode();
272
+ }
273
+ outputService.progress(`Toggling monitor ${monitorId}...`);
274
+ const isActive = await apiClient.toggleUrlMonitor(monitorId);
275
+ if (process.env.OBS_JSON_OUTPUT === 'true') {
276
+ outputService.formatJsonOutput({
277
+ id: monitorId,
278
+ is_active: isActive,
279
+ });
280
+ }
281
+ else {
282
+ outputService.success(`Monitor ${monitorId} is now ${isActive ? 'ACTIVE' : 'PAUSED'}.`);
283
+ }
284
+ }
285
+ catch (error) {
286
+ outputService.error(outputService.formatError(error));
287
+ process.exit(1);
288
+ }
289
+ });
290
+ return monitor;
291
+ }
292
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/commands/monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ declare const program: Command;
4
+ export { program };
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA8G9B,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+ // Silence dotenv/dotenvx before anything else
3
+ process.env.DOTENV_QUIET = 'true';
4
+ process.env.DOTENV_CONFIG_SILENT = 'true';
5
+ import { Command } from 'commander';
6
+ import dotenv from 'dotenv';
7
+ dotenv.config();
8
+ import chalk from 'chalk';
9
+ import { readFileSync } from 'fs';
10
+ // Import services
11
+ import { ConfigService } from './services/config.service.js';
12
+ import { ApiClient } from './services/api-client.service.js';
13
+ import { OutputService } from './services/output.service.js';
14
+ // Import command factories
15
+ import { createLoginCommand } from './commands/login.js';
16
+ import { createListCommand } from './commands/list.js';
17
+ import { createAiCheckCommand } from './commands/ai-check.js';
18
+ import { createMonitorCommand } from './commands/monitor.js';
19
+ import { createCheckCommand } from './commands/check.js';
20
+ import { createHeartbeatCommand } from './commands/heartbeat.js';
21
+ import { createApplyCommand } from './commands/apply.js';
22
+ import { createExportCommand } from './commands/export.js';
23
+ const packageJson = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
24
+ const { version } = packageJson;
25
+ // Create services directly
26
+ const configService = new ConfigService();
27
+ const outputService = new OutputService();
28
+ const apiClient = new ApiClient(configService, version);
29
+ const program = new Command();
30
+ // Set up the main program
31
+ program
32
+ .name('obs')
33
+ .description('ObserveOne CLI - AI-powered website monitoring and testing from the command line')
34
+ .version(version)
35
+ .option('-v, --verbose', 'Enable verbose output')
36
+ .option('--json', 'Output in JSON format')
37
+ .option('--api-url <url>', 'Override API URL')
38
+ .option('--api-key <key>', 'Override API key');
39
+ // Global error handler: don't treat help/version as errors
40
+ program.exitOverride((err) => {
41
+ const anyErr = err;
42
+ const code = anyErr?.code || '';
43
+ if (code === 'commander.helpDisplayed' || code === 'commander.version') {
44
+ process.exit(0);
45
+ }
46
+ throw err;
47
+ });
48
+ // Add commands with services
49
+ program.addCommand(createLoginCommand(configService, apiClient, outputService));
50
+ program.addCommand(createListCommand(configService, apiClient, outputService));
51
+ program.addCommand(createAiCheckCommand(configService, apiClient, outputService));
52
+ program.addCommand(createMonitorCommand(configService, apiClient, outputService));
53
+ program.addCommand(createCheckCommand(configService, apiClient, outputService));
54
+ program.addCommand(createHeartbeatCommand(configService, apiClient, outputService));
55
+ program.addCommand(createApplyCommand(configService, apiClient, outputService));
56
+ program.addCommand(createExportCommand(configService, apiClient, outputService));
57
+ // Global options handler
58
+ program.hook('preAction', (thisCommand) => {
59
+ const options = thisCommand.opts();
60
+ // Set global options
61
+ if (options.verbose) {
62
+ process.env.OBS_VERBOSE = 'true';
63
+ }
64
+ if (options.json) {
65
+ process.env.OBS_JSON_OUTPUT = 'true';
66
+ outputService.enableJsonMode();
67
+ }
68
+ if (options.apiUrl) {
69
+ configService.setCommandLineApiUrl(options.apiUrl);
70
+ }
71
+ if (options.apiKey) {
72
+ configService.setApiKey(options.apiKey);
73
+ }
74
+ });
75
+ // Error handling
76
+ program.configureOutput({
77
+ writeErr: (str) => process.stderr.write(str),
78
+ writeOut: (str) => process.stdout.write(str),
79
+ });
80
+ // Helper for formatting fatal errors
81
+ function handleFatalError(error, prefix) {
82
+ const msg = error?.message || '';
83
+ const code = error?.code || '';
84
+ if (msg.includes('(outputHelp)') ||
85
+ code === 'commander.helpDisplayed' ||
86
+ code === 'commander.version') {
87
+ process.exit(0);
88
+ return;
89
+ }
90
+ if (process.env.OBS_JSON_OUTPUT === 'true' || process.argv.includes('--json')) {
91
+ const envelope = {
92
+ status: 'ERROR',
93
+ error: {
94
+ message: msg || (typeof error === 'string' ? error : 'Unknown fatal error'),
95
+ },
96
+ metadata: {
97
+ timestamp: new Date().toISOString(),
98
+ },
99
+ };
100
+ console.log(JSON.stringify(envelope, null, 2));
101
+ }
102
+ else {
103
+ console.error(chalk.red(`❌ ${prefix}:`), msg || error);
104
+ if (process.env.OBS_VERBOSE === 'true' && error?.stack) {
105
+ console.error(error.stack);
106
+ }
107
+ }
108
+ process.exit(1);
109
+ }
110
+ // Handle uncaught errors
111
+ process.on('uncaughtException', (error) => {
112
+ handleFatalError(error, 'Uncaught Exception');
113
+ });
114
+ process.on('unhandledRejection', (reason) => {
115
+ handleFatalError(reason, 'Unhandled Rejection');
116
+ });
117
+ // Parse arguments with safety net for help/version
118
+ try {
119
+ program.parse();
120
+ }
121
+ catch (err) {
122
+ handleFatalError(err, 'Parse Error');
123
+ }
124
+ export { program };
125
+ //# sourceMappingURL=index.js.map