Scripts
Scripts are just processes. They are written almost exactly like applications, with a few key differences:
- Scripts always terminate, while apps may run indefinitely.
When writing a script, you cannot control the
OnExit
behavior like you can with an application - Scripts are called with an initial set of arguments (passed in via the
terminal
) - Scripts are registered in the
scripts.json
file instead of themanifest.json
file
Writing a Script
Consider the simplest possible script: echo
, which takes in an argument, and prints it out again:
#![allow(unused)] fn main() { use kinode_process_lib::{await_next_request_body, call_init, println, Address, Response}; wit_bindgen::generate!({ path: "wit", world: "process", }); call_init!(init); fn init(_our: Address) { let Ok(args) = await_next_request_body() else { println!("echo: failed to get args, aborting"); return; }; match String::from_utf8(args.clone()) { Ok(s) => println!("{}", s), Err(_) => println!("{:?}", args), } } }
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 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.
In this case, echo
sends simply reserializes the body to a String
and prints it out.
Publishing a Script
Unlike processes associated with a long-running application, which will be put into the manifest.json
, scripts must be registered in a separate scripts.json
file.
While very similar, there are a few important differences; here's an example that could live in your packages pkg/scripts.json
file:
{
"echo.wasm": {
"root": false,
"public": false,
"request_networking": false,
"request_capabilities": [],
"grant_capabilities": []
}
}
This scripts.json
file corresponds to a package which publishes a single script, echo
, which doesn't request root
capabilities, or any capabilities for that matter.
The keys of this object are the process paths inside of the pkg/
folder.
The name of the script will be the file path, with .wasm
taken off.
The object that echo.wasm
points to is very similar to manifest.json
, with a few things removed, and root
has been added:
root
means that all the capabilities held by theterminal:terminal:sys
are passed to this script (this is powerful, and rarely needed)public
: same asmanifest.json
- corresponds to whether or not other processes can messageecho.wasm
without the messsaging caprequest_networking
: same asmanifest.json
- corresponds to whether or not this script will need to send messaages over the networkrequest_capabilities
: same asmanifest.json
- a list of capabilities that will be granted to this script on startup (NOTE if you haveroot
, there is no reason to populaterequest_capabilities
as well)grant_capabilities
: same asmanifest.json
- a list of messaging caps toecho.wasm
to be given to other processes on startup As long as you have ascripts.json
file, your scripts will be callable from the terminal when someone else downloads your package
Calling a Script
After having called kit bs
, simply type my_script:my_package:publisher <ARGS>
in the terminal.
For instance, the echo
script is published as part of terminal:sys
, so you can call
echo:terminal:sys Hello World!
Aliasing a Script
If you are going to be calling your script very often, you can alias it to something shorter like so:
alias echo echo:terminal:sys
so now you can call echo
like echo Hello World!
.
To remove the alias, simply run:
alias echo