diff --git a/README.md b/README.md index 31abb225..0b4d12c2 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ ```sh cargo install mdbook cargo install mdbook-linkcheck +cargo install mdbook-webinclude mdbook serve ``` diff --git a/book.toml b/book.toml index a4bc0797..eab21d34 100644 --- a/book.toml +++ b/book.toml @@ -13,3 +13,5 @@ enable = true level = 1 [output.linkcheck] + +[preprocessor.webinclude] diff --git a/src/apis/frontend_development.md b/src/apis/frontend_development.md index 79dbf8e5..1e0eb654 100644 --- a/src/apis/frontend_development.md +++ b/src/apis/frontend_development.md @@ -42,11 +42,17 @@ Your UI should be developed and compiled with the base URL set to the appropriat #### Vite -In `vite.config.ts` (or `.js`) set `base` to your full process name, i.e. `base: '/my_process:my_package:template.os'`. +In `vite.config.ts` (or `.js`) set `base` to your full process name, i.e. +``` +base: '/my_process:my_package:template.os' +``` #### Create React App -In `package.json` set `homepage` to your full process name, i.e. `homepage: '/my_process:my_package:template.os'`. +In `package.json` set `homepage` to your full process name, i.e. +``` +homepage: '/my_process:my_package:template.os' +``` ### Proxying HTTP Requests @@ -59,7 +65,10 @@ Follow the `server` entry in the [kit template](https://github.com/kinode-dao/ki #### Create React App -In `package.json` set `proxy` to your Kinode's URL, i.e. `proxy: 'http://localhost:8080'`. +In `package.json` set `proxy` to your Kinode's URL, i.e. +``` +proxy: 'http://localhost:8080' +``` ### Making HTTP Requests diff --git a/src/apis/kinode_wit.md b/src/apis/kinode_wit.md index 7133c522..eca31ac9 100644 --- a/src/apis/kinode_wit.md +++ b/src/apis/kinode_wit.md @@ -16,17 +16,17 @@ To see exactly how to use WIT to write Kinode processes, see the [My First App]( To see `kinode.wit` for itself, see the [file in the GitHub repo](https://github.com/kinode-dao/kinode-wit/blob/master/kinode.wit). Since this interface applies to all processes, it's one of the places in the OS where breaking changes are most likely to make an impact. To that end, the version of the WIT file that a process uses must be compatible with the version of Kinode OS on which it runs. -We intend to achieve perfect backwards compatibility upon first major release (1.0.0) of the OS and the WIT file. +Kinode DAO intends to achieve perfect backwards compatibility upon first major release (1.0.0) of the OS and the WIT file. After that point, since processes signal the version of the WIT file they use, subsequent updates can be made without breaking existing processes or needing to change the version they use. ## Types -[These 14 types](https://github.com/kinode-dao/kinode-wit/blob/373542a9a94ae61a7d216159f9f7bdf9266cd935/kinode.wit#L8-L103) make up the entirety of the shared type system between processes and the kernel. +[These 15 types](https://github.com/kinode-dao/kinode-wit/blob/758fac1fb144f89c2a486778c62cbea2fb5840ac/kinode.wit#L8-L106) make up the entirety of the shared type system between processes and the kernel. Most types presented here are implemented in the [process standard library](../process_stdlib/overview.md) for ease of use. ## Functions -[These 15 functions](https://github.com/kinode-dao/kinode-wit/blob/373542a9a94ae61a7d216159f9f7bdf9266cd935/kinode.wit#L105-L184) are available to processes. +[These 16 functions](https://github.com/kinode-dao/kinode-wit/blob/758fac1fb144f89c2a486778c62cbea2fb5840ac/kinode.wit#L108-L190) are available to processes. They are implemented in the kernel. Again, the process standard library makes it such that these functions often don't need to be directly called in processes, but they are always available. The functions are generally separated into 4 categories: system utilities, process management, capabilities management, and message I/O. diff --git a/src/apis/terminal.md b/src/apis/terminal.md index 2a45f0fc..9a995015 100644 --- a/src/apis/terminal.md +++ b/src/apis/terminal.md @@ -1,4 +1,5 @@ # Terminal API + It is extremely rare for an app to have direct access to the terminal api. Normally, the terminal will be used to call scripts, which will have access to the process in question. For documentation on using, writing, publishing, and composing scripts, see the [terminal use documentation](../terminal.md), or for a quick start, the [script cookbook](../cookbook/writing_scripts.md). @@ -14,18 +15,27 @@ This is a powerful capability, equivalent to giving an application `root` author For this reason, users are unlikely to grant direct terminal access to most apps. If one does have the capability to send `Request`s to the terminal, they can execute commands like so: -`script_name:package_name:publisher_name ` +``` +script_name:package_name:publisher_name +``` -For example, the `hi` script, which pings another node's terminal with a message, can be called like so: `hi:terminal:sys default-router-1.os what's up?`. +For example, the `hi` script, which pings another node's terminal with a message, can be called like so: +``` +hi:terminal:sys default-router-1.os what's up? +``` In this case, the arguments are both `default-router-1.os` and the message `what's up?`. Some commonly used scripts have shorthand aliases because they are invoked so frequently. -For example, `hi:terminal:sys` can be shortened to just `hi` as in: `hi default-router-1.os what's up?`. +For example, `hi:terminal:sys` can be shortened to just `hi` as in: +``` +hi default-router-1.os what's up? +``` -The other most commonly used script is `m:terminal:sys`, or just `m` - which stands for `Message`. `m` let's you send a request to any node or application like so: -```bash +The other most commonly used script is `m:terminal:sys`, or just `m` - which stands for `Message`. +`m` lets you send a request to any node or application like so: +``` m john.os@proc:pkg:pub '{"foo":"bar"}' ``` -Note that if your process has the ability to message the `terminal` app, then that process can call any script - of which there may be many on a machine, so we cannot possibly write all of them down in this document. +Note that if your process has the ability to message the `terminal` app, then that process can call any script. However, they will all have this standard calling convention of ` `. diff --git a/src/apis/websocket.md b/src/apis/websocket.md index a0fbe9b5..b3d1498e 100644 --- a/src/apis/websocket.md +++ b/src/apis/websocket.md @@ -8,7 +8,7 @@ The process receives the `channel_id` for pushing data into the WebSocket, and a To open a WebSocket channel, connect to the main route on the node `/` and send a `WsRegister` message as either text or bytes. -The simplest way to connect from a browser is to use the `@uqbar/client-encryptor-api` like so: +The simplest way to connect from a browser is to use the `@kinode/client-api` like so: ```rs const api = new KinodeEncryptorApi({ @@ -22,7 +22,7 @@ const api = new KinodeEncryptorApi({ }) ``` -`@uqbar/client-encryptor-api` is available here: [https://www.npmjs.com/package/@uqbar/client-encryptor-api](https://www.npmjs.com/package/@uqbar/client-encryptor-api) +`@kinode/client-api` is available here: [https://www.npmjs.com/package/@kinode/client-api](https://www.npmjs.com/package/@kinode/client-api) Simple JavaScript/JSON example: diff --git a/src/assets/register-connect-wallet.png b/src/assets/register-connect-wallet.png index 1b811e80..a1750ed0 100644 Binary files a/src/assets/register-connect-wallet.png and b/src/assets/register-connect-wallet.png differ diff --git a/src/assets/register-have-wallet.png b/src/assets/register-have-wallet.png index 4b626316..06100754 100644 Binary files a/src/assets/register-have-wallet.png and b/src/assets/register-have-wallet.png differ diff --git a/src/assets/homepage.png b/src/assets/register-homepage.png similarity index 100% rename from src/assets/homepage.png rename to src/assets/register-homepage.png diff --git a/src/assets/register-need-wallet.png b/src/assets/register-need-wallet.png index 68e95bd0..40dcb395 100644 Binary files a/src/assets/register-need-wallet.png and b/src/assets/register-need-wallet.png differ diff --git a/src/assets/register-select-name.png b/src/assets/register-select-name.png index a8bbae99..d9f17443 100644 Binary files a/src/assets/register-select-name.png and b/src/assets/register-select-name.png differ diff --git a/src/assets/register-set-password.png b/src/assets/register-set-password.png index 7fc6c4e7..40c9c10c 100644 Binary files a/src/assets/register-set-password.png and b/src/assets/register-set-password.png differ diff --git a/src/chess_app/chat.md b/src/chess_app/chat.md index d9902c15..695e76b4 100644 --- a/src/chess_app/chat.md +++ b/src/chess_app/chat.md @@ -235,7 +235,7 @@ A simple demonstration of how to extend the functionality of a given process. There are a few key things to keep in mind when doing this, if you want to build stable, maintainable, upgradable applications: - By adding chat, you changed the format of the "chess protocol" implicitly declared by this program. -If a user is running the old code, their version won't know how to handle the new `Message` request type we added. +If a user is running the old code, their version won't know how to handle the new `Message` request type you added. **Depending on the serialization/deserialization strategy used, this might even create incompatibilities with the other types of requests.** This is a good reason to use a serialization strategy that allows for "unknown" fields, such as JSON. If you're using a binary format, you'll need to be more careful about how you add new fields to existing types. diff --git a/src/chess_app/chess_engine.md b/src/chess_app/chess_engine.md index fa59b962..109b69f9 100644 --- a/src/chess_app/chess_engine.md +++ b/src/chess_app/chess_engine.md @@ -36,12 +36,12 @@ fn init(our: Address) { } ``` -Now, we have access to a chess board and can manipulate it easily. +Now, you have access to a chess board and can manipulate it easily. The [pleco docs](https://github.com/pleco-rs/Pleco#using-pleco-as-a-library) show everything you can do using the pleco library. But this isn't very interesting by itself! -We want to play chess with other people. -Let's start by creating a persisted state for the chess app and a `body` format for sending messages to other nodes. +Chess is a multiplayer game. +To make your app multiplayer, start by creating a persisted state for the chess app and a `body` format for sending messages to other nodes. In `my_chess/src/lib.rs` add the following simple Request/Response interface and persistable game state: ```rust @@ -90,7 +90,7 @@ The `ChessState` `struct` shown above can also be persisted using the `set_state Note that the `Game` `struct` here has `board` as a `String`. This is because the `Board` type from pleco doesn't implement `Serialize` or `Deserialize`. We'll have to convert it to a string using `fen()` before persisting it. -Then, we will convert it back to a `Board` with `Board::from_fen()` when we load it from state. +Then, you will convert it back to a `Board` with `Board::from_fen()` when you load it from state. The code below will contain a version of the `init()` function that creates an event loop and handles ChessRequests. First, however, it's important to note that these types already bake in some assumptions about our "chess protocol". diff --git a/src/chess_app/putting_everything_together.md b/src/chess_app/putting_everything_together.md index fad26b64..42eda985 100644 --- a/src/chess_app/putting_everything_together.md +++ b/src/chess_app/putting_everything_together.md @@ -3,10 +3,10 @@ After adding a frontend in the previous chapter, your chess game is ready to play. Hopefully, you've been using `kit build ` to test the code as the tutorial has progressed. -If not, do so now in order to get a compiled package we can install onto a node. +If not, do so now in order to get a compiled package you can install onto a node. Next, use `kit start-package -p ` to install the package. -You should see the printout we added to `init()` in your terminal: `chess by : start`. +You should see the printout you added to `init()` in your terminal: `chess by : start`. Remember that you determine the process names via the `manifest.json` file inside `/pkg`, and the package & publisher name from `metadata.json` located at the top level of the project. Open your chess frontend by navigating to your node's URL (probably something like `http://localhost:8080`), and use the names you chose as the path. diff --git a/src/chess_app/setup.md b/src/chess_app/setup.md index 01bba7b3..c0a00edd 100644 --- a/src/chess_app/setup.md +++ b/src/chess_app/setup.md @@ -1,11 +1,11 @@ # Environment Setup To prepare for this tutorial, follow the environment setup guide [here](../my_first_app/chapter_1.md), i.e. [start a fake node](../my_first_app/chapter_1.md#booting-a-fake-kinode-node) and then, in another terminal, run: -```bash +``` kit new my_chess cd my_chess kit build kit start-package ``` -Once you have the template app installed and can see it running on your testing node, continue to the next chapter... \ No newline at end of file +Once you have the template app installed and can see it running on your testing node, continue to the next chapter... diff --git a/src/cookbook/file_transfer.md b/src/cookbook/file_transfer.md index 95d001f7..34c735a8 100644 --- a/src/cookbook/file_transfer.md +++ b/src/cookbook/file_transfer.md @@ -542,7 +542,7 @@ let mut file: Option = None; let mut size: Option = None; ``` -And then in the main loop we pass it to `handle_message()`: +And then in the main loop, pass it to `handle_message()`: ```rust struct Component; @@ -726,7 +726,7 @@ WorkerRequest::Size(incoming_size) => { One more thing: once you're done sending, you can exit the process; the worker is not needed anymore. Change your `handle_message()` function to return a `Result` instead telling the main loop whether it should exit or not. -As a bonus, we can add a print when it exits of how long it took to send/receive! +As a bonus, you can add a print when it exits of how long it took to send/receive! ```rust fn handle_message( diff --git a/src/cookbook/writing_scripts.md b/src/cookbook/writing_scripts.md index b6d5dbd4..8c39f3ac 100644 --- a/src/cookbook/writing_scripts.md +++ b/src/cookbook/writing_scripts.md @@ -30,9 +30,10 @@ fn init(_our: Address) { } ``` From writing applications, this should look very familiar - the imports, `wit_bindgen::generate!`, `call_init!`, `init(our: Address)`, etc. are all exactly the same. -The first unique thing about scripts is that we will have no `loop` where we `await_message`. -Instead, our initial arguments will come from a single message from the terminal - which we get by calling `await_next_message_body()`. -Next, all we do is `String`ify the message body, and print it out. +The first unique thing about scripts is that they have no `loop` over `await_message`. +Instead, the initial arguments will come from a single message from the terminal. +`process_lib` provides a convenience function, `await_next_message_body()`, to make it easy to read. +Next, simply `String`ify the message body, and print it out. Arbitrary logic can be put below `await_next_message_body` - just like an app, you can fire-off a number of requests, choose to await their responses, handle errors, etc. just like normal. diff --git a/src/design_philosophy.md b/src/design_philosophy.md index 2233e159..c8a27d67 100644 --- a/src/design_philosophy.md +++ b/src/design_philosophy.md @@ -34,7 +34,7 @@ Those features include: The above properties are achieved by governance. Successful protocols launched on Kinode will be ones that decentralize their governance in order to maintain these properties. -We believe that systems that don't proactively specify their point of control will eventually centralize, even if unintentionally. +Kinode DAO believes that systems that don't proactively specify their point of control will eventually centralize, even if unintentionally. The governance of Kinode itself must be designed to encourage decentralization, playing a role in the publication and distribution of userspace software protocols. In practice, this looks like an on-chain permissionless App Store. @@ -50,4 +50,4 @@ Our current architecture relies on the following systems: - Wasmtime: a standalone Wasm runtime In addition, Kinode is inspired by the [Bytecode Alliance](https://bytecodealliance.org/) and their vision for secure, efficient, and modular software. -We make extensive use of their tools and standards. +Kinode DAO makes extensive use of their tools and standards. diff --git a/src/hosted-nodes.md b/src/hosted-nodes.md index 52ee1124..3402674a 100644 --- a/src/hosted-nodes.md +++ b/src/hosted-nodes.md @@ -5,7 +5,7 @@ These hosted Kinodes are useful for both end users and developers. This guide is largely targeted at developers who want to develop Kinode applications using their hosted Kinode. End users may also find the [Managing Your Kinode](#managing-your-kinode) section useful. -Here, we use `ssh` extensively. +Here, `ssh` is used extensively. This guide is specifically tailored to `ssh`s use for the Kinode hosting service. A more expansive guide can be found [here](https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys). diff --git a/src/http_server_and_client.md b/src/http_server_and_client.md index e74bece9..cbf28cae 100644 --- a/src/http_server_and_client.md +++ b/src/http_server_and_client.md @@ -18,6 +18,8 @@ At startup, the server either: The server then binds this port, listening for HTTP and WebSocket requests. +You can find usage examples [here](./cookbook/talking_to_the_outside_world.md). + ## Private and Public Serving All server functionality can be either private (authenticated) or public. diff --git a/src/identity_system.md b/src/identity_system.md index edb11aa5..6249fedd 100644 --- a/src/identity_system.md +++ b/src/identity_system.md @@ -45,4 +45,4 @@ The main takeaway for the identity system is that _domain provenance_ and _domai Like .eth for ENS, the KNS domain space is fixed inside the `.os` top-level domain. However, Kinode DAO has the right to manage domains, including domains other than `.os`, so domain availability is likely to expand in the future (subject to governance decisions). -Eventually, we hope to link various TLDs to existing NFT communities and other identity systems. +Eventually, Kinode DAO hopes to link various TLDs to existing NFT communities and other identity systems. diff --git a/src/install.md b/src/install.md index fd263ca0..adcdad11 100644 --- a/src/install.md +++ b/src/install.md @@ -5,11 +5,11 @@ After acquiring the software, you can learn how to run it and [Join the Network] - If you are just interested in starting development as fast as possible, skip to [My First Kinode Application](./build-and-deploy-an-app.md). - If you want to run a Kinode without managing it yourself, use the [Valet](https://valet.kinode.org) hosted service. -- If you want to make edits to the Kinode core software, see [Build From Source](#build-from-source). +- If you want to make edits to the Kinode core software, see [Build From Source](#option-3-build-from-source). ## Option 1: Download Binary (Recommended) -The Kinode DAO distributes pre-compiled binaries for Ubuntu and MacOS. +The Kinode DAO distributes pre-compiled binaries for MacOS and Linux Debian derivatives, like Ubuntu. First, get the software itself by downloading a [precompiled release binary](https://github.com/kinode-dao/kinode/releases). Choose the correct binary for your particular computer architecture and OS. @@ -17,7 +17,6 @@ There is no need to download the `simulation-mode` binary — it is used behind Extract the `.zip` file: the binary is inside. Note that some operating systems, particularly Apple, may flag the download as suspicious. -While the binary has not been tested exhaustively on all Linux distributions, it should _just work_. ### Apple @@ -29,7 +28,7 @@ Then, go to `System Settings > Privacy and Security` and click to `Open Anyway` ## Option 2: Docker Kinode can also be run using Docker. -Linux and MacOS are supported. +MacOS and Debian derivatives of Linux, like Ubuntu, are supported. Windows may work but is not officially supported. ### Installing Docker @@ -93,13 +92,13 @@ If your system doesn't already have `cmake` and OpenSSL, download them: #### Linux -```sh +```bash sudo apt-get install cmake libssl-dev ``` #### Mac -```sh +```bash brew install cmake openssl ``` diff --git a/src/kit/boot-fake-node.md b/src/kit/boot-fake-node.md index 7d5a8204..7a435da3 100644 --- a/src/kit/boot-fake-node.md +++ b/src/kit/boot-fake-node.md @@ -18,7 +18,7 @@ You can start a network of fake nodes that can communicate with each other (but You'll need to start a new terminal for each fake node. For example, to start two fake nodes, `fake.dev` and `fake2.dev`: -``` +```bash kit boot-fake-node # In a new terminal diff --git a/src/kit/chain.md b/src/kit/chain.md index c541165e..4184548c 100644 --- a/src/kit/chain.md +++ b/src/kit/chain.md @@ -11,11 +11,11 @@ The default port is `8545` and the chain ID is `31337`. ## Discussion `kit chain` starts an anvil node with the arguments `--load-state kinostate.json`. -This json file includes the [KNS](https://github.com/kinode-dao/KNS) & app_store contracts, and is included in the `kit` binary. +This json file includes the [KNS](https://github.com/kinode-dao/KNS) & `app_store` contracts, and is included in the `kit` binary. -The [kinostate.json](https://github.com/kinode-dao/kit/blob/master/src/chain/kinostate.json) file can be found written into /tmp/kinode-kit-cache/kinostate-{hash}.json upon running the command. +The [kinostate.json](https://github.com/kinode-dao/kit/blob/master/src/chain/kinostate.json) file can be found written into `/tmp/kinode-kit-cache/kinostate-{hash}.json` upon running the command. -Note that while the kns_indexer and app_store apps in fake nodes use this chain to index events, any events loaded from a json statefile, aren't replayed upon restarting anvil. +Note that while the `kns_indexer` and `app_store` apps in fake nodes use this chain to index events, any events loaded from a json statefile, aren't replayed upon restarting anvil. ## Arguments diff --git a/src/kit/inject-message.md b/src/kit/inject-message.md index c1dc3d4b..5ca98536 100644 --- a/src/kit/inject-message.md +++ b/src/kit/inject-message.md @@ -2,7 +2,7 @@ `kit inject-message` injects the given message to the node running at given port/URL, e.g., -``` +```bash kit inject-message foo:foo:template.os '{"Send": {"target": "fake2.os", "message": "hello world"}}' ``` diff --git a/src/kit/install.md b/src/kit/install.md index eecacd57..232f4a16 100644 --- a/src/kit/install.md +++ b/src/kit/install.md @@ -43,9 +43,14 @@ The first chapter of the [My First Kinode App tutorial](../my_first_app/chapter_ ## Getting kit +`kit` requires Rust. To get `kit`, run -``` +```bash +# Install Rust if you don't have it. +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + +# Install `kit`. cargo install --git https://github.com/kinode-dao/kit --locked ``` diff --git a/src/kit/new.md b/src/kit/new.md index 8164c1bd..beab96dc 100644 --- a/src/kit/new.md +++ b/src/kit/new.md @@ -10,7 +10,7 @@ creates the default template (a Rust chat app with no UI) in the `foo/` director ## Example Usage -``` +```bash # Create the default template: rust chat with no UI kit new my_rust_chat diff --git a/src/kit/run-tests.md b/src/kit/run-tests.md index b9902248..887ab521 100644 --- a/src/kit/run-tests.md +++ b/src/kit/run-tests.md @@ -49,7 +49,10 @@ Path to [`.toml`](https://toml.io/en/) file specifying tests to run; defaults to ## `tests.toml` The testing protocol is specified by a `.toml` file. -[`tests.toml`](https://github.com/kinode-dao/core_tests/blob/master/tests.toml), from [core tests](https://github.com/kinode-dao/core_tests), will be used as an example. +[`tests.toml`](https://github.com/kinode-dao/core_tests/blob/master/tests.toml), from [core tests](https://github.com/kinode-dao/core_tests), will be used as an example: +```toml +{{#webinclude https://raw.githubusercontent.com/kinode-dao/core_tests/master/tests.toml}} +``` The top-level of `tests.toml` consists of three fields: @@ -76,7 +79,7 @@ Given a valid path, that repo will be compiled and used. For example: ```toml -runtime = { FetchVersion = "latest" } +{{#webinclude https://raw.githubusercontent.com/kinode-dao/core_tests/master/tests.toml 1}} ``` @@ -87,7 +90,7 @@ If given `runtime = RepoPath`, `runtime_build_release` decides whether to build For example: ```toml -runtime_build_release = true +{{#webinclude https://raw.githubusercontent.com/kinode-dao/core_tests/master/tests.toml 3}} ``` @@ -107,23 +110,10 @@ Key | Value Type | Value Description Each test package is [a single-process package that accepts and responds with certain messages](#test-package-interface). + For example: ```toml -[[tests]] -setup_package_paths = ["chat"] -test_packages = [ - { path = "chat_test", grant_capabilities = ["chat:chat:template.os"] }, - { path = "key_value_test", grant_capabilities = ["kv:distro:sys"] }, - { path = "sqlite_test", grant_capabilities = ["sqlite:distro:sys"] }, -] -timeout_secs = 5 -# Plan to include defects = Latency, Dropping, ..., All -network_router = { port = 9001, defects = "None" } - -[[tests.nodes]] -... - -[[tests.nodes]] +{{#webinclude https://raw.githubusercontent.com/kinode-dao/core_tests/master/tests.toml 6:15}} ... ``` @@ -147,17 +137,7 @@ Key | Value Type | Value Description For example: ```toml -[[tests.nodes]] -port = 8080 -home = "home/first" -fake_node_name = "first.os" -runtime_verbosity = 0 - -[[tests.nodes]] -port = 8081 -home = "home/second" -fake_node_name = "second.os" -runtime_verbosity = 0 +{{#webinclude https://raw.githubusercontent.com/kinode-dao/core_tests/master/tests.toml 15:25}} ``` @@ -166,34 +146,9 @@ runtime_verbosity = 0 A test package is a single-process package that accepts and responds with certain messages. The interface is defined as: + ```wit -interface tester { - variant request { - run(run-request), - } - - variant response { - run(result<_, fail-response>) - } - - record run-request { - input-node-names: list, - test-names: list, - test-timeout: u64, - } - - record fail-response { - test: string, - file: string, - line: u32, - column: u32, - } -} - -world tester-sys-v0 { - import tester; - include process-v0; -} +{{#webinclude https://raw.githubusercontent.com/kinode-dao/kinode/main/kinode/packages/tester/api/tester%3Asys-v0.wit}} ``` A `run` `request` starts the test. diff --git a/src/kit/view-api.md b/src/kit/view-api.md index bac0fd13..a23872a8 100644 --- a/src/kit/view-api.md +++ b/src/kit/view-api.md @@ -11,7 +11,7 @@ lists all the APIs of packages downloaded by the Kinode running at port 8080. ## Example Usage -``` +```bash # Fetch and display the API for the given package kit view-api app_store:sys ``` diff --git a/src/login.md b/src/login.md index f9aaacc1..d4ce3684 100644 --- a/src/login.md +++ b/src/login.md @@ -70,7 +70,7 @@ On the "Active Endpoints" tab, there are tabs for "HTTPS" and "WebSockets". Sele In a terminal window, run: ```bash -./kinode home +./kinode path/to/home ``` A new browser tab should open, but if not, look in the terminal for this line: @@ -155,7 +155,7 @@ The networking key is how your node communicates securely with other nodes, and After setting the node password, you will be greeted with the homepage. -![Homepage](./assets/homepage.png) +![Homepage](./assets/register-homepage.png) Try downloading, installing, and using some apps on the App Store. Come ask for recommendations in the [Kinode Discord](https://discord.gg/mYDj74NkfP)! diff --git a/src/my_first_app/chapter_1.md b/src/my_first_app/chapter_1.md index 073b6fb3..de3744fd 100644 --- a/src/my_first_app/chapter_1.md +++ b/src/my_first_app/chapter_1.md @@ -173,8 +173,6 @@ The only required fields are `package_name`, `current_version`, and `publisher`, ```bash $ cat my_chat_app/metadata.json -``` -```json { "name": "my_chat_app", "description": "", diff --git a/src/my_first_app/chapter_2.md b/src/my_first_app/chapter_2.md index c68a0374..f87410ce 100644 --- a/src/my_first_app/chapter_2.md +++ b/src/my_first_app/chapter_2.md @@ -114,7 +114,7 @@ to see this code in the node you set up in the last section. ## Sending a Message -To send a message to another process, `use` the [`Request`](https://docs.rs/kinode_process_lib/latest/kinode_process_lib/struct.Request.html) type from the [process_lib](../process_stdlib/overview.md), which will provide all the necessary functionality. +To send a message to another process, `use` the [`Request`](https://docs.rs/kinode_process_lib/latest/kinode_process_lib/struct.Request.html) type from the [`process_lib`](../process_stdlib/overview.md), which will provide all the necessary functionality. ```rust use kinode_process_lib::{await_message, call_init, println, Address, Request}; ``` @@ -279,4 +279,4 @@ fn my_init_fn(our: Address) { This basic structure can be found in the majority of Kinode processes. The other common structure is a thread-like process, that sends and handles a fixed series of messages and then exits. -In the next section, we will cover how to turn this very basic request-response pattern into something that can be extensible and composable. +In the next section, you will learn how to turn this very basic request-response pattern into something that can be extensible and composable. diff --git a/src/my_first_app/chapter_3.md b/src/my_first_app/chapter_3.md index d199fabe..f19307d5 100644 --- a/src/my_first_app/chapter_3.md +++ b/src/my_first_app/chapter_3.md @@ -9,7 +9,7 @@ In the last section, you created a simple request-response pattern that uses str This is fine for certain limited cases, but in practice, most Kinode processes written in Rust use a `body` type that is serialized and deserialized to bytes using [Serde](https://serde.rs/). There are a multitude of libraries that implement Serde's `Serialize` and `Deserialize` traits, and the process developer is responsible for selecting a strategy that is appropriate for their use case. -Some popular options are `bincode`, [`rmp_serde`](https://docs.rs/rmp-serde/latest/rmp_serde/), and `serde_json`. +Some popular options are `bincode`, [`rmp_serde`](https://docs.rs/rmp-serde/latest/rmp_serde/) ([MessagePack](https://msgpack.org/index.html)), and `serde_json`. In this section, you will use `serde_json` to serialize your Rust structs to a byte vector of JSON. ### Defining the `body` Type @@ -67,7 +67,7 @@ Writing interoperable code is necessary for enabling permissionless composabilit ### Handling Messages In this example, you will learn how to handle a Request. -So, create a request that uses the new `body` type (you won't need to send a Response back, so we can remove `.expect_response()`): +So, create a request that uses the new `body` type (you won't need to send a Response back, so you can remove `.expect_response()`): ```rust Request::to(&our) diff --git a/src/my_first_app/chapter_4.md b/src/my_first_app/chapter_4.md index bffd06b6..c6235fff 100644 --- a/src/my_first_app/chapter_4.md +++ b/src/my_first_app/chapter_4.md @@ -36,7 +36,7 @@ fn my_init_fn(our: Address) { ``` `http::bind_http_path("/", false, false)` arguments mean the following: -- The first argument is the path to bind. +- The first argument is the path to bind. Note that requests will be namespaced under the process name, so this will be accessible at e.g. `/my_process_name/`. - The second argument marks whether to serve the path only to authenticated clients In order to skip authentication, set the second argument to false here. @@ -110,7 +110,7 @@ fn handle_http_message(our: &Address, message: &Message) { } ``` -Instead of directly parsing the `body` type from the message, parse the type that the `http_server` process gives us. +Instead of directly parsing the `body` type from the message, parse the type that the `http_server` process gives us. This type is defined in the `kinode_process_lib::http` module for us: ```rust // ... @@ -300,7 +300,7 @@ If you just want to serve an API, you've seen enough now to handle PUTs and GETs But the classic personal node app also serves a webpage that provides a user interface for your program. You *could* add handling to root `/` path to dynamically serve some HTML on every GET. -But for maximum ease and efficiency, use the static bind command on `/` and move the PUT handling to `/api`. +But for maximum ease and efficiency, use the static bind command on `/` and move the PUT handling to `/api`. To do this, edit the bind commands in `my_init_fn` to look like this: ```rust @@ -308,7 +308,7 @@ http::bind_http_path("/api", true, false).unwrap(); http::serve_index_html(&our, "ui", true, false, vec!["/"]).unwrap(); ``` -Note that you are setting `authenticated` to `true` in the `serve_index_html` and `bind_http_path` calls. +Note that you are setting `authenticated` to `true` in the `serve_index_html` and `bind_http_path` calls. The result of this is that the webpage will be able to get served by the browser, but not by the raw cURL request. Now you can add a static `index.html` file to the package. @@ -393,8 +393,7 @@ However, if you insist upon staying, you will learn how to customize your app ic #### Encoding an Icon Choosing an emblem is a difficult task. -Thankfully, we have chosen one for you. -Let's use this gosling: +Here is one you can use: ![gosling](../assets/gosling.png) @@ -409,7 +408,7 @@ base64 < gosling.png >> icon ``` Then, move `icon` next to `lib.rs` in your app's directory. -Finally, include the icon data in your `lib.rs` file, early on, just after the imports: +Finally, include the icon data in your `lib.rs` file, early on, just after the imports: ```rs const ICON: &str = include_str!("./icon"); @@ -417,13 +416,13 @@ const ICON: &str = include_str!("./icon"); #### Clicking the Button -The Kinode process lib exposes an [`add_to_homepage`](https://docs.rs/kinode_process_lib/0.8.3/kinode_process_lib/homepage/fn.add_to_homepage.html) function that you can use to add your app to the homepage. +The Kinode process lib exposes an [`add_to_homepage`](https://docs.rs/kinode_process_lib/latest/kinode_process_lib/homepage/fn.add_to_homepage.html) function that you can use to add your app to the homepage. In your `my_init_fn`, add the following line: ```rs homepage::add_to_homepage( - "My App Name", // the name of your app + "My App Name", // the name of your app ICON, // the icon data (base64 encoded, prepended with "data:image/png;base64,") "/", // the path to your app's UI (/my_process:my_package:template.os/ is prepended automatically) ).unwrap(); @@ -433,12 +432,12 @@ Now, you can build and reinstall your package with `kit bs`, reload your node's To dock your app, click the heart icon on it. Click the icon itself to go to the UI served by your app. -### Writing a Widget +### Writing a Widget -A widget is an HTML iframe. +A widget is an HTML iframe. Kinode apps can send widgets to the `homepage` process, which will display them on the user's homepage. They are quite simple to configure. -In `add_to_homepage`, add an additional field: +In `add_to_homepage`, add an additional field: ```rs // inside the init function again @@ -583,4 +582,4 @@ It then creates some HTML to display the apps in a nice little list. -``` \ No newline at end of file +``` diff --git a/src/networking_protocol.md b/src/networking_protocol.md index 34285eee..981e8256 100644 --- a/src/networking_protocol.md +++ b/src/networking_protocol.md @@ -16,7 +16,7 @@ The former allows for completely direct peer-to-peer connections, and the latter The networking protocol can and will be implemented in multiple underlying protocols. Since the protocol is encrypted, a secure underlying connection with TLS or HTTPS is never necessary. -WebSockets are prioritized since we expect to quickly build Kinodes that run purely in-browser. +WebSockets are prioritized since to make purely in-browser Kinodes a possibility. The other transport protocols with slots in the onchain identity data structure are: TCP, UDP, and WebTransport. ### 2. Onchain Networking Information @@ -60,7 +60,7 @@ All data structures are serialized and deserialized using [MessagePack](https:// The WebSockets protocol uses the [Noise Protocol Framework](http://www.noiseprotocol.org/noise.html) to encrypt all messages end-to-end. The parameters used are `Noise_XX_25519_ChaChaPoly_BLAKE2s`. -Using the XX pattern means we follow this interactive pattern: +Using the XX pattern means following this interactive pattern: ``` -> e <- e, ee, s, es diff --git a/src/process/capabilities.md b/src/process/capabilities.md index 8307b40c..82aafb51 100644 --- a/src/process/capabilities.md +++ b/src/process/capabilities.md @@ -11,10 +11,10 @@ pub struct Capability { } ``` The kernel abstracts away the process of ensuring that a capability is not forged. -As a process developer, if a capability comes in on a message or is granted to you by the kernel, you can guarantee that it is legitimate. +As a process developer, if a capability comes in on a message or is granted to you by the kernel, you are guaranteed that it is legitimate. -Runtime processes, including the kernel itself, the filesystem, and the HTTP client, issue capabilities to processes. -Then, when a request is made by a process, the responder verifies the process's capability. +Runtime processes, including the kernel itself, the filesystem, and the HTTP client, issue capabilities to processes. +Then, when a request is made by a process, the responder verifies the process's capability. If the process does not have the capability to make such a request, it will be denied. To give a concrete example: the filesystem can read/write, and it has the capabilities for doing so. diff --git a/src/process_stdlib/overview.md b/src/process_stdlib/overview.md index 68405d3b..12351799 100644 --- a/src/process_stdlib/overview.md +++ b/src/process_stdlib/overview.md @@ -9,7 +9,7 @@ See [here](https://github.com/kinode-dao/process_lib/releases) for a list of pub In your `Cargo.toml` file, use a version tag like this: ```toml -kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib.git", tag = "v0.5.4-alpha" } +kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib.git", tag = "v0.8.1" } ``` To use a specific commit hash, use this: @@ -17,17 +17,18 @@ To use a specific commit hash, use this: kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib.git", rev = "5305453" } ``` -Make sure to use a recent version of the process_lib while the system is in alpha and very active development. +Make sure to use a recent version of the `process_lib` while the system is in beta and very active development. -The major version of the process_lib will always match the major version of Kinode OS. +The major version of the `process_lib` will always match the major version of Kinode OS. Since the current major version of both is 0, breaking changes can occur at any time. Once the major version reaches 1, breaking changes will only occur between major versions. -As is, developers may have to update their version of process_lib as they update Kinode OS. +As is, developers may have to update their version of `process_lib` as they update Kinode OS. Since Kinode apps use the [WebAssembly Component Model](https://component-model.bytecodealliance.org/), they are built on top of a [WIT](https://component-model.bytecodealliance.org/design/wit.html) (Wasm Interface Type) [package](https://github.com/kinode-dao/kinode-wit/blob/master/kinode.wit). -[`wit-bindgen`](https://github.com/bytecodealliance/wit-bindgen) is used to generate Rust code from a WIT file. +[`wit-bindgen`](https://github.com/bytecodealliance/wit-bindgen) is used to generate Rust code from a WIT file. The generated code then contains the core types and functions that are available to all Kinode apps. However, the types themselves are unwieldy to use directly, and runtime modules present APIs that can be drastically simplified by using helper functions and types in the process standard library. -Almost all code examples in this book make use of the process lib. For specific examples of its usage, check out the [docs](https://docs.rs/kinode_process_lib) or just follow the tutorials later in this book. +Almost all code examples in this book make use of the `process_lib`. +For specific examples of its usage, check out the [docs](https://docs.rs/kinode_process_lib) or just follow the tutorials later in this book. diff --git a/src/terminal.md b/src/terminal.md index f9ddb604..914191db 100644 --- a/src/terminal.md +++ b/src/terminal.md @@ -98,16 +98,16 @@ Each top-level key represents the path of a process in your package, usually jus Within this JSON object, for each key (i.e., process) the value is an object that specifies the configuration for that particular process. The object can contain the following fields: -- `root` (Boolean): Indicates whether the script has "root" privileges - meaning whether it gets _every_ capability that the terminal has (not necessarily every capability in existence on your machine) -- `public` (Boolean): Determines if the script is publicly accessible by other processes -- `request_networking` (Boolean): Specifies whether the script will get networking capabilities -- `request_capabilities` (Array): An array that lists the capabilities requested by the script. Each element in the array can be either a string or an object. - The string represents a `ProcessId` that this script will be able to message. When an object is used, it specifies a different kind of capability from `issuer` with `params` as an arbitrary json object. -- `grant_capabilities` (Array of strings): An array of `ProcessId`s which represents which processes will be able to send a `Response` back to this script. - If this script is public, `grant_capabilities` can stay empty. +Field | Type | Description +------------------------ | ---------------- | ----------- +`"root"` | Boolean | Indicates whether the script has "root" privileges - meaning whether it gets _every_ capability that the terminal has (not necessarily every capability in existence on your machine) +`"public"` | Boolean | Determines if the script is publicly accessible by other processes +`"request_networking"` | Boolean | Specifies whether the script will get networking capabilities +`"request_capabilities"` | Array | An array that lists the capabilities requested by the script. Each element in the array can be either a string or an object. The string represents a `ProcessId` that this script will be able to message. When an object is used, it specifies a different kind of capability from `issuer` with `params` as an arbitrary json object. +`"grant_capabilities"` | Array of strings | An array of `ProcessId`s which represents which processes will be able to send a `Response` back to this script. If this script is public, `grant_capabilities` can stay empty. Processes may not necessarily use all these fields. -For instance, "m.wasm" only uses root, public, and `request_networking`, omitting `request_capabilities` and `grant_capabilities`. +For instance, `m.wasm` only uses root, public, and `request_networking`, omitting `request_capabilities` and `grant_capabilities`. ### Example