exp: client host and demo app using wasm/wasmtime
diff --git a/apps/client/hello/main.go b/apps/client/hello/main.go
new file mode 100644
index 0000000..21cb8dd
--- /dev/null
+++ b/apps/client/hello/main.go
@@ -0,0 +1,97 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"syscall"
+	"unsafe"
+
+	"github.com/ahmetalpbalkan/go-cursor"
+	"github.com/bytecodealliance/wasmtime-go"
+)
+
+type WindowSize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+func check(err error) {
+	if err != nil {
+		panic(err)
+	}
+}
+
+func main() {
+	store := wasmtime.NewStore(wasmtime.NewEngine())
+	linker := wasmtime.NewLinker(store.Engine)
+	err := linker.DefineWasi()
+	check(err)
+	wasiConfig := wasmtime.NewWasiConfig()
+	store.SetWasi(wasiConfig)
+	err = linker.FuncNew(
+		"env",
+		"hello",
+		wasmtime.NewFuncType(
+			[]*wasmtime.ValType{wasmtime.NewValType(wasmtime.KindI32)},
+			[]*wasmtime.ValType{}),
+		func(c *wasmtime.Caller, args []wasmtime.Val) ([]wasmtime.Val, *wasmtime.Trap) {
+			if len(args) != 1 {
+				check(fmt.Errorf("%+v", args))
+			}
+			id := args[0].I32()
+			fmt.Printf("Hello %d\n", id)
+			return []wasmtime.Val{}, nil
+		})
+	check(err)
+	err = linker.FuncWrap("env", "cursorHide", func() {
+		fmt.Print(cursor.Hide())
+	})
+	check(err)
+	err = linker.FuncWrap("env", "cursorShow", func() {
+		fmt.Print(cursor.Show())
+	})
+	check(err)
+	err = linker.FuncWrap("env", "cursorSet", func(x, y int32) {
+		fmt.Print(cursor.MoveTo(int(x), int(y)))
+	})
+	check(err)
+	err = linker.FuncWrap("env", "clearScreen", func() {
+		fmt.Print(cursor.ClearEntireScreen())
+	})
+	check(err)
+	err = linker.FuncWrap("env", "flush", func() {
+		// fmt.Print(cursor.Flush())
+	})
+	check(err)
+	err = linker.FuncWrap("env", "draw", func(x, y int32) {
+		fmt.Printf("\x1b7\x1b[%d;%df%s\x1b8", x, y, ".")
+	})
+	check(err)
+	err = linker.FuncWrap("env", "getSize", func() (int32, int32, int32, int32) {
+		var ws WindowSize
+		retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
+			uintptr(syscall.Stdin),
+			uintptr(syscall.TIOCGWINSZ),
+			uintptr(unsafe.Pointer(&ws)))
+		if int(retCode) == -1 {
+			panic(errno)
+		}
+		return int32(ws.Row), int32(ws.Col), int32(ws.Xpixel), int32(ws.Ypixel)
+	})
+	check(err)
+
+	wasm, err := os.ReadFile("call_host/target/wasm32-wasi/debug/call_host.wasm")
+	check(err)
+	module, err := wasmtime.NewModule(store.Engine, wasm)
+	check(err)
+	instance, err := linker.Instantiate(store, module)
+	check(err)
+	run := instance.GetFunc(store, "run")
+	if run == nil {
+		panic("not a function")
+	}
+	_, err = run.Call(store)
+	check(err)
+}