@hasna/machines 0.0.29 → 0.0.30

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 (2) hide show
  1. package/dist/cli/index.js +20 -14
  2. package/package.json +2 -2
package/dist/cli/index.js CHANGED
@@ -3164,9 +3164,15 @@ function print(value, json, text) {
3164
3164
  else
3165
3165
  console.log(text);
3166
3166
  }
3167
+ function hasJsonOption(options) {
3168
+ return Boolean(options?.json || options?.opts?.().json || options?.optsWithGlobals?.().json || options?.parent?.opts?.().json || options?.parent?.optsWithGlobals?.().json);
3169
+ }
3170
+ function wantsJson(actionOptions, command) {
3171
+ return hasJsonOption(actionOptions) || hasJsonOption(command);
3172
+ }
3167
3173
  function registerWebhookCommands(program2, options) {
3168
3174
  const webhooks = program2.command(options.webhooksCommandName ?? "webhooks").description("Manage Hasna event webhook subscriptions");
3169
- webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions) => {
3175
+ webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions, command) => {
3170
3176
  const timestamp = new Date().toISOString();
3171
3177
  const channel = {
3172
3178
  id: actionOptions.id,
@@ -3187,11 +3193,11 @@ function registerWebhookCommands(program2, options) {
3187
3193
  throw new Error(`Transport ${actionOptions.transport} is reserved for future use and cannot be added yet`);
3188
3194
  }
3189
3195
  const saved = await createClient(options).addChannel(channel);
3190
- print(sanitizeChannelForOutput(saved), Boolean(actionOptions.json), `Added ${saved.transport} channel ${saved.id}`);
3196
+ print(sanitizeChannelForOutput(saved), wantsJson(actionOptions, command), `Added ${saved.transport} channel ${saved.id}`);
3191
3197
  });
3192
- webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
3198
+ webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
3193
3199
  const channels = await createClient(options).listChannels();
3194
- if (actionOptions.json) {
3200
+ if (wantsJson(actionOptions, command)) {
3195
3201
  console.log(JSON.stringify(sanitizeChannelsForOutput(channels), null, 2));
3196
3202
  return;
3197
3203
  }
@@ -3203,11 +3209,11 @@ function registerWebhookCommands(program2, options) {
3203
3209
  console.log(`${channel.id} ${channel.enabled ? "enabled" : "disabled"} ${channel.transport} ${channel.webhook?.url ?? channel.command?.command ?? channel.transport}`);
3204
3210
  }
3205
3211
  });
3206
- webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions) => {
3212
+ webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
3207
3213
  const removed = await createClient(options).removeChannel(id);
3208
- print({ removed }, Boolean(actionOptions.json), removed ? `Removed ${id}` : `Channel not found: ${id}`);
3214
+ print({ removed }, wantsJson(actionOptions, command), removed ? `Removed ${id}` : `Channel not found: ${id}`);
3209
3215
  });
3210
- webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions) => {
3216
+ webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
3211
3217
  const result = await createClient(options).testChannel(id, {
3212
3218
  source: options.source,
3213
3219
  type: actionOptions.type,
@@ -3215,13 +3221,13 @@ function registerWebhookCommands(program2, options) {
3215
3221
  message: actionOptions.message,
3216
3222
  data: parseJsonObject(actionOptions.data, { test: true })
3217
3223
  });
3218
- print(result, Boolean(actionOptions.json), `${result.status}: ${result.channelId}`);
3224
+ print(result, wantsJson(actionOptions, command), `${result.status}: ${result.channelId}`);
3219
3225
  });
3220
3226
  return webhooks;
3221
3227
  }
3222
3228
  function registerEventCommands(program2, options) {
3223
3229
  const events = program2.command(options.eventsCommandName ?? "events").description("Emit, list, and replay Hasna events");
3224
- events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions) => {
3230
+ events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions, command) => {
3225
3231
  const result = await createClient(options).emit({
3226
3232
  source: actionOptions.source ?? options.source,
3227
3233
  type,
@@ -3232,9 +3238,9 @@ function registerEventCommands(program2, options) {
3232
3238
  data: parseJsonObject(actionOptions.data, {}),
3233
3239
  metadata: parseJsonObject(actionOptions.metadata, {})
3234
3240
  }, { deliver: actionOptions.deliver, dedupe: actionOptions.dedupe });
3235
- print(result, Boolean(actionOptions.json), `${result.deduped ? "Deduped" : "Emitted"} ${result.event.id} to ${result.deliveries.length} channel(s)`);
3241
+ print(result, wantsJson(actionOptions, command), `${result.deduped ? "Deduped" : "Emitted"} ${result.event.id} to ${result.deliveries.length} channel(s)`);
3236
3242
  });
3237
- events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
3243
+ events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
3238
3244
  let rows = await createClient(options).listEvents();
3239
3245
  if (actionOptions.source)
3240
3246
  rows = rows.filter((event) => event.source === actionOptions.source);
@@ -3242,7 +3248,7 @@ function registerEventCommands(program2, options) {
3242
3248
  rows = rows.filter((event) => event.type === actionOptions.type);
3243
3249
  if (actionOptions.limit)
3244
3250
  rows = rows.slice(-actionOptions.limit);
3245
- if (actionOptions.json) {
3251
+ if (wantsJson(actionOptions, command)) {
3246
3252
  console.log(JSON.stringify(rows, null, 2));
3247
3253
  return;
3248
3254
  }
@@ -3253,14 +3259,14 @@ function registerEventCommands(program2, options) {
3253
3259
  for (const event of rows)
3254
3260
  console.log(`${event.time} ${event.id} ${event.source} ${event.type} ${event.severity}`);
3255
3261
  });
3256
- events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
3262
+ events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
3257
3263
  const result = await createClient(options).replay({
3258
3264
  eventId: actionOptions.id,
3259
3265
  source: actionOptions.source,
3260
3266
  type: actionOptions.type,
3261
3267
  dryRun: actionOptions.dryRun
3262
3268
  });
3263
- print(result, Boolean(actionOptions.json), `Replayed ${result.events.length} event(s), ${result.deliveries.length} delivery result(s)`);
3269
+ print(result, wantsJson(actionOptions, command), `Replayed ${result.events.length} event(s), ${result.deliveries.length} delivery result(s)`);
3264
3270
  });
3265
3271
  return events;
3266
3272
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/machines",
3
- "version": "0.0.29",
3
+ "version": "0.0.30",
4
4
  "description": "Machine fleet management CLI + MCP for developers",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -67,7 +67,7 @@
67
67
  "bun": ">=1.0.0"
68
68
  },
69
69
  "dependencies": {
70
- "@hasna/events": "^0.1.3",
70
+ "@hasna/events": "^0.1.7",
71
71
  "@modelcontextprotocol/sdk": "^1.26.0",
72
72
  "chalk": "^5.6.2",
73
73
  "commander": "^13.1.0",