🦆

Navigation

🧑‍🦯

Yo - Define & Unify

This section is about the Heart and Soul of this project.

Why?!

Yo is a Command-Line tool and scripting framework I wrote because of two main reasons:

1. Define
I needed somewhere to define my sentences for the voice assistant, and a stable solution for defining the language processor's 'tools' (scripts) for execution.

2. Unify
Reduced scatter. Ever since I was a kid I have had a golden talent for scattering scripts around me, like a crazy mad man on speed, which sadly in the end of course lead to me loosing a lot of value.

Key Features

Centralized Script Management

Define all your scripts in one place with consistent structure, eliminating scattered scripts across your system.

Built entirely in Nix for declarative, reproducible script management across your entire system.

Unified --help command, Markdown rendered beautifully in the terminal that have extensive parameter documentation.

Parameter System

Type validation, optional parameters, default values, allowed values, and both positional & named parameter support.

Automated Execution

Schedule scripts to run at boot, periodically, or specific times with systemd integration.

Smart Validation

Comprehensive error checking with friendly duck error messages and parameter validation.

YO Script Structure

I chose to define my scripts like this:
⮞ Hide Scriot Structure

{ # 🦆says⮞yo! letz do a script yo!
  config,
  lib,
  pkgs,
  cmdHelpers, # 🦆says⮞shared functionz (/bin/helpers.nix)
  ...
} : let
in { # 🦆says⮞qwack
  yo = {  
    scripts = {
      bed = { # 🦆says⮞plx pick da script name
        description = "Bed controller";
        # 🦆says⮞for da --help cmd in da terminal md table & README markdown table
        category = "🛖 Home Automation";
        autoStart = false; # 🦆says⮞run bed@boot?
        runEvery = []; # 🦆says⮞periodic start (minutes)
        runAt = []; # 🦆says⮞scheduled start (list of strings - "HH:MM" 24h format)
        logLevel = "INFO"; # 🦆says⮞duckTrace loggin'
        parameters = [    
          { # 🦆says⮞paramz haz extensive validation
            name = "part";
            description = "Which part of the bed (head/feet)";
            type = "string";
            values = [ # 🦆says⮞doez not run if $part is something else than
              "feet"
              "head"
            ];
            default = "head"; # 🦆says⮞if --part iz omitted default value iz uzed for --part
          }
          { 
            name = "state";
            description = "Move up or down";
            type = "string";
            values = [ "down" "up" ];
            default = "up";
          }     
        ];
        helpFooter = ''
          echo "🦆says⮞extra code to be ran and displayed in da scripts --help cmd"     
        '';
        code = ''
          ${cmdHelpers} # 🦆says⮞load da shared functionz yo
          dt_debug "Sending bed $part $down" # 🦆says⮞ duckTrace logging
          # 🦆says⮞ rezt of da script code
        '';   
        voice = { # 🦆says⮞enabled by default if sentences are defined
          priority = 2; # 🦆says⮞1-5 (5 lowest)
          fuzzy = {
            enable = true; # 🦆says⮞ enabled by default if sentences are defined
            threashhold = 15; # 🦆says⮞set a script specific fuzzy threashhold
          };  
          sentences = [
# 🦆says⮞ [these|words] are optiional & can be omitted
# 🦆says⮞ (these|words) are alternatives - u have to say one of them
# 🦆says⮞ {this} word is a parameter (must match BOTH scripts parameter AND entity list 
            "[send|control] bed[s] {part} {state}"
            "(take|send|control) {state] [the] bed[s] {part}"
          ];
          lists = { # 🦆says⮞ entity lists
            part.wildcard = false; # 🦆says⮞ entities can be wildcards (anything)
            part.values = [
              { # 🦆says⮞ if u say one of these words
                "in" = "[head|heads|bedhead|top]";
                out = "head"; # 🦆says⮞ it becomes this word
              }
              { "in" = "[foot|foots|feet|feets]"; out = "feet"; }
            ];
            state.values = [
              { "in" = "[up|upp]"; out = "up"; }             
              { "in" = "[down|downs]"; out = "down"; } 
            ];
          };  
        };
      };
    };  
  
  };}

yo --help



⮞ dis is rly helpful if you forget a scripts name or sumeting! quack quack



yo script --help



⮞ dis is rly helpful if you forget a scripts parameter or sumeting! quack quack




⮞ View Complete yo Structure

{ # 🦆 duck say ⮞ yo! letz do a script yo!
  config,
  lib,
  pkgs,
  ...
} : let
in { # 🦆 duck say ⮞ qwack
  yo = {
    pkgs                # 🦆 duck say ⮞ read-only - final yo scripts package
    sorryPhrases        # 🦆 duck say ⮞ TTS phrases when no voice match found
    SplitWords          # 🦆 duck say ⮞ Words used for command chaining
    wakeWord            # 🦆 duck say ⮞ path to .tflite wake word model
    generatedPatterns   # 🦆 duck say ⮞ read-only - generated regex patterns count
    understandsPhrases  # 🦆 duck say ⮞ read-only - understood phrases count
    
    scripts = {
      example = {
        description     # 🦆 duck say ⮞ script description
        category        # 🦆 duck say ⮞ category for sorting/grouping
        aliases         # 🦆 duck say ⮞ alternative command names
        logLevel        # 🦆 duck say ⮞ duckTrace log level
        helpFooter      # 🦆 duck say ⮞ extra code for --help output
        autoStart       # 🦆 duck say ⮞ run at startup via systemd
        runEvery        # 🦆 duck say ⮞ run periodically every X minutes
        runAt           # 🦆 duck say ⮞ run at specific times daily
        code            # 🦆 duck say ⮞ the actual script cod
        
        voicePatterns   # 🦆 duck say ⮞ read-only - generated regex patterns
        voicePhrases    # 🦆 duck say ⮞ read-only - theoretical phrase coverage
        voiceReady      # 🦆 duck say ⮞ read-only - has voice commands configured
        voice = {
          enabled       # 🦆 duck say ⮞ generate voice intents
          priority      # 🦆 duck say ⮞ processing priority (1=highest)
          fuzzy = {
            enable      # 🦆 duck say ⮞ enable fuzzy voice matching
            threshold   # 🦆 duck say ⮞ similarity threshold (0.0-1.0)
          };
          sentences     # 🦆 duck say ⮞ voice command patterns
          lists         # 🦆 duck say ⮞ entity lists for parameters
            wildcard    # 🦆 duck say ⮞ accept free-form text / wildcard parameter
            values      # 🦆 duck say ⮞ value mappings
              "in" =    # 🦆 duck say ⮞ input value
              out =     # 🦆 duck say ⮞ output value  
            };
          };
        };        
      };
    };  
      
  };}

Read More?

On the next page, I will explain further and in greater detail what actually happends when you execute a yo script.
I will also present the source code - so that if you want to - you could create your own.

Table of Content:

Yo! - The Execution Workflow