devhelm 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DevHelm
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,81 @@
1
+ # DevHelm CLI
2
+
3
+ The official command-line interface for [DevHelm](https://devhelm.io) — manage monitors, deployments, and infrastructure as code.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g devhelm
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Authenticate
15
+ devhelm auth login
16
+
17
+ # List monitors
18
+ devhelm monitors list
19
+
20
+ # Validate a configuration file
21
+ devhelm validate devhelm.yml
22
+
23
+ # Deploy monitors from config
24
+ devhelm deploy
25
+ ```
26
+
27
+ ## Authentication
28
+
29
+ The CLI resolves credentials in this order:
30
+
31
+ 1. `DEVHELM_API_TOKEN` environment variable (highest priority)
32
+ 2. Active auth context from `~/.devhelm/contexts.json`
33
+
34
+ ```bash
35
+ # Interactive login (creates a "default" context)
36
+ devhelm auth login
37
+
38
+ # Manage multiple contexts
39
+ devhelm auth context create staging --api-url https://api.devhelm.io --token sk_...
40
+ devhelm auth context use staging
41
+ devhelm auth context list
42
+ ```
43
+
44
+ ## Commands
45
+
46
+ | Command | Description |
47
+ |---------|-------------|
48
+ | `devhelm version` | Print CLI version |
49
+ | `devhelm monitors list` | List all monitors |
50
+ | `devhelm monitors get <id>` | Get monitor details |
51
+ | `devhelm validate [file]` | Validate devhelm.yml |
52
+ | `devhelm deploy` | Deploy configuration |
53
+ | `devhelm status` | Show deployment status |
54
+
55
+ Run `devhelm --help` for the full command list.
56
+
57
+ ## Development
58
+
59
+ ```bash
60
+ git clone https://github.com/devhelmhq/cli.git
61
+ cd cli
62
+ npm install
63
+ npm run build
64
+
65
+ # Run in dev mode
66
+ node bin/dev.js version
67
+ node bin/dev.js monitors list
68
+
69
+ # Run tests
70
+ npm test
71
+
72
+ # Lint
73
+ npm run lint
74
+
75
+ # Type check
76
+ npm run typecheck
77
+ ```
78
+
79
+ ## License
80
+
81
+ MIT
package/bin/dev.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({development: true, dir: import.meta.url})
package/bin/run.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({dir: import.meta.url})
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class MonitorsList extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/monitors/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAQ,MAAM,aAAa,CAAA;AAK1C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,OAAgB,WAAW,SAAsB;IAEjD,OAAgB,QAAQ,WAGvB;IAED,OAAgB,KAAK;;MAEpB;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAyB3B"}
@@ -0,0 +1,34 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { ApiClient } from '../../lib/api-client.js';
3
+ import { resolveToken, resolveApiUrl } from '../../lib/auth.js';
4
+ import { AuthError } from '../../lib/errors.js';
5
+ export default class MonitorsList extends Command {
6
+ static description = 'List all monitors';
7
+ static examples = [
8
+ '<%= config.bin %> monitors list',
9
+ '<%= config.bin %> monitors list --json',
10
+ ];
11
+ static flags = {
12
+ json: Flags.boolean({ description: 'Output as JSON', default: false }),
13
+ };
14
+ async run() {
15
+ const { flags } = await this.parse(MonitorsList);
16
+ const token = resolveToken();
17
+ if (!token)
18
+ throw new AuthError();
19
+ const client = new ApiClient({ baseUrl: resolveApiUrl(), token });
20
+ const monitors = await client.get('/platform/monitors?size=50');
21
+ if (flags.json) {
22
+ this.log(JSON.stringify(monitors.content, null, 2));
23
+ return;
24
+ }
25
+ if (monitors.content.length === 0) {
26
+ this.log('No monitors found.');
27
+ return;
28
+ }
29
+ for (const m of monitors.content) {
30
+ this.log(` ${m.id}\t${m.status}\t${m.type}\t${m.name}`);
31
+ }
32
+ }
33
+ }
34
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/monitors/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAC,SAAS,EAAC,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAA;AAE7C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,MAAM,CAAU,WAAW,GAAG,mBAAmB,CAAA;IAEjD,MAAM,CAAU,QAAQ,GAAG;QACzB,iCAAiC;QACjC,wCAAwC;KACzC,CAAA;IAED,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAC,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAC,CAAC;KACrE,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAE9C,MAAM,KAAK,GAAG,YAAY,EAAE,CAAA;QAC5B,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,SAAS,EAAE,CAAA;QAEjC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAC,OAAO,EAAE,aAAa,EAAE,EAAE,KAAK,EAAC,CAAC,CAAA;QAC/D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAC/B,4BAA4B,CAC7B,CAAA;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YACnD,OAAM;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;YAC9B,OAAM;QACR,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;QAC1D,CAAC;IACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Version extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AAKnC,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;IAC1C,OAAgB,WAAW,SAA0B;IAErD,OAAgB,QAAQ,WAAgC;IAElD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAM3B"}
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ import { readFileSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { dirname, join } from 'node:path';
5
+ export default class Version extends Command {
6
+ static description = 'Print the CLI version';
7
+ static examples = ['<%= config.bin %> version'];
8
+ async run() {
9
+ await this.parse(Version);
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf8'));
12
+ this.log(`devhelm/${pkg.version} ${process.platform}-${process.arch} node-${process.version}`);
13
+ }
14
+ }
15
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AACnC,OAAO,EAAC,YAAY,EAAC,MAAM,SAAS,CAAA;AACpC,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AACtC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAC,MAAM,WAAW,CAAA;AAEvC,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;IAC1C,MAAM,CAAU,WAAW,GAAG,uBAAuB,CAAA;IAErD,MAAM,CAAU,QAAQ,GAAG,CAAC,2BAA2B,CAAC,CAAA;IAExD,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACzB,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;QACzF,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAChG,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { run } from '@oclif/core';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { run } from '@oclif/core';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA"}
@@ -0,0 +1,12 @@
1
+ export interface ApiClientOptions {
2
+ baseUrl: string;
3
+ token: string;
4
+ }
5
+ export declare class ApiClient {
6
+ private baseUrl;
7
+ private token;
8
+ constructor(options: ApiClientOptions);
9
+ get<T>(path: string): Promise<T>;
10
+ post<T>(path: string, body: unknown): Promise<T>;
11
+ }
12
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,KAAK,CAAQ;gBAET,OAAO,EAAE,gBAAgB;IAK/B,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAehC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CAgBvD"}
@@ -0,0 +1,35 @@
1
+ export class ApiClient {
2
+ baseUrl;
3
+ token;
4
+ constructor(options) {
5
+ this.baseUrl = options.baseUrl.replace(/\/$/, '');
6
+ this.token = options.token;
7
+ }
8
+ async get(path) {
9
+ const response = await fetch(`${this.baseUrl}${path}`, {
10
+ headers: {
11
+ Authorization: `Bearer ${this.token}`,
12
+ 'Content-Type': 'application/json',
13
+ },
14
+ });
15
+ if (!response.ok) {
16
+ throw new Error(`API request failed: ${response.status} ${response.statusText}`);
17
+ }
18
+ return response.json();
19
+ }
20
+ async post(path, body) {
21
+ const response = await fetch(`${this.baseUrl}${path}`, {
22
+ method: 'POST',
23
+ headers: {
24
+ Authorization: `Bearer ${this.token}`,
25
+ 'Content-Type': 'application/json',
26
+ },
27
+ body: JSON.stringify(body),
28
+ });
29
+ if (!response.ok) {
30
+ throw new Error(`API request failed: ${response.status} ${response.statusText}`);
31
+ }
32
+ return response.json();
33
+ }
34
+ }
35
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,SAAS;IACZ,OAAO,CAAQ;IACf,KAAK,CAAQ;IAErB,YAAY,OAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QACjD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY;QACvB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACrC,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;QAClF,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,IAAY,EAAE,IAAa;QACvC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACrC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;QAClF,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;IACtC,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ export interface AuthContext {
2
+ name: string;
3
+ apiUrl: string;
4
+ token: string;
5
+ }
6
+ export declare function resolveToken(): string | undefined;
7
+ export declare function resolveApiUrl(): string;
8
+ export declare function getCurrentContext(): AuthContext | undefined;
9
+ export declare function listContexts(): {
10
+ current: string;
11
+ contexts: AuthContext[];
12
+ };
13
+ export declare function saveContext(context: AuthContext, setCurrent?: boolean): void;
14
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAUD,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAOjD;AAED,wBAAgB,aAAa,IAAI,MAAM,CAOtC;AAED,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,SAAS,CAI3D;AAED,wBAAgB,YAAY,IAAI;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;CAAC,CAOzE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,UAAO,GAAG,IAAI,CAKzE"}
@@ -0,0 +1,53 @@
1
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ const CONFIG_DIR = join(homedir(), '.devhelm');
5
+ const CONTEXTS_PATH = join(CONFIG_DIR, 'contexts.json');
6
+ export function resolveToken() {
7
+ if (process.env.DEVHELM_API_TOKEN) {
8
+ return process.env.DEVHELM_API_TOKEN;
9
+ }
10
+ const ctx = getCurrentContext();
11
+ return ctx?.token;
12
+ }
13
+ export function resolveApiUrl() {
14
+ if (process.env.DEVHELM_API_URL) {
15
+ return process.env.DEVHELM_API_URL;
16
+ }
17
+ const ctx = getCurrentContext();
18
+ return ctx?.apiUrl ?? 'https://api.devhelm.io';
19
+ }
20
+ export function getCurrentContext() {
21
+ const file = readContextsFile();
22
+ if (!file)
23
+ return undefined;
24
+ return file.contexts[file.current];
25
+ }
26
+ export function listContexts() {
27
+ const file = readContextsFile();
28
+ if (!file)
29
+ return { current: '', contexts: [] };
30
+ return {
31
+ current: file.current,
32
+ contexts: Object.values(file.contexts),
33
+ };
34
+ }
35
+ export function saveContext(context, setCurrent = true) {
36
+ const file = readContextsFile() ?? { current: '', contexts: {} };
37
+ file.contexts[context.name] = context;
38
+ if (setCurrent)
39
+ file.current = context.name;
40
+ writeContextsFile(file);
41
+ }
42
+ function readContextsFile() {
43
+ if (!existsSync(CONTEXTS_PATH))
44
+ return undefined;
45
+ return JSON.parse(readFileSync(CONTEXTS_PATH, 'utf8'));
46
+ }
47
+ function writeContextsFile(file) {
48
+ if (!existsSync(CONFIG_DIR)) {
49
+ mkdirSync(CONFIG_DIR, { recursive: true });
50
+ }
51
+ writeFileSync(CONTEXTS_PATH, JSON.stringify(file, null, 2));
52
+ }
53
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAC,MAAM,SAAS,CAAA;AAC1E,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAa9B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;AAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAA;AAEvD,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAA;IACtC,CAAC;IAED,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAA;IAC/B,OAAO,GAAG,EAAE,KAAK,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAA;IACpC,CAAC;IAED,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAA;IAC/B,OAAO,GAAG,EAAE,MAAM,IAAI,wBAAwB,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAA;IAC/B,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAA;IAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAA;IAC/B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAC,CAAA;IAC7C,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;KACvC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAoB,EAAE,UAAU,GAAG,IAAI;IACjE,MAAM,IAAI,GAAG,gBAAgB,EAAE,IAAI,EAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAC,CAAA;IAC9D,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAA;IACrC,IAAI,UAAU;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAA;IAC3C,iBAAiB,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,SAAS,CAAA;IAChD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAkB;IAC3C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;IAC1C,CAAC;IAED,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7D,CAAC"}
@@ -0,0 +1,12 @@
1
+ export declare class DevhelmError extends Error {
2
+ exitCode: number;
3
+ constructor(message: string, exitCode?: number);
4
+ }
5
+ export declare class AuthError extends DevhelmError {
6
+ constructor(message?: string);
7
+ }
8
+ export declare class ApiError extends DevhelmError {
9
+ status: number;
10
+ constructor(status: number, message: string);
11
+ }
12
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAa,SAAQ,KAAK;IAG5B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,GAAE,MAAU;CAK9B;AAED,qBAAa,SAAU,SAAQ,YAAY;gBAC7B,OAAO,SAAuD;CAI3E;AAED,qBAAa,QAAS,SAAQ,YAAY;IAE/B,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM;CAKlB"}
@@ -0,0 +1,23 @@
1
+ export class DevhelmError extends Error {
2
+ exitCode;
3
+ constructor(message, exitCode = 1) {
4
+ super(message);
5
+ this.exitCode = exitCode;
6
+ this.name = 'DevhelmError';
7
+ }
8
+ }
9
+ export class AuthError extends DevhelmError {
10
+ constructor(message = 'Not authenticated. Run `devhelm auth login` first.') {
11
+ super(message, 2);
12
+ this.name = 'AuthError';
13
+ }
14
+ }
15
+ export class ApiError extends DevhelmError {
16
+ status;
17
+ constructor(status, message) {
18
+ super(`API error (${status}): ${message}`, 3);
19
+ this.status = status;
20
+ this.name = 'ApiError';
21
+ }
22
+ }
23
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,YAAa,SAAQ,KAAK;IAG5B;IAFT,YACE,OAAe,EACR,WAAmB,CAAC;QAE3B,KAAK,CAAC,OAAO,CAAC,CAAA;QAFP,aAAQ,GAAR,QAAQ,CAAY;QAG3B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,SAAU,SAAQ,YAAY;IACzC,YAAY,OAAO,GAAG,oDAAoD;QACxE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACjB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAA;IACzB,CAAC;CACF;AAED,MAAM,OAAO,QAAS,SAAQ,YAAY;IAE/B;IADT,YACS,MAAc,EACrB,OAAe;QAEf,KAAK,CAAC,cAAc,MAAM,MAAM,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;QAHtC,WAAM,GAAN,MAAM,CAAQ;QAIrB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAA;IACxB,CAAC;CACF"}
@@ -0,0 +1,60 @@
1
+ {
2
+ "commands": {
3
+ "version": {
4
+ "aliases": [],
5
+ "args": {},
6
+ "description": "Print the CLI version",
7
+ "examples": [
8
+ "<%= config.bin %> version"
9
+ ],
10
+ "flags": {},
11
+ "hasDynamicHelp": false,
12
+ "hiddenAliases": [],
13
+ "id": "version",
14
+ "pluginAlias": "devhelm",
15
+ "pluginName": "devhelm",
16
+ "pluginType": "core",
17
+ "strict": true,
18
+ "enableJsonFlag": false,
19
+ "isESM": true,
20
+ "relativePath": [
21
+ "dist",
22
+ "commands",
23
+ "version.js"
24
+ ]
25
+ },
26
+ "monitors:list": {
27
+ "aliases": [],
28
+ "args": {},
29
+ "description": "List all monitors",
30
+ "examples": [
31
+ "<%= config.bin %> monitors list",
32
+ "<%= config.bin %> monitors list --json"
33
+ ],
34
+ "flags": {
35
+ "json": {
36
+ "description": "Output as JSON",
37
+ "name": "json",
38
+ "allowNo": false,
39
+ "type": "boolean"
40
+ }
41
+ },
42
+ "hasDynamicHelp": false,
43
+ "hiddenAliases": [],
44
+ "id": "monitors:list",
45
+ "pluginAlias": "devhelm",
46
+ "pluginName": "devhelm",
47
+ "pluginType": "core",
48
+ "strict": true,
49
+ "enableJsonFlag": false,
50
+ "isESM": true,
51
+ "relativePath": [
52
+ "dist",
53
+ "commands",
54
+ "monitors",
55
+ "list.js"
56
+ ]
57
+ }
58
+ },
59
+ "version": "0.1.0"
60
+ }
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "devhelm",
3
+ "version": "0.1.0",
4
+ "description": "DevHelm CLI — manage monitors, deployments, and infrastructure as code",
5
+ "author": "DevHelm <hello@devhelm.io>",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/devhelmhq/cli",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/devhelmhq/cli.git"
11
+ },
12
+ "bugs": "https://github.com/devhelmhq/cli/issues",
13
+ "type": "module",
14
+ "bin": {
15
+ "devhelm": "./bin/run.js"
16
+ },
17
+ "files": [
18
+ "bin",
19
+ "dist",
20
+ "oclif.manifest.json"
21
+ ],
22
+ "main": "dist/index.js",
23
+ "types": "dist/index.d.ts",
24
+ "scripts": {
25
+ "build": "tsc -b && oclif manifest",
26
+ "lint": "eslint src/ test/",
27
+ "lint:fix": "eslint src/ test/ --fix",
28
+ "test": "vitest run",
29
+ "test:watch": "vitest",
30
+ "typecheck": "tsc --noEmit",
31
+ "postpack": "rm -f oclif.manifest.json",
32
+ "prepack": "npm run build"
33
+ },
34
+ "oclif": {
35
+ "bin": "devhelm",
36
+ "dirname": "devhelm",
37
+ "commands": {
38
+ "strategy": "pattern",
39
+ "target": "./dist/commands"
40
+ },
41
+ "plugins": [
42
+ "@oclif/plugin-help",
43
+ "@oclif/plugin-not-found"
44
+ ],
45
+ "topicSeparator": " "
46
+ },
47
+ "engines": {
48
+ "node": ">=18.0.0"
49
+ },
50
+ "keywords": [
51
+ "devhelm",
52
+ "monitoring",
53
+ "cli",
54
+ "uptime",
55
+ "infrastructure-as-code",
56
+ "devops"
57
+ ],
58
+ "dependencies": {
59
+ "@oclif/core": "^4.10.5",
60
+ "@oclif/plugin-help": "^6.2.43",
61
+ "@oclif/plugin-not-found": "^3.2.80"
62
+ },
63
+ "devDependencies": {
64
+ "@types/node": "^25.5.2",
65
+ "@typescript-eslint/eslint-plugin": "^8.58.1",
66
+ "@typescript-eslint/parser": "^8.58.1",
67
+ "eslint": "^10.2.0",
68
+ "oclif": "^4.23.0",
69
+ "typescript": "^6.0.2",
70
+ "vitest": "^4.1.4"
71
+ }
72
+ }