@griffin-app/griffin-cli 1.0.39 → 1.0.40

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 (50) hide show
  1. package/dist/cli.js +0 -0
  2. package/dist/commands/apply.d.ts +9 -0
  3. package/dist/commands/apply.js +76 -0
  4. package/dist/commands/config.d.ts +36 -0
  5. package/dist/commands/config.js +144 -0
  6. package/dist/commands/configure-runner-host.d.ts +2 -0
  7. package/dist/commands/configure-runner-host.js +41 -0
  8. package/dist/commands/deploy.d.ts +1 -0
  9. package/dist/commands/deploy.js +36 -0
  10. package/dist/commands/execute-remote.d.ts +1 -0
  11. package/dist/commands/execute-remote.js +33 -0
  12. package/dist/commands/hub/config.d.ts +27 -0
  13. package/dist/commands/hub/config.js +102 -0
  14. package/dist/commands/hub/plan.d.ts +8 -0
  15. package/dist/commands/hub/plan.js +75 -0
  16. package/dist/commands/local/config.d.ts +28 -0
  17. package/dist/commands/local/config.js +82 -0
  18. package/dist/commands/logs.d.ts +1 -0
  19. package/dist/commands/logs.js +20 -0
  20. package/dist/commands/plan.d.ts +8 -0
  21. package/dist/commands/plan.js +58 -0
  22. package/dist/commands/run-remote.d.ts +11 -0
  23. package/dist/commands/run-remote.js +98 -0
  24. package/dist/commands/run.d.ts +4 -0
  25. package/dist/commands/run.js +86 -0
  26. package/dist/commands/runner.d.ts +12 -0
  27. package/dist/commands/runner.js +53 -0
  28. package/dist/commands/status.d.ts +8 -0
  29. package/dist/commands/status.js +75 -0
  30. package/dist/core/plan-diff.d.ts +41 -0
  31. package/dist/core/plan-diff.js +257 -0
  32. package/dist/output/context.d.ts +18 -0
  33. package/dist/output/context.js +22 -0
  34. package/dist/output/index.d.ts +3 -0
  35. package/dist/output/index.js +2 -0
  36. package/dist/output/renderer.d.ts +6 -0
  37. package/dist/output/renderer.js +348 -0
  38. package/dist/output/types.d.ts +153 -0
  39. package/dist/output/types.js +1 -0
  40. package/dist/providers/registry.d.ts +24 -0
  41. package/dist/providers/registry.js +109 -0
  42. package/dist/schemas/payload.d.ts +6 -0
  43. package/dist/schemas/payload.js +8 -0
  44. package/dist/test-discovery.d.ts +4 -0
  45. package/dist/test-discovery.js +25 -0
  46. package/dist/test-runner.d.ts +6 -0
  47. package/dist/test-runner.js +56 -0
  48. package/dist/utils/console.d.ts +5 -0
  49. package/dist/utils/console.js +5 -0
  50. package/package.json +3 -3
@@ -0,0 +1,153 @@
1
+ import type { ApplyResult } from "../core/apply.js";
2
+ import type { DiffResult } from "../core/diff.js";
3
+ /**
4
+ * Base result type for all CLI commands.
5
+ * Discriminated union: success yields data; failure yields error and optional hint.
6
+ * exitCode: if set, used when exiting (default 0 for success, 1 for failure).
7
+ */
8
+ export type CommandResult<T> = {
9
+ success: true;
10
+ data: T;
11
+ warnings?: string[];
12
+ exitCode?: number;
13
+ } | {
14
+ success: false;
15
+ error: string;
16
+ hint?: string;
17
+ exitCode?: number;
18
+ };
19
+ export interface InitResultData {
20
+ projectId: string;
21
+ stateFile: string;
22
+ environments: string[];
23
+ variablesCreated: boolean;
24
+ nextSteps: string[];
25
+ }
26
+ export interface ConnectResultData {
27
+ url: string;
28
+ tokenSet: boolean;
29
+ }
30
+ export interface LoginResultData {
31
+ success: true;
32
+ }
33
+ export interface LogoutResultData {
34
+ success: true;
35
+ }
36
+ export interface GenerateKeyResultData {
37
+ apiKey: string;
38
+ }
39
+ export interface ValidateMonitorInfo {
40
+ name: string;
41
+ filePath: string;
42
+ exportName: string;
43
+ nodes: number;
44
+ edges: number;
45
+ frequency?: {
46
+ every: number;
47
+ unit: string;
48
+ };
49
+ }
50
+ export interface ValidateResultData {
51
+ monitors: ValidateMonitorInfo[];
52
+ valid: boolean;
53
+ }
54
+ export interface EnvListResultData {
55
+ environments: string[];
56
+ default: string | null;
57
+ }
58
+ export interface StatusResultData {
59
+ url: string;
60
+ token: string | null;
61
+ updatedAt: string | null;
62
+ }
63
+ export interface RunSummary {
64
+ id: string;
65
+ monitorId: string | null;
66
+ status: string;
67
+ success?: boolean;
68
+ duration_ms?: number;
69
+ startedAt: string;
70
+ errors?: string[];
71
+ }
72
+ export interface RunsResultData {
73
+ runs: RunSummary[];
74
+ total: number;
75
+ }
76
+ export interface MetricsResultData {
77
+ period: string;
78
+ periodStart: string;
79
+ periodEnd: string;
80
+ monitors: {
81
+ total: number;
82
+ passing: number;
83
+ failing: number;
84
+ noRecentRuns: number;
85
+ };
86
+ runs: {
87
+ total: number;
88
+ successful: number;
89
+ failed: number;
90
+ successRate: number;
91
+ };
92
+ latency: {
93
+ p50DurationMs: number | null;
94
+ p95DurationMs: number | null;
95
+ p99DurationMs: number | null;
96
+ };
97
+ uptimePercent: number;
98
+ failingMonitors: Array<{
99
+ monitorId: string;
100
+ monitorName: string;
101
+ lastFailureAt: string;
102
+ consecutiveFailures: number;
103
+ }>;
104
+ }
105
+ export interface MonitorResultData {
106
+ diff: DiffResult;
107
+ hasChanges: boolean;
108
+ }
109
+ export interface ApplyResultData {
110
+ diff: DiffResult;
111
+ applied: ApplyResult;
112
+ dryRun: boolean;
113
+ }
114
+ export interface LocalRunResultData {
115
+ results: Array<{
116
+ file: string;
117
+ success: boolean;
118
+ }>;
119
+ passed: number;
120
+ failed: number;
121
+ total: number;
122
+ }
123
+ export interface HubRunResultData {
124
+ runId: string;
125
+ status: string;
126
+ success?: boolean;
127
+ duration_ms?: number;
128
+ startedAt: string;
129
+ errors?: string[];
130
+ waited?: boolean;
131
+ }
132
+ export interface NotificationRuleSummary {
133
+ id: string;
134
+ name: string;
135
+ monitorId: string | null;
136
+ trigger: unknown;
137
+ channels: string[];
138
+ enabled: boolean;
139
+ }
140
+ export interface NotificationsListResultData {
141
+ rules: NotificationRuleSummary[];
142
+ }
143
+ export interface NotificationsAddResultData {
144
+ id: string;
145
+ name: string;
146
+ }
147
+ export interface NotificationsDeleteResultData {
148
+ id: string;
149
+ }
150
+ export interface NotificationsTestResultData {
151
+ success: boolean;
152
+ message: string;
153
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Hardcoded provider registry for integration connect.
3
+ * Defines categories, providers, auth methods, and required fields.
4
+ */
5
+ export type AuthMethod = "oauth" | "credentials";
6
+ export interface ProviderField {
7
+ key: string;
8
+ label: string;
9
+ secret?: boolean;
10
+ required?: boolean;
11
+ default?: string;
12
+ }
13
+ export interface ProviderDefinition {
14
+ category: string;
15
+ provider: string;
16
+ displayName: string;
17
+ authMethod: AuthMethod;
18
+ configFields?: ProviderField[];
19
+ credentialFields?: ProviderField[];
20
+ }
21
+ export declare function getCategories(): string[];
22
+ export declare function getProviders(category: string): ProviderDefinition[];
23
+ export declare function getProvider(category: string, provider: string): ProviderDefinition | null;
24
+ export declare function getAllProvidersByCategory(): Map<string, ProviderDefinition[]>;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Hardcoded provider registry for integration connect.
3
+ * Defines categories, providers, auth methods, and required fields.
4
+ */
5
+ const providers = [
6
+ // Notifications - OAuth
7
+ {
8
+ category: "notifications",
9
+ provider: "slack",
10
+ displayName: "Slack",
11
+ authMethod: "oauth",
12
+ },
13
+ {
14
+ category: "notifications",
15
+ provider: "pagerduty",
16
+ displayName: "PagerDuty",
17
+ authMethod: "oauth",
18
+ },
19
+ // Notifications - Credentials
20
+ {
21
+ category: "notifications",
22
+ provider: "webhook",
23
+ displayName: "Webhook",
24
+ authMethod: "credentials",
25
+ configFields: [{ key: "url", label: "Webhook URL", required: true }],
26
+ },
27
+ //{
28
+ // category: "notifications",
29
+ // provider: "email",
30
+ // displayName: "Email (SES)",
31
+ // authMethod: "credentials",
32
+ // configFields: [
33
+ // { key: "fromAddress", label: "From Address", required: true },
34
+ // { key: "sesRegion", label: "SES Region", required: true },
35
+ // {
36
+ // key: "toAddresses",
37
+ // label: "To Addresses (comma-separated)",
38
+ // required: true,
39
+ // },
40
+ // ],
41
+ //},
42
+ // Secrets - Credentials
43
+ {
44
+ category: "secrets",
45
+ provider: "env",
46
+ displayName: "Environment Variables",
47
+ authMethod: "credentials",
48
+ configFields: [{ key: "prefix", label: "Env Prefix", required: false }],
49
+ },
50
+ {
51
+ category: "secrets",
52
+ provider: "aws",
53
+ displayName: "AWS Secrets Manager",
54
+ authMethod: "credentials",
55
+ configFields: [{ key: "region", label: "AWS Region", required: true }],
56
+ credentialFields: [
57
+ { key: "accessKeyId", label: "Access Key ID", secret: true },
58
+ { key: "secretAccessKey", label: "Secret Access Key", secret: true },
59
+ ],
60
+ },
61
+ {
62
+ category: "secrets",
63
+ provider: "vault",
64
+ displayName: "HashiCorp Vault",
65
+ authMethod: "credentials",
66
+ configFields: [{ key: "address", label: "Vault Address", required: true }],
67
+ credentialFields: [{ key: "token", label: "Vault Token", secret: true }],
68
+ },
69
+ // Metrics - Credentials
70
+ {
71
+ category: "metrics",
72
+ provider: "datadog",
73
+ displayName: "Datadog",
74
+ authMethod: "credentials",
75
+ configFields: [
76
+ {
77
+ key: "site",
78
+ label: "Datadog Site",
79
+ default: "datadoghq.com",
80
+ },
81
+ ],
82
+ credentialFields: [
83
+ {
84
+ key: "api_key",
85
+ label: "API Key",
86
+ secret: true,
87
+ required: true,
88
+ },
89
+ ],
90
+ },
91
+ ];
92
+ const categories = ["notifications", "secrets", "metrics"];
93
+ export function getCategories() {
94
+ return [...categories];
95
+ }
96
+ export function getProviders(category) {
97
+ return providers.filter((p) => p.category === category);
98
+ }
99
+ export function getProvider(category, provider) {
100
+ return (providers.find((p) => p.category === category && p.provider === provider) ??
101
+ null);
102
+ }
103
+ export function getAllProvidersByCategory() {
104
+ const map = new Map();
105
+ for (const cat of categories) {
106
+ map.set(cat, getProviders(cat));
107
+ }
108
+ return map;
109
+ }
@@ -0,0 +1,6 @@
1
+ import { type TestMonitorV1 } from "griffin-hub-sdk";
2
+ /**
3
+ * Compute a deterministic hash of a monitor payload.
4
+ * Used for change detection.
5
+ */
6
+ export declare function hashMonitorPayload(monitor: TestMonitorV1): string;
@@ -0,0 +1,8 @@
1
+ import objectHash from "object-hash";
2
+ /**
3
+ * Compute a deterministic hash of a monitor payload.
4
+ * Used for change detection.
5
+ */
6
+ export function hashMonitorPayload(monitor) {
7
+ return objectHash(monitor);
8
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Discovers test files in __griffin__ directories.
3
+ */
4
+ export declare function findTestFiles(basePath?: string): string[];
@@ -0,0 +1,25 @@
1
+ import * as path from "path";
2
+ import { glob } from "glob";
3
+ /**
4
+ * Discovers test files in __griffin__ directories.
5
+ */
6
+ export function findTestFiles(basePath = ".") {
7
+ const absolutePath = path.resolve(basePath);
8
+ // Find all __griffin__ directories
9
+ const griffinDirs = findgriffinDirectories(absolutePath);
10
+ // Find all .ts files in those directories
11
+ const testFiles = [];
12
+ for (const griffinDir of griffinDirs) {
13
+ const tsFiles = findTsFiles(griffinDir);
14
+ testFiles.push(...tsFiles);
15
+ }
16
+ return testFiles;
17
+ }
18
+ function findgriffinDirectories(basePath) {
19
+ const pattern = path.join(basePath, "**", "__griffin__");
20
+ return glob.sync(pattern, { absolute: true });
21
+ }
22
+ function findTsFiles(griffinDir) {
23
+ const pattern = path.join(griffinDir, "*.ts");
24
+ return glob.sync(pattern, { absolute: true });
25
+ }
@@ -0,0 +1,6 @@
1
+ import "tsx";
2
+ import { ExecutionResult } from "@griffin-app/griffin-plan-executor";
3
+ /**
4
+ * Runs a TypeScript test file and executes the resulting JSON monitor.
5
+ */
6
+ export declare function runTestFile(filePath: string, envName: string): Promise<ExecutionResult>;
@@ -0,0 +1,56 @@
1
+ import "tsx";
2
+ import { Value } from "typebox/value";
3
+ import { executeMonitorV1, AxiosAdapter, } from "@griffin-app/griffin-plan-executor";
4
+ import { MonitorDSLSchema } from "@griffin-app/griffin-ts/schema";
5
+ import { randomUUID } from "crypto";
6
+ import { loadVariables } from "./core/variables.js";
7
+ import { getProjectId } from "./core/state.js";
8
+ import { resolveMonitor } from "./resolve.js";
9
+ import { terminal } from "./utils/terminal.js";
10
+ import { createSecretsProviderForCLI } from "./core/secrets.js";
11
+ function validateDsl(monitor) {
12
+ const errors = Value.Errors(MonitorDSLSchema, monitor);
13
+ if (errors.length > 0) {
14
+ throw new Error(`Invalid monitor: ${JSON.stringify([...errors], null, 2)}`);
15
+ }
16
+ return monitor;
17
+ }
18
+ /**
19
+ * Runs a TypeScript test file and executes the resulting JSON monitor.
20
+ */
21
+ export async function runTestFile(filePath, envName) {
22
+ const variables = await loadVariables(envName);
23
+ const projectId = await getProjectId();
24
+ const defaultExport = await import(filePath);
25
+ const rawMonitor = validateDsl(defaultExport.default);
26
+ terminal.dim(`Project ID: ${projectId}`);
27
+ const resolvedMonitor = resolveMonitor(rawMonitor, projectId, envName, variables);
28
+ // Create secret provider from environment configuration
29
+ const secretProvider = await createSecretsProviderForCLI();
30
+ try {
31
+ const result = await executeMonitorV1({
32
+ ...resolvedMonitor,
33
+ id: randomUUID(),
34
+ }, "default-org", {
35
+ mode: "local",
36
+ httpClient: new AxiosAdapter(),
37
+ secretProvider,
38
+ });
39
+ return result;
40
+ }
41
+ catch (error) {
42
+ throw new Error(`Error executing monitor: ${error instanceof Error ? error.message : String(error)}`);
43
+ }
44
+ }
45
+ //function findWorkspaceRoot(): string {
46
+ // let current = process.cwd();
47
+ // while (current !== path.dirname(current)) {
48
+ // const testCliPath = path.join(current, "griffin-cli");
49
+ // const testSystemPath = path.join(current, "griffin-ts");
50
+ // if (fs.existsSync(testCliPath) && fs.existsSync(testSystemPath)) {
51
+ // return current;
52
+ // }
53
+ // current = path.dirname(current);
54
+ // }
55
+ // return process.cwd();
56
+ //}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @deprecated Use terminal from "./terminal.js" instead
3
+ * This file is kept for backwards compatibility
4
+ */
5
+ export { terminal as console, colors } from "./terminal.js";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @deprecated Use terminal from "./terminal.js" instead
3
+ * This file is kept for backwards compatibility
4
+ */
5
+ export { terminal as console, colors } from "./terminal.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@griffin-app/griffin-cli",
3
- "version": "1.0.39",
3
+ "version": "1.0.40",
4
4
  "description": "CLI tool for running and managing griffin API tests",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,8 +24,8 @@
24
24
  "author": "",
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
- "@griffin-app/griffin-core": "0.3.1",
28
- "@griffin-app/griffin-executor": "0.2.1",
27
+ "@griffin-app/griffin-core": "0.3.4",
28
+ "@griffin-app/griffin-executor": "0.2.2",
29
29
  "@griffin-app/griffin-hub-sdk": "1.0.31",
30
30
  "better-auth": "^1.4.17",
31
31
  "cli-table3": "^0.6.5",