Skip to content

Commit

Permalink
Merge pull request #191 from jurij-jukic/section-5
Browse files Browse the repository at this point in the history
Section 5: My First Kinode App
  • Loading branch information
jurij-jukic authored May 20, 2024
2 parents 2dcdb9e + d3e0de1 commit 6b8040b
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 129 deletions.
4 changes: 2 additions & 2 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
- [`reset-cache`](./kit/reset-cache.md)
- [My First Kinode Application](./build-and-deploy-an-app.md)
- [Environment Setup](./my_first_app/chapter_1.md)
- [Sending Some Messages, Using Some Tools](./my_first_app/chapter_2.md)
- [Defining Your Protocol](./my_first_app/chapter_3.md)
- [Sending and Responding to a Message](./my_first_app/chapter_2.md)
- [Messaging with Larger Data Types](./my_first_app/chapter_3.md)
- [Frontend Time](./my_first_app/chapter_4.md)
- [Sharing with the World](./my_first_app/chapter_5.md)
- [In-Depth Guide: Chess App](./chess_app.md)
Expand Down
4 changes: 2 additions & 2 deletions src/build-and-deploy-an-app.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# My First Kinode Application

In these tutorials, you'll setup your development environment and learn about the `kit` tools.
You'll learn about templates and also walk through writing an application from the group up, backend and frontend.
You'll learn about templates and also walk through writing an application from the ground up, backend and frontend.
And finally, you'll learn how to deploy applications through the Kinode app store.

For the purposes of this documentation, terminal commands are provided as-is for ease of copying EXCEPT when the output of the command is also shown.
For the purposes of this documentation, terminal commands are provided as-is for ease of copying except when the output of the command is also shown.
In that case, the command is prepended with a `$ ` to distinguish the command from the output.
The `$ ` should not be copied into the terminal.
81 changes: 49 additions & 32 deletions src/my_first_app/chapter_1.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Environment Setup

In this chapter, you'll walk through setting up a Kinode development environment.
In this section, you'll walk through setting up a Kinode development environment.
By the end, you will have created a Kinode application, or package, composed of one or more processes that run on a live Kinode.
The application will be a simple chat interface: `my_chat_app`.

Expand Down Expand Up @@ -53,41 +53,55 @@ Kinode packages are sets of one or more Kinode [processes](../process/processes.
A Kinode package is represented in Unix as a directory that has a `pkg/` directory within.
Each process within the package is its own directory.
By default, the `kit new` command creates a simple, one-process package, a chat app.
Other templates, including a Python template and a UI-enabled template can be used by passing different flags to `kit new` (see `kit new --help`).
Other templates, including a Python template and a UI-enabled template can be used by passing [different flags to `kit new`](../kit/new.html#discussion).
The default template looks like:

```bash
$ tree my_chat_app
my_chat_app
├── metadata.json
├── my_chat_app
│   ├── Cargo.toml
│   └── src
│   └── lib.rs
└── pkg
└── manifest.json
├── Cargo.toml
├── metadata.json
├── my_chat_app
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
├── pkg
│ ├── manifest.json
│ └── scripts.json
└── send
├── Cargo.toml
└── src
└── lib.rs
```

The `my_chat_app/` package here contains one process, also named `my_chat_app/`.
The process directory contains source files and other metadata for compiling that process.
The `my_chat_app/` package here contains two processes:
- `my_chat_app/` — containing the main application code, and
- `send/` — containing a [script](../cookbook/writing_scripts.html).

In Rust processes, the standard Rust `Cargo.toml` file is included: it specifies dependencies.
It is exhaustively defined [here](https://doc.rust-lang.org/cargo/reference/manifest.html).
The `src/` directory is where the code for the process lives.
Rust process directories, like the ones here, contain:
- `src/` - source files where the code for the process lives, and
- `Cargo.toml` - the standard Rust file specifying dependencies, etc., for that process.

Another standard Rust `Cargo.toml` file, a [virtual manifest](https://doc.rust-lang.org/cargo/reference/workspaces.html#virtual-workspace) is also included in `my_chat_app/` root.

Also within the package directory is a `pkg/` directory.
The `pkg/` directory contains two files, `manifest.json` and `metadata.json`, that specify information the Kinode needs to run the package, which will be enumerated below.
The `pkg/` dirctory contains two files:
- `manifest.json` - specifes information the Kinode needs to run the package, and
- `scripts.json` - specifies details needed to run [scripts](../cookbook/writing_scripts.html).

The `pkg/` directory is also where `.wasm` binaries will be deposited by [`kit build`](#building-the-package).
The files in the `pkg/` directory are injected into the Kinode with [`kit start-package`](#starting-the-package).

Lastly, `metadata.json` contains app metadata which is used in the Kinode [App Store](./chapter_5.html)

Though not included in this template, packages with a frontend have a `ui/` directory as well.
For an example, look at the result of:
```bash
kit new my_chat_app_with_ui --ui
tree my_chat_app_with_ui
```
Note that not all templates have a UI-enabled version.
As of 240118, only the Rust chat template has a UI-enabled version.
More details about templates can be found [here](../kit/new.html#existshas-ui-enabled-version).

### `pkg/manifest.json`

Expand Down Expand Up @@ -124,8 +138,8 @@ Key | Value Type
`"process_wasm_path"` | String | The path to the process
`"on_exit"` | String (`"None"` or `"Restart"`) or Object (covered [elsewhere](./chapter_2.md#aside-on_exit)) | What to do in case the process exits
`"request_networking"` | Boolean | Whether to ask for networking capabilities from kernel
`"request_capabilities"` | Array of Strings or Objects | Strings are process IDs to request messaging capabilties from; Objects have a `"process"` field (process ID to request from) and a `"params"` field (capability to request)
`"grant_capabilities"` | Array of Strings or Objects | Strings are process IDs to grant messaging capabilties to; Objects have a `"process"` field (process ID to grant to) and a `"params"` field (capability to grant)
`"request_capabilities"` | Array of Strings or Objects | Strings are `ProcessId`s to request messaging capabilties from; Objects have a `"process"` field (`ProcessId` to request from) and a `"params"` field (capability to request)
`"grant_capabilities"` | Array of Strings or Objects | Strings are `ProcessId`s to grant messaging capabilties to; Objects have a `"process"` field (`ProcessId` to grant to) and a `"params"` field (capability to grant)
`"public"` | Boolean | Whether to allow any process to message us

### `metadata.json`
Expand Down Expand Up @@ -154,21 +168,21 @@ $ cat my_chat_app/metadata.json
"animation_url": ""
}
```
Here, the `publisher` is some default value, but for a real package, this field should contain the KNS id of the publishing node.
Here, the `publisher` is some default value, but for a real package, this field should contain the KNS ID of the publishing node.
The `publisher` can also be set with a `kit new --publisher` flag.
The rest of these fields are not required for development, but become important when publishing a package with the `app_store`.
The rest of these fields are not required for development, but become important when publishing a package with the [`app_store`](https://github.com/kinode-dao/kinode/tree/main/kinode/packages/app_store).

As an aside: each process has a unique process ID, used to address messages to that process, that looks like
As an aside: each process has a unique `processID`, used to address messages to that process, that looks like

```
<process_name>:<package_name>:<publisher>
```

You can read more about process IDs [here](../process/processes.md#overview).
You can read more about `processID`s [here](../process/processes.md#overview).

## Building the Package

To build the package, use the `kit build` tool.
To build the package, use the [`kit build`](../kit/build.md#) tool.

This tool accepts an optional directory path as the first argument, or, if none is provided, attempts to build the current working directory.
As such, either of the following will work:
Expand All @@ -188,7 +202,7 @@ kit build

Often, it is optimal to develop on a fake node.
Fake nodes are simple to set up, easy to restart if broken, and mocked networking makes development testing very straightforward.
To boot a fake Kinode for development purposes, use the `kit boot-fake-node` tool.
To boot a fake Kinode for development purposes, use the [`kit boot-fake-node` tool](../kit/boot-fake-node.md).

`kit boot-fake-node` downloads the OS- and architecture-appropriate Kinode core binary and runs it without connecting to the live network.
Instead, it connects to a mocked local network, allowing different fake nodes on the same machine to communicate with each other.
Expand Down Expand Up @@ -219,9 +233,12 @@ kit boot-fake-node --runtime-path ~/path/to/kinode

where `~/path/to/kinode` must be replaced with a path to the Kinode core repo.

Note that your node will be named `fake.dev`, as opposed to `fake.os`.
The `.dev` suffix is used for development nodes.

## Optional: Starting a Real Kinode

Alternatively, development sometimes calls for a real node, which has access to the actual Kinode network and its providers, such as integrated LLMs.
Alternatively, development sometimes calls for a real node, which has access to the actual Kinode network and its providers.

To develop on a real Kinode, connect to the network and follow the instructions to [setup a Kinode](../install.md).

Expand Down Expand Up @@ -250,7 +267,7 @@ or, if you are already in the correct package directory:
kit start-package -p 8080
```

where here the port provided following `-p` must match the port bound by the node or fake node (see discussion [above](#booting-a-fake-kinode-node)).
where here the port provided following `-p` must match the port bound by the node or fake node (see discussion [above](#booting-a-fake-kinode)).

The node's terminal should display something like

Expand All @@ -265,7 +282,7 @@ Congratulations: you've now built and installed your first application on Kinode
To test out the functionality of `my_chat_app`, spin up another fake node to chat with in a new terminal:

```bash
kit boot-fake-node -h /tmp/kinode-fake-node-2 -p 8081 -f fake2.os
kit boot-fake-node -h /tmp/kinode-fake-node-2 -p 8081 -f fake2.dev
```

The fake nodes communicate over a mocked local network.
Expand All @@ -285,20 +302,20 @@ kit start-package -p 8081
To send a chat message from the first node, run the following in its terminal:

```
m our@my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake2.os", "message": "hello world"}}'
m our@my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake2.dev", "message": "hello world"}}'
```

and replying, from the other terminal:

```
m our@my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake.os", "message": "wow, it works!"}}'
m our@my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake.dev", "message": "wow, it works!"}}'
```

Messages can also be injected from the outside.
From a bash terminal, use `kit inject-message`, like so:

```bash
kit inject-message my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake2.os", "message": "hello from the outside world"}}'
kit inject-message my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake.os", "message": "replying from fake2.os using first method..."}}' --node fake2.os
kit inject-message my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake.os", "message": "and second!"}}' -p 8081
kit inject-message my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake2.dev", "message": "hello from the outside world"}}'
kit inject-message my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake.dev", "message": "replying from fake2.dev using first method..."}}' --node fake2.dev
kit inject-message my_chat_app:my_chat_app:template.os '{"Send": {"target": "fake.dev", "message": "and second!"}}' -p 8081
```
Loading

0 comments on commit 6b8040b

Please sign in to comment.