omnigateway 0.3.0 → 0.4.1

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 (72) hide show
  1. package/README.md +175 -1
  2. package/bin/omni.js +1155 -40
  3. package/gateway.js +985 -89
  4. package/package.json +1 -1
  5. package/public/assets/{Chip-DbKk1ExR.js → Chip-BltJSw8A.js} +5 -5
  6. package/public/assets/Confirm-gd8Y6snu.js +4 -0
  7. package/public/assets/CopyValue-Dds-Ow9a.js +27 -0
  8. package/public/assets/{Field-B7GOsJf8.js → Field-D-14HF0x.js} +11 -11
  9. package/public/assets/Lamp-BDf7-dMa.js +25 -0
  10. package/public/assets/Match-CgNxphvS.js +1 -0
  11. package/public/assets/Meter-stpt3vQu.js +14 -0
  12. package/public/assets/Modal-Dj3LvMS9.js +82 -0
  13. package/public/assets/Rack-B4c0dbIb.js +180 -0
  14. package/public/assets/{Readout--CQnPjoO.js → Readout-Du15WYx0.js} +5 -5
  15. package/public/assets/{States-CQFkw1UZ.js → States-CxLDlCaw.js} +5 -5
  16. package/public/assets/{Table-Ba58Wg4-.js → Table-CVDZ69Zx.js} +1 -1
  17. package/public/assets/Toggle-DMk46RX2.js +39 -0
  18. package/public/assets/TokenBreakdown-BySwFK6Q.js +31 -0
  19. package/public/assets/_app-Dx_xnlud.js +1 -0
  20. package/public/assets/_app.accounts-DvBYnbfS.js +64 -0
  21. package/public/assets/_app.console-CoaRdkB1.js +44 -0
  22. package/public/assets/_app.database-CES5ec5g.js +39 -0
  23. package/public/assets/_app.index-DwOZe1A-.js +62 -0
  24. package/public/assets/_app.keys-B5HrAu2U.js +76 -0
  25. package/public/assets/_app.logs-NbfIexz0.js +68 -0
  26. package/public/assets/_app.models-B1MdFRtQ.js +148 -0
  27. package/public/assets/_app.plugins._pluginId-ByMziW8p.js +20 -0
  28. package/public/assets/_app.settings-BkDkGkKF.js +46 -0
  29. package/public/assets/_app.usage-DNpM8Nub.js +83 -0
  30. package/public/assets/dist-9ps0Qd15.js +1 -0
  31. package/public/assets/index-gMv8Qs7m.js +178 -0
  32. package/public/assets/login-cCXnl34r.js +36 -0
  33. package/public/assets/matchContext-BOenO3J2.js +1 -0
  34. package/public/assets/plus-fXfUTt6_.js +1 -0
  35. package/public/assets/queries-CIOPbRcE.js +142 -0
  36. package/public/assets/shared-B4o-2quR.js +84 -0
  37. package/public/assets/{trash-2-DTWWI3vA.js → trash-2-ZPh3619D.js} +1 -1
  38. package/public/index.html +7 -2
  39. package/public/shared/chunks/jsx-runtime-CznXPbDH.js +1 -0
  40. package/public/shared/chunks/react-GitiQ0dt.js +1 -0
  41. package/public/shared/chunks/react-dom-BTlfKTOo.js +1 -0
  42. package/public/shared/chunks/rolldown-runtime-CbXtAM7H.js +1 -0
  43. package/public/shared/jsx-runtime.js +1 -0
  44. package/public/shared/react-dom-client.js +9 -0
  45. package/public/shared/react-dom.js +1 -0
  46. package/public/shared/react-query.js +1 -0
  47. package/public/shared/react.js +1 -0
  48. package/public/shared/styled-components.js +7 -0
  49. package/public/assets/Confirm-C5DYoI93.js +0 -4
  50. package/public/assets/CopyValue-CXjietiZ.js +0 -27
  51. package/public/assets/Lamp-QRSv-SqM.js +0 -25
  52. package/public/assets/Meter-Dngwbpjo.js +0 -14
  53. package/public/assets/Modal-DfltaSCz.js +0 -82
  54. package/public/assets/Rack-D1zBw9SW.js +0 -151
  55. package/public/assets/Toggle-DWrWc9-9.js +0 -39
  56. package/public/assets/TokenBreakdown-CyHJv0O5.js +0 -31
  57. package/public/assets/_app-CTDgfstQ.js +0 -1
  58. package/public/assets/_app.accounts-DP6T8z7I.js +0 -64
  59. package/public/assets/_app.console-DYr7TCAl.js +0 -44
  60. package/public/assets/_app.database-BzO1S_VR.js +0 -39
  61. package/public/assets/_app.index-CBt6b-lA.js +0 -62
  62. package/public/assets/_app.keys-B8HGsPPS.js +0 -76
  63. package/public/assets/_app.logs-DKsxa2Su.js +0 -68
  64. package/public/assets/_app.models-CZD2UpM-.js +0 -148
  65. package/public/assets/_app.settings-B2C1LQIF.js +0 -46
  66. package/public/assets/_app.usage-CDWUXtZy.js +0 -83
  67. package/public/assets/dist-IkJ0qg-4.js +0 -1
  68. package/public/assets/index-ClU3Xqui.js +0 -186
  69. package/public/assets/login-E3gh2_Cl.js +0 -36
  70. package/public/assets/plus-DkO4vG-T.js +0 -1
  71. package/public/assets/queries-BJHk_wso.js +0 -144
  72. package/public/assets/shared-Bp35cgFf.js +0 -84
package/README.md CHANGED
@@ -356,6 +356,7 @@ Use `--db <path>` to point one command somewhere else.
356
356
  | `omni credentials …` | list, show, enable, disable, retier, refresh, remove |
357
357
  | `omni models …` | list, show, put, remove, `dry-run`, `catalog` |
358
358
  | `omni keys …` | list, create, revoke |
359
+ | `omni plugin …` | list, verify, install, remove; see [Plugins](#plugins) |
359
360
  | `omni settings get` / `set` | routing weights, retention, deadlines, and the runtime switches |
360
361
  | `omni admin set-password` | change the console password |
361
362
  | `omni db migrate` | create or upgrade the database |
@@ -701,7 +702,180 @@ Worth knowing before you deploy it:
701
702
  - Behind a reverse proxy, set `OMNI_BASE_URL` to the public HTTPS origin so
702
703
  OAuth callbacks match what the providers have registered.
703
704
  - The gateway talks to your providers and to nobody else. No telemetry, no CDN
704
- fonts, no third-party origins.
705
+ fonts, no third-party origins. A plugin may declare outbound origins of its
706
+ own, and `omni plugin verify <id>` shows exactly which ones it asked for — as
707
+ does its manifest, which is a plain file you can read before installing.
708
+ - **Plugins run inside the gateway process, with its privileges.** The
709
+ capability context they are handed is a guardrail against mistakes, not a
710
+ sandbox against malice: a plugin shares the process holding your encryption
711
+ key and decrypted provider credentials, and can reach past the context if it
712
+ wants to. Install plugins you wrote or audited, and read a plugin's manifest —
713
+ it lists every capability and outbound origin it asked for.
714
+
715
+ ## Plugins
716
+
717
+ A plugin adds routes, storage, and a screen in the console to one installation,
718
+ without being part of OmniGateway. Most installations run none.
719
+
720
+ ```bash
721
+ omni plugin install ./some-plugin # a directory, or a .tgz
722
+ omni plugin install https://…/x.tgz # a tarball over https, never http
723
+ omni plugin install some-plugin@1.2.3 # a package name, through the npm registry
724
+ omni plugin verify some-plugin # every check the next boot will run
725
+ omni plugin list # what is installed, and whether it would load
726
+ omni restart # plugins load at boot, so this is required
727
+ ```
728
+
729
+ **Nothing in the package is executed by any of these.** There is no dependency
730
+ resolution, no `node_modules`, and no lifecycle script — the installer fetches,
731
+ checks, and unpacks, and the plugin's own code is first imported at the next boot.
732
+
733
+ A spec is resolved filesystem-first: directory, then local tarball, then URL,
734
+ then registry. That order is the safe one. The reverse would let a published
735
+ package shadow the directory you are standing in and turn `omni plugin install
736
+ some-plugin` into a download nobody asked for.
737
+
738
+ Installing by name refuses more than it accepts, and each refusal happens before
739
+ any bytes are fetched: the tarball must be served from the registry's own host,
740
+ the registry must advertise an integrity hash or a shasum, and only an exact
741
+ version or the registry's `latest` resolves — no ranges, no other dist-tags. Use
742
+ `--registry` (or `OMNI_PLUGIN_REGISTRY`) for a private registry; it must be
743
+ `https://`.
744
+
745
+ A URL you type is different, and the difference is the point: nothing downstream
746
+ has a digest to check it against, so TLS to the host you named is the only
747
+ assurance there is. That is why `http://` is refused rather than upgraded.
748
+
749
+ `omni plugin list` prints what this installation has — id, name, version, the
750
+ plugin API and console SDK it was built against, the capabilities it declared,
751
+ and whether the gateway would load it:
752
+
753
+ ```
754
+ ID NAME VERSION API SDK CAPABILITIES STATE
755
+ pokemon Pokémon Companion 1.0.0 1 ^1.0.0 storage,files,net:outbound,… ok
756
+ ```
757
+
758
+ A plugin that would *not* load is listed with the reason rather than hidden,
759
+ because a plugin missing from the console is exactly what you are trying to
760
+ explain. For one plugin's full detail — its entry points and the outbound
761
+ origins it declared — use `omni plugin verify <id>`.
762
+
763
+ ### Available plugins
764
+
765
+ There is no curated directory to browse, and there is no plan for one. A plugin
766
+ is a directory, a tarball, a URL or a package name you point `omni plugin
767
+ install` at, and you are expected to know where it came from — see the
768
+ [security note](#security) for why that is the model rather than an omission.
769
+
770
+ Resolving a name through npm makes distribution easier; it does not make an
771
+ unknown plugin safer. Integrity checking proves you received the bytes the
772
+ registry advertised, and nothing about who wrote them or what they do once the
773
+ gateway imports them.
774
+
775
+ None ship in this repository, deliberately. The first one did, and moving it out
776
+ is what proved the plugin API actually works from outside: while it built as a
777
+ workspace sibling it could reach internal packages no published plugin can, and
778
+ two bugs hid in exactly that gap.
779
+
780
+ | Plugin | What it does |
781
+ | --- | --- |
782
+ | [`omnigateway-plugin-pokemon`](https://github.com/harismawan/omnigateway-plugin-pokemon) | A Pokémon companion. Each gateway key raises one that hatches, evolves, and graduates into a Pokédex on the tokens that key spends, with a shop that spends a wallet of those same tokens. |
783
+
784
+ ```bash
785
+ omni plugin install omnigateway-plugin-pokemon
786
+ omni plugin verify pokemon
787
+ omni restart
788
+ ```
789
+
790
+ It needs outbound access to `pokeapi.co` and `raw.githubusercontent.com` for
791
+ species data and sprites, which its manifest declares and `omni plugin verify
792
+ pokemon` prints back. Those assets are Nintendo and Game Freak intellectual
793
+ property, fetched at runtime and never vendored — into that repository, this one,
794
+ or anything either publishes.
795
+
796
+ `verify` is the one to run before restarting a gateway that people are using: it
797
+ reaches the same verdict the next boot will, from the same code, without loading
798
+ the plugin.
799
+
800
+ ### Installing on a machine with no checkout
801
+
802
+ A published plugin installs by name, and the host needs no checkout and no build
803
+ toolchain:
804
+
805
+ ```bash
806
+ omni plugin install omnigateway-plugin-example
807
+ omni plugin verify example && omni restart
808
+ ```
809
+
810
+ An `npm pack` tarball is rooted at `package/` rather than at the plugin's name,
811
+ and that is fine: the manifest's `id` names the installed directory when the
812
+ archive root does not.
813
+
814
+ For a plugin you build yourself and do not publish, ship the tarball and install
815
+ from the path:
816
+
817
+ ```bash
818
+ # wherever you build — a workstation, CI
819
+ bun run build # your plugin's own build
820
+ tar -czf my-plugin.tgz -C dist my-plugin
821
+
822
+ # on the host
823
+ scp my-plugin.tgz gateway-host:/tmp/
824
+ ssh gateway-host 'omni plugin install /tmp/my-plugin.tgz && omni plugin verify my-plugin && omni restart'
825
+ ```
826
+
827
+ Whatever you pack, the manifest must sit at the **root** of the archive once one
828
+ wrapping directory is stripped. A build that nests it — `dist/my-plugin/omni-plugin.json`
829
+ inside a tarball made from the repository root — is refused with "has no
830
+ omni-plugin.json at its root", and that is the most common way a plugin that
831
+ builds fine turns out not to install.
832
+
833
+ Plaintext `http://` is refused outright and always will be: what arrives over
834
+ that fetch is code the gateway process will `import`, so anyone between you and
835
+ the host would be choosing what the gateway runs. Silently upgrading to `https://`
836
+ would be worse — it would install *something* from a URL you did not type.
837
+
838
+ **In Docker**, the image carries the gateway only, so a plugin arrives on a
839
+ volume rather than through the CLI. Mount it at `<root>/plugins/<id>` — the same
840
+ layout `install` writes — and restart the container:
841
+
842
+ ```bash
843
+ docker run --rm -p 9000:9000 \
844
+ -e OMNI_ENCRYPTION_KEY="$OMNI_ENCRYPTION_KEY" \
845
+ -v omnigateway-data:/data \
846
+ -v "$PWD/pokemon:/data/plugins/pokemon" \
847
+ omnigateway
848
+ ```
849
+
850
+ **Do not mount it `:ro`** if the plugin declares the `files` capability. A
851
+ plugin's cache lives at `<root>/plugins/<id>/data/`, inside its own directory, and
852
+ the capability creates that directory on every call — so a read-only mount fails
853
+ *reads* as well as writes, with an `EACCES` on `mkdir` rather than anything that
854
+ names the mount. Keeping a plugin's code immutable while its cache stays
855
+ writable is not expressible today; mount the directory read-write.
856
+
857
+ Removing one keeps its data:
858
+
859
+ ```bash
860
+ omni plugin remove some-plugin # directory goes, database tables stay
861
+ omni plugin remove some-plugin --purge # tables too, after confirming
862
+ ```
863
+
864
+ That default is deliberate. A plugin directory can be reinstalled from the
865
+ package it came from; whatever it accumulated in your database cannot be
866
+ reinstalled from anything.
867
+
868
+ Note what "directory goes" includes: a plugin's `data/` directory is removed
869
+ with it. That directory holds cached files a plugin can rebuild — it is excluded
870
+ from [snapshots](#snapshots-and-restore) for that reason, so it has no restore
871
+ path and is not meant to need one. Only the database tables are kept, and only
872
+ those are what `--purge` additionally drops. For the same reason, restoring a snapshot onto an
873
+ installation that no longer has a plugin leaves that plugin's tables in place —
874
+ `omni doctor` reports them, and nothing removes them for you.
875
+
876
+ Read the [security note](#security) on what a plugin can reach before installing
877
+ one you did not write. To write one, see
878
+ [docs/writing-a-plugin.md](docs/writing-a-plugin.md).
705
879
 
706
880
  ## Development
707
881