minks - Minimal KonsolScript

minks is a command line interface that runs KonsolScript (.ks) files via libkonsolscript and manages the KonsolScript plugin environment

minks script.ks              # run a script
minks                        # interactive REPL
minks --check script.ks      # validate without running
minks --debug script.ks      # trace execution to stderr
minks --sandbox script.ks    # audit: log File:/OS:/Konsol:Run calls to stderr
minks --version              # print version and exit

Exit codes

Code Meaning
0 Script ran successfully
1 Internal minks error (std::exception)
2 Uncaught KonsolScript exception — error printed to stderr with line number and stack trace

REPL

Run minks with no arguments to enter the interactive prompt:

$ minks
minks REPL  (Ctrl+D or 'exit' to quit)
>>> Var:Number x = 2;
>>> Var:Number _ret
>>> Math:Power(x, 10, _ret);
=> 1024
>>> function double(n) { return n * 2; }
>>> double(7);
=> 14
>>> exit

Managing installed plugins

minks install <name>          install plugin from current directory or exe directory
minks remove  <name>          delete it from the user plugin dir
minks list                    list all installed plugins

minks install searches for <name>.dll / .so / .dylib (then lib<name>…) in two places in order:

  1. Exe directory — the folder containing the minks binary itself (convenient when the plugin is bundled alongside minks)
  2. Working directory — wherever you ran minks install from

Installed plugins live in ~/.minks/plugins/ (Linux/macOS) or %APPDATA%\minks\plugins\ (Windows) and are available to all scripts without any flags.

If the plugin ships a manifest (<name>.json alongside the DLL), minks install automatically installs any required system library using the appropriate package manager:

Environment Action
Linux (apt) runs sudo apt install …
Linux (pacman) runs sudo pacman -S …
macOS runs brew install …
Windows + MSYS2 runs pacman -S $MINGW_PACKAGE_PREFIX-…
Windows (plain) prints a manual download link
cd curl_plugin
minks install kse_curl
# installed curl -> ~/.minks/plugins/curl.dll
# This plugin requires libcurl.
# Running: sudo apt install libcurl4-openssl-dev

Adding a search directory (CLI)

minks --plugin-path ./my_libs script.ks

--plugin-path can be repeated. Added dirs are checked before the defaults.

Sandbox mode

minks --sandbox script.ks

Logs every File:, OS:, and Konsol:Run call to stderr before it executes — useful for auditing what an untrusted script does with the filesystem or shell. The script still runs normally; calls are not blocked.

[sandbox] File:Open on line 12
[sandbox] OS:System on line 34

Check mode

minks --check script.ks      # or: minks -c script.ks

Parses and validates the script without executing it. Exits 0 if valid, 1 on errors. Useful for CI linting.

Debug mode

minks --debug script.ks      # or: minks -d script.ks

Prints a trace of each statement to stderr as it executes.

Version / help

minks --version              # or: minks -V
minks --help                 # or: minks -h

Shebang

Scripts may start with a shebang line — minks ignores it:

#!/usr/bin/env minks
Konsol:Print("Hello!");

Make the file executable (chmod +x script.ks) and run it directly on Linux/macOS.


Low-level explicit load (legacy / debug)

minks --plugin ./myplugin.dll script.ks
minks --plugin lib1.dll --plugin lib2.dll script.ks
minks -p ./kse_mysql.so -p ./kse_audio.so game.ks

--plugin (or -p) can be repeated. Libraries are loaded in the order given before the script runs. Prefer #include "name" in scripts over this flag for portability.

Working example — sample plugin

sample_plugin/kse_sample.cpp exposes a Sample class with six byRefMethod entries and one voidMethod. Build, install, and use:

# from sample_plugin/
make
minks install kse_sample   # searches cwd for kse_sample.dll/.so

# In your .ks script:
#include "kse_sample"

Or for a quick test without installing (explicit load by path):

minks --plugin sample_plugin\kse_sample.dll tests\20_plugin.ks   # Windows
minks --plugin ./sample_plugin/kse_sample.so tests/20_plugin.ks  # Linux

Available plugins

All plugins follow the ByRef convention — non-void methods write their result to the last argument, which must be a pre-declared variable.

Plugin exceptions extend Exception and expose e.message (String) and e.code (Number) in catch blocks.


curl — HTTP client

Requires: libcurl (installed automatically by minks install) Source: curl_plugin/kse_curl.cpp

cd curl_plugin && make
minks install kse_curl
#include "curl"

Curl:SetHeader("Authorization", "Bearer mytoken");
Var:String body;
Var:Number status;

try {
    Curl:Get("https://api.example.com/users", body);
} catch (CurlException e) {
    Konsol:Print("Error: ${e.message}");
}

Curl:Status(status);
Konsol:Print("${status}: ${body}");
Method Args Out Description
Curl:Get url String HTTP GET, returns response body
Curl:Post url, body String HTTP POST with body
Curl:Put url, body String HTTP PUT with body
Curl:Delete url String HTTP DELETE
Curl:Status Number HTTP status code of last request
Curl:SetHeader key, value void Set a persistent request header
Curl:ClearHeaders void Remove all set headers
Curl:SetTimeout seconds void Request timeout (default: 30)

sqlite — SQLite database

Requires: nothing — SQLite amalgamation is compiled directly into the plugin Source: sqlite_plugin/kse_sqlite.cpp Note: place sqlite3.c and sqlite3.h from sqlite.org/download.html (amalgamation zip) in sqlite_plugin/ before building

cd sqlite_plugin && make
minks install kse_sqlite
#include "sqlite"

Var:Number db;
Var:Boolean ok;
Var:String rows;

try {
    SQLite:Open("data.db", db);
} catch (SQLiteException e) {
    Konsol:Print("Error: ${e.message}");
}

SQLite:Exec(db, "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)", ok);
SQLite:Exec(db, "INSERT INTO users (name) VALUES ('Alice')", ok);
SQLite:Query(db, "SELECT * FROM users", rows);
Konsol:Print(rows);   // JSON array: [{"id":1,"name":"Alice"}]
SQLite:Close(db);

Query results are returned as a JSON string — use the Json: module to parse them.

Method Args Out Description
SQLite:Open path Number Open or create a database; returns handle
SQLite:Close handle void Close the database
SQLite:Exec handle, sql Boolean Run DDL / DML; true = success
SQLite:Query handle, sql String SELECT → JSON array of row objects
SQLite:QueryOne handle, sql String SELECT → first row as JSON object, or ""
SQLite:RowsAffected handle Number Rows changed by last Exec
SQLite:LastInsertId handle Number Row ID of last INSERT
SQLite:Error handle String Last error message, "" if none

mysql — MySQL database

Requires: libmysqlclient (installed automatically by minks install) Source: mysql_plugin/kse_mysql.cpp Note: update MYSQL_DIR in the Makefile to your MySQL Connector/C path on Windows

cd mysql_plugin && make
minks install kse_mysql
#include "mysql"

Var:Number db;
Var:Boolean ok;
Var:String rows;

try {
    MySQL:Connect("localhost", "root", "secret", "mydb", db);
} catch (MySQLException e) {
    Konsol:Print("Connect failed (${e.code}): ${e.message}");
}

MySQL:Exec(db, "INSERT INTO users (name) VALUES ('Alice')", ok);
MySQL:Query(db, "SELECT * FROM users", rows);
Konsol:Print(rows);   // JSON array
MySQL:Close(db);

Query results are returned as a JSON string — use the Json: module to parse them.

Method Args Out Description
MySQL:Connect host, user, pass, db Number Connect; returns handle. Throws MySQLException on failure
MySQL:ConnectPort host, port, user, pass, db Number Connect with explicit port
MySQL:Close handle void Close the connection
MySQL:Exec handle, sql Boolean Run DDL / DML; true = success
MySQL:Query handle, sql String SELECT → JSON array of row objects
MySQL:QueryOne handle, sql String SELECT → first row as JSON object, or ""
MySQL:RowsAffected handle Number Rows changed by last Exec
MySQL:LastInsertId handle Number Auto-increment ID of last INSERT
MySQL:Error handle String Last error message, "" if none

zip — Zip archives

Requires: libzip (installed automatically by minks install) Source: zip_plugin/kse_zip.cpp

cd zip_plugin && make
minks install kse_zip
#include "zip"

Var:Number z;
Var:Boolean ok;
Var:String content;

try {
    Zip:Open("archive.zip", z);
} catch (ZipException e) {
    Konsol:Print("Error: ${e.message}");
}

Zip:AddText(z, "hello.txt", "Hello from minks!", ok);
Zip:AddFile(z, "data/config.json", "config.json", ok);
Zip:Close(z);

Zip:Open("archive.zip", z);
Zip:Read(z, "hello.txt", content);
Konsol:Print(content);
Zip:Close(z);
Method Args Out Description
Zip:Open path Number Open or create archive; returns handle. Throws ZipException on failure
Zip:Close handle void Write changes to disk and release handle
Zip:Discard handle void Close without saving changes
Zip:AddFile handle, entryName, filePath Boolean Add a file from disk (read at Close time)
Zip:AddText handle, entryName, content Boolean Add a string as a zip entry
Zip:AddDir handle, dirName Boolean Add a directory entry
Zip:Count handle Number Number of entries in the archive
Zip:Name handle, index String Entry name at zero-based index
Zip:Read handle, entryName String Read entry contents as a string
Zip:Extract handle, entryName, destPath Boolean Extract entry to a file on disk
Zip:Error handle String Last error message, "" if none

net — TCP networking

Requires: nothing — uses OS sockets (Winsock2 on Windows, BSD sockets on macOS/Linux)

Build:

cd net_plugin
make          # produces kse_net.dll / kse_net.so
#include "net"

Var:Number conn;
try {
    Net:Host("server", 4, "game", conn)
} catch (NetException e) {
    Konsol:Print("Host failed: ${e.message}")
    return
}
Konsol:Print("Hosting on port 2310, handle: ${conn}")

Var:String sender, msg;
Var:Boolean got;
while (true) {
    Net:Check(conn)
    Net:GetMessage(conn, sender, msg, got)
    if (got) { Konsol:Print("${sender}: ${msg}") }
}
Method Args Out Description
Net:Host playerName, maxPlayers, sessionName Number Start TCP server on port 2310; returns handle. Throws NetException on failure
Net:Join playerName, sessionName, hostIP Number Connect to host; returns handle. Throws NetException on failure
Net:Check handle void Poll for new connections and incoming data (call each loop tick)
Net:Send handle, msg Boolean Broadcast text message to all peers
Net:SendTo handle, target, msg Boolean Send text message to named peer
Net:SendData handle, code, msg Boolean Send typed data message (integer code + string payload)
Net:GetMessage handle sender, msg, Boolean Pop next text message; got=true if a message was available
Net:GetData handle sender, code, msg, Boolean Pop next data message; got=true if available
Net:Quit handle void Notify peers, close socket, release handle

→ To extend the engine or write a plugin, see contributing.md