@automagik/omni 2.260731.2 → 2.260731.3

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.
@@ -24,8 +24,13 @@
24
24
  * when the stored value is the legacy 5432 default.
25
25
  * 4. Always include `OMNI_PACKAGES_DIR` (drift-fix between install.ts and
26
26
  * restart.ts) and honor the dynamic `nodeEnv` / `logLevel` from config.
27
+ * 5. NEVER derive `OMNI_API_KEY` from the *active* server entry. The
28
+ * multi-server registry (`config.servers`) lets an operator point the CLI
29
+ * at a remote Omni API; the locally supervised process must keep using the
30
+ * LOCAL (`default`) entry, so `cliConfig` must always come from
31
+ * `loadLocalRuntimeConfig()` — which is also this module's default.
27
32
  */
28
- import type { Config, ServerConfig } from './config.js';
33
+ import { type Config, type ServerConfig } from './config.js';
29
34
  /**
30
35
  * Environment object suitable for passing to `runPm2` as `envOverrides`
31
36
  * (and onward to the managed omni-api process).
@@ -120,6 +125,10 @@ export declare function resolveDatabaseUrl(serverConfig: ServerConfig): string;
120
125
  * `useCanonicalPgserve: false` triggers a one-shot warning surfaced by
121
126
  * `omni doctor --fix` (which rewrites the config). The env keys remain
122
127
  * in {@link RuntimeEnv} until a future major bumps the env contract.
128
+ *
129
+ * `cliConfig` defaults to {@link loadLocalRuntimeConfig} — the LOCAL
130
+ * (`default`) server entry — so the local process can never inherit a remote
131
+ * server's API key even if a caller forgets to pass one (see rule 5 above).
123
132
  */
124
- export declare function buildRuntimeEnv(serverConfig: ServerConfig, cliConfig: Config): RuntimeEnv;
133
+ export declare function buildRuntimeEnv(serverConfig: ServerConfig, cliConfig?: Config): RuntimeEnv;
125
134
  //# sourceMappingURL=runtime-env.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../src/runtime-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASxD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IAQrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAQF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,OAAoB,CAAC;AAEtD,0EAA0E;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,GAAE,MAA6B,GAAG,MAAM,CAE3F;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAKxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAMrE;AAgBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAiBrE;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CA2CzF"}
1
+ {"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../src/runtime-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAA0B,MAAM,aAAa,CAAC;AASrF;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IAQrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAQF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,OAAoB,CAAC;AAEtD,0EAA0E;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,GAAE,MAA6B,GAAG,MAAM,CAE3F;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAKxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAMrE;AAgBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAiBrE;AAoBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,GAAE,MAAiC,GAAG,UAAU,CA2CpH"}
@@ -241330,7 +241330,7 @@ var init_sentry_scrub = __esm(() => {
241330
241330
  var require_package7 = __commonJS((exports, module) => {
241331
241331
  module.exports = {
241332
241332
  name: "@omni/api",
241333
- version: "2.260731.2",
241333
+ version: "2.260731.3",
241334
241334
  type: "module",
241335
241335
  exports: {
241336
241336
  ".": {
@@ -350216,6 +350216,13 @@ async function shouldProcessMessage3(agentRunner, accessService, chatsService, m
350216
350216
  log104.debug("Message from self, skipping", { instanceId: metadata.instanceId, from: payload.from });
350217
350217
  return null;
350218
350218
  }
350219
+ if (payload.content?.type === "reaction") {
350220
+ log104.debug("Skipping reaction dual-emit on message path (reaction.received owns dispatch)", {
350221
+ instanceId: metadata.instanceId,
350222
+ chatId: payload.chatId
350223
+ });
350224
+ return null;
350225
+ }
350219
350226
  if (isTrashEmojiOnly(payload.content?.text)) {
350220
350227
  log104.debug("Skipping trash emoji message (session-cleaner handles this)", {
350221
350228
  instanceId: metadata.instanceId,
package/dist/signing.d.ts CHANGED
@@ -23,11 +23,47 @@
23
23
  * See those files for the full spec.
24
24
  */
25
25
  import { type KeyObject } from 'node:crypto';
26
+ /**
27
+ * One server this keypair is registered with, and the host id THAT server
28
+ * issued for it.
29
+ *
30
+ * The id is per-server: each omni instance mints its own row (its own UUID)
31
+ * when the pubkey is handshaken there. Carrying a single id across servers
32
+ * makes every request to the other servers 401 "unknown host", which is why
33
+ * bindings are (url, hostId) pairs rather than bare urls.
34
+ */
35
+ export interface ServerBinding {
36
+ url: string;
37
+ hostId: string;
38
+ }
26
39
  export interface OmniHostMetadata {
40
+ /**
41
+ * The host id issued by the FIRST server this keypair was registered with.
42
+ * Kept as the legacy/default id (older CLIs read only this field, and
43
+ * {@link loadSigningContext} still uses it); never overwritten by binding an
44
+ * additional server — only a `--rotate` handshake replaces it.
45
+ */
27
46
  hostId: string;
28
47
  pubkey: string;
29
48
  hostname: string;
30
49
  registeredAt: string;
50
+ /**
51
+ * Servers this keypair is registered with, each with the host id that server
52
+ * issued. URLs are normalized by {@link normalizeServerUrl}.
53
+ *
54
+ * A handshake registers the pubkey with ONE server; other servers in the
55
+ * registry have never seen it, so signing headers sent to them are at best
56
+ * ignored and at worst rejected. Requests therefore carry X-Genie-* headers
57
+ * only for bound servers — everything else goes bearer-only.
58
+ *
59
+ * Legacy shapes are coerced on load (see {@link loadHostMetadata}):
60
+ * - ABSENT (host.json written before multi-server support) → bound to the
61
+ * local `default` entry, the only server those installs could have
62
+ * handshaken against, with the top-level `hostId`.
63
+ * - `string[]` (written before per-server ids) → each url paired with the
64
+ * top-level `hostId`.
65
+ */
66
+ boundServers?: ServerBinding[];
31
67
  }
32
68
  export interface SigningHeaders {
33
69
  'X-Genie-Host-Id': string;
@@ -65,11 +101,43 @@ export declare function signRequest(opts: {
65
101
  body: string;
66
102
  now?: Date;
67
103
  }): SigningHeaders;
104
+ /**
105
+ * Canonical form of a server base URL for binding comparisons: trimmed, with
106
+ * trailing slashes removed. Deliberately conservative — host casing and port
107
+ * are left alone so `localhost` and `127.0.0.1` stay distinct entries.
108
+ */
109
+ export declare function normalizeServerUrl(url: string): string;
110
+ /**
111
+ * Read `~/.omni/keys/host.json`, or null when this CLI has never handshaken.
112
+ *
113
+ * Requires the private key to exist too: metadata without a key cannot sign,
114
+ * and treating that state as "handshook" would make every caller fail later
115
+ * with a confusing crypto error instead of falling back to bearer-only.
116
+ */
117
+ export declare function loadHostMetadata(): OmniHostMetadata | null;
118
+ /** Bindings of loaded metadata — always populated by {@link loadHostMetadata}. */
119
+ export declare function boundServerBindings(meta: OmniHostMetadata): ServerBinding[];
120
+ /** Base URLs of the servers this keypair is registered with. */
121
+ export declare function boundServerUrls(meta: OmniHostMetadata): string[];
122
+ /** The binding for `url`, or undefined when that server has never seen this key. */
123
+ export declare function bindingForServer(meta: OmniHostMetadata, url: string): ServerBinding | undefined;
124
+ /**
125
+ * Signing context for a specific target server, or null when requests to that
126
+ * server must go out unsigned (no keypair at all, or a keypair the target
127
+ * server has never seen).
128
+ *
129
+ * Uses the host id THAT server issued — not the top-level one, which belongs to
130
+ * whichever server was handshaken first.
131
+ */
132
+ export declare function loadSigningContextForServer(url: string): SigningContext | null;
68
133
  /**
69
134
  * Load the operator's signing context from `~/.omni/keys/`. Returns null
70
135
  * when no keypair is present (the CLI then continues bearer-only — same
71
136
  * behavior as before this module existed).
72
137
  *
138
+ * Ignores server binding — callers that put headers on the wire should use
139
+ * {@link loadSigningContextForServer} instead.
140
+ *
73
141
  * Errors loading an existing keypair (file unreadable, malformed JSON,
74
142
  * etc.) bubble up — silently falling back to bearer would mask a key
75
143
  * file that was tampered with or partially written.
@@ -1 +1 @@
1
- {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAqE,MAAM,aAAa,CAAC;AAShH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC;CACzE;AAOD,iBAAS,cAAc,IAAI,MAAM,CAEhC;AAED,iBAAS,aAAa,IAAI,MAAM,CAE/B;AAED,iBAAS,YAAY,IAAI,MAAM,CAE9B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3G;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,cAAc,CASjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,GAAG,IAAI,CAa1D;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,IAAI;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,SAAS,CAAA;CAAE,CA2BzF;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAM9D;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM;;;;CAIlB,CAAC"}
1
+ {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAqE,MAAM,aAAa,CAAC;AAShH;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;;;;OAeG;IACH,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC;CACzE;AAOD,iBAAS,cAAc,IAAI,MAAM,CAEhC;AAED,iBAAS,aAAa,IAAI,MAAM,CAE/B;AAED,iBAAS,YAAY,IAAI,MAAM,CAE9B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3G;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,cAAc,CASjB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,GAAG,IAAI,CAS1D;AAsBD,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,aAAa,EAAE,CAE3E;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAEhE;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAG/F;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAU9E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,GAAG,IAAI,CAM1D;AAYD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,IAAI;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,SAAS,CAAA;CAAE,CA2BzF;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAM9D;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM;;;;CAIlB,CAAC"}
package/dist/status.d.ts CHANGED
@@ -6,10 +6,11 @@
6
6
  /**
7
7
  * Get inline status string for help display (synchronous).
8
8
  *
9
- * Returns config-based status:
10
- * - "configured (instance-name)" if API key and instance configured
11
- * - "configured (no default instance)" if API key but no instance
12
- * - "not configured" if no API key
9
+ * Returns config-based status, always naming the server entry it describes —
10
+ * with a registry of several servers, "configured" alone is ambiguous:
11
+ * - "server=prod, configured (instance-name)" if API key and instance configured
12
+ * - "server=prod, configured (no default instance)" if API key but no instance
13
+ * - "server=prod, not configured" if that entry has no API key
13
14
  *
14
15
  * Note: For live connection status, use `omni status` command.
15
16
  */
@@ -17,7 +18,7 @@ export declare function getInlineStatus(): string;
17
18
  /**
18
19
  * Get config summary for help footer.
19
20
  *
20
- * Returns: "instance=name, format=human" or similar
21
+ * Returns: "server=default, instance=name, format=human" or similar
21
22
  */
22
23
  export declare function getConfigSummary(): string;
23
24
  //# sourceMappingURL=status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAaxC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAWzC"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAcxC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAYzC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260731.2",
3
+ "version": "2.260731.3",
4
4
  "description": "LLM-optimized CLI for Omni",
5
5
  "type": "module",
6
6
  "bin": {
@@ -50,7 +50,8 @@
50
50
  "pdf-parse": "^1.1.1",
51
51
  "postgres": "^3.4.5",
52
52
  "qrcode-terminal": "^0.12.0",
53
- "sharp": "^0.34.5"
53
+ "sharp": "^0.34.5",
54
+ "zod": "^3.24.1"
54
55
  },
55
56
  "devDependencies": {
56
57
  "@omni/api": "workspace:*",