@ogment-ai/cli 0.3.2 → 0.3.4

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
@@ -26,6 +26,9 @@ ogment login
26
26
  # List available servers
27
27
  ogment servers
28
28
 
29
+ # Show runtime configuration and connectivity diagnostics
30
+ ogment info
31
+
29
32
  # Call a tool
30
33
  ogment call <server> <tool> '{"param": "value"}'
31
34
  ```
@@ -35,12 +38,10 @@ ogment call <server> <tool> '{"param": "value"}'
35
38
  ### Run Tests
36
39
 
37
40
  ```bash
38
- npm run test # Watch mode
39
- npm run test:run # Single run
40
- npm run test:coverage # Coverage (text + html + lcov)
41
- npm run test:ui # Vitest UI
42
- npm run test:changed # Run tests related to changed files
43
- npm run test:ci # CI profile (coverage + CI reporters)
41
+ pnpm test # Single run
42
+ pnpm test:coverage # Coverage (text + html + lcov)
43
+ pnpm test:changed # Run tests related to changed files
44
+ pnpm test:ci # CI profile (coverage + CI reporters)
44
45
  ```
45
46
 
46
47
  ## Commands
@@ -93,6 +94,15 @@ Delete local credentials. To revoke the API key (prevent all access), use the Og
93
94
  ogment logout
94
95
  ```
95
96
 
97
+ ### `ogment info`
98
+
99
+ Show effective runtime configuration, auth source, and live connectivity diagnostics against the configured Ogment base URL.
100
+
101
+ ```bash
102
+ ogment info
103
+ ogment info --json
104
+ ```
105
+
96
106
  ## Authentication Model
97
107
 
98
108
  Ogment uses **Clerk API keys** for machine authentication:
package/dist/cli.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import type { CommandContext } from "./commands/context.js";
3
3
  import { OutputManager } from "./output/manager.js";
4
+ import { type InfoService } from "./services/info.js";
4
5
  import { type ExitCode } from "./shared/exit-codes.js";
5
6
  export interface GlobalCliOptions {
6
7
  apiKey: string | undefined;
@@ -11,6 +12,7 @@ export interface GlobalCliOptions {
11
12
  }
12
13
  interface Runtime {
13
14
  context: CommandContext;
15
+ infoService?: InfoService;
14
16
  output: OutputManager;
15
17
  }
16
18
  export declare const runCli: (argv?: readonly string[], runtime?: Runtime) => Promise<ExitCode>;
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AASA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,uBAAuB,CAAC;AAO7E,OAAO,EAAE,aAAa,EAA0B,MAAM,qBAAqB,CAAC;AAK5E,OAAO,EAAa,KAAK,QAAQ,EAAoB,MAAM,wBAAwB,CAAC;AAIpF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,GAAG,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1B;AAED,UAAU,OAAO;IACf,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;CACvB;AA4XD,eAAO,MAAM,MAAM,GACjB,OAAM,SAAS,MAAM,EAA0B,EAC/C,UAAS,OAAyB,KACjC,OAAO,CAAC,QAAQ,CAmBlB,CAAC;AAEF,eAAO,MAAM,UAAU,QAAa,OAAO,CAAC,IAAI,CAG/C,CAAC;AAMF,eAAO,MAAM,gBAAgB,GAAI,eAAe,MAAM,EAAE,OAAO,MAAM,GAAG,SAAS,KAAG,OAanF,CAAC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AASA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,uBAAuB,CAAC;AAQ7E,OAAO,EAAE,aAAa,EAA0B,MAAM,qBAAqB,CAAC;AAG5E,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGzE,OAAO,EAAa,KAAK,QAAQ,EAAoB,MAAM,wBAAwB,CAAC;AAIpF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,GAAG,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1B;AAED,UAAU,OAAO;IACf,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC;CACvB;AAyfD,eAAO,MAAM,MAAM,GACjB,OAAM,SAAS,MAAM,EAA0B,EAC/C,UAAS,OAAyB,KACjC,OAAO,CAAC,QAAQ,CAmBlB,CAAC;AAEF,eAAO,MAAM,UAAU,QAAa,OAAO,CAAC,IAAI,CAG/C,CAAC;AAMF,eAAO,MAAM,gBAAgB,GAAI,eAAe,MAAM,EAAE,OAAO,MAAM,GAAG,SAAS,KAAG,OAanF,CAAC"}
package/dist/cli.js CHANGED
@@ -4,6 +4,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
4
4
  import { Command, CommanderError } from "commander";
5
5
  import { runCallCommand } from "./commands/call.js";
6
6
  import { runDescribeCommand } from "./commands/describe.js";
7
+ import { runInfoCommand } from "./commands/info.js";
7
8
  import { runServersCommand } from "./commands/servers.js";
8
9
  import { createBrowserOpener } from "./infra/browser.js";
9
10
  import { createFileCredentialsStore } from "./infra/credentials.js";
@@ -12,6 +13,7 @@ import { createHttpClient } from "./infra/http.js";
12
13
  import { OutputManager } from "./output/manager.js";
13
14
  import { createAccountService } from "./services/account.js";
14
15
  import { createAuthService } from "./services/auth.js";
16
+ import { createInfoService } from "./services/info.js";
15
17
  import { createMcpService } from "./services/mcp.js";
16
18
  import { UnexpectedError, ValidationError } from "./shared/errors.js";
17
19
  import { EXIT_CODE, exitCodeForError } from "./shared/exit-codes.js";
@@ -49,12 +51,24 @@ const createRuntime = () => {
49
51
  version: runtimeConfig.version,
50
52
  }),
51
53
  };
54
+ const infoService = createInfoService({
55
+ accountService: services.account,
56
+ baseUrl: runtimeConfig.baseUrl,
57
+ baseUrlSource: runtimeConfig.baseUrlSource,
58
+ configDir: runtimeConfig.configDir,
59
+ credentialsPath: runtimeConfig.credentialsPath,
60
+ credentialsStore,
61
+ envApiKey: runtimeConfig.envApiKey,
62
+ httpClient,
63
+ version: runtimeConfig.version,
64
+ });
52
65
  return {
53
66
  context: {
54
67
  apiKeyOverride: undefined,
55
68
  output,
56
69
  services,
57
70
  },
71
+ infoService,
58
72
  output,
59
73
  };
60
74
  };
@@ -175,6 +189,82 @@ const renderServerDetailsHuman = (output, payload) => {
175
189
  renderSchemaBlock(output, "Output schema", tool.outputSchema);
176
190
  }
177
191
  };
192
+ const formatLatency = (latencyMs) => {
193
+ if (latencyMs === null) {
194
+ return "n/a";
195
+ }
196
+ return `${latencyMs}ms`;
197
+ };
198
+ const renderInfoHuman = (output, payload) => {
199
+ output.info(`Diagnostics status: ${payload.summary.status.toUpperCase()}`);
200
+ output.info(`Generated at: ${payload.generatedAt}`);
201
+ output.info("");
202
+ output.info("Runtime:");
203
+ output.info(` CLI version: ${payload.runtime.cliVersion}`);
204
+ output.info(` Node version: ${payload.runtime.nodeVersion}`);
205
+ output.info(` Platform: ${payload.runtime.platform} (${payload.runtime.processArch})`);
206
+ output.info(` Environment: ${payload.runtime.executionEnvironment}`);
207
+ output.info("");
208
+ output.info("Config:");
209
+ output.info(` Base URL: ${payload.config.baseUrl} (${payload.config.baseUrlSource})`);
210
+ output.info(` Config dir: ${payload.config.configDir}`);
211
+ output.info(` Credentials path: ${payload.config.credentialsPath}`);
212
+ output.info("");
213
+ output.info("Auth:");
214
+ output.info(` API key source: ${payload.auth.apiKeySource}`);
215
+ output.info(` API key present: ${payload.auth.apiKeyPresent ? "yes" : "no"}`);
216
+ output.info(` API key fingerprint: ${payload.auth.apiKeyPreview ?? "none"}`);
217
+ output.info(` Credentials file exists: ${payload.auth.credentialsFileExists ? "yes" : "no"}`);
218
+ if (payload.auth.credentialsFileLoadError !== null) {
219
+ output.info(` Credentials load error: ${payload.auth.credentialsFileLoadError}`);
220
+ }
221
+ output.info("");
222
+ output.info("Remote:");
223
+ output.info(` Ping endpoint: ${payload.remote.ping.endpoint}`);
224
+ output.info(` Ping reachable: ${payload.remote.ping.reachable ? "yes" : "no"}`);
225
+ output.info(` Ping latency: ${formatLatency(payload.remote.ping.latencyMs)}`);
226
+ if (payload.remote.ping.status !== null) {
227
+ output.info(` Ping status: ${payload.remote.ping.status} ${payload.remote.ping.statusText ?? ""}`.trimEnd());
228
+ }
229
+ if (payload.remote.ping.error !== null) {
230
+ output.info(` Ping error: ${payload.remote.ping.error}`);
231
+ }
232
+ output.info(` Account check: ${payload.remote.account.status}`);
233
+ output.info(` Account latency: ${formatLatency(payload.remote.account.latencyMs)}`);
234
+ if (payload.remote.account.serverCount !== null) {
235
+ output.info(` Server count: ${payload.remote.account.serverCount}`);
236
+ }
237
+ if (payload.remote.account.orgCount !== null) {
238
+ output.info(` Organization count: ${payload.remote.account.orgCount}`);
239
+ }
240
+ if (payload.remote.account.serverPaths.length > 0) {
241
+ output.info(` Server paths: ${payload.remote.account.serverPaths.join(", ")}`);
242
+ }
243
+ if (payload.remote.account.message !== null) {
244
+ output.info(` Account message: ${payload.remote.account.message}`);
245
+ }
246
+ output.info("");
247
+ output.info("Documentation:");
248
+ output.info(` Config precedence: ${payload.documentation.configPrecedence.join(" -> ")}`);
249
+ output.info(" Quick commands:");
250
+ for (const command of payload.documentation.quickCommands) {
251
+ output.info(` ${command}`);
252
+ }
253
+ if (payload.summary.issues.length > 0) {
254
+ output.info("");
255
+ output.info("Issues:");
256
+ for (const issue of payload.summary.issues) {
257
+ output.info(` - ${issue}`);
258
+ }
259
+ }
260
+ if (payload.summary.nextActions.length > 0) {
261
+ output.info("");
262
+ output.info("Next actions:");
263
+ for (const action of payload.summary.nextActions) {
264
+ output.info(` - ${action}`);
265
+ }
266
+ }
267
+ };
178
268
  const createProgram = (runtime) => {
179
269
  const program = new Command();
180
270
  program.exitOverride();
@@ -260,6 +350,27 @@ const createProgram = (runtime) => {
260
350
  }
261
351
  runtime.output.success(data);
262
352
  });
353
+ program
354
+ .command("info")
355
+ .description("Show runtime configuration and connectivity diagnostics")
356
+ .action(async () => {
357
+ if (runtime.infoService === undefined) {
358
+ throw new UnexpectedError({
359
+ message: "Info service is not configured",
360
+ });
361
+ }
362
+ const result = await runInfoCommand({
363
+ apiKeyOverride: runtime.context.apiKeyOverride,
364
+ }, {
365
+ infoService: runtime.infoService,
366
+ });
367
+ const data = ensureSuccess(result, runtime.output);
368
+ if (runtime.output.mode === "human") {
369
+ renderInfoHuman(runtime.output, data);
370
+ return;
371
+ }
372
+ runtime.output.success(data);
373
+ });
263
374
  program
264
375
  .command("describe")
265
376
  .description("Describe this CLI as a tool set for agent registration")
@@ -271,7 +382,7 @@ const createProgram = (runtime) => {
271
382
  program.action(() => {
272
383
  if (runtime.output.mode === "json") {
273
384
  runtime.output.success({
274
- commands: ["login", "logout", "servers", "call", "describe"],
385
+ commands: ["login", "logout", "servers", "call", "info", "describe"],
275
386
  });
276
387
  return;
277
388
  }
@@ -282,6 +393,7 @@ const createProgram = (runtime) => {
282
393
  runtime.output.info(" login [--device]");
283
394
  runtime.output.info(" servers [path]");
284
395
  runtime.output.info(" call <serverPath> <toolName> [argsJson]");
396
+ runtime.output.info(" info");
285
397
  runtime.output.info(" logout");
286
398
  runtime.output.info(" describe");
287
399
  });
@@ -1 +1 @@
1
- {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/commands/describe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AAI1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAiH5D,eAAO,MAAM,kBAAkB,QAAO,UAAU,CAAC,eAAe,EAAE,KAAK,CAItE,CAAC"}
1
+ {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/commands/describe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AAI1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAiI5D,eAAO,MAAM,kBAAkB,QAAO,UAAU,CAAC,eAAe,EAAE,KAAK,CAItE,CAAC"}
@@ -56,6 +56,15 @@ const commandDefinitions = () => {
56
56
  serverPath: z.string(),
57
57
  toolName: z.string(),
58
58
  });
59
+ const infoOutputSchema = z.object({
60
+ auth: z.record(z.string(), z.unknown()),
61
+ config: z.record(z.string(), z.unknown()),
62
+ documentation: z.record(z.string(), z.unknown()),
63
+ generatedAt: z.string(),
64
+ remote: z.record(z.string(), z.unknown()),
65
+ runtime: z.record(z.string(), z.unknown()),
66
+ summary: z.record(z.string(), z.unknown()),
67
+ });
59
68
  const logoutOutputSchema = z.object({
60
69
  localCredentialsDeleted: z.boolean(),
61
70
  revoked: z.boolean(),
@@ -79,6 +88,12 @@ const commandDefinitions = () => {
79
88
  outputSchema: toJsonSchemaObject(callOutputSchema, "ogmentCallOutput"),
80
89
  parameters: toJsonSchemaObject(callInputSchema, "ogmentCallInput"),
81
90
  },
91
+ {
92
+ description: "Inspect local runtime configuration and remote diagnostics.",
93
+ name: "ogment_info",
94
+ outputSchema: toJsonSchemaObject(infoOutputSchema, "ogmentInfoOutput"),
95
+ parameters: toJsonSchemaObject(z.object({}), "ogmentInfoInput"),
96
+ },
82
97
  {
83
98
  description: "Revoke current session and delete local credentials.",
84
99
  name: "ogment_logout",
@@ -0,0 +1,12 @@
1
+ import type { Result as ResultType } from "better-result";
2
+ import type { InfoService } from "../services/info.js";
3
+ import type { InfoPayload } from "../shared/types.js";
4
+ export interface InfoCommandOptions {
5
+ apiKeyOverride: string | undefined;
6
+ }
7
+ interface RunInfoCommandDeps {
8
+ infoService: InfoService;
9
+ }
10
+ export declare const runInfoCommand: (options: InfoCommandOptions, deps: RunInfoCommandDeps) => Promise<ResultType<InfoPayload, never>>;
11
+ export {};
12
+ //# sourceMappingURL=info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../src/commands/info.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,UAAU,kBAAkB;IAC1B,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,eAAO,MAAM,cAAc,GACzB,SAAS,kBAAkB,EAC3B,MAAM,kBAAkB,KACvB,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,CAGxC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { Result } from "better-result";
2
+ export const runInfoCommand = async (options, deps) => {
3
+ const payload = await deps.infoService.collect(options.apiKeyOverride);
4
+ return Result.ok(payload);
5
+ };
@@ -1,5 +1,7 @@
1
+ import type { BaseUrlSource } from "../shared/types.js";
1
2
  export interface RuntimeConfig {
2
3
  baseUrl: string;
4
+ baseUrlSource: BaseUrlSource;
3
5
  configDir: string;
4
6
  credentialsPath: string;
5
7
  envApiKey: string | undefined;
@@ -7,5 +9,7 @@ export interface RuntimeConfig {
7
9
  }
8
10
  export declare const createRuntimeConfig: (env?: NodeJS.ProcessEnv, homeDirectory?: string) => RuntimeConfig;
9
11
  export declare const isInteractiveOutput: (stdout?: NodeJS.WriteStream) => boolean;
10
- export declare const detectExecutionEnvironment: (env?: NodeJS.ProcessEnv) => string;
12
+ type AncestorProcessReader = () => string[];
13
+ export declare const detectExecutionEnvironment: (env?: NodeJS.ProcessEnv, getAncestors?: AncestorProcessReader) => string;
14
+ export {};
11
15
  //# sourceMappingURL=env.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/infra/env.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB,GAC9B,MAAK,MAAM,CAAC,UAAwB,EACpC,gBAAe,MAAkB,KAChC,aAUF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,SAAQ,MAAM,CAAC,WAA4B,KAAG,OAEjF,CAAC;AA+BF,eAAO,MAAM,0BAA0B,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,MA+DjF,CAAC"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/infra/env.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB,GAC9B,MAAK,MAAM,CAAC,UAAwB,EACpC,gBAAe,MAAkB,KAChC,aAYF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,SAAQ,MAAM,CAAC,WAA4B,KAAG,OAEjF,CAAC;AA+BF,KAAK,qBAAqB,GAAG,MAAM,MAAM,EAAE,CAAC;AAE5C,eAAO,MAAM,0BAA0B,GACrC,MAAK,MAAM,CAAC,UAAwB,EACpC,eAAc,qBAA4C,KACzD,MA+DF,CAAC"}
package/dist/infra/env.js CHANGED
@@ -4,8 +4,10 @@ import { join } from "node:path";
4
4
  import { DEFAULT_OGMENT_BASE_URL, VERSION } from "../shared/constants.js";
5
5
  export const createRuntimeConfig = (env = process.env, homeDirectory = homedir()) => {
6
6
  const configDir = join(homeDirectory, ".config", "ogment");
7
+ const hasBaseUrlOverride = typeof env["OGMENT_BASE_URL"] === "string";
7
8
  return {
8
9
  baseUrl: env["OGMENT_BASE_URL"] ?? DEFAULT_OGMENT_BASE_URL,
10
+ baseUrlSource: hasBaseUrlOverride ? "env" : "default",
9
11
  configDir,
10
12
  credentialsPath: join(configDir, "credentials.json"),
11
13
  envApiKey: env["OGMENT_API_KEY"],
@@ -38,7 +40,7 @@ const getAncestorProcesses = () => {
38
40
  return [];
39
41
  }
40
42
  };
41
- export const detectExecutionEnvironment = (env = process.env) => {
43
+ export const detectExecutionEnvironment = (env = process.env, getAncestors = getAncestorProcesses) => {
42
44
  if (env["CURSOR_TRACE_ID"] !== undefined || env["CURSOR_SESSION_ID"] !== undefined) {
43
45
  return "Cursor";
44
46
  }
@@ -59,7 +61,7 @@ export const detectExecutionEnvironment = (env = process.env) => {
59
61
  if (env["CI"] !== undefined) {
60
62
  return "CI";
61
63
  }
62
- const ancestors = getAncestorProcesses();
64
+ const ancestors = getAncestors();
63
65
  const ancestorNames = ancestors.join(" ").toLowerCase();
64
66
  if (ancestorNames.includes("claude")) {
65
67
  return "Claude Code";
@@ -1,3 +1,4 @@
1
+ import { stdout } from "node:process";
1
2
  const installGreetingLines = [
2
3
  "Thanks for installing @ogment-ai/cli.",
3
4
  "",
@@ -8,5 +9,4 @@ const installGreetingLines = [
8
9
  "",
9
10
  "Docs: https://github.com/ogment-ai/ogment-cli/tree/main/packages/ogment#quick-start",
10
11
  ];
11
- process.stdout.write(`${installGreetingLines.join("\n")}\n`);
12
- export {};
12
+ stdout.write(`${installGreetingLines.join("\n")}\n`);
@@ -0,0 +1,24 @@
1
+ import type { CredentialsStore } from "../infra/credentials.js";
2
+ import type { HttpClient } from "../infra/http.js";
3
+ import type { AccountService } from "./account.js";
4
+ import type { BaseUrlSource, InfoPayload } from "../shared/types.js";
5
+ export interface InfoService {
6
+ collect(apiKeyOverride?: string): Promise<InfoPayload>;
7
+ }
8
+ interface InfoServiceDeps {
9
+ accountService: AccountService;
10
+ baseUrl: string;
11
+ baseUrlSource: BaseUrlSource;
12
+ configDir: string;
13
+ credentialsPath: string;
14
+ credentialsStore: CredentialsStore;
15
+ detectExecutionEnvironmentFn?: () => string;
16
+ envApiKey: string | undefined;
17
+ existsSyncFn?: (path: string) => boolean;
18
+ httpClient: HttpClient;
19
+ now?: () => number;
20
+ version: string;
21
+ }
22
+ export declare const createInfoService: (deps: InfoServiceDeps) => InfoService;
23
+ export {};
24
+ //# sourceMappingURL=info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../src/services/info.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EACV,aAAa,EAGb,WAAW,EAEZ,MAAM,oBAAoB,CAAC;AAsB5B,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACxD;AAED,UAAU,eAAe;IACvB,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,4BAA4B,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5C,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,UAAU,EAAE,UAAU,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAqFD,eAAO,MAAM,iBAAiB,GAAI,MAAM,eAAe,KAAG,WA+MzD,CAAC"}
@@ -0,0 +1,253 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync } from "node:fs";
3
+ import { Result } from "better-result";
4
+ import { detectExecutionEnvironment } from "../infra/env.js";
5
+ const maskApiKey = (apiKey) => {
6
+ if (apiKey.length <= 8) {
7
+ return `*** (sha256:${createHash("sha256").update(apiKey).digest("hex").slice(0, 12)})`;
8
+ }
9
+ const start = apiKey.slice(0, 4);
10
+ const end = apiKey.slice(-4);
11
+ const fingerprint = createHash("sha256").update(apiKey).digest("hex").slice(0, 12);
12
+ return `${start}...${end} (sha256:${fingerprint})`;
13
+ };
14
+ const resolveApiKey = (apiKeyOverride, envApiKey, credentialsStore) => {
15
+ if (typeof apiKeyOverride === "string" && apiKeyOverride.length > 0) {
16
+ return {
17
+ loadError: null,
18
+ source: "apiKeyOption",
19
+ value: apiKeyOverride,
20
+ };
21
+ }
22
+ if (typeof envApiKey === "string" && envApiKey.length > 0) {
23
+ return {
24
+ loadError: null,
25
+ source: "env",
26
+ value: envApiKey,
27
+ };
28
+ }
29
+ const storedCredentials = credentialsStore.load();
30
+ if (Result.isError(storedCredentials)) {
31
+ return {
32
+ loadError: storedCredentials.error.message,
33
+ source: "credentialsError",
34
+ value: null,
35
+ };
36
+ }
37
+ if (storedCredentials.value !== null) {
38
+ return {
39
+ loadError: null,
40
+ source: "credentialsFile",
41
+ value: storedCredentials.value.apiKey,
42
+ };
43
+ }
44
+ return {
45
+ loadError: null,
46
+ source: "none",
47
+ value: null,
48
+ };
49
+ };
50
+ const nextActionByIssueCode = {
51
+ auth_failed: "Run `ogment login` to refresh credentials.",
52
+ credentials_load_failed: "Check file permissions and contents of `~/.config/ogment/credentials.json`.",
53
+ no_api_key: "Run `ogment login` or set `OGMENT_API_KEY`.",
54
+ unreachable: "Verify `OGMENT_BASE_URL` and network connectivity.",
55
+ };
56
+ const toSummary = (issues) => {
57
+ const nextActions = new Set();
58
+ for (const issue of issues) {
59
+ const nextAction = nextActionByIssueCode[issue.code];
60
+ if (nextAction !== undefined) {
61
+ nextActions.add(nextAction);
62
+ }
63
+ }
64
+ nextActions.add("Run `ogment servers` to inspect available servers.");
65
+ return {
66
+ issues: issues.map((issue) => issue.message),
67
+ nextActions: [...nextActions],
68
+ status: issues.length > 0 ? "warning" : "ok",
69
+ };
70
+ };
71
+ export const createInfoService = (deps) => {
72
+ const detectEnvironment = deps.detectExecutionEnvironmentFn ?? detectExecutionEnvironment;
73
+ const existsSyncFn = deps.existsSyncFn ?? existsSync;
74
+ const now = deps.now ?? Date.now;
75
+ return {
76
+ collect: async (apiKeyOverride) => {
77
+ const apiKeyResolution = resolveApiKey(apiKeyOverride, deps.envApiKey, deps.credentialsStore);
78
+ const selectedApiKey = apiKeyResolution.value;
79
+ const credentialsFileExists = existsSyncFn(deps.credentialsPath);
80
+ const endpoint = `${deps.baseUrl}/api/v1/mcp-auth/me`;
81
+ const pingHeaders = typeof selectedApiKey === "string"
82
+ ? {
83
+ Authorization: `Bearer ${selectedApiKey}`,
84
+ }
85
+ : undefined;
86
+ const pingStartedAt = now();
87
+ const pingResult = await deps.httpClient.request(endpoint, pingHeaders === undefined ? undefined : { headers: pingHeaders });
88
+ const pingElapsedMs = now() - pingStartedAt;
89
+ const ping = pingResult.status === "ok"
90
+ ? {
91
+ endpoint,
92
+ error: null,
93
+ latencyMs: pingElapsedMs,
94
+ reachable: true,
95
+ status: pingResult.value.status,
96
+ statusText: pingResult.value.statusText,
97
+ }
98
+ : {
99
+ endpoint,
100
+ error: pingResult.error.message,
101
+ latencyMs: null,
102
+ reachable: false,
103
+ status: null,
104
+ statusText: null,
105
+ };
106
+ const collectAccount = async () => {
107
+ if (selectedApiKey === null) {
108
+ return {
109
+ errorType: null,
110
+ latencyMs: null,
111
+ message: "No API key available",
112
+ orgCount: null,
113
+ serverCount: null,
114
+ serverPaths: [],
115
+ status: "skipped",
116
+ };
117
+ }
118
+ const accountStartedAt = now();
119
+ const accountResult = await deps.accountService.fetchAccount(selectedApiKey);
120
+ const accountElapsedMs = now() - accountStartedAt;
121
+ if (accountResult.status === "ok") {
122
+ const servers = accountResult.value.orgs.flatMap((organization) => {
123
+ return organization.servers.map((server) => server.path);
124
+ });
125
+ return {
126
+ errorType: null,
127
+ latencyMs: accountElapsedMs,
128
+ message: null,
129
+ orgCount: accountResult.value.orgs.length,
130
+ serverCount: servers.length,
131
+ serverPaths: servers.slice(0, 5),
132
+ status: "success",
133
+ };
134
+ }
135
+ let normalizedStatus = "unexpected_error";
136
+ switch (accountResult.error._tag) {
137
+ case "AuthError": {
138
+ normalizedStatus = "auth_error";
139
+ break;
140
+ }
141
+ case "RemoteRequestError": {
142
+ normalizedStatus = "remote_error";
143
+ break;
144
+ }
145
+ case "ValidationError": {
146
+ normalizedStatus = "validation_error";
147
+ break;
148
+ }
149
+ default: {
150
+ normalizedStatus = "unexpected_error";
151
+ break;
152
+ }
153
+ }
154
+ return {
155
+ errorType: accountResult.error._tag,
156
+ latencyMs: accountElapsedMs,
157
+ message: accountResult.error.message,
158
+ orgCount: null,
159
+ serverCount: null,
160
+ serverPaths: [],
161
+ status: normalizedStatus,
162
+ };
163
+ };
164
+ const account = await collectAccount();
165
+ const issues = [];
166
+ if (!ping.reachable) {
167
+ issues.push({
168
+ code: "unreachable",
169
+ message: `Could not reach ${deps.baseUrl}: ${ping.error ?? "unknown error"}`,
170
+ });
171
+ }
172
+ if (apiKeyResolution.source === "none") {
173
+ issues.push({
174
+ code: "no_api_key",
175
+ message: "No API key found in --apiKey, OGMENT_API_KEY, or credentials file.",
176
+ });
177
+ }
178
+ if (apiKeyResolution.source === "credentialsError" && apiKeyResolution.loadError !== null) {
179
+ issues.push({
180
+ code: "credentials_load_failed",
181
+ message: `Failed to load credentials file: ${apiKeyResolution.loadError}`,
182
+ });
183
+ }
184
+ if (account.status === "auth_error") {
185
+ issues.push({
186
+ code: "auth_failed",
187
+ message: `Authentication failed: ${account.message ?? "unknown auth error"}`,
188
+ });
189
+ }
190
+ if (account.status === "remote_error") {
191
+ issues.push({
192
+ code: "remote_request_failed",
193
+ message: `Remote request failed: ${account.message ?? "unknown remote error"}`,
194
+ });
195
+ }
196
+ if (account.status === "validation_error") {
197
+ issues.push({
198
+ code: "response_validation_failed",
199
+ message: `Response validation failed: ${account.message ?? "unknown validation error"}`,
200
+ });
201
+ }
202
+ if (account.status === "unexpected_error") {
203
+ issues.push({
204
+ code: "unexpected_diagnostic_error",
205
+ message: `Unexpected diagnostic error: ${account.message ?? "unknown error"}`,
206
+ });
207
+ }
208
+ return {
209
+ auth: {
210
+ apiKeyPresent: selectedApiKey !== null,
211
+ apiKeyPreview: selectedApiKey === null ? null : maskApiKey(selectedApiKey),
212
+ apiKeySource: apiKeyResolution.source,
213
+ credentialsFileExists,
214
+ credentialsFileLoadError: apiKeyResolution.loadError,
215
+ },
216
+ config: {
217
+ baseUrl: deps.baseUrl,
218
+ baseUrlSource: deps.baseUrlSource,
219
+ configDir: deps.configDir,
220
+ credentialsPath: deps.credentialsPath,
221
+ },
222
+ documentation: {
223
+ configPrecedence: [
224
+ "--apiKey option",
225
+ "OGMENT_API_KEY environment variable",
226
+ "~/.config/ogment/credentials.json",
227
+ "default base URL when OGMENT_BASE_URL is unset",
228
+ ],
229
+ quickCommands: [
230
+ "ogment info",
231
+ "ogment login --device --non-interactive",
232
+ "ogment servers",
233
+ "ogment servers <path>",
234
+ 'ogment call <serverPath> <toolName> \'{"key":"value"}\'',
235
+ ],
236
+ },
237
+ generatedAt: new Date(now()).toISOString(),
238
+ remote: {
239
+ account,
240
+ ping,
241
+ },
242
+ runtime: {
243
+ cliVersion: deps.version,
244
+ executionEnvironment: detectEnvironment(),
245
+ nodeVersion: process.version,
246
+ platform: process.platform,
247
+ processArch: process.arch,
248
+ },
249
+ summary: toSummary(issues),
250
+ };
251
+ },
252
+ };
253
+ };
@@ -3,6 +3,6 @@ export declare const APP_DESCRIPTION = "Ogment CLI - secure your AI agents' SaaS
3
3
  export declare const DEFAULT_OGMENT_BASE_URL = "https://dashboard.ogment.ai";
4
4
  export declare const CLI_CLIENT_NAME = "Ogment CLI";
5
5
  export declare const CLI_REDIRECT_HOST = "127.0.0.1";
6
- export declare const VERSION = "0.3.0";
6
+ export declare const VERSION: string;
7
7
  export declare const AGENT_SUCCESS_HINT = "Use `ogment servers` to list available servers.";
8
8
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/shared/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,eAAe,yDAAyD,CAAC;AAEtF,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AACrE,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAE7C,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,eAAO,MAAM,kBAAkB,oDAAoD,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/shared/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,eAAe,yDAAyD,CAAC;AAEtF,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AACrE,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAM7C,eAAO,MAAM,OAAO,QAAsB,CAAC;AAE3C,eAAO,MAAM,kBAAkB,oDAAoD,CAAC"}
@@ -1,7 +1,9 @@
1
+ import { readFileSync } from "node:fs";
1
2
  export const APP_NAME = "ogment";
2
3
  export const APP_DESCRIPTION = "Ogment CLI - secure your AI agents' SaaS credentials";
3
4
  export const DEFAULT_OGMENT_BASE_URL = "https://dashboard.ogment.ai";
4
5
  export const CLI_CLIENT_NAME = "Ogment CLI";
5
6
  export const CLI_REDIRECT_HOST = "127.0.0.1";
6
- export const VERSION = "0.3.0";
7
+ const packageJson = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf8"));
8
+ export const VERSION = packageJson.version;
7
9
  export const AGENT_SUCCESS_HINT = "Use `ogment servers` to list available servers.";
@@ -50,4 +50,65 @@ export interface ToolCallSuccess {
50
50
  toolName: string;
51
51
  result: unknown;
52
52
  }
53
+ export type BaseUrlSource = "default" | "env";
54
+ export type InfoApiKeySource = "apiKeyOption" | "credentialsError" | "credentialsFile" | "env" | "none";
55
+ export interface InfoRuntimeDetails {
56
+ cliVersion: string;
57
+ executionEnvironment: string;
58
+ nodeVersion: string;
59
+ platform: string;
60
+ processArch: string;
61
+ }
62
+ export interface InfoConfigDetails {
63
+ baseUrl: string;
64
+ baseUrlSource: BaseUrlSource;
65
+ configDir: string;
66
+ credentialsPath: string;
67
+ }
68
+ export interface InfoAuthDetails {
69
+ apiKeyPresent: boolean;
70
+ apiKeyPreview: string | null;
71
+ apiKeySource: InfoApiKeySource;
72
+ credentialsFileExists: boolean;
73
+ credentialsFileLoadError: string | null;
74
+ }
75
+ export interface InfoPingCheck {
76
+ endpoint: string;
77
+ error: string | null;
78
+ latencyMs: number | null;
79
+ reachable: boolean;
80
+ status: number | null;
81
+ statusText: string | null;
82
+ }
83
+ export type InfoAccountStatus = "auth_error" | "remote_error" | "skipped" | "success" | "unexpected_error" | "validation_error";
84
+ export interface InfoAccountCheck {
85
+ errorType: string | null;
86
+ latencyMs: number | null;
87
+ message: string | null;
88
+ orgCount: number | null;
89
+ serverCount: number | null;
90
+ serverPaths: string[];
91
+ status: InfoAccountStatus;
92
+ }
93
+ export interface InfoDocumentation {
94
+ configPrecedence: string[];
95
+ quickCommands: string[];
96
+ }
97
+ export interface InfoSummary {
98
+ issues: string[];
99
+ nextActions: string[];
100
+ status: "ok" | "warning";
101
+ }
102
+ export interface InfoPayload {
103
+ auth: InfoAuthDetails;
104
+ config: InfoConfigDetails;
105
+ documentation: InfoDocumentation;
106
+ generatedAt: string;
107
+ remote: {
108
+ account: InfoAccountCheck;
109
+ ping: InfoPingCheck;
110
+ };
111
+ runtime: InfoRuntimeDetails;
112
+ summary: InfoSummary;
113
+ }
53
114
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,YAAY,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,33 +1,11 @@
1
1
  {
2
2
  "name": "@ogment-ai/cli",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Ogment Vault CLI — secure your AI agents' SaaS credentials",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "ogment": "./dist/cli.js"
8
8
  },
9
- "scripts": {
10
- "clean": "node -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true });\"",
11
- "build": "npm run clean && tsc -p tsconfig.build.json",
12
- "dev": "tsx src/cli.ts",
13
- "start": "node dist/cli.js",
14
- "postinstall": "node -e \"import('./dist/postinstall.js').catch(() => undefined)\"",
15
- "check-types": "tsc -p tsconfig.json --noEmit",
16
- "lint": "oxlint -c oxlint.config.ts --type-aware --type-check --tsconfig tsconfig.json src test/src test/e2e vitest.config.ts vitest.e2e.config.ts",
17
- "lint:fix": "npm run lint -- --fix",
18
- "format": "oxfmt --write src test/src test/e2e",
19
- "format:check": "oxfmt --check src test/src test/e2e",
20
- "test": "vitest -c vitest.config.ts",
21
- "test:run": "vitest run -c vitest.config.ts",
22
- "test:coverage": "npm run test:run -- --coverage",
23
- "test:e2e": "npm run build && vitest run -c vitest.e2e.config.ts",
24
- "test:e2e:live": "npm run build && OGMENT_E2E_LIVE=1 vitest run -c vitest.e2e.config.ts test/e2e/live.local.test.ts",
25
- "test:ui": "npm run test -- --ui",
26
- "test:changed": "npm run test:run -- --changed",
27
- "test:ci": "npm run test:coverage",
28
- "qa": "npm run lint && npm run check-types && npm run test:coverage",
29
- "prepublishOnly": "npm run build"
30
- },
31
9
  "exports": {
32
10
  ".": {
33
11
  "default": "./dist/cli.js"
@@ -61,24 +39,41 @@
61
39
  "node": ">=18"
62
40
  },
63
41
  "dependencies": {
64
- "@modelcontextprotocol/sdk": "^1.26.0",
65
- "@ogment-ai/cli-contract": "0.3.2",
42
+ "@modelcontextprotocol/sdk": "^1.27.0",
43
+ "@ogment-ai/cli-contract": "0.3.4",
66
44
  "better-result": "^2.7.0",
67
- "commander": "^13.1.0",
68
- "open": "^10.2.0",
45
+ "commander": "^14.0.3",
46
+ "open": "^11.0.0",
69
47
  "zod": "^4.3.6",
70
48
  "zod-to-json-schema": "^3.25.1"
71
49
  },
72
50
  "devDependencies": {
73
- "@types/node": "^22.18.12",
51
+ "@types/node": "^25.3.0",
74
52
  "@vitest/coverage-v8": "^4.0.18",
75
53
  "@vitest/ui": "^4.0.18",
76
54
  "opensrc": "^0.6.0",
77
- "oxfmt": "^0.34.0",
78
- "oxlint": "^1.49.0",
79
- "oxlint-tsgolint": "^0.14.1",
55
+ "oxfmt": "^0.35.0",
56
+ "oxlint": "^1.50.0",
57
+ "oxlint-tsgolint": "^0.14.2",
80
58
  "tsx": "^4.21.0",
81
59
  "typescript": "^5.9.3",
82
60
  "vitest": "^4.0.18"
61
+ },
62
+ "scripts": {
63
+ "clean": "node -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true });\"",
64
+ "build": "pnpm clean && tsc -p tsconfig.build.json",
65
+ "dev": "tsx src/cli.ts",
66
+ "start": "node dist/cli.js",
67
+ "local": "npm run build && CI=1 OGMENT_BASE_URL=${OGMENT_BASE_URL:-http://localhost:3000} node dist/cli.js",
68
+ "local:json": "npm run build && CI=1 OGMENT_BASE_URL=${OGMENT_BASE_URL:-http://localhost:3000} node dist/cli.js --json",
69
+ "postinstall": "node -e \"import('./dist/postinstall.js').catch(() => undefined)\"",
70
+ "lint": "oxlint -c oxlint.config.ts --type-aware --type-check --tsconfig tsconfig.json src test/src test/e2e vitest.config.ts vitest.e2e.config.ts",
71
+ "lint:fix": "pnpm lint -- --fix",
72
+ "format": "oxfmt --write src test/src test/e2e",
73
+ "format:check": "oxfmt --check src test/src test/e2e",
74
+ "test": "vitest run -c vitest.config.ts",
75
+ "test:coverage": "vitest run -c vitest.config.ts --coverage",
76
+ "test:e2e": "vitest run -c vitest.e2e.config.ts",
77
+ "test:changed": "pnpm test -- --changed"
83
78
  }
84
- }
79
+ }