@automagik/omni 2.260910.8 → 2.260910.10

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/dist/index.js CHANGED
@@ -40197,6 +40197,12 @@ function resolveTemplatePath(path, context) {
40197
40197
  const specialValue = resolveSpecialValue(trimmed, root, rest, context);
40198
40198
  if (specialValue !== undefined)
40199
40199
  return specialValue;
40200
+ if (trimmed === "payload_json")
40201
+ return JSON.stringify(context.payload);
40202
+ if (trimmed === "event_json") {
40203
+ const { id = null, type = null, timestamp = null, metadata = null } = context.event ?? {};
40204
+ return JSON.stringify({ id, type, timestamp, metadata, payload: context.payload });
40205
+ }
40200
40206
  if (root === "payload")
40201
40207
  return rest ? getNestedValue(context.payload, rest) : context.payload;
40202
40208
  if (root === "env")
@@ -74699,7 +74705,7 @@ __export(exports_embedded_canonical_migration, {
74699
74705
  EMBEDDED_PGSERVE_DATA_DIR: () => EMBEDDED_PGSERVE_DATA_DIR
74700
74706
  });
74701
74707
  import { execFileSync as execFileSync3, spawn, spawnSync as spawnSync2 } from "child_process";
74702
- import { existsSync as existsSync10, mkdirSync as mkdirSync7, mkdtempSync, readFileSync as readFileSync8, readdirSync as readdirSync3, symlinkSync as symlinkSync2 } from "fs";
74708
+ import { existsSync as existsSync10, mkdirSync as mkdirSync7, mkdtempSync, readFileSync as readFileSync9, readdirSync as readdirSync3, symlinkSync as symlinkSync2 } from "fs";
74703
74709
  import { createServer } from "net";
74704
74710
  import { arch, homedir as homedir8, platform, tmpdir } from "os";
74705
74711
  import { dirname as dirname2, join as join12 } from "path";
@@ -74725,7 +74731,7 @@ function defaultLog(line) {
74725
74731
  }
74726
74732
  function readDataDirMajor(dataDir) {
74727
74733
  try {
74728
- const major = Number.parseInt(readFileSync8(join12(dataDir, "PG_VERSION"), "utf8").trim(), 10);
74734
+ const major = Number.parseInt(readFileSync9(join12(dataDir, "PG_VERSION"), "utf8").trim(), 10);
74729
74735
  return Number.isFinite(major) ? major : null;
74730
74736
  } catch {
74731
74737
  return null;
@@ -74800,7 +74806,7 @@ function materializeReaderLibs(nativeDir) {
74800
74806
  const libDir = join12(nativeDir, "lib");
74801
74807
  try {
74802
74808
  const pkgRoot = dirname2(nativeDir);
74803
- const pairs = JSON.parse(readFileSync8(join12(nativeDir, "pg-symlinks.json"), "utf8"));
74809
+ const pairs = JSON.parse(readFileSync9(join12(nativeDir, "pg-symlinks.json"), "utf8"));
74804
74810
  for (const { source, target } of pairs) {
74805
74811
  const tgt = join12(pkgRoot, target);
74806
74812
  if (!existsSync10(tgt)) {
@@ -84148,13 +84154,13 @@ var init_postgres_js = __esm(() => {
84148
84154
  });
84149
84155
 
84150
84156
  // ../db/src/client.ts
84151
- import { readFileSync as readFileSync13 } from "fs";
84157
+ import { readFileSync as readFileSync14 } from "fs";
84152
84158
  function resolveSslConfig(caFile, env2 = process.env) {
84153
84159
  const path = caFile || env2.DATABASE_SSL_CA_FILE;
84154
84160
  if (!path) {
84155
84161
  return;
84156
84162
  }
84157
- return { ca: readFileSync13(path, "utf8"), rejectUnauthorized: true };
84163
+ return { ca: readFileSync14(path, "utf8"), rejectUnauthorized: true };
84158
84164
  }
84159
84165
  function getDefaultDatabaseUrl() {
84160
84166
  const url = process.env.DATABASE_URL;
@@ -115758,7 +115764,7 @@ var require_client2 = __commonJS((exports) => {
115758
115764
 
115759
115765
  // ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
115760
115766
  var require_esmLoader = __commonJS((exports) => {
115761
- var __filename = "/home/runner/work/omni/omni/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
115767
+ var __filename = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
115762
115768
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
115763
115769
  var core = require_cjs();
115764
115770
  var importInTheMiddle = require_import_in_the_middle();
@@ -137182,7 +137188,7 @@ import { fileURLToPath } from "url";
137182
137188
  // package.json
137183
137189
  var package_default = {
137184
137190
  name: "@automagik/omni",
137185
- version: "2.260910.8",
137191
+ version: "2.260910.10",
137186
137192
  repository: {
137187
137193
  type: "git",
137188
137194
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -139281,51 +139287,108 @@ one, or the entry named by the global flag:
139281
139287
  }
139282
139288
 
139283
139289
  // src/commands/automations.ts
139290
+ import { readFileSync as readFileSync7 } from "fs";
139284
139291
  init_output();
139292
+ function collectRepeated(value, previous) {
139293
+ return [...previous ?? [], value];
139294
+ }
139285
139295
  function parseJson(json, fieldName) {
139286
139296
  try {
139287
- return { ok: true, value: JSON.parse(json) };
139297
+ return JSON.parse(json);
139288
139298
  } catch {
139289
- return { ok: false, error: `Invalid JSON for ${fieldName}` };
139299
+ throw new Error(`Invalid JSON for ${fieldName}`);
139290
139300
  }
139291
139301
  }
139292
- function buildActionConfig(options) {
139293
- let config2 = {};
139294
- if (options.actionConfig) {
139295
- const result = parseJson(options.actionConfig, "--action-config");
139296
- if (!result.ok)
139297
- return result;
139298
- config2 = result.value;
139299
- }
139300
- if (options.action === "call_agent") {
139301
- if (options.agentId)
139302
- config2.agentId = options.agentId;
139303
- if (options.providerId)
139304
- config2.providerId = options.providerId;
139305
- if (options.responseAs)
139306
- config2.responseAs = options.responseAs;
139307
- if (!config2.agentId) {
139308
- return { ok: false, error: "call_agent action requires --agent-id or agentId in --action-config" };
139309
- }
139310
- }
139311
- return { ok: true, config: config2 };
139312
- }
139313
- function parseConditions(options) {
139314
- let conditions2;
139315
- let logic;
139316
- if (options.condition) {
139317
- const result = parseJson(options.condition, "--condition");
139318
- if (!result.ok)
139319
- return result;
139320
- conditions2 = result.value;
139302
+ function readDefinitionFile(path) {
139303
+ let text;
139304
+ try {
139305
+ text = readFileSync7(path, "utf-8");
139306
+ } catch (err2) {
139307
+ const reason = err2 instanceof Error ? err2.message : "Unknown error";
139308
+ throw new Error(`Cannot read --file '${path}': ${reason}`);
139321
139309
  }
139322
- if (options.conditionLogic) {
139323
- if (options.conditionLogic !== "and" && options.conditionLogic !== "or") {
139324
- return { ok: false, error: '--condition-logic must be "and" or "or"' };
139325
- }
139326
- logic = options.conditionLogic;
139310
+ const parsed = parseJson(text, "--file");
139311
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
139312
+ throw new Error("--file must contain a JSON object");
139327
139313
  }
139328
- return { ok: true, conditions: conditions2, logic };
139314
+ const readOnly = new Set(["id", "createdAt", "updatedAt", "managedByAgentId"]);
139315
+ const body = Object.fromEntries(Object.entries(parsed).filter(([key, value]) => !readOnly.has(key) && value !== null));
139316
+ return body;
139317
+ }
139318
+ function applyCallAgentShortcuts(config2, options) {
139319
+ if (options.agentId)
139320
+ config2.agentId = options.agentId;
139321
+ if (options.providerId)
139322
+ config2.providerId = options.providerId;
139323
+ if (options.responseAs)
139324
+ config2.responseAs = options.responseAs;
139325
+ }
139326
+ function buildActions(options) {
139327
+ const types8 = options.action ?? [];
139328
+ const configs = options.actionConfig ?? [];
139329
+ if (types8.length === 0) {
139330
+ if (configs.length > 0)
139331
+ throw new Error("--action-config requires a matching --action");
139332
+ return;
139333
+ }
139334
+ if (configs.length > types8.length) {
139335
+ throw new Error(`Got ${configs.length} --action-config for ${types8.length} --action`);
139336
+ }
139337
+ const firstCallAgent = types8.indexOf("call_agent");
139338
+ return types8.map((type, i6) => {
139339
+ const raw2 = configs[i6];
139340
+ const config2 = raw2 ? parseJson(raw2, `--action-config #${i6 + 1}`) : {};
139341
+ if (type === "call_agent") {
139342
+ if (i6 === firstCallAgent)
139343
+ applyCallAgentShortcuts(config2, options);
139344
+ if (!config2.agentId) {
139345
+ throw new Error("call_agent action requires --agent-id or agentId in --action-config");
139346
+ }
139347
+ }
139348
+ return { type, config: config2 };
139349
+ });
139350
+ }
139351
+ function parseConditionLogic(logic) {
139352
+ if (logic === undefined)
139353
+ return;
139354
+ if (logic !== "and" && logic !== "or")
139355
+ throw new Error('--condition-logic must be "and" or "or"');
139356
+ return logic;
139357
+ }
139358
+ function buildDefinition(options) {
139359
+ const body = options.file ? readDefinitionFile(options.file) : {};
139360
+ const actions2 = buildActions(options);
139361
+ if (actions2)
139362
+ body.actions = actions2;
139363
+ if (options.name !== undefined)
139364
+ body.name = options.name;
139365
+ if (options.description !== undefined)
139366
+ body.description = options.description;
139367
+ if (options.trigger !== undefined)
139368
+ body.triggerEventType = options.trigger;
139369
+ if (options.condition !== undefined)
139370
+ body.triggerConditions = parseJson(options.condition, "--condition");
139371
+ const logic = parseConditionLogic(options.conditionLogic);
139372
+ if (logic !== undefined)
139373
+ body.conditionLogic = logic;
139374
+ if (options.priority !== undefined)
139375
+ body.priority = options.priority;
139376
+ if (options.transactionalEmissions !== undefined)
139377
+ body.transactionalEmissions = options.transactionalEmissions;
139378
+ return body;
139379
+ }
139380
+ function buildCreateBody(options) {
139381
+ const body = buildDefinition(options);
139382
+ if (!body.name)
139383
+ throw new Error('--name is required (or "name" in --file)');
139384
+ if (!body.triggerEventType)
139385
+ throw new Error('--trigger is required (or "triggerEventType" in --file)');
139386
+ if (!body.actions || body.actions.length === 0) {
139387
+ throw new Error('At least one --action is required (or "actions" in --file)');
139388
+ }
139389
+ if (options.disabled)
139390
+ body.enabled = false;
139391
+ return body;
139329
139392
  }
139330
139393
  function createAutomationsCommand() {
139331
139394
  const automations2 = new Command("automations").description("Manage automations");
@@ -139363,39 +139426,15 @@ function createAutomationsCommand() {
139363
139426
  error(`Failed to get automation: ${message2}`);
139364
139427
  }
139365
139428
  });
139366
- automations2.command("create").description("Create an automation").requiredOption("--name <name>", "Automation name").requiredOption("--trigger <event>", "Trigger event type (e.g., message.received)").requiredOption("--action <type>", "Action type (webhook, send_message, emit_event, log, call_agent)").option("--action-config <json>", "Action config as JSON").option("--condition <json>", "Trigger conditions as JSON array").option("--condition-logic <logic>", 'Condition logic: "and" (all must match) or "or" (any must match)').option("--description <desc>", "Automation description").option("--priority <n>", "Priority (higher = runs first)", (v4) => Number.parseInt(v4, 10)).option("--disabled", "Create in disabled state").option("--transactional-emissions", "Buffer the run's emit_event publishes and flush them in order only when every action succeeded; " + "a failed run publishes zero (#988). Defaults to off (immediate publishing)").option("--agent-id <id>", "Agent ID (for call_agent action)").option("--provider-id <id>", "Provider ID (for call_agent action)").option("--response-as <var>", "Store agent response as variable (for call_agent action)").action(async (options) => {
139429
+ automations2.command("create").description("Create an automation").option("--file <path>", "Full definition as JSON (the `get` output works as-is); explicit flags override it").option("--name <name>", "Automation name").option("--trigger <event>", "Trigger event type (e.g., message.received)").option("--action <type>", "Action type (webhook, send_message, emit_event, log, call_agent); repeat for ordered multi-action", collectRepeated).option("--action-config <json>", "Action config as JSON; the i-th pairs with the i-th --action", collectRepeated).option("--condition <json>", "Trigger conditions as JSON array").option("--condition-logic <logic>", 'Condition logic: "and" (all must match) or "or" (any must match)').option("--description <desc>", "Automation description").option("--priority <n>", "Priority (higher = runs first)", (v4) => Number.parseInt(v4, 10)).option("--disabled", "Create in disabled state").option("--transactional-emissions", "Buffer the run's emit_event publishes and flush them in order only when every action succeeded; " + "a failed run publishes zero (#988). Defaults to off (immediate publishing)").option("--agent-id <id>", "Agent ID (for the first call_agent action)").option("--provider-id <id>", "Provider ID (for the first call_agent action)").option("--response-as <var>", "Store agent response as variable (for the first call_agent action)").action(async (options) => {
139367
139430
  const client = getClient();
139368
139431
  try {
139369
- const actionResult = buildActionConfig(options);
139370
- if (!actionResult.ok) {
139371
- error(actionResult.error);
139372
- return;
139373
- }
139374
- const conditionResult = parseConditions(options);
139375
- if (!conditionResult.ok) {
139376
- error(conditionResult.error);
139377
- return;
139378
- }
139379
- const automation = await client.automations.create({
139380
- name: options.name,
139381
- description: options.description,
139382
- triggerEventType: options.trigger,
139383
- triggerConditions: conditionResult.conditions,
139384
- conditionLogic: conditionResult.logic,
139385
- actions: [
139386
- {
139387
- type: options.action,
139388
- config: actionResult.config
139389
- }
139390
- ],
139391
- priority: options.priority,
139392
- enabled: !options.disabled,
139393
- transactionalEmissions: options.transactionalEmissions
139394
- });
139432
+ const automation = await client.automations.create(buildCreateBody(options));
139395
139433
  success(`Automation created: ${automation.id}`, {
139396
139434
  id: automation.id,
139397
139435
  name: automation.name,
139398
139436
  trigger: automation.triggerEventType,
139437
+ actions: automation.actions.length,
139399
139438
  enabled: automation.enabled
139400
139439
  });
139401
139440
  } catch (err2) {
@@ -139403,19 +139442,21 @@ function createAutomationsCommand() {
139403
139442
  error(`Failed to create automation: ${message2}`);
139404
139443
  }
139405
139444
  });
139406
- automations2.command("update <id>").description("Update an automation").option("--name <name>", "New name").option("--description <desc>", "New description").option("--priority <n>", "New priority", (v4) => Number.parseInt(v4, 10)).option("--transactional-emissions", "Buffer the run's emit_event publishes and flush them in order only when every action succeeded; " + "a failed run publishes zero (#988)").option("--no-transactional-emissions", "Return the automation to immediate mid-sequence publishing").action(async (id, options) => {
139445
+ automations2.command("update <id>").description("Update an automation in place (id and execution logs are kept)").option("--file <path>", "Full definition as JSON (the `get` output works as-is); explicit flags override it").option("--name <name>", "New name").option("--description <desc>", "New description").option("--trigger <event>", "New trigger event type").option("--condition <json>", "Replace trigger conditions (JSON array)").option("--condition-logic <logic>", 'Condition logic: "and" or "or"').option("--action <type>", "Replace the actions list; repeat for ordered multi-action", collectRepeated).option("--action-config <json>", "Action config as JSON; the i-th pairs with the i-th --action", collectRepeated).option("--priority <n>", "New priority", (v4) => Number.parseInt(v4, 10)).option("--transactional-emissions", "Buffer the run's emit_event publishes and flush them in order only when every action succeeded; " + "a failed run publishes zero (#988)").option("--no-transactional-emissions", "Return the automation to immediate mid-sequence publishing").option("--agent-id <id>", "Agent ID (for the first call_agent action)").option("--provider-id <id>", "Provider ID (for the first call_agent action)").option("--response-as <var>", "Store agent response as variable (for the first call_agent action)").action(async (id, options) => {
139407
139446
  const client = getClient();
139408
139447
  try {
139448
+ const body = buildDefinition(options);
139449
+ if (Object.keys(body).length === 0) {
139450
+ error("Nothing to update: pass at least one field flag or --file");
139451
+ return;
139452
+ }
139409
139453
  const automationId = await resolveAutomationId(id);
139410
- const automation = await client.automations.update(automationId, {
139411
- name: options.name,
139412
- description: options.description,
139413
- priority: options.priority,
139414
- transactionalEmissions: options.transactionalEmissions
139415
- });
139454
+ const automation = await client.automations.update(automationId, body);
139416
139455
  success(`Automation updated: ${automation.id}`, {
139417
139456
  id: automation.id,
139418
- name: automation.name
139457
+ name: automation.name,
139458
+ trigger: automation.triggerEventType,
139459
+ actions: automation.actions.length
139419
139460
  });
139420
139461
  } catch (err2) {
139421
139462
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
@@ -142475,7 +142516,7 @@ init_src2();
142475
142516
  init_config();
142476
142517
  init_output();
142477
142518
  import { spawnSync } from "child_process";
142478
- import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync2, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
142519
+ import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync8, renameSync as renameSync2, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
142479
142520
  import { homedir as homedir7 } from "os";
142480
142521
  import { join as join11 } from "path";
142481
142522
  import { gunzipSync as gunzipSync2, gzipSync as gzipSync2 } from "zlib";
@@ -142668,7 +142709,7 @@ function getEmbeddedPgserveDataDir() {
142668
142709
  }
142669
142710
  function embeddedServerMajor() {
142670
142711
  try {
142671
- const v4 = Number.parseInt(readFileSync7(join11(getEmbeddedPgserveDataDir(), "PG_VERSION"), "utf8").trim(), 10);
142712
+ const v4 = Number.parseInt(readFileSync8(join11(getEmbeddedPgserveDataDir(), "PG_VERSION"), "utf8").trim(), 10);
142672
142713
  return Number.isFinite(v4) ? v4 : null;
142673
142714
  } catch {
142674
142715
  return null;
@@ -142683,7 +142724,7 @@ function getCanonicalPgserveDataDir() {
142683
142724
  if (!existsSync9(PGSERVE_CONFIG_PATH))
142684
142725
  return PGSERVE_DEFAULT_DATA_DIR;
142685
142726
  try {
142686
- const raw2 = readFileSync7(PGSERVE_CONFIG_PATH, "utf8");
142727
+ const raw2 = readFileSync8(PGSERVE_CONFIG_PATH, "utf8");
142687
142728
  const parsed = JSON.parse(raw2);
142688
142729
  return typeof parsed.dataDir === "string" && parsed.dataDir.length > 0 ? parsed.dataDir : PGSERVE_DEFAULT_DATA_DIR;
142689
142730
  } catch {
@@ -142765,7 +142806,7 @@ async function restoreSnapshotToCanonical(dump, canonicalDatabaseUrl) {
142765
142806
  raw(` snapshot: ${dump.snapshotPath}`);
142766
142807
  raw(` canonical data dir: ${getCanonicalPgserveDataDir()}`);
142767
142808
  raw(` canonical URL: ${canonicalDatabaseUrl}`);
142768
- const compressed = readFileSync7(dump.snapshotPath);
142809
+ const compressed = readFileSync8(dump.snapshotPath);
142769
142810
  const sql = gunzipSync2(compressed);
142770
142811
  const result = spawnSync("psql", ["-v", "ON_ERROR_STOP=1"], {
142771
142812
  env: { ...process.env, ...pgEnvFromUrl(canonicalDatabaseUrl) },
@@ -143673,7 +143714,7 @@ Safety:
143673
143714
  }
143674
143715
 
143675
143716
  // src/commands/done.ts
143676
- import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
143717
+ import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
143677
143718
  import { basename, extname } from "path";
143678
143719
 
143679
143720
  // src/context.ts
@@ -143787,7 +143828,7 @@ async function handleMedia(client, ctx, mediaPath, caption) {
143787
143828
  }
143788
143829
  try {
143789
143830
  const mediaType = getMediaType(mediaPath);
143790
- const buffer3 = readFileSync9(mediaPath);
143831
+ const buffer3 = readFileSync10(mediaPath);
143791
143832
  const base64 = buffer3.toString("base64");
143792
143833
  const filename = basename(mediaPath);
143793
143834
  await client.messages.sendMedia({
@@ -143846,7 +143887,7 @@ function createDoneCommand() {
143846
143887
 
143847
143888
  // src/commands/events.ts
143848
143889
  init_src();
143849
- import { readFileSync as readFileSync10 } from "fs";
143890
+ import { readFileSync as readFileSync11 } from "fs";
143850
143891
  init_zod();
143851
143892
  init_config();
143852
143893
  init_output();
@@ -144034,13 +144075,19 @@ function loadSchemaArtifact(options) {
144034
144075
  if ((options.file ? 1 : 0) + (options.schema ? 1 : 0) !== 1) {
144035
144076
  throw new Error("Provide the JSON Schema via exactly one of --file <path> or --schema <json>");
144036
144077
  }
144037
- const raw2 = options.file ? readFileSync10(options.file, "utf-8") : options.schema;
144078
+ const raw2 = options.file ? readFileSync11(options.file, "utf-8") : options.schema;
144038
144079
  const parsed = JSON.parse(raw2);
144039
144080
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
144040
144081
  throw new Error("The JSON Schema artifact must be a JSON object");
144041
144082
  }
144042
144083
  return parsed;
144043
144084
  }
144085
+ function loadPayload(options) {
144086
+ if ((options.file ? 1 : 0) + (options.payload ? 1 : 0) !== 1) {
144087
+ throw new Error("Provide the payload via exactly one of --file <path> or --payload <json>");
144088
+ }
144089
+ return JSON.parse(options.file ? readFileSync11(options.file, "utf-8") : options.payload);
144090
+ }
144044
144091
  function summarizeSchemaRow(row) {
144045
144092
  return {
144046
144093
  eventType: row.eventType,
@@ -144093,6 +144140,29 @@ function createSchemaCommand() {
144093
144140
  error(`Failed to get schema: ${message2}`);
144094
144141
  }
144095
144142
  });
144143
+ schema.command("validate <eventType>").description("Validate a payload against the registered schema without emitting an event (exit 1 on violations)").option("--file <path>", "Path to a JSON payload file").option("--payload <json>", "Inline JSON payload").action(async (eventType, options) => {
144144
+ let result;
144145
+ try {
144146
+ const payload = loadPayload(options);
144147
+ const res = await schemaApiRequest(`/${encodeURIComponent(eventType)}/validate`, {
144148
+ method: "POST",
144149
+ body: JSON.stringify({ payload })
144150
+ });
144151
+ result = res.data;
144152
+ } catch (err2) {
144153
+ const message2 = err2 instanceof Error ? err2.message : "Unknown error";
144154
+ error(`Failed to validate payload: ${message2}`, undefined, 2);
144155
+ }
144156
+ if (result.valid) {
144157
+ success(`Payload is valid for ${result.eventType} (schema version ${result.version})`, result);
144158
+ return;
144159
+ }
144160
+ if (getCurrentFormat() === "human") {
144161
+ for (const line of result.errors)
144162
+ raw(` - ${line}`);
144163
+ }
144164
+ error(`Payload violates the schema for ${result.eventType} (schema version ${result.version}): ${result.errors.length} issue(s)`, getCurrentFormat() === "json" ? result : undefined);
144165
+ });
144096
144166
  return schema;
144097
144167
  }
144098
144168
  function eventListRow(e10) {
@@ -144626,7 +144696,7 @@ function createEventsCommand() {
144626
144696
  }
144627
144697
 
144628
144698
  // src/commands/film.ts
144629
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
144699
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "fs";
144630
144700
  import { resolve as resolvePath } from "path";
144631
144701
  init_output();
144632
144702
  function createFilmCommand() {
@@ -144670,7 +144740,7 @@ function createFilmCommand() {
144670
144740
  let imageMimeType;
144671
144741
  if (options.reference) {
144672
144742
  try {
144673
- const ref = readFileSync11(resolvePath(options.reference));
144743
+ const ref = readFileSync12(resolvePath(options.reference));
144674
144744
  imageBase64 = ref.toString("base64");
144675
144745
  imageMimeType = mimeForImagePath(options.reference);
144676
144746
  } catch (err2) {
@@ -144742,7 +144812,7 @@ function mimeForImagePath(path) {
144742
144812
  }
144743
144813
 
144744
144814
  // src/commands/follow-up.ts
144745
- import { readFileSync as readFileSync12 } from "fs";
144815
+ import { readFileSync as readFileSync13 } from "fs";
144746
144816
  init_output();
144747
144817
  var VALID_SCOPES = ["agents", "instances", "chats"];
144748
144818
  function assertScope(scope) {
@@ -144760,9 +144830,9 @@ async function resolveScopedId(scope, id) {
144760
144830
  function readJsonArg(raw2) {
144761
144831
  let body = raw2;
144762
144832
  if (body === "-") {
144763
- body = readFileSync12(0, "utf8");
144833
+ body = readFileSync13(0, "utf8");
144764
144834
  } else if (body.startsWith("@")) {
144765
- body = readFileSync12(body.slice(1), "utf8");
144835
+ body = readFileSync13(body.slice(1), "utf8");
144766
144836
  }
144767
144837
  try {
144768
144838
  return JSON.parse(body);
@@ -146476,7 +146546,7 @@ function formatKeyRow(key) {
146476
146546
  function parseCommaSeparated(value) {
146477
146547
  return value.split(",").map((s2) => s2.trim()).filter(Boolean);
146478
146548
  }
146479
- function collectRepeated(value, previous) {
146549
+ function collectRepeated2(value, previous) {
146480
146550
  return [...previous ?? [], value];
146481
146551
  }
146482
146552
  async function readLineFromStdin() {
@@ -146695,7 +146765,7 @@ async function handleDelete(client, id) {
146695
146765
  }
146696
146766
  function createKeysCommand() {
146697
146767
  const keys = new Command("keys").description("Manage API keys");
146698
- keys.command("create").description("Create a new API key (optionally from a profile template)").requiredOption("--name <name>", "Key name").option("--profile <name>", "Profile template: cs | personal | scout | coworker | admin").option("--scopes <scopes>", "Comma-separated scopes (legacy \u2014 omit when --profile is set; scopes derive from the profile)").option("--lock-chat <jid>", "Lock this key to a chat (repeat for multiple)", collectRepeated).option("--lock-instance <id>", "Lock this key to an instance (repeat for multiple)", collectRepeated).option("--owner <jid>", "Scout: owner JID \u2014 populates outboundRecipientAllowlist").option("--denylist-preset <key>", "Coworker: denylist preset key (overrides profile default)").option("--instances <ids>", "Comma-separated instance IDs to restrict access (legacy)").option("--description <desc>", "Key description").option("--rate-limit <n>", "Rate limit (requests/minute)", Number.parseInt).option("--expires <date>", "Expiration date (ISO 8601)").action(async (options) => {
146768
+ keys.command("create").description("Create a new API key (optionally from a profile template)").requiredOption("--name <name>", "Key name").option("--profile <name>", "Profile template: cs | personal | scout | coworker | admin").option("--scopes <scopes>", "Comma-separated scopes (legacy \u2014 omit when --profile is set; scopes derive from the profile)").option("--lock-chat <jid>", "Lock this key to a chat (repeat for multiple)", collectRepeated2).option("--lock-instance <id>", "Lock this key to an instance (repeat for multiple)", collectRepeated2).option("--owner <jid>", "Scout: owner JID \u2014 populates outboundRecipientAllowlist").option("--denylist-preset <key>", "Coworker: denylist preset key (overrides profile default)").option("--instances <ids>", "Comma-separated instance IDs to restrict access (legacy)").option("--description <desc>", "Key description").option("--rate-limit <n>", "Rate limit (requests/minute)", Number.parseInt).option("--expires <date>", "Expiration date (ISO 8601)").action(async (options) => {
146699
146769
  const needsClient = options.profile !== "admin";
146700
146770
  const client = needsClient ? getClient() : null;
146701
146771
  try {
@@ -148098,7 +148168,7 @@ init_output();
148098
148168
  init_src();
148099
148169
  import { execFileSync as execFileSync4, execSync } from "child_process";
148100
148170
  import * as nodeCrypto2 from "crypto";
148101
- import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "fs";
148171
+ import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "fs";
148102
148172
  import { homedir as homedir11 } from "os";
148103
148173
  import { dirname as dirname6, resolve as resolve3 } from "path";
148104
148174
  import { createInterface as createInterface2 } from "readline";
@@ -148331,7 +148401,7 @@ var PLUGIN_MARKER = "plugin-openclaw/omni.ts";
148331
148401
  function readOpenClawConfig(configPath) {
148332
148402
  if (!existsSync15(configPath))
148333
148403
  return {};
148334
- const raw2 = readFileSync14(configPath, "utf-8").trim();
148404
+ const raw2 = readFileSync15(configPath, "utf-8").trim();
148335
148405
  if (!raw2)
148336
148406
  return {};
148337
148407
  return JSON.parse(raw2);
@@ -149503,7 +149573,7 @@ function createScheduleCommand() {
149503
149573
  }
149504
149574
 
149505
149575
  // src/commands/see.ts
149506
- import { existsSync as existsSync16, readFileSync as readFileSync15, statSync as statSync5 } from "fs";
149576
+ import { existsSync as existsSync16, readFileSync as readFileSync16, statSync as statSync5 } from "fs";
149507
149577
  import { extname as extname4 } from "path";
149508
149578
  init_output();
149509
149579
  var MIME_BY_EXT = {
@@ -149546,7 +149616,7 @@ function loadMedia(file) {
149546
149616
  error(`File is empty: ${file}`);
149547
149617
  }
149548
149618
  try {
149549
- return { buffer: readFileSync15(file), mimeType: guessMimeType(file) };
149619
+ return { buffer: readFileSync16(file), mimeType: guessMimeType(file) };
149550
149620
  } catch (err2) {
149551
149621
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
149552
149622
  return error(`Failed to read ${file}: ${message2}`);
@@ -149621,7 +149691,7 @@ function createSeeCommand() {
149621
149691
  }
149622
149692
 
149623
149693
  // src/commands/send.ts
149624
- import { existsSync as existsSync17, readFileSync as readFileSync16 } from "fs";
149694
+ import { existsSync as existsSync17, readFileSync as readFileSync17 } from "fs";
149625
149695
  import { basename as basename5, extname as extname5 } from "path";
149626
149696
  init_source();
149627
149697
  init_zod();
@@ -149642,7 +149712,7 @@ function getMediaType2(path) {
149642
149712
  return "document";
149643
149713
  }
149644
149714
  function readFileAsBase64(path) {
149645
- const buffer3 = readFileSync16(path);
149715
+ const buffer3 = readFileSync17(path);
149646
149716
  return buffer3.toString("base64");
149647
149717
  }
149648
149718
  function parseLoadingMessages(value) {
@@ -151715,7 +151785,7 @@ async function cleanupLegacyArtifacts(skipList) {
151715
151785
  init_output();
151716
151786
 
151717
151787
  // src/update-diagnostics.ts
151718
- import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync17, writeFileSync as writeFileSync11 } from "fs";
151788
+ import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync18, writeFileSync as writeFileSync11 } from "fs";
151719
151789
  import { homedir as homedir13 } from "os";
151720
151790
  import { join as join18 } from "path";
151721
151791
  var UPDATE_DIAGNOSTICS_SCHEMA_VERSION = 1;
@@ -151750,7 +151820,7 @@ function tailFileLines(path, maxLines) {
151750
151820
  if (!existsSync19(path))
151751
151821
  return [];
151752
151822
  try {
151753
- const raw2 = readFileSync17(path, "utf8");
151823
+ const raw2 = readFileSync18(path, "utf8");
151754
151824
  const lines = raw2.split(/\r?\n/);
151755
151825
  if (lines.length > 0 && lines[lines.length - 1] === "")
151756
151826
  lines.pop();
@@ -152434,7 +152504,7 @@ ${lines.join(`
152434
152504
  }
152435
152505
 
152436
152506
  // src/commands/webhooks.ts
152437
- import { readFileSync as readFileSync18 } from "fs";
152507
+ import { readFileSync as readFileSync19 } from "fs";
152438
152508
  init_zod();
152439
152509
  init_output();
152440
152510
  var SIGNATURE_ALGORITHMS = ["hmac-sha256", "hmac-sha1", "token-match"];
@@ -152522,7 +152592,7 @@ function resolveEventTypeMapping(raw2) {
152522
152592
  if (raw2.startsWith("@")) {
152523
152593
  const path = raw2.slice(1);
152524
152594
  try {
152525
- text3 = readFileSync18(path, "utf-8");
152595
+ text3 = readFileSync19(path, "utf-8");
152526
152596
  } catch (err2) {
152527
152597
  const reason = err2 instanceof Error ? err2.message : "Unknown error";
152528
152598
  throw new Error(`Cannot read --event-type-mapping file '${path}': ${reason}`);
@@ -152737,7 +152807,7 @@ function createWebhooksCommand() {
152737
152807
  error(`Failed to delete webhook source: ${message2}`);
152738
152808
  }
152739
152809
  });
152740
- webhooks.command("trigger").description("Trigger a custom event").requiredOption("--type <type>", "Event type").requiredOption("--payload <json>", "Event payload as JSON").option("--instance <id>", "Instance ID").option("--correlation-id <id>", "Correlation ID").action(async (options3) => {
152810
+ webhooks.command("trigger").description("Trigger a custom event").requiredOption("--type <type>", "Event type").requiredOption("--payload <json>", "Event payload as JSON").option("--instance <id>", "Instance ID").option("--correlation-id <id>", "Correlation ID").option("--causation-id <event-id>", "Parent event ID (keeps the causality tree for mid-flow emissions, #1072)").action(async (options3) => {
152741
152811
  const client = getClient();
152742
152812
  try {
152743
152813
  let payload;
@@ -152751,7 +152821,8 @@ function createWebhooksCommand() {
152751
152821
  eventType: options3.type,
152752
152822
  payload,
152753
152823
  instanceId: options3.instance,
152754
- correlationId: options3.correlationId
152824
+ correlationId: options3.correlationId,
152825
+ causationId: options3.causationId
152755
152826
  });
152756
152827
  success(`Event triggered: ${result.eventId}`, {
152757
152828
  eventId: result.eventId,
@@ -152808,7 +152879,7 @@ init_config();
152808
152879
  init_output();
152809
152880
 
152810
152881
  // src/manifest-pin.ts
152811
- import { existsSync as existsSync21, readFileSync as readFileSync19, renameSync as renameSync3, writeFileSync as writeFileSync12 } from "fs";
152882
+ import { existsSync as existsSync21, readFileSync as readFileSync20, renameSync as renameSync3, writeFileSync as writeFileSync12 } from "fs";
152812
152883
  import { homedir as homedir14 } from "os";
152813
152884
  import { join as join20 } from "path";
152814
152885
  var PACKAGE_NAME2 = "@automagik/omni";
@@ -152818,7 +152889,7 @@ function pinManifestEntry(manifestPath, exactVersion) {
152818
152889
  return false;
152819
152890
  let manifest;
152820
152891
  try {
152821
- manifest = JSON.parse(readFileSync19(manifestPath, "utf-8"));
152892
+ manifest = JSON.parse(readFileSync20(manifestPath, "utf-8"));
152822
152893
  } catch {
152823
152894
  return false;
152824
152895
  }
@@ -722,6 +722,8 @@ export interface TriggerEventBody {
722
722
  eventType: string;
723
723
  payload: Record<string, unknown>;
724
724
  correlationId?: string;
725
+ /** Parent event id — stamps `causationId` so `events trace` parents this emission (#1072). */
726
+ causationId?: string;
725
727
  instanceId?: string;
726
728
  }
727
729
  /**