-
This computer is a Windows 11 system with Cygwin installed.
-
Cygwin's
/bindirectory is in thePATHenvironment variable. -
Your Bash tool executes commands in the Cygwin Bash shell located at
C:\apps\cygwin\bin\bash.exe, which is/bin/bashinside any Cygwin app. -
Most Linux commands are available in the Cygwin Bash shell. If you need any that are not installed, ask me to install them.
-
My personal
~/bindirectory (and some its sub-directories) are also in thePATHenvironment variable. I commonly put wrapper scripts that launch Windows apps in~/bin/win32. This avoids adding a lot of directories to myPATH. -
The Cygwin man pages are installed. Use
man TOPIC >/tmp/TOPIC.txtto save a man page in plain text that you can read. -
Cygwin symlinks corresponding to each Windows drive letter have been created as follows:
/a -> /cygdrive/a /b -> /cygdrive/b /c -> /cygdrive/c ... /z -> /cygdrive/z-
Native Windows apps and commands cannot follow Cygwin symlinks, even when invoked from a Cygwin Bash shell.
-
The target of a Cygwin symlink can found using Cygwin command
readlink -m SYMLINK.
-
-
My Cygwin home directory is
C:\franl. My Windows home directory isC:\Users\flitt. -
When I write
~, it always means my Cygwin home directory (/cygdrive/c/franl=C:\franl), never my Windows home directory. -
When I mean my Windows home directory, I will write
C:\Users\flittor say "my Windows home directory" explicitly. -
In a Cygwin Bash shell and all Cygwin apps, the value of environment variable
HOMEis/cygdrive/c/franl, my Cygwin home directory. -
In all Windows apps, even those spawned by a Cygwin app, the value of
HOMEisC:\franl, even though that is not my Windows home directory. This causes some Windows apps to use my Cygwin home directory, though some still useC:\Users\flitt\. This can be confusing, so please be careful with any activity involving my home directories.
-
I will give pathnames to you in both Cygwin-style (
/c/franl/bin/...,/c/temp,~/bin, etc.), and Windows-style (C:\franl\bin,C:\temp, etc.). It is your responsibility to convert them between styles depending on which tool you are giving them to. This section and the next will guide you with this. -
Use pathnames in Bash commands as follows:
-
When invoking a Cygwin app from Bash, all pathnames should use forward slashes and, and absolute pathnames should have a
/cygdrive/...prefix. Example:ls -l path/to/file /cygdrive/e/somefile. -
When invoking a native Windows app from Bash, all pathnames should use backslashes, be single-quoted to escape the backslashes, and absolute pathnames should have a Windows drive letter prefix. Examples:
powershell -File 'path\to\script.ps1'andpowershell -File 'C:\temp\script.ps1.
-
-
In all cases, if a pathname contains whitespace or Bash metacharacters, the entire pathname must be single-quoted, regardless of whether it is being given to a Cygwin app or a native Windows app.
-
If single-quotes are not an option for escaping metacharacters, escape each one with a backslash.
-
A oddity of Cygwin: When a native Windows process starts a Cygwin program, the Cygwin runtime re-parses the Windows command line and performs its own glob/brace expansion, which can corrupt the final command line. Additional argument quoting should fix this.
-
Your file access tools do not understand Cygwin-style pathnames.
-
Always give Windows-style pathnames to your file access tools.
-
Do not use
findto search the entire filesystem by file name, though it's OK to use it for searching by other criteria. -
Search for files by name using the
escommand in Bash.esis a CLI front-end to the Everything search app that does extremely fast filesystem-wide pathname searches. -
Run
es --helpto see this usage:
usage: $ME [ -d | -s | -f ] [ -u | -w ] [ STRING | -r REGEX ]
Shows pathnames on local disks matching STRING (or REGEX with switch '-r'). The search is
case-insensitive and matches anywhere in the absolute pathname, so STRING and REGEX can
match `/` characters in the pathname. Results are sorted by absolute pathname by default.
The output contains forward slashes (`/`) by default. Use -w to get backslashes.
IMPORTANT: If STRING or REGEX contain shell metacharacters (e.g., `*`, `?`, `|`, etc.),
they must be properly quoted.
-r -> Match filenames using the given REGEX instead of a fixed STRING.
-f -> Show only pathnames, without modification times or sizes.
-d -> Sort results by modification time (newest first).
-s -> Sort results by size (largest first)
-u -> Display pathnames with UNIX-style forward slashes (default).
-w -> Display pathnames with Windows-style backslashes.
Examples:
# Show all files and directories under D:/somedir, sorted by size.
$ es -s D:/somedir/
# Show all items with names starting 'foo' under any sub-directory of 'franl' on any drive.
$ es -f '/franl/.*/foo'
# Show all items named 'FETCH_HEAD' in a '.git' directory, sorted by modification time.
$ es -d -r '/.git/FETCH_HEAD$'
-
When running
es, prefer to use forward slashes inSTRINGandREGEX, otherwise backslashes must be escaped. -
escan produce a lot of output, depending on the search string/regex. Pipe its output throughheador other tools to limit it. -
esdoes not understand Cygwin-style/cygpath/...prefixes. When necessary, use a Windows-style drive letter prefix (C:/...,D:/..., etc.).
-
Never recursively
grepthe entire filesystem. -
Recursive
grepcommands are acceptable in directories that don't contain too many files. Use theestool to quickly count the files below a given directory, as follows:es -f 'C:/path/to/directory/' | wc -l. -
The
ugreputility is available inPATH. It's' a drop-in replacement for Gnugrepthat supports searching UTF-8, UTF-16 and UTF-32 encoded files, PDF documents, and image metadata. Useugrep --helpto see usage.
-
The following compilers and tools are installed and available in the Bash shell:
gcc,g++,go,rustc,cargo,python,uv,uvx,npm,npx,git, andgh. Some of these are native Window apps, and some are Cygwin apps. -
Node.js is installed and can be executed using command
node. -
When you need to perform non-trivial mathematical calculations, use Python to do the math.
-
If you need additional compilers or tools installed, confirm with the user before installing them.
-
Two Python interpreters are available, and they behave differently in ways that cause subtle bugs, so choose deliberately:
-
Cygwin's
python(/usr/bin/python) is a POSIX build:os.pathuses Cygwin-style pathnames,os.getcwd()returns a/cygdrive/...path, and it can follow Cygwin symlinks. -
The native Windows Python (
/c/Windows/py.exe, which runsC:\Program Files\Python313\python.exe) uses backslash-awarentpathsemantics,os.getcwd()returns aC:\...path, and it cannot follow Cygwin symlinks.
-
-
Default to Cygwin's
pythonfor scripts you run yourself from the Bash shell, because it matches the shell's filesystem view (pipes, redirects, and symlinks). -
For a script that something else launches, use and test with that same Python interpreter. Testing under the wrong interpreter can pass while production fails.
-
When a script may run under either interpreter, parse pathnames separator-agnostically (for example, split on both
/and\) rather than relying onos.path. -
For standalone script deliverables, keep using PEP 723 metadata with
uv/uvx(see the Python Scripting Guidelines below);uvprovisions its own interpreter.
-
When you create new files containing source code or text, always use UTF-8 text encoding.
-
When you modify existing files, use the same text encoding as the rest of the file.
-
When you create new files, you should use UNIX-style newlines (a single line-feed character).
-
When you modify existing files, you must use the same newline convention as the rest of the file.
-
Never convert an existing file from one newline convention to the other. If you have a compelling reason to do this, confirm with the user first.
-
It's OK to have indefinitely long lines (despite the below rule to limit the length of source code lines), because Markdown renderers handle that gracefully.
-
Avoid hard line breaks with
<br/>, because not all renderers handle that. -
Instead of
<br/>, use two trailing spaces at the end of a line to indicate a line break. -
When creating a new Markdown document, list yourself as the author.
A skill is a collection of files (packaged in ZIP format) with the extension .skill that can be read by an AI at inference-time to learn new skills. When you write a skill, follow these guidelines:
-
The skill syntax specification is available at
https://agentskills.io. -
Do not add any directories to a skill other than the standard ones (and only if they are non-empty):
scripts,references, andassets. -
Always write a skill's markdown files in UTF-8 encoding without a BOM (byte-order mark).
-
Always use UNIX-style newlines (a single line-feed character) in skill files.
-
Use spaces for all indentation.
-
The name of the ZIP'ed skill file should have the
.skillextension.
-
Keep lines of source code less than 100 columns wide.
-
Avoid single-character identfiers.
-
In loops, use meaningful identifiers, such as
index,counter, andloopCount, instead of single-character identifiers. -
Prefer Python and Bash as scripting languages. Avoid Windows batch scripts and Powershell scripts, unless absolutely necessary.
-
Many of my scripts and source files mix tabs and spaces in indentation. Mid-line tabs and spaces are also used to align columns in array literals and before trailing comments.
-
The string-replacement edit tool requires its
old_stringto match content in the file byte-for-byte, including every tab and space. -
Although tabs and spaces are distinct characters that are present in the read tool's output, you cannot reproduce a mixed-whitespace region with byte-exact reliability by retyping it, so the match fails.
-
When an edit fails on such a file, do not keep retrying with guessed whitespace. Instead, use one of these reliable approaches:
-
Anchor the
old_stringon a short, unique single line that has little or no leading whitespace. -
Run
cat -A(orsed -n 'START,ENDp' FILE | cat -A) on the target region first to see the real tabs (^I) and spaces, then reproduce them exactly. -
For tricky multi-line regions, perform the replacement with a scripted literal
str.replace(for example, a small Python script that reads the file, asserts the old text matches exactly once, replaces it, and writes it back).
-
-
Do not convert files from tabs to spaces (or vice versa) to make editing easier.
-
In Python scripts, use PEP 723 metadata to specify dependencies.
-
Using PEP 723 metadata allows
uvanduvxto automatically obtain dependencies when the script is run.
-
In Bash scripts, all variable names must be fully uppercase, as follows:
COUNT=0,FILENAME="file.txt", etc. -
In Bash scripts, local variables in Bash functions must start with a leading underscore to avoid shadowing global variables, as follows:
local _COUNTER=0. Conversely, never use a leading underscore in a global variable. -
Prefer the new test command (
[[ ... ]]) instead of the traditional one ([ ... ]). -
Use the proper argument syntax for the new test command, such as using
&&instead of-ato indicate Boolean AND operations, and||instead of-oto indicate Boolean OR operations. To see full usage details, runhelp [[in Bash.
-
After editing an AutoHotkey v2 script, syntax-check it without running it via
AutoHotkey64.exe /validate 'C:\path\to\script.ahk'(exit code 0 and no output means success). -
Validate the top-level script that
#Includes the edited file, not the included fragment alone, so that globals and other includes resolve.
-
Always write well-commented source code.
-
Comments should be complete sentences.
-
Put comments on the line above the code they reference, rather than on the same line.
-
Comments can appear on the same line as code only if the comment is very short. In this case, the comment is exempt from the rule that it must be a complete sentence.
-
Comments should explain the purpose and rationale of the code and not simply restate what the code does.
-
Do not talk to the user through comments in code.
-
Do not comment trivial code, such as Python and Go
importstatements or the initialization of local variables, unless the comment explains something important for a developer to understand.
-
You have read access and write access to my GitHub repositories via command
git. -
gitneeds no credentials, because SSH access to GitHub is already configured. -
My GitHub user name is
fpl9000, and my GitHub profile is located athttps://github.com/fpl9000.
-
When running commands to build executables, make sure the executable name ends with
.exe, because this is a Windows system. -
When building a graphical Go application, always pass switch
-ldflags "-H windowsgui"so that the application does not create a console window when it is launched. -
When using GCC to build a graphical application, always pass switch
-Wl,--subsystem,windowsso that the application does not create a console window when it is launched.