# Fresh — Concept Overview

## The problem

Every project accumulates a pile of little operational scripts: *build*, *clean*, *install*,
*run*, *deploy*, *watch the logs*. They almost never do anything exotic. They:

- run a system command with a few variables spliced in,
- copy or move some files (after making sure the target directory exists),
- occasionally do the same thing across a small list of variants,
- and print helpful usage text when someone forgets the arguments.

Yet the tools we reach for are wildly over-powered for this. **Bash** gives you the whole system
but forces you to hand-write argument parsing, quoting rules, `mkdir -p` guards, `set -euo
pipefail` incantations, and `chmod +x` dances. **Make** bends awkwardly around anything that isn't
file-to-file compilation. **Just**, **Task**, and friends are closer, but still inherit a lot of
shell surface area and ceremony.

The result is that a 10-line intention turns into a 150-line script — most of it defensive
plumbing, not the actual work.

## The idea

**Fresh** is a deliberately small language whose entire job is to map friendly **subcommands** to
short lists of **operations**. You write what you *mean*:

```fresh
#!/usr/bin/env fresh

NAME             Dtracker Extension Tool
HELP_DESCRIPTION Build and deploy an extension.

EXTENSION_NAME  = dtracker
DEPLOYMENT_USER = dedrone
DEPLOYMENT_HOST = 192.168.1.234

DEF build
    RUN rm $EXTENSION_NAME/target/*.jar
    RUN mvn package

DEF deploy
    COPY $EXTENSION_NAME/target/$EXTENSION_NAME*.jar out/staging/
```

Then:

```bash
$ ./de build          # runs the two commands in the build task
$ ./de deploy         # copies the jar; creates out/staging/ if it doesn't exist
$ ./de help           # auto-generated: lists every task and its description
```

Every `DEF` block automatically becomes a subcommand. Help is generated for free. File
destinations create their parent directories automatically. You never call `chmod`, never write an
argument parser, never remember `set -e`.

## Design philosophy

1. **Conciseness is the product.** The measure of success is how few lines it takes to express a
   real build/deploy script. If a feature adds ceremony to the common case, it doesn't belong in
   the core.
2. **The obvious thing happens.** Destinations are created. Missing files are clear errors, not
   silent no-ops. A failing command stops the task (fail-fast by default). No hidden global state.
3. **No permission management, ever.** Fresh scripts are invoked through the `fresh` interpreter,
   so there is no executable bit to set. File operations use sane default modes. "It just works"
   is a hard requirement, not a nicety.
4. **Readable by non-authors.** A teammate who has never seen Fresh should understand a script on
   first read. Keywords are verbs in caps (`RUN`, `COPY`, `MOVE`, `MKDIR`); everything else looks
   like the shell they already know.
5. **Start tiny, grow on rails.** v0.1 can do almost nothing — run a predefined command and move a
   file — and that is genuinely useful. Each phase adds power *without* adding weight to the simple
   case. Advanced features (params, matrices, remote deploy) are opt-in.

## What Fresh is not

- Not a general-purpose language. No arbitrary data structures, no user-defined functions beyond
  tasks, no arithmetic engine. If you need that, call out to a real program with `RUN`.
- Not a replacement for CI. Fresh is the thing your CI *calls* (`fresh build`), and the thing you
  run locally to do the same steps identically.
- Not a shell. It orchestrates commands; it does not try to be one.

## Who it's for

Individual developers and small teams who maintain project automation by hand and are tired of
copy-pasting the same defensive Bash. Anyone who has ever written `if [ ! -d "$dir" ]; then mkdir
-p "$dir"; fi` for the hundredth time is the target user.

## The one-sentence pitch

> **Fresh turns a short list of "what to do" into a self-documenting command-line tool — and
> nothing you write ever needs a permission fix, an argument parser, or a `mkdir -p`.**
