AI-Created Software

Last Updated: October 14, 2026

The following is AI-generated (aka vibe-coded) software. The software is specific to my needs and my system and may not work for you or your system. Support is limited, but if you report a bug I'll certainly look into it. All code is provided in a zip file for you to review should you choose.

Scriptary

A Windows desktop library for your Python, PowerShell and batch scripts. Scriptary reads each script’s arguments and turns them into a form. It remembers the values you use and runs scripts in a built-in console with full color and live progress output. It also records changes to your library so you can undo them, roll them back or restore a single script.


Contents


Features at a glance

  • One library for .py, .pyw, .ps1 and .bat scripts, with groups, virtual folders, labels, clones and notes.
  • Automatic argument forms. Python arguments are read from argparse code, PowerShell arguments from the param() block, and batch arguments from %1–%9.
  • Saved parameters per script, with an unsaved-changes indicator and a live preview of the exact command that will run.
  • Parameter aliases: call a parameter by a name of your own in Scriptary, such as one spelling across all your scripts, without editing the script.
  • Built-in console using a real Windows pseudo-console (ConPTY) and a terminal emulator. Colors, progress bars and \r updates display correctly, and you can type input back to the script. Tabs can be pinned so they aren’t closed by accident, and are reopened with their output when Scriptary starts again.
  • Run as administrator for scripts that need elevation. Scripts that probably need it are detected and marked ⛨.
  • Launching detached for scripts with a graphical interface: no console window, and the script keeps running when Scriptary closes. Its result is still recorded, and its output is shown if it fails.
  • Search and filters by name, description, path, GUI/no GUI, admin, last result, file type, and whether a script is in a chain, scheduled, has a reminder or is tucked away, and by tag.
  • Sorting by name, date registered or last run, within each group and folder or across the whole list.
  • Chains: two or more scripts run one after another, stopping at the first that fails.
  • Schedules: run a script or a chain automatically at set times while Scriptary is running, or be reminded to run it yourself.
  • Keyboard shortcuts of your own: Ctrl+Shift (or Ctrl+Shift+Alt) and a letter, digit or F-key runs a script or a chain on its saved values, or opens a Manage window, a menu or clicks a button of the main window. Keys that another program or Windows has taken are refused.
  • Undo, redo and a full change history. Undo one change, roll back to a point in time, or restore a single script’s settings and parameters.
  • Tags: give a script any number of tags from its right-click menu, and filter the list by them.
  • Tucking away: keep a script you rarely use in its group or folder, but out of the way behind one “+ N more tucked away” line. Search, filters and due reminders still find it.
  • Archiving: retire a script you no longer use without losing its saved values, notes or run history. It leaves the list and search, and can be brought back at any time.
  • Library reports under Manage: parameter names across the library (with aliases for many parameters at once), parameters with no help text, unused saved values and aliases, a run report, archived scripts and tags.
  • Safe storage. Files are saved atomically, damaged files are detected and preserved, and a last-known-good copy of each data file is kept.
  • Portable paths. Paths are stored against tokens such as %OneDrive% or %SCRIPTARY_HOME%, so a shared library works on several machines.
  • System tray support and a single running instance.

Requirements

Component Needed? Purpose
Windows Required Scriptary uses Windows APIs (ConPTY, UAC, Explorer integration).
Python 3.8 or later Required Runs Scriptary itself.
pyte Required Terminal emulation for the output console.
pywinpty Rarely needed A fallback pseudo-console for Windows versions older than 10/1809.
Scriptary uses the pseudo-console built into Windows directly, so on current Windows this is not required.
pystray and Pillow Optional System tray icon; closing the window then minimizes to the tray.
Archivo font Optional The interface is designed around Archivo. Put its .ttf files in Resources\Fonts next to scriptary.pyw (no installation needed) or install it; otherwise Segoe UI is used.
PowerShell 7 (pwsh.exe) Optional Needed only for PowerShell scripts written for version 7. See Which PowerShell?.

Install everything with:

python -m pip install pyte pystray pillow

If pyte is missing when Scriptary starts, it offers to install it for you.


Getting started

  1. Put scriptary.pyw (and scriptary.ico, if you have it) in a folder of your choice.

  2. Double-click scriptary.pyw, or run:

    pythonw scriptary.pyw
  3. Click + Add to register a script, or 🔍 Scan to add every script in a folder tree. Both are in the button grid at the bottom of the sidebar.

  4. Select a script, fill in its parameters, and click ▶ Run.

Only one copy of the GUI runs at a time. Starting it again brings the existing window to the front.

Choosing where data is stored

By default, Scriptary keeps its data files next to scriptary.pyw — or next to the executable, when it has been built into one. To keep them somewhere else, pass --working-folder-path:

pythonw scriptary.pyw --working-folder-path "C:\Scriptary\config"
pythonw scriptary.pyw --working-folder-path configs\myteam

A relative path is taken from the folder holding scriptary.pyw (or the executable). The folder is created if needed; if it can’t be, Scriptary says so and doesn’t start. The option’s old name, --config-dir, still works.

A relative path is resolved from the folder containing scriptary.pyw (or the executable).

Restarting Scriptary

For picking up changes to Scriptary’s own code, start it with --show-self-restart-option TRUE:

pythonw scriptary.pyw --show-self-restart-option TRUE

Manage ▾ then ends with Restart Scriptary, and the tray menu has Restart above Exit. Scriptary closes and starts again with the same command line, --working-folder-path included, and reopens as it always does (same window, sort, collapsed sections and selected script; no output tabs). The option also accepts =TRUE, and 1, YES or ON in any case; FALSE, 0, NO or OFF, or leaving it out, keeps the entry hidden. Any other value, or the option without a value, is a mistake, and Scriptary says so instead of starting.

When Scriptary isn’t already running as administrator, Restart as Administrator follows (in Manage ▾ below Restart Scriptary, in the tray menu below Restart): it closes Scriptary the same way, then starts it again elevated, through the usual UAC prompt. Scripts then run with administrator rights without a prompt of their own. If the prompt is declined, or the elevated start fails, Scriptary starts again without administrator rights, so it never just disappears. Drive letters mapped to network shares while unelevated may be missing in the elevated Scriptary, as Windows keeps them apart.

While Scriptary runs as administrator, Restart without Administrator Rights takes that entry’s place. Windows doesn’t let a program give up its rights, so Scriptary asks Explorer, which runs with your ordinary rights, to start it again. If Explorer can’t be asked, or itself runs as administrator (with UAC off, or as the built-in Administrator account), Scriptary says so and starts again as administrator. A plain Restart keeps the rights Scriptary has.

Knowing that Scriptary runs as administrator

However it was started (Restart as Administrator, or Run as administrator from Explorer), Scriptary shows that it runs as administrator. The window’s title is Administrator: Scriptary, as Windows’ own Command Prompt shows it, on the taskbar and in Alt+Tab. The status bar has a red ⛨ Administrator badge, beside the RAM line, and the tray icon’s tooltip says Scriptary (Administrator).
Every script it runs then has administrator rights. With --show-self-restart-option TRUE, clicking the badge restarts Scriptary without them.

Restarting, like exiting, asks first when parameter changes are unsaved or scripts are still running. Scripts running in output tabs are stopped, including those running as administrator. A script running as administrator in a window of its own keeps running, but its result is not recorded. Scripts launched detached aren’t asked about: they keep running, and how they end is recorded when Scriptary next starts.


Adding scripts

Action What it does
+ Add Register one script. If the file is already in the library, a clone is added instead (see below). The new script goes into the selected script’s group or folder.
🔍 Scan Recursively add every .py, .pyw, .ps1 and .bat file in a folder. Files already registered are skipped (by path: a file with the name of a registered script in another folder is added), and so are virtual environments, site-packages, __pycache__, node_modules and hidden folders. Files and folders ignored in Manage ▾ → Find Unregistered Scripts… are skipped as well; to see the list first and pick, use that report.
⟳ Refresh Re-read every script. Files that haven’t changed since the last read are skipped; files that have disappeared are marked missing.
Refresh Arguments (right-click) Re-read one script regardless of its modification time. Its clones are refreshed with it, and unsaved values are kept for arguments that still exist.
Several scripts at once (right-click) Ctrl+click adds a script to the selection (or takes it out), Shift+click selects a run of scripts, and Ctrl+A every script shown.
Right-click one of them to refresh, move, add to a chain, tag, tuck away, archive or remove them all; each is one step for Undo.
Move To ticks a group or folder only when every selected script is in it, and Add to Chain appends them in the order they are listed; a script that can’t be a step is left out, and the menu says how many. The parameter panel shows the script clicked last.
Clone (right-click) Add a second entry for the same file, with its own label and saved parameters. Useful for keeping several presets of one script.
Locate File… / Change File… (right-click) Point an entry at a moved or renamed file. If other missing scripts moved the same way (for example, a whole folder was moved), Scriptary offers to relink them too.
− Remove Remove the selected script from the library. The file on disk is not touched, and the removal can be undone.

When a registered file can’t be found, the script’s detail panel shows a red banner with a Locate file… button.


How arguments are detected

Script type Method Badge
Python Static analysis of argparse calls. The script is only read, never run. ⬤ detected via static analysis
Python, with Argument detection enabled Runtime probe, then static analysis, then parsing --help output. More accurate for scripts that build their parsers dynamically, but the script is executed. ⬤ detected via runtime probe / –help output
PowerShell The param() block: parameter names, types, [switch] parameters and [ValidateSet(...)] values (shown as buttons, like argparse choices=). The .SYNOPSIS comment is used as the description, and each .PARAMETER comment (or else the HelpMessage) as the parameter’s help; the first paragraph of each is kept. ⬤ PowerShell script
Batch %1–%9 tokens. A REM or :: comment on the line above a token’s first use becomes its help text. ⬤ Batch script

A Python script with no argparse calls of its own, such as a launcher that imports its app from a folder beside it, has its imports followed: the arguments come from the first module, among those in the script’s folder, that adds any (the standard library and installed packages are never read). The detail panel names that module after the method, e.g. argparse, read statically from scriptary_app/config.py, and ⟳ Refresh always reads such a script again, since a change to that module doesn’t change the script’s own date. Static analysis also reads choices= given as the name of a tuple or list of strings in the same module, and leaves out options hidden with help=argparse.SUPPRESS.

For a single Python script, Detect Arguments by Running Script… (right-click) runs the full detection once without turning the global option on. You are asked to confirm first, because any side effects of running the script will really happen.

Scriptary also looks for two other traits, shown next to the detection method and usable as filters:

  • ⧉ graphical interface: the script opens a window, e.g. Tkinter or Qt in Python, or Windows Forms, WPF, Out-GridView or message boxes in PowerShell. A Python launcher that imports no toolkit itself has its imports followed, as for its arguments, so an app whose window is in a module in its folder counts too.
  • ⛨ elevation: the script requires, checks for, or requests administrator rights.

Organizing the library

  • The right-click menu groups a script’s items, top to bottom: Launch Detached (how it runs by default), Run (or Launch for a script launched detached, as the ▶ button says) and the other ways to run it, its arguments, running it without a click (chains, schedules, reminders, keyboard shortcut), its label, note and tags, its history, its file (with Add Script), and where it is kept (Move To, Tuck Away, Archive, Remove from Library). Collapse All and Expand All end the menu. With several scripts selected, the menu keeps the same order.
  • Groups: named collections created with + Group. Move scripts into them from the right-click menu (Move To → Groups).
  • Folders: scripts are listed under the folder they live in on disk. You can also move a script into another folder, or into a new virtual folder that exists only in Scriptary. A virtual folder can be removed, which sends its scripts back to their own folders.
  • Renaming a folder makes it a group: a folder section is named after a directory on disk, so it cannot be given a name of your own and stay a folder. Rename Folder as Group (right-click) turns any folder section — one from disk or a virtual one — into a group with the name you type, and moves its scripts into it.
    Nothing on disk is renamed or moved. Giving it the name of a group you already have merges the scripts into that group. Like other library changes, it can be undone.
  • Labels: Rename Label changes the name shown in the list without renaming the file.
  • Notes: ✎ Add note (on the detail panel or in the right-click menu) attaches free-text notes to a script.
    Notes appear under the title only for scripts that have one; long notes collapse with a Show all link.
  • Tags: right-click a script → Tags to label it in ways that cut across groups and folders. A script can have any number of tags.
    • New Tag… creates a tag and puts it on the script. A name you already use, in any mix of upper and lower case, reuses that tag.
    • On this script lists the script’s own tags, ticked.
      Click one to take it off.
    • Used elsewhere lists tags other scripts have. Click one to put it on this script too.
    • Previously used lists tags no script has any more, because their last script lost the tag or was archived. They are kept so you can use them again. Archived scripts keep their tags, so unarchiving one brings its tags back into use.
    • Rename Tag renames a tag on every script that has it, archived ones included. Renaming a tag to the name of another tag merges the two, after asking.
    • Delete Tag removes a tag from Scriptary and from every script that has it, after asking.
    • Manage Tags… opens the Tags window (see Tags).

    Every tag change can be undone.

  • Tuck Away: right-click a script → Tuck Away for one you rarely use but don’t want to forget. It stays in its group or folder, listed after the others behind one + N more tucked away line. Click the line to show them (it then reads − hide N tucked away), and again to hide them.
    The group or folder’s count includes them, and they still run from keyboard shortcuts, chains and schedules. A search or a filter lists tucked-away scripts like any other, and one whose reminder is due is shown among the others until it has run. Right-click → Untuck brings a script back. Sorted across the whole list, one line at the end holds every tucked-away script. A clone of a tucked-away script is not tucked away. Tucking away can be undone.
  • Archive: right-click a script → Archive to retire it. An archived script no longer appears in the list or in search results, but everything about it is kept, and the date it was archived is recorded. Manage ▾ → Archived Scripts… lists them, to unarchive or remove (see Archived scripts). A script that is a step of a chain can’t be archived; Scriptary names the chain so you can take it out first.
  • Search: the search box filters by name, description or path. Press Ctrl+F to jump to it and Esc to clear it.
  • FILTER ▾: in four groups. Show only: GUI / No GUI, Admin / No admin. Status: Failed / Succeeded on their last run, Due (a reminder is due), Idle 6+ months, Never run. Set up: In a chain (a step of any chain), Scheduled (has a scheduled run), Has reminder, Tucked away; a schedule or reminder that is switched off still counts. File type: .bat, .ps*, .py*.
    Tags: every tag at least one listed script has (previously used tags are not offered); a script with any ticked tag matches. Ticking several options narrows the list further, and the ticked tags together count as one option. While filters or a search are active, a strip under the search box shows each filter as a chip (click one to remove it) and how many scripts are shown, e.g. 9 of 31.
  • SORT ▾: sort by Name, Date registered or Last run, ascending or descending, either within each group and folder (the sections stay in alphabetical order) or across the whole list. Sorted across the whole list, the list is flat: there are no group or folder headers, and each row names its group or folder instead. Scripts never run come last whichever way the list is sorted by last run. The date column shows the date the list is sorted by. The button is highlighted while the sort is not the default (Name, A to Z, within each group and folder); Reset returns to it. When a run finishes, the list is re-sorted and the selected script stays where it is on screen.
  • Date registered: when a script was added to the library, or cloned. Scripts added before Scriptary recorded this were given their file’s last modification date, once.
  • ▾ / ▸ (right of the search box): collapse or expand every group and folder. Not available while the list is sorted across its whole length.
  • Between sessions: Scriptary reopens with the same sort, the same groups and folders collapsed or expanded, the same tucked-away scripts shown or hidden, and the same script selected. The search box starts empty and no output tabs are open.
  • Status dot: each script’s dot is green if its last run succeeded, red if it failed, and gray if it has never run.

Running scripts

The script header

Above the parameters, the selected script’s name is shown with a red ADMIN badge if it needs elevation. Under it is a line giving the script’s path, how its arguments were read and how many there are. ✎ Note, Clone and History on the right do the same as the matching right-click menu items.

The parameter panel

Each detected argument gets a row:

  • Text fields for ordinary values; ON / OFF switches for flags; and for arguments with a fixed set of up to six choices, a row of those choices with the current one highlighted (longer lists use a drop-down). Unless the argument is required (or positional), clicking the highlighted choice again deselects it: the row then reads not passed, and the option is left out of the command, default and all.
  • Required arguments are marked with a red *, and ⓘ shows the argument’s help text.
  • Path arguments get three buttons: ⋯ browse, 📁 open the location in Explorer, and ↗ open the file with its associated application.
  • Environment variables such as %USERPROFILE%\Documents are expanded when the script runs.
  • Copying names: click or double-click a flag name to select it, or right-click it for options that copy the flag, the flag with its value, or every flag.
  • Aliases: a parameter with an alias shows the alias, with the script’s own flag dimmed after it.

Panel actions:

Button Action
Save Save the current values for this script. If the script has a schedule or a reminder, even one turned off, and the values have changed, Scriptary first lists its schedules and asks you to confirm: OK saves, Cancel keeps your edits unsaved.
Cancel Undo the unsaved changes to this script’s values and go back to the saved ones.
Clear Empty every field.
↕ Fit Resize the panel to show every parameter, while keeping room for the console.
▶ Run Run with the current values; they don’t have to be saved first.
⛨ Run as admin Shown to the left of ▶ Run for scripts that need elevation (see below).

PARAMETERS ▴, at the left of the bar, collapses the panel to the script’s title and that bar, giving the rest of the height to the output; the buttons on the bar still work. PARAMETERS ▾ opens it again at the height it had before, and so does dragging the divider under the bar (the panel then opens at the height you drag it to) or ↕ Fit. The panel stays as you left it the next time Scriptary starts.

The panel keeps the rows of the last eight scripts you showed, so going back to one of them shows it at once. Holding ↑ or ↓ in the script list moves the selection at the key’s pace, and the parameters follow when you let go.

Unsaved edits are kept when you switch between scripts. The ● Unsaved cell in the sidebar turns red and shows how many scripts have unsaved changes; clicking it jumps to the first one, opening only the group or folder that holds it. Scriptary warns you before discarding unsaved edits.

Command preview

The COMMAND box under the parameters shows the exact command that will be run, updated as you type, with the flags highlighted. The box shows one line until you click COMMAND ▾ to open it; open, a command too long for one line wraps and the box grows to show all of it (as long as the parameters keep room on the panel; past that it scrolls). COMMAND ▴ closes it to one line again, and the box stays as you left it the next time Scriptary starts. Copy puts it on the clipboard.

Parameter aliases

An alias is a name of your own for a parameter. Scriptary shows it in the parameter panel and its reports in place of the script’s name for the parameter. The script is not changed: it is still run with its own flags, so the command preview doesn’t change, and saved values stay where they are. Aliases are useful to give one parameter the same name in every script (output-dir, whether a script spells it --output_dir, --outputDir or -OutputDir), or to name a batch file’s %1.

  • Setting one: right-click a parameter’s name → Set Alias…, or right-click a script → Parameter Aliases… to see every parameter of the script with a field for its alias. Empty a field to remove the alias. Each field is checked as you type, so two parameters can swap aliases in one go.
  • For many scripts at once: Manage ▾ → Parameter Names… (see Library reports).
  • One per parameter. An alias starts with a letter and holds only letters, digits, - and _, up to 40 characters. Within one script it can’t be the alias or the name of another parameter. Case and the difference between - and _ don’t count for that, so Out_Dir and out-dir are the same name.
  • Clones share them. An alias belongs to the file’s parameter, so every clone of the script has it.
  • When the script changes. If a parameter is renamed in the script, Refresh Arguments offers to carry its alias over, with its saved values. An alias whose parameter has gone is kept until you move or delete it in Manage ▾ → Unused Saved Values….
  • Setting, changing and removing aliases are recorded in History, so Undo reverses them. Aliases are stored in the library, so like everything else they are per computer.

Run as administrator

⛨ Run as admin asks Windows for administrator rights (the UAC prompt) and runs the script in an output tab like any other run: its colors, typed input, Stop and the exit code all work as usual. Run as administrator is also available from the right-click menu for any script.

For a script that can’t run at all without administrator rights (PowerShell’s #Requires -RunAsAdministrator), ⛨ Run as admin is the solid green button and ▶ Run the tinted one; for the others, ▶ Run stays the solid one. Either way, ▶ Run is always the button at the end of the bar, with ⛨ Run as admin to its left.

How it works: Windows doesn’t let a program that isn’t elevated read the console of one that is, so Scriptary starts a hidden, elevated copy of itself through the UAC prompt. That helper runs the script and passes its output back over a private connection that only this Scriptary can use. Each run asks once and has its own helper, which ends with the script. If Scriptary closes, the script is stopped, as it would be in any other tab. The script runs from its own folder.

If the helper can’t be used, the tab says so and the script runs in a console window of its own instead; Windows then asks once more. In a window of its own, only the exit code comes back to the library. To always use a window, untick Show the output in a Scriptary tab under Run as administrator in the Interpreters & execution settings (or set admin_runs_in_tab to false in the settings file).

A script that asks for elevation itself (⛨ requests elevation) is already elevated when run this way, so it doesn’t open a window of its own either.

If Scriptary itself is already running as administrator, ▶ Run is enough and the extra button is hidden.

Launching detached

A script with a graphical interface (⧉) doesn’t need a console, and an app it opens shouldn’t close when Scriptary does. Such a script is launched detached: ▶ Run reads ▶ Launch, and the script starts on its own, with no console window and no output tab, and keeps running when Scriptary closes or restarts. The status bar says it was launched.

  • Which scripts: a script detected as having a graphical interface is launched detached when it is added to the library. Turn it on or off for any script with right-click → Launch Detached (✔ when on); with several scripts selected, it changes them all as one step for Undo. Scripts already in the library before this version keep running in a tab until you turn it on.
  • Run in a Tab, in the right-click menu of a detached script, runs it in an output tab once instead, for when you need its output, for example to debug it.
  • Its result is recorded like any other run: the status dot, Run History… and the Run Report include it, and Started from says Detached. Scriptary checks every two seconds while it runs, and when it next starts for scripts that ended while it was closed. If a launch ended without saying how (it was killed, or the computer restarted), its exit code is recorded as unknown.
  • Its output is shown only when something went wrong: when it exits with a code other than 0, or ends within five seconds (an app that closes that quickly usually failed to start), a tab opens with what it printed, often a traceback, marked launched detached in its footer. A clean exit only updates the list and the status bar.
  • Parameters are the panel’s, as with ▶ Run. From a keyboard shortcut, a chain or a schedule, it launches on its saved values.
  • No typed input and no Stop: a detached script has no console to type into. Close it as you would close the app itself.
  • Run as administrator works as before, in a tab or a window of its own.

How it works: Scriptary starts a small helper, a copy of itself with no window, outside anything that would end it with Scriptary. The helper starts the script without a console window, writes what it prints to a log, waits for it to end and writes down its exit code. Python scripts run with python.exe, never pythonw.exe, so what they print reaches the log. Each launch’s files are kept in the COMPUTER_detached folder in the working folder until Scriptary has recorded it; the logs of the newest 50 launches are kept after that.


The output console

Every run opens a new tab in the output area.

  • Tab names leave out the script’s extension (.py, .pyw, .ps1, .bat). When the tabs don’t all fit, long names are shortened in the middle (backup_ph…to_nas), so the end of a name, often what tells two scripts apart, stays visible; short names keep their full width and the room they don’t need goes to the long ones. No name is shortened below about eight characters: past that, the tabs scroll. Hover over a tab to see its full name, how its run ended (or that it is still running), the chain that ran it and whether it is pinned.

  • Full terminal output: colors, cursor movement, progress bars and \r updates display as they would in a terminal (requires pyte). The 16 standard terminal colors are darkened to stay readable as text on the white background, each with a contrast of at least 4.5:1. Light gray and white stay light, since scripts use them on a dark background.

  • Input: type into the STDIN field at the bottom of a tab and press Send or Enter to answer prompts. While a script runs, its tab moves the keyboard to the field as output arrives, unless you are typing in another field, such as a parameter.

  • ⏹ Stop ends the process. Copy output and Save output export the tab’s text.

  • Find: press Ctrl+F in a tab (in its output or its STDIN field), or click Find in its footer, to look through its output. Every match is highlighted, in any case, and the one you are on is filled blue, with 3 of 12 beside the field.
    Enter or ▼ goes to the next match, Shift+Enter or ▲ to the previous one, round the end to the start; Esc or ✕ closes it. Text selected on one line of the output is what is looked for. Matches in output that arrives while Find is open are highlighted as it comes. Ctrl+F anywhere else still goes to the search box.

  • Closing a tab: point at its run state (■, ✓ or ✗, on the right) and it turns into a red ✕; click that, or middle-click anywhere on the tab. Elsewhere on the tab the run state stays in sight. Close all closes every tab except pinned ones.

  • ‹ › beside Close all scroll the tabs when there are more than fit, even with their names shortened. Each is enabled only while tabs are hidden on its side, and the tab you select is always scrolled fully into view.

  • The command at the top of a tab shows one line, cut short with …, until you click COMMAND ▾ to show all of it; COMMAND ▴ closes it again. The choice applies to every tab and is kept the next time Scriptary starts.

  • Right-click a tab to Pin Tab or Unpin Tab, Unpin All Tabs, Select Script in Library (scrolls the script list to the script that ran in the tab and selects it, opening its group or folder), Close Tab, or Close Other Tabs (every other tab that is not pinned).

  • Pinned tabs: a pinned tab shows a thumbtack before its name, shows no ✕ on hover and can’t be closed (a middle-click doesn’t close it either), by Close all, Close Other Tabs or a schedule’s next run, until you unpin it. Its script can still be stopped.

  • Unpinning every tab: Unpin All Tabs, on a tab’s right-click menu or on Close all’s, unpins every pinned tab at once. Undo Unpin All, on the same menus, pins them again (those still open); the undo isn’t kept once Scriptary closes. Right-click Close all for Close All, Unpin All Tabs and Unpin and Close All, which asks first, since closed tabs can’t be brought back.

  • Run state: each tab shows a green ■ after its name while running, then a green ✓ or a red ✗. The tab’s footer shows the exit code, how long the run took and when it ended, for example ✓ Exited 0 — 53s (Fri Oct 9 @ 12:13pm), so a scheduled run that finished unattended says when it ran; and the script’s status dot in the list is updated.

  • pythonw.exe scripts: if the Python path points at pythonw.exe, the matching python.exe is used, since pythonw has no console to show output in.

The minimum console height can be set with the console_min_height key in the settings file.

Output tabs between sessions

The open tabs are kept when Scriptary closes and reopened when it next starts, in the same order, with the same tab in front. Each keeps its output (colors included), how its run ended, whether it was a chain’s, and whether it was pinned. They are saved to COMPUTER_console.json when a run ends, when a tab is closed, pinned or unpinned, and when Scriptary closes, so they also survive Windows shutting down while Scriptary sits in the tray.

  • A reopened tab runs nothing. Its footer shows how the run ended and when, for example ✓ Exited 0 — 3s (Fri Oct 9 @ 2:02pm) · restored.
    Copy output and Save output still work.
  • A script still running when Scriptary closed comes back as ✗ Scriptary closed while this was running, with its output up to that point.
  • Only the newest 2000 lines of each tab are kept. Change this with the console_restore_lines key in the settings file.
  • To turn this off, untick Reopen output tabs when Scriptary starts (under Output tabs in the Interpreters & execution settings), or set restore_console_tabs to false in the settings file. Tabs already kept are then forgotten.

Interpreters and execute fields

The Interpreters & execution strip at the top always shows which interpreters will run, e.g. python 3.12.4 · pwsh 7.4.5 · cmd /K /E:ON (versions are read in the background). Click it to open or close the settings below it; it starts closed on a new install. Every field remembers its history; the 🗑 button next to a field removes the current entry from that history.

Field Purpose
Python path The interpreter used for Python scripts. Leave empty to use the Python that runs Scriptary.
Python execute Run any Python command line in a new tab.
PowerShell path The PowerShell executable, plus any options, used for .ps1 scripts, e.g. "C:\Program Files\PowerShell\pwsh.exe" -NoLogo -NonInteractive -File.
Leave empty to use powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Windows PowerShell 5.1).
PowerShell execute Run any PowerShell command line in a new tab.
Command execute Run any command line in a new tab.
Command options /C exits after running, /K keeps cmd.exe open (and takes priority over /C), and /E turns command echoing on.
Argument detection Allows Python scripts to be executed when their arguments are detected (see How arguments are detected).
Output tabs Whether the output tabs are reopened, with their output, when Scriptary starts (see Output tabs between sessions).
Run as administrator Whether a run as administrator shows its output in a tab (the default) or runs in a console window of its own (see Run as administrator).

Which PowerShell?

  • pwsh.exe (PowerShell 7) is the current, actively developed version. Use it for new scripts, for scripts marked #Requires -Version 7, and when you want UTF-8 file handling by default.
  • powershell.exe (Windows PowerShell 5.1) is built into Windows. Use it for scripts that depend on older Windows-only modules or commands such as Get-WmiObject.

The two versions have separate profiles, module folders and execution-policy settings, so a script can behave differently between them.

Note: with the PowerShell path left empty, every PowerShell run (normal, elevated and command-line) uses powershell.exe -NoProfile -ExecutionPolicy Bypass -File, i.e. Windows PowerShell 5.1. Set the path to pwsh.exe to use PowerShell 7 everywhere.


Undo, redo and change history

Scriptary records every meaningful change to the library, saved parameters and interpreter settings, and lets you reverse them.

Undo and redo

↶ Undo (Ctrl+Z) and ↷ Redo (Ctrl+Y), on the right of the Interpreters & execution strip, reverse and reapply library changes:

  • refresh, scan, add, remove and clone;
  • group and folder changes, and moving scripts between them;
  • locating a moved file, and detecting arguments by running a script.

A confirmation lists what the change did and warns if the same scripts were changed again afterwards. Hovering over ↶ Undo shows what it would undo. When a removed script comes back, it is selected and scrolled into view, even inside a collapsed group or behind an active search.

In text fields, Ctrl+Z and Ctrl+Y keep their normal text undo and redo.

The History dialog

Open it with History in the top strip, or with History… in a script’s right-click menu to see only that script’s changes. The list shows every recorded change, newest first; undone changes are grayed out. The pane below shows exactly what changed, with old → new values.

Action Available in What it does
Undo this change All changes Reverses only the selected change. On an entry that was itself an undo, this becomes Redo.
Roll back to before this All changes Returns the library, saved parameters and recorded settings to their state just before the selected change. The roll-back is recorded as a single change, so it can be undone too.
Restore this script One script (the Only … checkbox) Puts that script back as it was before the selected change. Its library entry (arguments, description, note, label, group, folder) is restored and saved. Its parameter values are loaded as unsaved edits, so you can review them and press Save to keep them. Other scripts are not affected.

What is and isn’t recorded

Recorded: – script entries, groups, folders, labels, notes and parameter aliases; – saved parameters; – Python and PowerShell paths, command options, the argument-detection option, the output-tabs option and the lines each tab keeps, and the minimum console height.

Not recorded: – window size and position, pane sizes, collapsed groups, the list’s sort, and the selected script; – the text in the execute fields, and field histories; – last-run times and results; – the output tabs themselves.

To keep the history small and readable: – Saves that change nothing are skipped. – Repeated edits with the same label within two minutes are merged into one entry, and an edit that ends up back where it started disappears. – Only the previous values of what changed are stored, not copies of whole files. – Old entries are pruned after 60 days, or beyond 300 entries.


Chains: running scripts in order

A chain runs scripts one after another, each in its own output tab, stopping at the first that does not exit 0. It saves writing a wrapper script for “back up, then sync, then tidy”.

A chain is a thing of its own, with its own name and its own order — not an order stored on the scripts. A script can appear in several chains, or more than once in one, and where it is filed stays a separate question from what runs after it.

Building one

Manage ▾ → Chains…

Action What it does
+ New chain Create an empty chain and name it.
+ Add selected Append whatever is selected in Scriptary’s list. The list stays usable while the editor is open, so search it, filter it or open a group to find what you want. A script that cannot be a step is refused, with the reason.
↑ / ↓ Move the selected step earlier or later.
− Remove step Take a step out of the chain.
Rename / − Remove Rename the chain, or delete it. The scripts stay in the library.
Shortcut… Give the chain a keyboard shortcut (see Keyboard shortcuts).
Select in Library Jump to the selected step’s script.
▶ Run chain Run it now.

Every change to a chain is recorded, so Undo reverses it like any other library change.

Running one

Chains ▾, next to Manage, lists your chains — click one to run it. Or press ▶ Run chain in the editor, or the chain’s keyboard shortcut if it has one (the menu shows it). A chain can also run at set times, or remind you to run it: Chains ▾ → Schedule ▸ (see Schedules for chains).

You can also build a chain without opening the editor: right-click a script → Add to Chain, which lists your chains and the step the script would become, and offers New chain…. With several scripts selected, it adds them all as steps in the order they are listed, as one step for Undo.

Each step opens its own tab, named 2/4 sync.ps1, and the tab is brought to the front as its step starts. At the top of each tab is a line saying where it sits in the chain and how the previous step ended. When a step fails, its tab says so and names the steps that were not run:

Chain 'Nightly' stopped: step 2 of 4 exited 3.
Not run: 3/4  tidy.py, 4/4  report.py

Stopping a step with ⏹ Stop counts as a failure and ends the chain.

A step that is launched detached opens no tab and isn’t waited for: the chain moves on to the next step as soon as it has started, and the next step’s tab says previous step launched detached. Only a launch that fails to start stops the chain.

What a chain will not do

A chain is checked before it starts, and will not start at all if any step cannot run — better to be told up front than to stop half way.

  • Scripts that need administrator rights cannot be chained. Each elevated run waits for someone to accept a UAC prompt, and a script that elevates itself reports the exit code of the copy that asked for elevation, not of the work. If Scriptary is itself running as administrator the question does not arise and such steps are allowed.
  • A script whose file is missing, or one that has been removed from the library, blocks the chain until you fix or remove the step.

Two things worth knowing

  • Steps run on their saved values. ▶ Run uses what is on screen, which belongs to the selected script; the other steps of a chain are not selected and have nothing on screen. A step with unsaved edits runs its saved values, and the editor says so in its Status column. Press Save first.
  • Batch steps run with /C. A .bat normally runs inside a cmd.exe that is kept open for you to type into, which never ends — and so would never hand the chain its exit code. Chained batch steps exit instead, whatever Command options says.

Schedules: runs at set times, and reminders

A schedule attaches times to a script and does one of two things when a time comes round:

  • Run it automatically. The script runs by itself, as if you had clicked ▶ Run, while Scriptary is running (hidden in the tray counts).
  • Remind me to run it. The script is marked ⏰ in the list until you run it. Use this for jobs you want to watch, or ones that need you there.

A schedule belongs to one script entry, or to one chain (see Schedules for chains). For a script with clones, each clone has its own schedules and runs on its own saved values.

Making one

Right-click a script → Schedule ▸:

Item What it does
Run Automatically… Make a schedule that runs the script.
Remind Me to Run It… Make a reminder.
Change: … One item for each schedule the script already has.
All Schedules… Open Manage ▾ → Schedules….

Choose when it should happen:

When Example
On chosen days at a time Every day at 02:00; weekdays at 09:00
Every N minutes, hours or days, from a start time Every 15 minutes from 14:05 (:05, :20, :35, :50)
Monthly on a day at a time The 1st at 09:00. A day the month doesn’t have (the 31st in April) means its last day.
Once at a date and time 2026-10-03 at 18:00. It removes itself once done.
N days after its last successful run (reminders only) 30 days after the script last exited 0

The dialog shows the next few times as you type, so you can check it before saving. Like every check box and radio button in Scriptary, its are drawn at your display’s scaling, so they stay in proportion on a 4K screen.

Manage ▾ → Schedules… lists every schedule with what it does, when it next happens and how the last one went. From there you can add a schedule for the selected script, change one, turn it off and on, remove it, or clear a reminder (see Reminders). A schedule that pins its tab shows Runs, pins tab.

Adding, changing, turning off and removing a schedule are recorded in History, so Undo reverses them.

Automatic runs

A scheduled run differs from clicking ▶ Run in a few ways, all because nobody is at the panel when it starts:

  • It runs on the saved values. What is on screen belongs to the selected script, so a scheduled run ignores unsaved edits. Press Save first. Saving changed values of a script that has a schedule or a reminder, or is a step of a chain that has one, asks you to confirm first, since its next scheduled run will use them. A schedule that is turned off asks too, marked turned off, since it may be turned back on later.
  • It opens in the background. The run gets a tab marked ⏱ (e.g. ⏱ backup.py), headed with its schedule. The tab you are looking at stays in front, and the status bar says the run started. When the schedule’s next run starts, it replaces the previous run’s tab if that run has finished.
  • It can keep each run’s tab. Tick Pin its tab when the run finishes, so the next run does not replace it to have each run’s tab pinned once it ends, whatever its exit code.
    Pinned tabs stay open, and are kept between sessions, until you unpin them (right-click the tab). Reminders don’t have this option.
  • It is recorded like any other run. The status dot, Run History… and the Run Report all include it; Started from says Schedule. A failed run while the window is hidden in the tray shows a tray notification.
  • Batch files run with /C, as chain steps do, so that they finish and return their exit code.
  • Scripts that need administrator rights are not run, unless Scriptary itself is running as administrator. A UAC prompt would wait for someone to accept it. The time is noted as not run, with the reason.
  • It doesn’t overlap itself. If the previous run from the same schedule is still going when the next is due, the new one is noted as not run.
  • A script launched detached opens no tab and isn’t waited for: it is launched each time it falls due, even if the last launch is still open, and the schedule notes Launched with the time.

Missed runs. If Scriptary wasn’t running at a scheduled time, or the computer was asleep, the schedule runs once when Scriptary is next running, however many times were missed. Untick If Scriptary was not running at the time, run it once when it next is to skip missed times instead.
Several runs due at once start a few seconds apart. A run counts as missed when it starts more than five minutes late.

Changing a schedule starts it afresh. Times before the change, or before a schedule was turned back on, never count as missed.

Reminders

  • Where due reminders show:
    • A due reminder puts ⏰ after the script’s name in the list. Hover it to see since when and why.
    • A strip above the buttons at the bottom of the sidebar says how many scripts are due. Click it to list only those, and again to list everything. FILTER ▾ → Status → Due does the same.
  • Clearing a reminder. Only a successful run (exit 0) clears it. That includes ▶ Run, running as administrator, a chain step, a scheduled run, or scriptary.pyw --command run (a command-line run counts once the window next reads the library: ⟳ Refresh or a restart). A run that fails leaves it due, and the reminder says the last attempt failed.
  • When it comes back. After a successful run, the reminder returns at its next time. A “N days after its last successful run” reminder counts from that run. If the script has never succeeded, it counts from when you made the reminder.
  • Putting one off. Right-click a due script → Reminder Due ▸ to Snooze it for 1 hour, 4 hours or until tomorrow, or to Skip This Time.
    A snooze applies to this occurrence only.
  • Clear Reminder, in Manage ▾ → Schedules…, clears the selected reminder without a successful run: for example after a run that exited with a code other than 0, when you have dealt with it another way. The next reminder is counted from now, as with Skip This Time: a “N days after” reminder comes back N days from now, and any other at its next time after now.
    The button is available only once the reminder’s time has passed (snoozed or not).

Schedules for chains

A chain can be scheduled like a script: Chains ▾ → Schedule ▸ → the chain → Run Automatically… or Remind Me to Run It…. The same submenu lists the chain’s schedules to change, and Manage ▾ → Schedules… lists them with the scripts’, as Chain ‘name’.

  • A scheduled chain runs as if you had started it, with the differences of an automatic run: it opens its step tabs in the background, marked ⏱ (e.g. ⏱ 2/3 sync.ps1), the first headed with its schedule.
    Its next run replaces the finished tabs of the previous one, and Pin its tabs when the run ends keeps them all. The schedule’s Status says how it went: finished, or where it stopped, e.g. stopped at step 2 of 3 (exited 1).
  • It is held to a chain’s rules. A chain that couldn’t start by hand (a step that needs administrator rights, whose file is missing or that was removed, or no steps at all) is noted as not run, with the reason.
  • One chain at a time. If a chain is still running when another (or the same one) is due, the due one is noted as not run, e.g. Not run at 07:00: the chain ‘Backup’ was still running.
    Missed runs are made up as for scripts.
  • Reminders for a chain show on the Chains ▾ button, as Chains ⏰ 1 ▾, and on the chain in the menu, marked ⏰ due. Chains ▾ → ⏰ Reminder: name ▸ snoozes or skips it. Only a run in which every step exits 0 clears it, however the chain was started: from the menu, the editor, a shortcut or a schedule. A “N days after its last successful run” reminder counts from the chain’s last such run.

What is kept where

Schedules are stored in the library (COMPUTER_registry.json). What has happened to each schedule is stored in COMPUTER_settings.json and isn’t part of History: when it last ran, what it noted, snoozes and skips, and how each chain last ran. Like everything else, schedules are per computer, so a shared configuration folder doesn’t run a script on every PC.


Library reports

Manage ▾, on the right of the Interpreters & execution strip, opens reports over the whole library. Each shows a count beside its name when there is something to look at.

Report Shows
Parameter Names Every parameter name in the library, grouped so that different spellings of one name sit together, with aliases for many parameters at once (see below).
Parameters Without Help Every parameter whose ⓘ would have nothing to show (see below).
Unused Saved Values Values saved under a name no parameter of the script has any more, values left behind by scripts you removed, and aliases of parameters a script no longer has.
Saved Paths Every file or folder path in the scripts’ saved values, one row per path, with its script and parameter: a sortable table to find paths that point at an old place or another computer’s drive. A value counts as a path by its shape (a drive, a share, an environment variable, ~, . or .. at the start), whether or not it exists here.
Run Report Runs, successes, typical durations and failing streaks per script.
Archived Scripts Every archived script and the date it was archived, to unarchive or remove from Scriptary (see below).
Tags Every tag, to rename, merge or delete (see below).
Script List Every script with its name, full path, group or folder and tags, to export as a TSV file (see below).
Find Unregistered Scripts The .py, .pyw, .ps1 and .bat files in a folder, and the folders under it, that aren’t in the library, in a sortable table with their folder, language and modification date; files and folders you don’t want offered can be ignored (see below).

Manage ▾ also opens the Chains and Schedules editors and the Keyboard Shortcuts list, with counts. The Schedules count includes how many reminders are due.

Each Manage window is open once at most: choosing it again, from the menu or with its keyboard shortcut, brings the open window to the front.

Tables in these windows (and in History):

  • Column widths: the columns fit their contents when a table first fills. Once you drag a column’s edge, the widths you set are kept for that table from then on. A table you have never resized fits its contents again each time it opens.
  • Sorting: click a heading to sort by that column, and click it again to reverse the order. A small triangle beside the heading shows the sorted column, pointing up for ascending and down for descending. The sort stays as it is when the table refreshes after a change, such as an undo in the main window, and the table reopens with the last sort you used, in later sessions too. A table you have never sorted opens in its own order. The History list is not sortable: it is always newest first.

Where windows open: every popup window opens where you last closed it, including the small ones such as the name, note, schedule, shortcut and alias dialogs. The resizable ones also keep their size and whether they were maximized; the others are as large as their contents. A window whose place is off the screen, because a monitor has gone or the resolution changed, is pulled back onto it.

Select in Library, in the reports that offer it, opens the group or folder holding the script, and its tucked-away line if the script is behind it, so the script is reached even if it was hidden. Other groups and folders stay as you left them. A search that narrows the script out of the list is the one thing that can hide it; the status bar says so.

Parameter names

The list on the left has one row per name, whatever language the script is written in: --output-dir, --output_dir and -OutputDir sit together. A parameter with an alias is listed under its alias. Batch parameters (%1–%9) are listed once they have one. While Only names spelled more than one way is ticked, only those are listed; untick it to see every name.

Select one or more names to see where they are used on the right, with the script’s own name for each parameter. Then:

Action What it does
Set Alias Gives every parameter listed on the right (or only the selected rows) the alias typed in Alias as, which starts as the most used spelling. Scriptary lists what it will change first.
Parameters already called that are left alone, and a parameter whose own name is that loses its alias.
Remove Aliases Removes the aliases of the parameters listed on the right (or of the selected rows).
Double-click a row Opens that script’s Parameter Aliases.

Either is one change, so one Undo reverses it.

Parameters without help

A parameter’s help text is read from the script itself — help= on a Python argument, a comment above a PowerShell parameter, a REM or :: comment above a batch token — and it is what the ⓘ beside the parameter shows. Anything without one leaves you guessing when you fill the form.

The report lists one row per undocumented parameter, with the script, the parameter, what the script is written in, and the folder the file is in. Select a row and click Select in Library (or double-click it) to jump to that script.

Write the help in the script, then use Refresh Arguments from the right-click menu to read it again. Clones share their file’s parameters, so each file is listed once, and scripts whose file is missing are left out — their parameters are the last ones read and there is no file to edit.

Archived scripts

Right-click a script → Archive takes it out of the list and out of search results without forgetting it: its label, note, group, saved parameter values and run history all stay, and the date and time it was archived is recorded. Archived scripts are also left out of Parameter Names, Parameters Without Help, Saved Paths and the Run Report, and out of the command line’s --command list.

A script that is a step of a chain can’t be archived — the chain would stop running with nothing in the list to explain why. Scriptary tells you which chains use it; remove it from them in Manage ▾ → Chains… first.

Manage ▾ → Archived Scripts… lists every archived script, newest first, with the date it was archived, what it is written in and its folder. Select one or more rows, then:

Button What it does
Unarchive Puts the scripts back in the list, in the group or folder they were in, and selects the first.
Remove from Scriptary… After asking, removes the scripts from the library together with their saved parameter values. The files on disk are not deleted.

Both are recorded in the change history, so Undo reverses either. Adding a file that is only in the archive (+ Add) offers to unarchive it instead of adding it again.

Tags

Manage ▾ → Tags… (or Tags → Manage Tags… in a script’s right-click menu) lists every tag Scriptary knows, with how many listed scripts and how many archived scripts have it, and whether it is In use or Previously used. Previously used tags are grayed out. Select one or more rows, then:

Button What it does
Show in List Filters the list by the tag, and by no other tag. Other ticked filters are kept. Only for a tag in use.
Rename… Renames the tag everywhere. The name of another tag merges the two, after asking. Double-click a row to do the same.
Merge… Merges two or more tags into one: one of them, another tag or a new name. Every script with any of them gets the kept tag, once.
Delete… After asking, removes the tags from Scriptary and from every script that has them. Delete does the same.

A tag ticked in the filter stays ticked when it is renamed or merged.
Every change is recorded in the change history, so Undo reverses it.

Script list

Manage ▾ → Script List… lists every script in the library, one row each:

Column What it holds
Name The name as Scriptary’s list shows it: its label, if you gave it one.
Path The full path of the script’s file on this computer, including the file name, with environment variables such as %OneDrive% filled in.
Group or folder The group the script is in, or otherwise the folder section it is listed under.
Tags Its tags as a comma-separated list, each in double quotes: "nas","nightly". A double quote inside a tag is doubled.

Archived scripts are left out unless you tick Include archived scripts; they are then grayed out and marked (archived). Select in Library (or a double-click, or Enter) selects the script in the list.

Export TSV… saves the same four columns as a tab-separated file, with a heading line, in the order the table is sorted. The file is UTF-8 with a byte-order mark and Windows line ends, so Excel opens it with accented names intact. TSV has no quoting, so a tab or line break inside a value is saved as a space.

Find unregistered scripts

Manage ▾ → Find Unregistered Scripts… looks through a folder, and every folder under it, for .py, .pyw, .ps1 and .bat files that aren’t in the library. Type or paste the folder (environment variables such as %OneDrive% work) and press Enter or Scan, or pick it with Browse…. The folder is remembered, and looked through again the next time the window opens. A large folder is looked through in the background; Stop ends it early and keeps what was found so far.

Column What it holds
File The script’s file name.
Folder The folder it is in, relative to the one scanned (. for that folder itself).
Written in Python, PowerShell or Batch.
Modified When the file was last changed.

A script counts as registered when any entry in the library points at its file — archived and tucked-away scripts included — compared by path, not by name: a backup.py in another folder than the registered one is listed. Virtual environments (any folder with a pyvenv.cfg, and venv), site-packages, __pycache__, node_modules and hidden folders (a name starting with .) are passed by unless you tick Include virtual environments, site-packages, pycache, node_modules and hidden folders.

Add to Library registers the selected scripts (Ctrl+click and Shift+click select several), as one step for Undo; they leave the table, and come back if you undo. Open Folder (or a double-click, or Enter) shows the file in Explorer, and Copy Path copies its full path.

Ignoring. Right-click a script, or select it and click Ignore ▾, to leave it out of the list from now on: Ignore This File, or Ignore Folder for any folder it is in, up to the one scanned. With several scripts selected, the menu ignores those files, or the folders they are in. A folder takes everything under it, wherever you scan from.
Ignored… (with the count) lists what you ignore, by kind and full path: Un-ignore (or Delete) brings a file or folder back, and Ignore a Folder… adds one before you scan it. 🔍 Scan leaves ignored scripts out too.
The list is kept in COMPUTER_settings.json with paths stored like the scripts’ own (%OneDrive% …), and every change to it is one step for Undo and shows in History.


Data files and safety

All files are prefixed with the computer name, so several PCs can share one config folder (for example, on OneDrive) without overwriting each other’s data.

File Contents
COMPUTER_registry.json The script library: entries, detected arguments, parameter aliases, groups, folders, labels, notes, chains, schedules and last-run results.
COMPUTER_saved_params.json Saved parameter values for each script.
COMPUTER_settings.json Interpreter settings, field histories, options, collapsed sections, dialog layouts, keyboard shortcuts for Scriptary’s own actions, and what has happened to each schedule.
COMPUTER_settings.ini The window’s own settings: its size, place and whether it is maximized, the dividers, the list’s sort and selected script, and the folder a script was last added from. A value that can’t be read is ignored, so the file can be edited by hand. Older versions kept these in the .json file; they move here the first time Scriptary starts.
COMPUTER_history.json The change history used by Undo and History.
COMPUTER_console.json The output tabs kept for the next start-up, with their output. See Output tabs between sessions.
COMPUTER_detached\ Scripts launched detached: each launch’s details and how it ended, until Scriptary has recorded it, and the logs of the newest 50 launches.
*.json.bak One last-known-good copy of each of the first three files, refreshed at start-up only when its contents have changed.
*.corrupt-DATE.json A preserved copy of a file that couldn’t be read. Created only when damage is found.

How your data is protected

  • Atomic saves. Each file is written to a temporary file and then swapped in, so a crash or full disk can’t leave a half-written file.
  • Damaged files are never overwritten. If a data file can’t be read at start-up, it is preserved as .corrupt-DATE.json, and Scriptary offers to restore the last good copy, showing its date. If you decline, Scriptary starts with empty data, and the backup is kept under a dated name.
  • Locked files aren’t mistaken for empty ones. If a file stays locked (by a sync client, for example), Scriptary reports an error, not treating the file as empty and saving over it.

Portable paths

Script paths are stored relative to the first matching location, with the longest match taking priority:

%SCRIPTARY_HOME% (the folder containing scriptary.pyw, or the executable it was built into), %OneDriveCommercial%, %OneDriveConsumer%, %OneDrive%, %LOCALAPPDATA%, %APPDATA%, %USERPROFILE%, %PUBLIC%, %ProgramData%, %ProgramFiles(x86)%, %ProgramFiles%, %SystemRoot%.

A library stored this way resolves correctly on any machine where the same folders exist.


Keyboard shortcuts

Manage ▾ → Keyboard Shortcuts… lists every shortcut:

  1. yours;
  2. Scriptary’s own, which can’t be changed;
  3. every Ctrl+Shift and Ctrl+Shift+Alt combination that Windows or another program on this computer has taken, with what it does where that can be told. A global hotkey (such as a graphics driver’s overlay key) shows as Taken by another program, because Windows doesn’t say which program holds it.

Your own shortcuts

Give a script or a chain a shortcut, and pressing it runs that script or chain, whichever script is selected.

  • Script: right-click it → Keyboard Shortcut…, or select it and click + Shortcut for selected script in the Keyboard Shortcuts list.
  • Chain: Shortcut… in the Chains editor, or + Shortcut for a chain… in the Keyboard Shortcuts list.

In the dialog, press the keys you want. Each check is made as you press them, and the dialog says whether the keys can be used:

  • Allowed keys: Ctrl+Shift or Ctrl+Shift+Alt with a letter, a digit or F1–F12, such as Ctrl+Shift+B, Ctrl+Shift+3, Ctrl+Shift+F5 or Ctrl+Shift+Alt+B. That is 96 combinations.
    • These never get in the way of typing.
    • Ctrl+Alt without Shift isn’t allowed because on many keyboards it is AltGr, which types characters such as @.
    • Use the left Alt key. The right Alt key is AltGr on many keyboards, and AltGr+Shift types characters on many layouts (Polish, Czech, Nordic, US-International and others). A press with the right Alt held is left to type, so a Ctrl+Shift+Alt shortcut only answers to the left Alt.
    • Scriptary’s own Ctrl+Shift+Z (redo in text fields) is refused, and so is Ctrl+Shift+Alt+F4, which Windows treats as Alt+F4 and closes the window.
  • One key, one thing. Choosing a key another script, chain or action already has moves it, and the dialog says so before you save.
  • Keys the rest of Windows has taken are refused.
    Windows gives such a key to its owner even while Scriptary is in front, so a Scriptary shortcut on it would never work. Scriptary checks three places:
    • a global hotkey another program has registered;
    • a Windows input-language hotkey (for example Ctrl+Shift+0 on some computers);
    • the shortcut key of a shortcut in the Start menu or on the desktop.

    Programs that watch the keyboard directly, such as keyboard remappers, can’t be detected and aren’t listed. If pressing a combination in the dialog shows nothing at all, such a program took the keys before Scriptary saw them.

Assigning, changing and removing a shortcut are recorded in History, so Undo reverses them. A clone doesn’t copy its original’s shortcut.

How a shortcut runs:

  • Only in Scriptary’s main window. A shortcut works while the main window is in front, wherever the focus is in it, including a parameter field. It does nothing while the Chains editor, Schedules or any dialog is in front, and nothing when Scriptary is hidden or another program is in front.
  • On saved values. Like a chain step, a script runs on its saved values, not on what is on screen. If the script has unsaved edits, the tab says they were not used. Press Save first.
  • In a tab brought to the front, like ▶ Run. The tab starts with a line naming the shortcut. Started from in the Run Report says Keyboard shortcut.
  • Detached scripts are launched, as ▶ Launch does: no tab, and it may be launched again while the last launch is still open. See Launching detached.
  • Not twice at once. Pressing it again while its last run is still going does nothing, and the status bar says why. Holding the keys down counts as one press.
  • Administrator rights. A script that needs administrator rights runs elevated, as with ⛨ Run as admin, and asks you to accept the UAC prompt. A chain still can’t contain such a script.
  • When it can’t run. A shortcut for an archived script, one whose file is missing, or a chain that can’t start says why in the status bar. The Keyboard Shortcuts list shows the same in its Status column.

If a shortcut’s keys are taken by another program later on, Scriptary notices when it starts and says so in the status bar. The Keyboard Shortcuts list checks again each time it opens.

Shortcuts are kept in the library (COMPUTER_registry.json), so, like schedules, they are per computer.

Shortcuts for Scriptary’s own windows, menus and buttons

+ Shortcut for an action… in the Keyboard Shortcuts list gives a key to one of these:

Where Actions
Manage ▾ Tags, Archived Scripts, Script List, Find Unregistered Scripts, Parameter Names, Parameters Without Help, Unused Saved Values, Saved Paths, Run Report, Chains, Schedules, Keyboard Shortcuts, and Restart Scriptary and Restart as Administrator or without Administrator Rights (only when they are offered)
Top strip the Chains ▾ and Manage ▾ menus, History
Search row the FILTER ▾ and SORT ▾ menus
Sidebar + Add, ⟳ Refresh, ● Unsaved
Script header ✎ Note, Clone
Parameter bar ▶ Run, Save, ↕ Fit
Output tab in front ⏹ Stop, Save output, Copy output, Find

The key does just what the menu item or button does. ▶ Run runs the selected script on the values on screen, unlike a script’s own shortcut, which runs its saved values. Stop, Save output, Copy output and Find act on the output tab in front. If the button is hidden or can’t be clicked at that moment, the key does nothing and the status bar says why.

− Remove, Clear and CLOSE ALL are left out on purpose: each is one stray key press from losing something.

A button’s tooltip and the Manage ▾ menu show the key. These shortcuts are preferences, kept in COMPUTER_settings.json; they aren’t recorded in History, so Undo doesn’t reverse them.

Scriptary’s own shortcuts

Shortcut Action Where
Ctrl+F Go to the search box Main window
Ctrl+F Find in the tab’s output Output tab (its output or STDIN field)
↑ / ↓ Move through the script list (held, the parameters follow when you let go) Main window
Ctrl+Z Undo the last library change (text undo inside text fields) Main window
Ctrl+Y Redo (text redo inside text fields) Main window
Esc Clear the search Search box
Ctrl+Y, Ctrl+Shift+Z Redo typing Text fields
Ctrl+C, Ctrl+X, Ctrl+V Copy, cut, paste Text fields
Ctrl+A Select all of the field’s text Text fields
Right-click Cut, Copy, Paste and Select all, each available only when it can act Text fields
Ctrl+C Copy the parameter’s name Parameter names, in the parameter panel
Enter Send what was typed to the running script Output console’s input box
Enter, Shift+Enter Next match, previous match An output tab’s Find field
Esc Close Find An output tab’s Find field or output
Enter OK / Save Name, schedule and shortcut dialogs
Enter Go to the selected script Parameters Without Help, Saved Paths, Run Report, Script List
Enter Scan the folder typed; open the selected script’s folder Find Unregistered Scripts
Delete Remove the selected row Unused Saved Values, Archived Scripts, Schedules, Keyboard Shortcuts
Esc Close / Cancel Dialogs

Command line

The same library can be used without the window. Use python.exe, not pythonw.exe, so that output appears in your terminal. Every option is written --name VALUE (or --name=VALUE), in any order; python scriptary.pyw --help lists them all.

python scriptary.pyw --command add --script-file-path SCRIPT     Register a script
python scriptary.pyw --command list                              List scripts with their IDs (archived scripts are left out)
python scriptary.pyw --command run --script-name NAME            Run a script with its saved parameters
python scriptary.pyw --command remove --script-name NAME         Remove a script from the library
python scriptary.pyw --selftest TRUE                             Check Scriptary's own functions (see Testing)
python scriptary.pyw --help                                      List every option
Option What it does
--command {add,remove,list,run} Do this in the terminal instead of opening the window. Left out, the window opens.
--script-file-path SCRIPT The script to add, for --command add.
--script-name NAME The script to remove or run: see Naming a script.
--working-folder-path FOLDER Where the library, saved values and settings are kept (see Choosing where data is stored). Its old name, --config-dir, still works.
--show-self-restart-option TRUE Offer Restart Scriptary, and Restart as Administrator or without Administrator Rights (see Restarting Scriptary).
--selftest TRUE Check that Scriptary’s own functions work, on scripts it writes to a temporary folder, without touching the library; then say which optional parts are installed. Exits with 0 when every check passed.

A mistake on the command line (an unknown option, an option without its value or given twice, --command run without --script-name, a bare word such as list) is reported as Error: … with “Use –help for usage.”, and Scriptary exits with 2. Started with pythonw.exe, which has no console, it shows the mistake in a message box instead.

Naming a script

<script> can be any of the following, checked in this order:

  1. its ID, or the first 6 or more characters of it, as shown by --command list;
  2. its label;
  3. its file name, with or without the extension (backup.py or backup).

Matching ignores letter case. If a name matches more than one script (for example, a script and its clones), nothing is run or removed.
Scriptary lists the matching scripts instead, so you can use a label or ID:

> python scriptary.pyw --command run --script-name backup
'backup' matches 2 scripts by file name. Use a label or ID instead:
   75c240ad  backup.py
   609317a2  Backup to NAS (backup.py)

> python scriptary.pyw --command run --script-name "backup to nas"

What --command run does

It behaves like the GUI’s ▶ Run button, but in your terminal:

  • Parameters: it uses the values saved in the GUI for that script. Unsaved edits in an open GUI aren’t used.
  • Interpreter: Python scripts use the Python path setting, or the Python running Scriptary if it’s empty.
    PowerShell scripts use the PowerShell path setting, or Windows PowerShell if it’s empty. Batch files run through cmd.exe.
  • Working folder: PowerShell and batch scripts run from their own folder; Python scripts run from the current one.
  • Output: the command is printed first (on stderr), then the script’s output and input use your terminal directly.
  • Exit code: Scriptary exits with the script’s exit code, so --command run can be used in other scripts and scheduled tasks. The result also updates the script’s status dot in the GUI.
  • Administrator rights: if the script needs them and the terminal isn’t elevated, a warning is printed. Run the terminal as administrator in that case.

Exit codes from Scriptary itself: 1 means the script or its file wasn’t found, the name matched more than one script, or a data file is damaged; 2 means a mistake on the command line.
(Before, a name that matched several scripts gave 2.)

Other notes

  • --command add and --command remove are recorded in the change history, so they can be undone from the GUI.
  • If a data file is damaged, the commands stop without changing anything and ask you to open the GUI, which offers to restore the last good copy.

Testing

The tests use pytest (python -m pip install pytest).
From the Scriptary folder:

python -m pytest                   Everything
python -m pytest -m "not gui"      Everything except the tests that open windows
python run_tests.py                The same, from Scriptary itself (see its --help)
python scriptary.pyw --selftest TRUE   A quick check of Scriptary's own functions, without pytest

The 863 tests take about ten minutes; 365 of them don’t open windows and take about twenty seconds. One is skipped outside Windows. The tests never touch your own library: each one works in a temporary folder.
tests\README.md explains the result lines, the tools for checking that the list draws the same, and the check for dead code.

The tests that open windows are run at 150% display scaling too (on Linux: an Xvfb display started with -dpi 144). Among them, test_fit.py checks that at the window’s smallest size (900 × 640 at 100%) no button is cut off and the script list still shows three rows.


Troubleshooting

Output has no colors or progress bars. Scripts only run on a pseudo-console when pyte is installed and this Windows provides one (10/1809 and later); otherwise output comes through plain pipes. Install pyte and restart Scriptary.

Scripts take a few seconds to start. Scriptary uses the pseudo-console built into Windows. If that is unavailable it falls back to pywinpty, which ships its own console (conpty.dll and OpenConsole.exe) that on some machines takes about three seconds to start, whatever the command. In that case Scriptary measures both of pywinpty’s backends once and uses the faster, and the status bar says when it switches. To decide for yourself, set pty_backend in the settings file to system, conpty or winpty.

A PowerShell script is blocked by the execution policy. Each PowerShell version has its own execution policy.
Check it with Get-ExecutionPolicy -List in the same version your PowerShell path points at. Alternatively, add -ExecutionPolicy Bypass to the PowerShell path.

Accented or non-English characters are garbled in a PowerShell script. Windows PowerShell 5.1 reads a script without a byte-order mark using the system’s legacy code page. Save the script as UTF-8 with BOM, or run it with pwsh.exe.

--command run says a name matches several scripts. Use --command list to see the IDs, then run the script by its label or ID.

An old command line stopped working. Commands are options now: scriptary.pyw run backup is scriptary.pyw --command run --script-name backup, and add SCRIPT is --command add --script-file-path SCRIPT. Update scheduled tasks and shortcuts that start Scriptary this way.

“Settings not saved”. Scriptary couldn’t write COMPUTER_settings.ini, for example because the working folder is read-only or a sync client held the file. Scriptary goes on, but the window’s size, dividers and choices may not be kept for the next start. The message names the file and the reason, and is shown once until a save works again.

“Scriptary could not read its … file” at start-up. A data file was damaged, for example by an interrupted sync. Choose Yes to restore the last good copy. The damaged file is kept beside it as .corrupt-DATE.json if you need to recover anything from it by hand.

I undid something by mistake. Press Ctrl+Y, or open History, select the Undo: entry and click Redo.

A script launched detached never showed its window.
If it failed, a tab with its output opened when Scriptary noticed. If nothing opened, look at its log, the newest .log file in the COMPUTER_detached folder, or right-click it and choose Run in a Tab to see its output as it runs.

A script’s arguments look wrong. Right-click it and choose Refresh Arguments. For Python scripts that build their parsers dynamically, use Detect Arguments by Running Script….


Limitations

  • Windows only. Scriptary relies on the Windows pseudo-console, UAC and the taskbar. The tests run under Linux too, where the Windows-only parts are skipped or stood in for, so those parts are only ever checked on Windows.
  • Display scaling is that of the main display when Scriptary starts. On a second monitor with a different scaling, Windows stretches its window, and the text there is slightly soft.
  • Arguments are read, not known. Reading a script’s source (or its --help) finds the arguments of ordinary argparse, PowerShell and batch scripts; a parser built at run time needs Detect Arguments by Running Script….
  • One window. Only one copy of Scriptary runs at a time on a computer.
Download Release:
⬇️ Scriptary.zip
(1 votes, average: 5.00 out of 5)

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail.