# Hello World - KonsolScript Demos

Four ready-to-run scripts that show what KonsolScript can do right out of the box.


1. Fetch + JSON parse

Fetch a post from the public JSONPlaceholder API and parse the response - curl, Json. No API key needed.

// curl_json.ks - HTTP fetch + JSON parse demo
//
// Install once, then run:
//   minks install kse_curl    (from inside curl_plugin/)
//   minks helloworld/curl_json.ks
//
// Or load explicitly without installing:
//   minks --plugin curl_plugin\kse_curl.dll helloworld\curl_json.ks   (Windows)
//   minks --plugin ./curl_plugin/kse_curl.so helloworld/curl_json.ks  (Linux)
//   minks --plugin ./curl_plugin/kse_curl.dylib helloworld/curl_json.ks  (Mac)

#include "kse_curl"

Konsol:Print("=== Curl + Json Demo ===");

// fetch a post from the public JSONPlaceholder API
Var:String response;
Var:Number status;

try {
    Curl:Get("https://jsonplaceholder.typicode.com/posts/1", response);
} catch (CurlException e) {
    Konsol:Print("fetch failed: ${e.message}");
    Konsol:Exit(1);
}

Curl:Status(status);
Konsol:Print("HTTP ${status}");

// parse and extract fields
Json:Parse(response, post);

Var:Number userId;
Var:Number postId;
Var:String title;
Var:String body;

Json:Get("userId", post, userId);
Json:Get("id",     post, postId);
Json:Get("title",  post, title);
Json:Get("body",   post, body);

Json:Free(post);

Konsol:Print("Post #${postId} by user ${userId}");
Konsol:Print("Title: ${title}");
Konsol:Print("---");
Konsol:Print(body);


2. Claude AI chat

Send a prompt to the Anthropic Claude API and print the reply - curl, Json, environment variables.

Set your API key first:

$env:ANTHROPIC_API_KEY = "sk-ant-..."   # Windows PowerShell
export ANTHROPIC_API_KEY=sk-ant-...     # Linux / macOS
// claude_chat.ks - Call the Anthropic Claude API from KonsolScript
//
// Set your API key first:
//   $env:ANTHROPIC_API_KEY = "sk-ant-..."   (Windows PowerShell)
//   export ANTHROPIC_API_KEY=sk-ant-...      (Linux / macOS)
//
// Run:
//   minks helloworld\claude_chat.ks
//
// Or load the plugin explicitly without installing:
//   minks --plugin curl_plugin\kse_curl.dll helloworld\claude_chat.ks   (Windows)
//   minks --plugin ./curl_plugin/kse_curl.so helloworld/claude_chat.ks  (Linux)
//   minks --plugin ./curl_plugin/kse_curl.dylib helloworld/claude_chat.ks  (Mac)

#include "kse_curl"

// -- API key from environment --------------------------------------------------

Var:String apiKey;
OS:GetEnv("ANTHROPIC_API_KEY", apiKey);

if (apiKey == "") {
    Konsol:Print("Error: ANTHROPIC_API_KEY is not set.");
    Konsol:Exit(1);
}

// -- Build request -------------------------------------------------------------

Var:String prompt = "Explain KonsolScript in one sentence.";
Var:String model  = "claude-haiku-4-5-20251001";

Var:String reqBody = """{
  "model": "${model}",
  "max_tokens": 256,
  "messages": [{"role": "user", "content": "${prompt}"}]
}""";

Curl:SetHeader("x-api-key", apiKey);
Curl:SetHeader("anthropic-version", "2023-06-01");
Curl:SetHeader("Content-Type", "application/json");

Konsol:Print("Prompt: ${prompt}");
Konsol:Print("Sending to ${model}...");

// -- Send request --------------------------------------------------------------

Var:String response;
Var:Number status;

try {
    Curl:Post("https://api.anthropic.com/v1/messages", reqBody, response);
} catch (CurlException e) {
    Konsol:Print("Request failed: ${e.message}");
    Curl:ClearHeaders();
    Konsol:Exit(1);
}

Curl:Status(status);
Curl:ClearHeaders();

if (status != 200) {
    Konsol:Print("API error (${status}): ${response}");
    Konsol:Exit(1);
}

// -- Parse response: { "content": [ { "type": "text", "text": "..." } ] } -----

Var:Number root;
Json:Parse(response, root);

Var:String reply;
Json:Get("content.0.text", root, reply);

Json:Free(root);

// -- Print reply ---------------------------------------------------------------

Konsol:Print("");
Konsol:Print("Claude says:");
Konsol:Print(reply);


3. Number guessing game

A classic guessing game - random number, hints, attempt counter. Pure stdlib: Math, Time, Konsol.

// guess_game.ks - Number guessing game
//
// Run:
//   minks helloworld\guess_game.ks

// seed RNG from the process timer so each run picks a different number
Var:Number seed;
Time:GetTimer(seed);
Math:Seed(seed);

Var:Number secret;
Math:Random(100, secret);
secret = secret + 1;       // 1 – 100

Konsol:Print("=== Guess the Number ===");
Konsol:Print("I'm thinking of a number between 1 and 100.");
Konsol:Print("Type your guess and press Enter.");
Konsol:Print("");

Var:Number guess = 0;
Var:Number attempts = 0;
Var:String input;
Var:Boolean ok;

while (guess != secret) {
    Konsol:Input(input);
    Konsol:IsNumeric(input, ok);
    if (!ok) {
        Konsol:Print("Please enter a number.");
        continue;
    }
    guess = input;
    attempts = attempts + 1;
    if (guess < secret) {
        Konsol:Print("Too low! Try again.");
    } else if (guess > secret) {
        Konsol:Print("Too high! Try again.");
    }
}

Konsol:Print("");
Konsol:Print("Correct! The number was ${secret}.");
Konsol:Print("You got it in ${attempts} attempt(s).");


4. AI log triage

Scan a log file for ERROR and WARN entries using Regex, then optionally send the findings to Claude for a diagnosis. Works without an API key - prints a plain summary of issues found.

Sample log:

[2026-05-17 08:01:02] INFO  Server started on port 8080
[2026-05-17 08:01:03] INFO  Connected to database: mydb@localhost
[2026-05-17 08:03:11] INFO  GET /api/users 200 (12ms)
[2026-05-17 08:03:45] WARN  Slow query detected: SELECT * FROM orders (320ms, threshold 200ms)
[2026-05-17 08:04:02] INFO  GET /api/products 200 (8ms)
[2026-05-17 08:05:17] ERROR Failed to send email: SMTP connection refused (host: mail.example.com:587)
[2026-05-17 08:06:30] INFO  POST /api/orders 201 (45ms)
[2026-05-17 08:07:55] WARN  Memory usage at 81% - consider restarting the worker
[2026-05-17 08:09:10] ERROR Database query failed: deadlock detected on table 'inventory'
[2026-05-17 08:09:10] ERROR Transaction rolled back for order #8821
[2026-05-17 08:10:00] INFO  GET /api/users 200 (11ms)
[2026-05-17 08:11:33] WARN  Retrying failed job 'send_invoice' (attempt 2 of 3)
[2026-05-17 08:12:48] ERROR Unhandled exception in worker: NullReferenceException at PaymentService.cs:142
[2026-05-17 08:13:00] INFO  Worker restarted successfully
[2026-05-17 08:14:05] INFO  GET /health 200 (2ms)

helloworld/sample.log

Script:

// log_triage.ks - Scan a log file for errors, then ask Claude to diagnose them
//
// Works without an API key - prints a plain summary of issues found.
// With ANTHROPIC_API_KEY set, also sends the issues to Claude for analysis.
//
// Run:
//   minks helloworld\log_triage.ks
//
// With plugin loaded explicitly:
//   minks --plugin curl_plugin\kse_curl.dll helloworld\log_triage.ks   (Windows)
//   minks --plugin ./curl_plugin/kse_curl.so helloworld/log_triage.ks  (Linux)
//   minks --plugin ./curl_plugin/kse_curl.dylib helloworld/log_triage.ks  (Mac)

#include "kse_curl"

Var:String logFile = "helloworld/sample.log";

// -- Read and scan the log -----------------------------------------------------

Konsol:Print("=== Log Triage: ${logFile} ===");
Konsol:Print("");

Var:Number fh;
Var:Boolean exists;
Path:IsFile(logFile, exists);

if (!exists) {
    Konsol:Print("Log file not found: ${logFile}");
    Konsol:Exit(1);
}

File:Open(logFile, "r", fh);

Var:String line;
Var:Boolean eof;
Var:Boolean matched;
Var:Number errorCount = 0;
Var:Number warnCount  = 0;
Var:String issues     = "";

while (true) {
    File:EOF(fh, eof);
    if (eof) { break; }
    File:ReadLine(fh, line);

    Regex:Match("ERROR", line, matched);
    if (matched) {
        errorCount = errorCount + 1;
        issues = "${issues}  [ERROR] ${line}\n";
        continue;
    }

    Regex:Match("WARN", line, matched);
    if (matched) {
        warnCount = warnCount + 1;
        issues = "${issues}  [WARN]  ${line}\n";
    }
}

File:Close(fh);

// -- Print local summary -------------------------------------------------------

Konsol:Print("Found ${errorCount} error(s) and ${warnCount} warning(s).");
Konsol:Print("");

if (errorCount == 0 && warnCount == 0) {
    Konsol:Print("No issues found.");
    Konsol:Exit(0);
}

Konsol:Print("Issues:");
Konsol:Print(issues);

// -- Ask Claude for a diagnosis (only if API key is set) ----------------------

Var:String apiKey;
OS:GetEnv("ANTHROPIC_API_KEY", apiKey);

if (apiKey == "") {
    Konsol:Print("Tip: set ANTHROPIC_API_KEY to get an AI diagnosis.");
    Konsol:Exit(0);
}

Konsol:Print("Sending issues to Claude for analysis...");
Konsol:Print("");

Var:String prompt = "You are a senior DevOps engineer. Analyze these log issues and give a concise diagnosis with recommended actions:\n\n${issues}";
Var:String reqBody = """{
  "model": "claude-haiku-4-5-20251001",
  "max_tokens": 512,
  "messages": [{"role": "user", "content": "${prompt}"}]
}""";

Curl:SetHeader("x-api-key", apiKey);
Curl:SetHeader("anthropic-version", "2023-06-01");
Curl:SetHeader("Content-Type", "application/json");

Var:String response;
Var:Number status;

try {
    Curl:Post("https://api.anthropic.com/v1/messages", reqBody, response);
} catch (CurlException e) {
    Konsol:Print("Request failed: ${e.message}");
    Curl:ClearHeaders();
    Konsol:Exit(1);
}

Curl:Status(status);
Curl:ClearHeaders();

if (status != 200) {
    Konsol:Print("API error (${status}): ${response}");
    Konsol:Exit(1);
}

Var:Number root;
Json:Parse(response, root);

Var:Number contentArr;
Json:Get("content", root, contentArr);

Var:Number firstItem;
Json:Get(0, contentArr, firstItem);

Var:String diagnosis;
Json:Get("text", firstItem, diagnosis);

Json:Free(root);

Konsol:Print("Claude's diagnosis:");
Konsol:Print(diagnosis);