nervur 0.22.2-7 → 0.23.0
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/AUTHORING.md +87 -57
- package/COMMAND.md +73 -22
- package/FACES.md +22 -17
- package/FACULTIES.md +50 -30
- package/GROUNDS.md +185 -82
- package/README.md +8 -8
- package/dist/bench/bench-ground.d.ts +6 -6
- package/dist/bench/bench-ground.js +55 -27
- package/dist/browser/browser-ground.d.ts +4 -4
- package/dist/browser/browser-ground.js +95 -31
- package/dist/edge/edge-ground.d.ts +5 -5
- package/dist/edge/edge-ground.js +85 -61
- package/dist/edge/secret-unlock.d.ts +1 -1
- package/dist/edge/secret-unlock.js +1 -1
- package/dist/ground/dock.d.ts +1460 -0
- package/dist/ground/dock.js +1159 -0
- package/dist/ground/ground.d.ts +138 -235
- package/dist/ground/ground.js +610 -661
- package/dist/ground/views.d.ts +17 -0
- package/dist/ground/views.js +20 -0
- package/dist/house/crossing.d.ts +3 -2
- package/dist/house/crossing.js +5 -4
- package/dist/house/house.d.ts +11 -1
- package/dist/house/house.js +104 -26
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/node/bridge.d.ts +3 -3
- package/dist/node/bridge.js +2 -2
- package/dist/node/cli.js +63 -31
- package/dist/node/hand.d.ts +4 -3
- package/dist/node/hand.js +3 -3
- package/dist/node/node-ground.d.ts +6 -7
- package/dist/node/node-ground.js +167 -101
- package/dist/node/shell.d.ts +11 -0
- package/dist/node/shell.js +35 -0
- package/dist/node/tcp-carry.d.ts +4 -2
- package/dist/node/tcp-carry.js +14 -5
- package/package.json +2 -1
package/AUTHORING.md
CHANGED
|
@@ -11,8 +11,8 @@ The shop has three classes and one faculty.
|
|
|
11
11
|
- `Order` is one order, from its first item to its shipping.
|
|
12
12
|
- `Shop` is the steward, the being that runs the house.
|
|
13
13
|
- `Lobby` is the public being, which strangers may ask.
|
|
14
|
-
- `Payments` is a faculty that charges money, which
|
|
15
|
-
|
|
14
|
+
- `Payments` is a faculty that charges money, which `recipe.ts` holds
|
|
15
|
+
by name.
|
|
16
16
|
|
|
17
17
|
## Words
|
|
18
18
|
|
|
@@ -32,7 +32,8 @@ The shop has three classes and one faculty.
|
|
|
32
32
|
| state | a name read from her cells that decides which asks exist |
|
|
33
33
|
| house | what holds beings, keeps their cells, and seals every ask |
|
|
34
34
|
| ground | the process houses run in, holding one key and sealing their seeds, faculties and secrets under it |
|
|
35
|
-
| registry | code that
|
|
35
|
+
| registry | code that holds faculties by name, for the ground to stand |
|
|
36
|
+
| body | a faculty stood: the living instance houses and bodies use |
|
|
36
37
|
|
|
37
38
|
## A being
|
|
38
39
|
|
|
@@ -588,8 +589,8 @@ type Answer = { result: { pending: boolean } } | { error: { message: string } };
|
|
|
588
589
|
/**
|
|
589
590
|
* A payment provider in the ground's process. It answers a call id it has
|
|
590
591
|
* seen with the answer it gave, so an effect sent twice charges once. A
|
|
591
|
-
* provider that changes the world keeps these in the memory its
|
|
592
|
-
* receives, where a restart and a move keep them.
|
|
592
|
+
* provider that changes the world keeps these in the memory its faculty's
|
|
593
|
+
* `up` receives, where a restart and a move keep them.
|
|
593
594
|
*/
|
|
594
595
|
export class Payments {
|
|
595
596
|
readonly #answered = new Map<string, Answer>();
|
|
@@ -619,19 +620,19 @@ export const paymentsOffer = (payments: Payments): Offer => ({ blueprint: Paymen
|
|
|
619
620
|
|
|
620
621
|
An offer is `{ blueprint, object, kinds?, window? }`. The object answers
|
|
621
622
|
each call with its call id, and one that changes the world answers a
|
|
622
|
-
call id it has seen with the answer it gave. A registry holds
|
|
623
|
-
|
|
624
|
-
its
|
|
625
|
-
[Writing a faculty](FACULTIES.md) teaches the
|
|
626
|
-
written in Python.
|
|
623
|
+
call id it has seen with the answer it gave. A registry holds each
|
|
624
|
+
faculty by name, as `{ up, install? }`. The ground raises a faculty by
|
|
625
|
+
its `up` when an entry names it, and the entry's `kinds` grants it to
|
|
626
|
+
the classes it names. [Writing a faculty](FACULTIES.md) teaches the
|
|
627
|
+
craft whole, with a faculty written in Python.
|
|
627
628
|
|
|
628
629
|
```ts
|
|
629
630
|
// recipe.ts
|
|
630
631
|
import { Payments, paymentsOffer } from './payments.ts';
|
|
631
632
|
|
|
632
|
-
// A registry: the ground
|
|
633
|
+
// A registry: the ground raises each faculty an entry names by its `up` here.
|
|
633
634
|
export const faculties = {
|
|
634
|
-
payments: () => paymentsOffer(new Payments()),
|
|
635
|
+
payments: { up: () => paymentsOffer(new Payments()) },
|
|
635
636
|
};
|
|
636
637
|
```
|
|
637
638
|
|
|
@@ -640,8 +641,8 @@ export const faculties = {
|
|
|
640
641
|
A ground is the process houses run in, and you write none. `nervur up`
|
|
641
642
|
runs one on a folder of code: a folder for each house, and each module
|
|
642
643
|
your entries name. It holds one key in `state/`, and keeps every entry
|
|
643
|
-
sealed
|
|
644
|
-
which bodies.
|
|
644
|
+
sealed as the cells of its dock's beings: which faculties stand, and
|
|
645
|
+
which houses open on which bodies.
|
|
645
646
|
|
|
646
647
|
### The shop's folder
|
|
647
648
|
|
|
@@ -680,29 +681,44 @@ npx nervur up .
|
|
|
680
681
|
The ground boots in one order, and a stop is that order reversed, on an
|
|
681
682
|
interrupt and on `SIGTERM`.
|
|
682
683
|
|
|
683
|
-
1. **
|
|
684
|
-
|
|
685
|
-
start.
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
684
|
+
1. **Primordial.** Its ledger goes up and takes the lock on its state,
|
|
685
|
+
so one ground runs on it. Its unlock, crypto and tools go up. Its key
|
|
686
|
+
is read from `state/key`, drawn there on the first start.
|
|
687
|
+
2. **The ground's work.** The library's `ground` faculty goes up, which
|
|
688
|
+
the dock alone reaches.
|
|
689
|
+
3. **Dock.** The ground's own house opens in the ledger, under a seed
|
|
690
|
+
its key derives. Its beings hold every entry, seed, secret and
|
|
691
|
+
setting as their cells.
|
|
692
|
+
4. **Ladder.** The dock's steward joins your entries to the defaults its
|
|
693
|
+
code fixes, yours winning by name. Each entry is held to what its
|
|
694
|
+
faculty takes. Each body is installed where its entry is new, and
|
|
695
|
+
goes up. One that fails stays down, and says why.
|
|
696
|
+
5. **Houses.** Each house opens on its bodies, and its door joins the
|
|
697
|
+
carry.
|
|
698
|
+
6. **Hand.** The hand takes its socket, and the ground tells systemd it
|
|
699
|
+
is up.
|
|
700
|
+
|
|
701
|
+
Its environment names what opens its memory, its key and its hand, and
|
|
702
|
+
nothing else.
|
|
703
|
+
|
|
704
|
+
| Variable | What it names |
|
|
696
705
|
| --- | --- |
|
|
697
|
-
| `NERVUR_TCP_PORT` | its TCP port, 9110 where unset |
|
|
698
|
-
| `NERVUR_HTTP_PORT` | its HTTP port, for Quo over the web and every handler; no HTTP where unset |
|
|
699
|
-
| `NERVUR_ADDRESSES` | the public addresses it writes into invitations, by commas: `tcp`, `https`, `http`, `wss` or `ws` |
|
|
700
|
-
| `NERVUR_ORIGINS` | the pages of other origins it answers on the web, by commas; a page of its own host needs none |
|
|
701
|
-
| `NERVUR_ALLOW_PRIVATE` | `1` to dial private and loopback addresses, as two grounds on one machine do |
|
|
702
|
-
| `NERVUR_BIND` | the address it listens on, `0.0.0.0` where unset |
|
|
703
706
|
| `NERVUR_STATE` | its state, `state/` in its folder where unset |
|
|
704
707
|
| `NERVUR_UNLOCK` | `keychain:<account>` keeps its key in the macOS keychain, in place of `state/key` |
|
|
705
|
-
| `
|
|
708
|
+
| `NERVUR_HAND` | its hand's socket, `state/hand` where unset |
|
|
709
|
+
|
|
710
|
+
Every other setting is an arg of an entry its dock keeps, set through
|
|
711
|
+
the hand. Its `tcp` entry listens on every address at 9110. Its `web`
|
|
712
|
+
entry serves the ground's one listener over HTTP, for Quo over the web
|
|
713
|
+
and every handler, once its args name a `port`. It names that listener
|
|
714
|
+
in its `faculties`. Both take `bind`, the public `addresses` written
|
|
715
|
+
into invitations, and `allowPrivate` to dial loopback addresses, as two
|
|
716
|
+
grounds on one machine do. `web` also takes the `origins` of pages it
|
|
717
|
+
answers. `wait set` keeps its bound on every ask.
|
|
718
|
+
|
|
719
|
+
```bash
|
|
720
|
+
npx nervur faculties update name=web make=web faculties='["listener"]' args='{"port":8080}'
|
|
721
|
+
```
|
|
706
722
|
|
|
707
723
|
The state holds the key in a file its owner alone reads, and the
|
|
708
724
|
ground's ledger. Every house keeps its rows in that ledger, sealed. A
|
|
@@ -714,10 +730,11 @@ lost key is a lost ground.
|
|
|
714
730
|
|
|
715
731
|
The ladder stands once, and the ground stands it again at every start.
|
|
716
732
|
The first entry stands the folder's `recipe.ts` as a registry, by the
|
|
717
|
-
|
|
733
|
+
faculty `module` the folder's registry holds. The second raises the
|
|
734
|
+
payments from it. An entry names only faculties that stand already.
|
|
718
735
|
|
|
719
736
|
```bash
|
|
720
|
-
npx nervur faculties add name=recipe make=module args='{"at":"recipe.ts"}'
|
|
737
|
+
npx nervur faculties add name=recipe from=folder make=module args='{"at":"recipe.ts"}'
|
|
721
738
|
```
|
|
722
739
|
|
|
723
740
|
```bash
|
|
@@ -727,19 +744,21 @@ npx nervur faculties add name=payments from=recipe make=payments
|
|
|
727
744
|
A house is added once, and the ground opens it again at every start.
|
|
728
745
|
|
|
729
746
|
```bash
|
|
730
|
-
npx nervur houses add name=shop classes='{"
|
|
747
|
+
npx nervur houses add name=shop classes='{"faculty":"folder","at":"classes"}' faculties='["payments"]'
|
|
731
748
|
```
|
|
732
749
|
|
|
733
|
-
`classes` names the body
|
|
734
|
-
own, and a registry may add more, a git repository among
|
|
735
|
-
keeps its rows in the ground's ledger unless its entry
|
|
736
|
-
|
|
737
|
-
faculty's entry names in `kinds` the classes that hold
|
|
750
|
+
`classes` names the faculty whose body serves the house's code. `folder`
|
|
751
|
+
is the ground's own, and a registry may add more, a git repository among
|
|
752
|
+
them. A house keeps its rows in the ground's ledger unless its entry
|
|
753
|
+
names a `memory` faculty. `faculties` names what the house receives, and
|
|
754
|
+
within it each faculty's entry names in `kinds` the classes that hold
|
|
755
|
+
it. `houses update` and `faculties update` land a new entry in one
|
|
756
|
+
write, and `faculties restart` takes a body down and up again.
|
|
738
757
|
|
|
739
758
|
A secret reaches a faculty the same way, and never through the
|
|
740
759
|
environment. `npx nervur secrets set -` reads `{ name, value }` from
|
|
741
|
-
standard input into the
|
|
742
|
-
the secrets its
|
|
760
|
+
standard input into a being of the dock, whose cells no one reads. A
|
|
761
|
+
faculty's entry names the secrets its `up` receives in `secrets`.
|
|
743
762
|
|
|
744
763
|
### The hand
|
|
745
764
|
|
|
@@ -751,8 +770,10 @@ describes.
|
|
|
751
770
|
npx nervur help
|
|
752
771
|
```
|
|
753
772
|
|
|
754
|
-
|
|
755
|
-
|
|
773
|
+
Two words ask the dock, the ground's own steward, so `houses list` asks
|
|
774
|
+
her `housesList`. A faculty named alone shows its methods, and a method
|
|
775
|
+
after it is called through the dock. Args are one JSON object, or words
|
|
776
|
+
`key=value`.
|
|
756
777
|
|
|
757
778
|
```bash
|
|
758
779
|
npx nervur houses list
|
|
@@ -805,16 +826,17 @@ with `loginctl enable-linger`. On macOS, the agent goes to
|
|
|
805
826
|
houses in a page. Every tab and the service worker of one origin share
|
|
806
827
|
one ground: the one holding the Web Lock runs it, and the others reach
|
|
807
828
|
its hand over a `BroadcastChannel`. When it closes, the next opens the
|
|
808
|
-
ground from the same storage. `hand`
|
|
809
|
-
|
|
810
|
-
|
|
829
|
+
ground from the same storage. `hand` takes the same requests the
|
|
830
|
+
command sends: `describe`, and an ask of a being in a named house. A
|
|
831
|
+
request that names no house asks the dock's steward, as
|
|
832
|
+
`{ method: 'housesList' }`.
|
|
811
833
|
|
|
812
834
|
Its bodies are the browser's. The ground's key is sealed under an AES
|
|
813
835
|
key that IndexedDB holds unextractable, and its memory is IndexedDB.
|
|
814
|
-
Classes load from the page's own origin through the `origin`
|
|
815
|
-
|
|
816
|
-
refused. The registry is the object you pass:
|
|
817
|
-
|
|
836
|
+
Classes load from the page's own origin through the `origin` faculty, `{
|
|
837
|
+
faculty: 'origin', at: '/house/index.js' }`, and a path off the origin
|
|
838
|
+
is refused. The registry is the object you pass: faculties by name,
|
|
839
|
+
foundation and custom alike, beside the terrain's own.
|
|
818
840
|
|
|
819
841
|
Any script on the origin can use the ground's keys, so the ground is
|
|
820
842
|
whoever serves the origin's script. Give it an origin of its own, serve
|
|
@@ -841,7 +863,7 @@ app's web view, on two interfaces the shell fills in native code:
|
|
|
841
863
|
The library holds the rest. The ground's key goes into the secret store,
|
|
842
864
|
and its memory into the native store, which the system never evicts as
|
|
843
865
|
it may a web view's storage. A push token reaches the ground through a
|
|
844
|
-
faculty your registry
|
|
866
|
+
faculty your registry holds.
|
|
845
867
|
|
|
846
868
|
## What the house guarantees
|
|
847
869
|
|
|
@@ -899,7 +921,15 @@ at her call, or where an ask arrives.
|
|
|
899
921
|
- A call on the house beside `House.open`, `door` and `ask`.
|
|
900
922
|
- A faculty in a house's code. Faculties are the ground's.
|
|
901
923
|
- A drawer opened with a key that did not seal it.
|
|
902
|
-
- A secret read by a being, a describe or anyone but a
|
|
903
|
-
names.
|
|
904
|
-
- A faculty
|
|
924
|
+
- A secret read by a being, a describe or anyone but a faculty whose
|
|
925
|
+
entry names it.
|
|
926
|
+
- A faculty raised any way but its `up`, foundation or custom.
|
|
927
|
+
- An entry named `dock`, for a house or a faculty. The dock is the
|
|
928
|
+
library's.
|
|
929
|
+
- A secret or a move asked by anyone but the hand.
|
|
930
|
+
- A grant naming a faculty or a secret the ground does not hold.
|
|
931
|
+
- A secret's cells read through the hand.
|
|
932
|
+
- An entry naming, making or granting `ground` or `shell`. Both are the
|
|
933
|
+
dock's alone.
|
|
934
|
+
- A second ground on the state one runs on.
|
|
905
935
|
- A ground an owner must write. Each terrain's ships.
|
package/COMMAND.md
CHANGED
|
@@ -17,11 +17,11 @@ alone reads.
|
|
|
17
17
|
npx nervur up .
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
The ground stops cleanly on an interrupt and on `SIGTERM`.
|
|
21
|
-
lock on its state, so a second `nervur up` on
|
|
22
|
-
start. Keep `state/` as you keep an ssh key:
|
|
23
|
-
its ledger holds the ground, and without the
|
|
24
|
-
nothing.
|
|
20
|
+
The ground stops cleanly on an interrupt and on `SIGTERM`. Its ledger
|
|
21
|
+
holds a lock on its state while it stands, so a second `nervur up` on
|
|
22
|
+
the same folder refuses to start. Keep `state/` as you keep an ssh key:
|
|
23
|
+
whoever holds its key and its ledger holds the ground, and without the
|
|
24
|
+
key the ledger opens nothing.
|
|
25
25
|
|
|
26
26
|
`nervur service` prints what keeps the ground running across reboots: a
|
|
27
27
|
systemd unit on Linux, a launchd job on macOS. Nothing is installed; you
|
|
@@ -33,20 +33,38 @@ npx nervur service /srv/shop
|
|
|
33
33
|
|
|
34
34
|
## Settings
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
The environment names only what opens the ground's memory, its key and
|
|
37
|
+
its hand.
|
|
37
38
|
|
|
38
|
-
|
|
|
39
|
+
| Variable | What it names |
|
|
39
40
|
| --- | --- |
|
|
40
41
|
| `NERVUR_STATE` | the state folder, `state/` in the ground's folder where unset |
|
|
41
|
-
| `NERVUR_TCP_PORT` | the TCP port Quo listens on, 9110 where unset |
|
|
42
|
-
| `NERVUR_HTTP_PORT` | the port of the web listener, which faces and Quo over the web share; none where unset |
|
|
43
|
-
| `NERVUR_BIND` | the address both listen on, every interface where unset |
|
|
44
|
-
| `NERVUR_ADDRESSES` | the public addresses written into invitations, by commas |
|
|
45
|
-
| `NERVUR_ORIGINS` | the page origins the web listener answers, by commas |
|
|
46
|
-
| `NERVUR_ALLOW_PRIVATE` | `1` to let the ground dial a private or loopback address |
|
|
47
42
|
| `NERVUR_UNLOCK` | on macOS, `keychain:<account>` keeps the key in the keychain in place of `state/key` |
|
|
48
43
|
| `NERVUR_HAND` | where the hand's socket is, `state/hand` where unset; a relative path is read from where the command runs |
|
|
49
|
-
|
|
44
|
+
|
|
45
|
+
Every other setting is an entry the ground's dock keeps, set through the
|
|
46
|
+
hand and kept across a restart. The `tcp` entry listens on the loopback
|
|
47
|
+
at 9110 until you name another bind, and the `web` entry listens on no
|
|
48
|
+
port until one is named. The web serves the ground's one listener,
|
|
49
|
+
which its entry names in `faculties`.
|
|
50
|
+
|
|
51
|
+
| Arg | Of | What it sets |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| `port` | `tcp`, `web` | the port it listens on; with none, it only dials |
|
|
54
|
+
| `bind` | `tcp`, `web` | the address it listens on, every interface where unset |
|
|
55
|
+
| `addresses` | `tcp`, `web` | the public addresses written into invitations |
|
|
56
|
+
| `origins` | `web` | the page origins the web listener answers |
|
|
57
|
+
| `allowPrivate` | `tcp`, `web` | `true` to let the ground dial a private or loopback address |
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx nervur faculties update name=web make=web faculties='["listener"]' args='{"port":8080,"addresses":["https://shop.example/quo"]}'
|
|
61
|
+
npx nervur wait set wait=30000
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`faculties catalog` prints every faculty the ground can raise and what
|
|
65
|
+
each takes, so an entry it refuses says which arg failed. `wait set`
|
|
66
|
+
keeps the longest any ask may run, in milliseconds, and `wait show`
|
|
67
|
+
prints it.
|
|
50
68
|
|
|
51
69
|
A ground that people reach names its public addresses. Without them, it
|
|
52
70
|
writes only the addresses it listens on, which a stranger cannot reach.
|
|
@@ -62,22 +80,31 @@ Every other word goes to the ground's hand, a socket in `state/` that
|
|
|
62
80
|
your user alone may open. Run the command in the ground's folder, or
|
|
63
81
|
name the socket with `--at <socket>` or `NERVUR_HAND`.
|
|
64
82
|
|
|
65
|
-
`help` prints what the ground holds:
|
|
66
|
-
why it is down, and each house.
|
|
83
|
+
`help` prints what the ground holds: the asks of its dock, each faculty
|
|
84
|
+
with its methods or why it is down, and each house.
|
|
67
85
|
|
|
68
86
|
```bash
|
|
69
87
|
npx nervur help
|
|
70
88
|
```
|
|
71
89
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
90
|
+
The dock is the ground's own house, and its steward changes the ground.
|
|
91
|
+
Two words ask her, so `houses add` asks `housesAdd`. One word alone
|
|
92
|
+
prints the asks it begins. `secrets set` keeps a secret in a being of
|
|
93
|
+
the dock, whose cells no one reads. `faculties add` raises a faculty by
|
|
94
|
+
the `up` its entry names, and `houses add` opens a house on its entry.
|
|
95
|
+
Each answers why the body is down or the house closed, where it is.
|
|
96
|
+
Each `update` lands a new entry in one write, and `faculties restart`
|
|
97
|
+
takes a body down and up again. A faculty named with a method is called
|
|
98
|
+
through the dock, and named alone it prints its methods.
|
|
99
|
+
|
|
100
|
+
An entry names only faculties and secrets the ground holds already. A
|
|
101
|
+
module and a program stand on the folder's registry, so their entries
|
|
102
|
+
say `from=folder`.
|
|
76
103
|
|
|
77
104
|
```bash
|
|
78
|
-
npx nervur faculties add name=recipe make=module args='{"at":"recipe.ts"}'
|
|
105
|
+
npx nervur faculties add name=recipe from=folder make=module args='{"at":"recipe.ts"}'
|
|
79
106
|
npx nervur faculties add name=payments from=recipe make=payments secrets='["stripe-key"]'
|
|
80
|
-
npx nervur houses add name=main classes='{"
|
|
107
|
+
npx nervur houses add name=main classes='{"faculty":"folder","at":"house"}' faculties='["payments"]'
|
|
81
108
|
```
|
|
82
109
|
|
|
83
110
|
`ask` asks a being of a house, as the house's owner. `--id <being>` names
|
|
@@ -96,6 +123,22 @@ repair, or a look at what her asks do not show.
|
|
|
96
123
|
npx nervur ask main --cells
|
|
97
124
|
```
|
|
98
125
|
|
|
126
|
+
`ask dock` asks the dock's own beings, since no house takes that name.
|
|
127
|
+
`faculty.<name>`, `house.<name>` and the steward hold every entry, seed
|
|
128
|
+
and setting, and a secret's cells are shown to no one.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx nervur ask dock --id faculty.web --cells
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`shell run` runs a command on the ground's machine, in its code folder,
|
|
135
|
+
and prints its exit code and what it printed. The words after `--` are
|
|
136
|
+
the command line. Its environment holds nothing of the ground's.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npx nervur shell run -- git status
|
|
140
|
+
```
|
|
141
|
+
|
|
99
142
|
The command asks no watch. A watch is held by a being on her standing,
|
|
100
143
|
or by a page through a face, where something waits on its answer.
|
|
101
144
|
|
|
@@ -116,6 +159,14 @@ secret never stands on a command line or in a shell's history.
|
|
|
116
159
|
npx nervur secrets set - < stripe-key.json
|
|
117
160
|
```
|
|
118
161
|
|
|
162
|
+
`--call <id>`, before the words, names the ask's call id. The same ask
|
|
163
|
+
sent again with the same id answers what the first answered, and runs
|
|
164
|
+
nothing twice. So a script that lost an answer sends its ask again.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
npx nervur --call deploy-42 houses update name=main classes='{"faculty":"folder","at":"house"}'
|
|
168
|
+
```
|
|
169
|
+
|
|
119
170
|
Each word prints one JSON value, the answer, and its exit code says what
|
|
120
171
|
came back.
|
|
121
172
|
|
package/FACES.md
CHANGED
|
@@ -106,11 +106,12 @@ tries again acts once.
|
|
|
106
106
|
|
|
107
107
|
```ts
|
|
108
108
|
// api.ts
|
|
109
|
-
import type {
|
|
109
|
+
import type { Body, FacultyContext, Handler } from 'nervur';
|
|
110
110
|
import { need, s, type Json } from 'nervur/being';
|
|
111
111
|
|
|
112
112
|
type Answer = Awaited<ReturnType<FacultyContext['call']>>;
|
|
113
113
|
type Entry = { method: string; description?: string; args?: Json; hints?: Json };
|
|
114
|
+
type Calls = Pick<FacultyContext, 'call' | 'describe'>;
|
|
114
115
|
|
|
115
116
|
/** What the steward arms the face with. */
|
|
116
117
|
export const FaceBlueprint = need('face', {
|
|
@@ -124,9 +125,8 @@ export const FaceBlueprint = need('face', {
|
|
|
124
125
|
* asks to an agent as tools.
|
|
125
126
|
*/
|
|
126
127
|
export class Api {
|
|
127
|
-
#context:
|
|
128
|
+
#context: Calls | undefined;
|
|
128
129
|
#signup = '';
|
|
129
|
-
#calls = 0;
|
|
130
130
|
|
|
131
131
|
arm({ signup }: { signup: string }, context: FacultyContext): Promise<Answer> {
|
|
132
132
|
this.#context = context;
|
|
@@ -134,14 +134,19 @@ export class Api {
|
|
|
134
134
|
return Promise.resolve({ result: null });
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
// Told its house opened: every door's token answers from the first request, after any restart.
|
|
138
|
+
opened(context: Calls): void {
|
|
139
|
+
this.#context = context;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
#held(): Calls {
|
|
138
143
|
if (this.#context === undefined) throw new Error('the face is not armed');
|
|
139
144
|
return this.#context;
|
|
140
145
|
}
|
|
141
146
|
|
|
142
|
-
// Each call
|
|
147
|
+
// Each call an id drawn afresh, so no life of the face repeats one.
|
|
143
148
|
#ask(token: string, method: string, args: Json): Promise<Answer> {
|
|
144
|
-
return this.#held().call({ token, method, args, id: `api:${
|
|
149
|
+
return this.#held().call({ token, method, args, id: `api:${crypto.randomUUID()}` });
|
|
145
150
|
}
|
|
146
151
|
|
|
147
152
|
async #tools(token: string): Promise<Json> {
|
|
@@ -179,8 +184,8 @@ export class Api {
|
|
|
179
184
|
};
|
|
180
185
|
}
|
|
181
186
|
|
|
182
|
-
/** The
|
|
183
|
-
export const apiOffer = (api: Api):
|
|
187
|
+
/** The face as a body. */
|
|
188
|
+
export const apiOffer = (api: Api): Body => ({ blueprint: FaceBlueprint, object: api, handler: api.handler, opened: (context) => api.opened(context) });
|
|
184
189
|
```
|
|
185
190
|
|
|
186
191
|
**The describe maps onto tools by renaming.** An ask is a tool, its
|
|
@@ -190,24 +195,24 @@ tools.
|
|
|
190
195
|
|
|
191
196
|
## The registry
|
|
192
197
|
|
|
193
|
-
The ground
|
|
194
|
-
NodeGround stands the module below with the
|
|
195
|
-
face from it by an entry that names `from`. The
|
|
196
|
-
`face` among its faculties, and the steward's `arm`
|
|
197
|
-
signup.
|
|
198
|
+
The ground raises the face from a registry by its `up`, as it raises any
|
|
199
|
+
faculty. A NodeGround stands the module below with the faculty
|
|
200
|
+
`module`, and the face from it by an entry that names `from`. The
|
|
201
|
+
house's entry names `face` among its faculties, and the steward's `arm`
|
|
202
|
+
hands the face its signup.
|
|
198
203
|
|
|
199
204
|
```ts
|
|
200
205
|
// recipe.ts
|
|
201
206
|
import { Api, apiOffer } from './api.ts';
|
|
202
207
|
|
|
203
|
-
// A registry: the ground
|
|
208
|
+
// A registry: the ground raises the face by its `up` when an entry names it.
|
|
204
209
|
export const faculties = {
|
|
205
|
-
face: () => apiOffer(new Api()),
|
|
210
|
+
face: { up: () => apiOffer(new Api()) },
|
|
206
211
|
};
|
|
207
212
|
```
|
|
208
213
|
|
|
209
214
|
```bash
|
|
210
|
-
npx nervur faculties add name=recipe make=module args='{"at":"recipe.ts"}'
|
|
215
|
+
npx nervur faculties add name=recipe from=folder make=module args='{"at":"recipe.ts"}'
|
|
211
216
|
npx nervur faculties add name=face from=recipe make=face
|
|
212
217
|
```
|
|
213
218
|
|
|
@@ -229,7 +234,7 @@ import { faculties } from './recipe.ts';
|
|
|
229
234
|
test('A person signs up at the face, and reaches their member as an API and as tools', async (t) => {
|
|
230
235
|
const ground = await BenchGround.open({ network: new FakeNetwork(), host: 'desk', modules: { desk }, registry: { faculties } });
|
|
231
236
|
t.after(() => ground.down());
|
|
232
|
-
await ground.hand({
|
|
237
|
+
await ground.hand({ method: 'facultiesAdd', args: { name: 'face', make: 'face' } });
|
|
233
238
|
await ground.add('desk', 'desk', { faculties: ['face'] });
|
|
234
239
|
await ground.ask({ house: 'desk', method: 'arm' });
|
|
235
240
|
const web = async (path: string, body?: unknown, token?: string) =>
|