Metadata-Version: 2.4
Name: codepills
Version: 0.4.0
Summary: Importable Python utilities from codepills.
Author: octanima-labs
License: MIT
Project-URL: Homepage, https://github.com/octanima-labs/codepills
Project-URL: Repository, https://github.com/octanima-labs/codepills
Keywords: utilities,scripts,snippets,stdlib
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# Code Pills

Code Pills is a curated collection of standalone scripts and reusable snippets.
The repository is managed with `codepills.py`, a standard-library Python CLI for
checking metadata, searching entries, copying snippets, importing scripts, and
running standalone tools.

## Layout

- `codepills.py`: repository helper CLI.
- Category directories such as `python/`, `bash/`, `powershell/`, `javascript/`, and `typescript/` contain standalone scripts and snippets.
- `*/.codepills.json`: category configuration. Only top-level directories with this file are managed by Code Pills commands.
- `*/snippets.*`: normalized snippet notebooks configured per category.

## Quick Start

Run commands from the repository root.

```bash
git clone git@github.com:octanima-labs/codepills.git codepills
cd codepills
python codepills.py check
python codepills.py ensurepath
python codepills.py search
python codepills.py search --type snippet -t linux
python codepills.py search --type script -t python -D
python codepills.py get py0006
python codepills.py get -c python/pingwave
python codepills.py run python/pingwave --tests
```

## Python Package API

The PyPI package installs only the Python modules as the `codepills` import
package. It does not install the Bash, JavaScript, or PowerShell collections as
Python modules, and the repository helper `codepills.py` remains separate from
the package API.

```bash
pip install codepills
```

Use module-first imports:

```python
from codepills.dirinit import create_structure, plan_structure
from codepills.snippets import safe_filename
from codepills.zipperzero import ZipperZero
```

The package root is intentionally minimal and does not re-export every utility.
Documented public names are also declared in each module's `__all__`. Private
helpers, parser builders, test helpers, and CLI internals are importable only as
implementation details and are not stable package API.

Supported first-pass imports:

```python
from codepills.dirinit import (
    CreateAction,
    CreateMode,
    PlannedEntry,
    StructureEntry,
    parse_structure_file,
    plan_structure,
    create_structure,
)
from codepills.bename import (
    RenamePlan,
    RenameResult,
    preview_renames,
    rename_paths,
    render_name,
)
from codepills.snippets import Cprint, cprint, safe_filename
from codepills.pingwave import (
    PingResult,
    build_ping_command,
    output_shows_all_packets_lost,
    ping_target,
    ping_targets,
    result_line,
    format_file_result,
    format_summary,
    write_output_file,
)
from codepills.massrun import (
    PLACEHOLDERS,
    RunResult,
    has_placeholder,
    substitute_placeholders,
    build_argv_command,
    resolve_cwd,
    find_targets,
    run_for_target,
    run_targets,
    run_matching,
)
from codepills.zipperzero import ZipperZero
from codepills.freezenv import (
    BASE_PACKAGES,
    OUTPUT_FILENAME,
    FreezenvError,
    discover_venv,
    discover_venvs_recursive,
    find_site_packages,
    freeze_requirements,
    write_requirements,
    freeze_venv,
)
from codepills.browpic import (
    DEFAULT_PORT,
    IMAGE_EXTS,
    MIME_TYPES,
    get_mime,
    create_server,
    serve,
)
from codepills.beautify import (
    BeautifyError,
    beautify_file,
    beautify_html,
    beautify_json,
    beautify_paths,
    beautify_xml,
    detect_syntax,
)
```

To start a fresh Code Pills collection from this toolset:

```bash
python codepills.py ensurepath
codepills reset --force
git remote add origin <YOUR_REPO_URL>
```

## CLI

After running `python codepills.py ensurepath`, examples can use `codepills`
directly instead of `python codepills.py` in new shell sessions.

### Ensure Path

Install the `codepills` command into the user PATH.

```bash
python codepills.py ensurepath
```

On POSIX systems this makes `codepills.py` executable, creates a
`~/.local/bin/codepills` symlink, and adds `~/.local/bin` to a shell startup file
when needed. On Windows it creates a `codepills.cmd` shim in `%USERPROFILE%\.local\bin`
and adds that directory to the user PATH.

### Reset

Reset the repository into a fresh Code Pills collection.

```bash
codepills reset
codepills reset --force
```

`reset` empties configured category folders, recreates empty snippet notebooks,
removes the current `.git` directory, and runs `git init`. It keeps
`codepills.py`, `README.md`, category folders, and each category's
`.codepills.json`. It does not configure a remote.

After reset, configure your own remote:

```bash
git remote add origin <YOUR_REPO_URL>
```

Without `--force`, `reset` asks for confirmation with a default No answer.

### Check

Validate standalone script metadata and normalized snippets.

```bash
python codepills.py check
```

### Search

Search scripts and snippets by metadata.

```bash
python codepills.py search [--type script|snippet] [-D] [-n NAME] [-d TEXT] [-t TAG] [-p PLATFORM]
```

- `-n`, `--name`: case-insensitive substring match on name/title.
- `-d`, `--description`: case-insensitive substring match on description.
- `-t`, `--tag`: exact case-insensitive tag match. Can be repeated.
- `-p`, `--platform`: exact case-insensitive platform match. Can be repeated.
- `--type`: restrict results to `script` or `snippet`. Can be repeated.
- `-D`, `--details`: include description and tags columns.

Multiple filters use AND logic.

### Get

Retrieve one or more snippets or standalone scripts.

```bash
python codepills.py get py0001
python codepills.py get python/pingwave
python codepills.py get javascript/xda
python codepills.py get py0001 python/pingwave
python codepills.py get -c py0001 javascript/xda
```

Snippet references use stable IDs whose two-letter prefix is the category alias,
such as `py0001`, `sh0001`, `ps0001`, `js0001`, and `ts0001` when TypeScript
snippets exist.

Script references can use a configured category, a category alias, or a bare
filename with a configured extension:

- `python/pingwave` or `python/pingwave.py`
- `py/pingwave` or `py/pingwave.py`
- `pingwave.py`
- `javascript/xda`, `js/xda`, or `xda.js`

Bare extensionless filenames such as `pingwave` are invalid because they do not
identify a category. Nested script references such as `bash/aws/testrds.sh` are
not supported.

For snippets, `get` prints only the snippet content; the ID/header metadata is
omitted. For scripts, `get` prints the absolute path to the resolved script
file. When multiple entries are selected, they are separated by two blank lines.

Use `-c` or `--copy` to copy retrieved content to the clipboard. Snippets copy
the snippet content, while scripts copy the full script file content rather than
the displayed path.

Clipboard support uses platform commands when available:

- Linux: `wl-copy`, `xclip`, or `xsel`
- macOS: `pbcopy`
- Windows: `clip` or PowerShell `Set-Clipboard`

If clipboard copy fails, the retrieved display output is still printed.

### Run

Run a standalone script and pass through all remaining arguments.

```bash
python codepills.py run python/pingwave --tests
python codepills.py run python/zipperzero --self-test
python codepills.py run powershell/barabara -h
```

The script reference is a configured category/name, alias/name, or filename with
a configured extension. Examples:

- `python/pingwave` or `python/pingwave.py`
- `py/pingwave` or `pingwave.py`
- `bash/swap_file` or `bash/swap_file.sh`
- `powershell/barabara` or `powershell/barabara.ps1`
- `javascript/xda` or `javascript/xda.js`

`run` executes standalone scripts only. Snippets are not runnable through this
command. A script must include the metadata tag `cli` to be runnable through
`codepills run`; browser JavaScript snippets/scripts should omit `cli` and are
blocked from CLI execution.

### Import

Import an existing script into the repository and add metadata when needed.

```bash
python codepills.py import /path/to/tool.py
python codepills.py import /path/to/tool.py --name better-name
```

The destination category is chosen from the file extension configured in a
category's `.codepills.json`:

- `.py` -> `python/`
- `.sh` -> `bash/`
- `.ps1` -> `powershell/`
- `.js` -> `javascript/`
- `.ts` -> `typescript/`

`--name` is a filename stem only; the original extension is preserved. Files
without an extension, or with an extension that no category declares, are
rejected. Existing destination files are not overwritten.

The generated `repo` metadata is inferred from `git remote origin`. If `origin`
is not configured, `import` fails with a clear error.

## Standalone Script Metadata

Every standalone script must start with a parseable `CODEPILLS-META` header.
If a shebang is present, it must remain the first line and the metadata follows it.

Required fields:

- `schema: codepills.tool/v1`
- `name`
- `version` using `X.Y.Z`
- `author`
- `description`
- `repo`, pointing to the script's public source URL
- `license`
- `usage`
- `tags`
- `requires`
- `platforms`

Run `python codepills.py check` after editing scripts. `check` requires `repo`
to be present, but it does not require the URL to match the current local
`origin`; imported scripts may preserve their original upstream URLs.

## Category Configuration

Top-level directories are managed by Code Pills only when they contain a
`.codepills.json` file. Directories without this file are treated as repository
support content and ignored by Code Pills commands.

Example JavaScript category config:

```json
{
  "extensions": [".js"],
  "alias": "js",
  "interpreter": ["node"],
  "lineComment": "//",
  "snippets": "snippets.js",
  "metadataComment": {
    "type": "block",
    "open": "/*",
    "close": "*/"
  }
}
```

Category config fields:

- `extensions`: one or more lowercase file extensions owned by the category.
- `alias`: lowercase two-character alias, also used as the snippet ID prefix.
- `interpreter`: command used by `codepills run` for non-shebang scripts. The
  token `sys.executable` resolves to the current Python executable.
- `lineComment`: line comment prefix used by the category's snippet notebook.
- `snippets`: snippet notebook filename, including extension.
- `metadataComment`: metadata header comment style. Use `type: "line"` with
  `prefix`, or `type: "block"` with `open` and `close`.

Aliases and extensions must be unique across all configured categories.

## Snippet Format

Snippets live in the `snippets` file configured by each category. Each snippet
has a stable ID, metadata header, and content body.

```python
# ### ID: py0001 ###
# Title: Input multiline values
# Description: Read standard input until an empty line and return all entered lines.
# Tags:
# - input
# - stdin
# Platforms:
# - Linux
# - macOS
# - Windows

def input_multiline():
    ...
```

ID prefixes are category aliases:

- Python: `py0001`
- Bash: `sh0001`
- PowerShell: `ps0001`
- JavaScript: `js0001`
- TypeScript: `ts0001`

IDs are stable once assigned. When adding a snippet, use the lowest available
number for that language.

## Maintenance

Before committing changes, run:

```bash
python codepills.py check
```

Useful focused checks:

```bash
python -m py_compile codepills.py
python codepills.py get python/pingwave
python codepills.py get py/pingwave
python codepills.py get pingwave.py
python codepills.py get py0001
python codepills.py run python/pingwave --help
python python/freezenv.py --tests
python python/zipperzero.py --self-test
python python/pingwave.py --tests
bash -n bash/swap_file.sh
```

Do not execute `bash/swap_file.sh` as a smoke test unless you intentionally want
to modify system swap configuration.
