Migrated from ~/Projects/DAPS_TESTING
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-09 14:10:38 +01:00
.github/workflows feat: big bang 2026-09-09 14:10:38 +01:00
daps feat: big bang 2026-09-09 14:10:38 +01:00
.gitignore feat: big bang 2026-09-09 14:10:38 +01:00
pyproject.toml feat: big bang 2026-09-09 14:10:38 +01:00
README.md feat: big bang 2026-09-09 14:10:38 +01:00

DAPS

not AI.

Definitely A Python Shell. A shell written in pure Python.

PyPI


DAPS is available on PyPI!

pip install daps-pip

Usage

Basic shell commands work as expected, e.g. cd, ls, pipes (|), redirection (>, >>, <, 2>, &>), and background jobs (&).

Built-in commands include:

  • cd <dir> – Change directory. Runs any registered on_cd hooks and checks for .dapsrc.
  • clear – Clears the screen (and re-runs the greeter if cleargreet is enabled).
  • clearhist – Clears shell history. After running this, history won't be recorded again until the shell is restarted.
  • exit – Exits the shell. Prompts for confirmation first if confirm_exit is enabled.
  • jobs – Lists background jobs.
  • fg [job_id] – Brings a background job to the foreground.
  • bg [job_id] – Resumes a stopped job in the background.
  • source <file> / . <file> – Runs a .daps script inline, so any variables it sets persist in your current shell (unlike a subshell).
  • set / export / unset / readonly / declare – Standard POSIX-style variable builtins. Bare VAR=value assignment is also supported.
  • secretpython – Drops into a live Python REPL inside the running shell process.

Inline interpreters

  • p!<code> – Runs <code> as Python, directly in the shell's own process (e.g. p!2 + 2).
  • n!<code> – Runs <code> as JavaScript via Node.js (node must be installed).

Scripting

DAPS understands three kinds of scripts:

  • .daps files – Run natively (not shelled out) via source/. or by executing the file directly. Supports if / elif / else / end, for <var> in <items> / end, while <cond> / end, and break / continue. Conditions are shell commands; exit code 0 is truthy.
  • .sh / .bash / .fish / .zsh / .ksh files – Shelled out to the matching interpreter.
  • Shebang scripts – The shebang line decides the interpreter, same as normal Unix behavior.

Modules

Drop a .py file into ~/.config/daps/modules/ and its top-level functions become callable as modulename.function args... from the shell.

Plugins

Drop a .py file into ~/.config/daps/plugins/ defining main(bg, daps) (or the older main(bg)), and it's loaded automatically at startup. Plugins get a daps registry handle to extend the shell:

  • daps.add_prefix(prefix, handler) – e.g. a custom r! for Ruby.
  • daps.add_builtin(name, handler) – register a new flat command.
  • daps.add_alias(name, expansion) – ship a default alias (only applies if the user hasn't already set one).
  • daps.add_completer(fn) – contribute extra tab-completion candidates.
  • daps.on_precmd(fn) / daps.on_postcmd(fn) – hooks that run before/after every command.
  • daps.on_cd(fn) – hook that runs whenever the shell changes directory.
  • daps.on_exit(fn) – hook that runs right before the shell exits.
  • daps.set_prompt_hook(fn) – fully override the prompt text.
  • daps.on(event, fn) / daps.emit(event, **data) – simple pub/sub between plugins.

Plugins can never override core builtins or the p!/n! prefixes.

Per-directory .dapsrc

If a directory contains a .dapsrc file, DAPS will offer to run it (as plain Python, exec'd against the shell's own namespace) whenever you cd into that directory. You must explicitly trust a directory first:

  • dapsrc.allow [path] – Trust .dapsrc in the given (or current) directory.
  • dapsrc.deny [path] – Revoke trust for a directory.

Configuration

DAPS is configured via ~/.config/daps/config.py, a real Python file — not JSON. It's created automatically on first run with every option commented out. To configure the shell, edit the daps object it defines:

daps = Config()

daps.lock = False               # Require PAM password auth on shell start
daps.motd = True                # Show the message of the day on startup
daps.aliases = {}                # Command aliases, e.g. {"ll": "ls -la"}
daps.devicename = False         # Show product name instead of hostname in the prompt
daps.cleargreet = False         # Re-run the greeter every time `clear` is run
daps.greeter = None             # 'daps' for the built-in sysfetch, or a shell command string, or None
daps.language = None             # Force a UI language: en, es, fr, de, ru, ja, pt, zh, it
daps.env = {}                    # Environment variables set at startup
daps.path = []                   # Extra directories prepended to PATH at startup
daps.startup_commands = []       # Commands run once at startup, after the greeter
daps.history_size = 1000         # Max lines kept in ~/.daps.history
daps.prompt_symbols = {"root": "#", "user": "$"}
daps.confirm_exit = False        # Ask for confirmation before `exit` closes the shell
daps.show_exec_time = False      # Show how long each command took
daps.exec_time_threshold = 1.0   # Only show the timer if the command took at least this long
daps.starship = False            # Use Starship for the prompt instead of the built-in one

Note: Built-in commands can't be overridden by aliases or plugin builtins.


greeter

Runs on shell startup. Set to "daps" to use the built-in sysfetch-style system info greeter, a shell command string to run something else (e.g. fastfetch), or None to disable it.

daps.greeter = "daps"

aliases

Simple command aliases:

daps.aliases = {
    "ll": "ls -l",
}

cleargreet

Whether the greeter re-runs every time you use clear:

daps.cleargreet = True

devicename

Show the device's product name (e.g. ASUS E410MA) in the prompt instead of the hostname (e.g. fedora):

daps.devicename = True

starship

If you'd rather use Starship for prompt rendering instead of DAPS's built-in prompt (or a plugin's set_prompt_hook):

daps.starship = True

lock

Requires a password (checked via PAM against your system account) before the shell will start:

daps.lock = True

motd

Whether the "message of the day" banner (version, tips) is shown on startup:

daps.motd = False

language

Forces the UI language instead of auto-detecting it from your system locale. Affects things like error messages and sysfetch labels. One of en, es, fr, de, ru, ja, pt, zh, it:

daps.language = "fr"

env

A dict of environment variables to set every time the shell starts, before anything else runs:

daps.env = {
    "EDITOR": "nvim",
    "PROJECT_ENV": "dev",
}

path

Extra directories to prepend to PATH at startup:

daps.path = ["~/.local/bin", "~/scripts"]

startup_commands

A list of commands run once, in order, right after the greeter finishes. Supports cd (which actually changes the shell's working directory) and otherwise runs each command through the system shell:

daps.startup_commands = [
    "cd ~/projects",
    "echo Ready to work",
]

history_size

The maximum number of lines kept in ~/.daps.history. Older entries are trimmed on startup:

daps.history_size = 5000

prompt_symbols

The character shown after the username/host in the prompt, depending on whether you're root or a normal user:

daps.prompt_symbols = {"root": "#", "user": "$"}

confirm_exit

If enabled, running exit asks Exit shell? [y/N] before actually closing the shell:

daps.confirm_exit = True

show_exec_time

Prints how long each command took to run, right after it finishes:

daps.show_exec_time = True

exec_time_threshold

Only used when show_exec_time is enabled — the timer is only printed if the command took at least this many seconds:

daps.exec_time_threshold = 0.5

Example of a full config

daps = Config()

daps.lock = False
daps.motd = True
daps.aliases = {"ll": "ls -l"}
daps.devicename = True
daps.cleargreet = True
daps.greeter = "daps"
daps.language = None
daps.env = {"EDITOR": "nvim"}
daps.path = ["~/.local/bin"]
daps.startup_commands = ["cd ~/projects"]
daps.history_size = 5000
daps.prompt_symbols = {"root": "#", "user": "$"}
daps.confirm_exit = True
daps.show_exec_time = True
daps.exec_time_threshold = 0.5
daps.starship = False

More Information

  • More features are coming soon!
  • DAPS is protected by the GNU license, meaning any contributions or derivatives of the program must be fully open source.

© 2026, Nytrix Labs