Commands
Last updated: 2026-10-29
1. The three commands
pepito can run three command lines of your choice, or ones your IT department deploys. They share one way of being called and one set of variables, described here.
- Transcription command. Produces the transcript in place of the Apple engine. pepito passes the audio and the recording's files to this command, on this Mac. What the command does with them (sending them to a server, for instance) is up to the command. Guide and whisper.cpp example: Transcription command.
- LLM command. Answers the prompts that write the minutes, suggest a title and choose tags, instead of a language model provider. pepito passes the prompt and the recording's files to this command, on this Mac. What it does with them is up to it.
- Post-processing command. Runs after each processing of a recording, for its side effects. pepito passes the recording's files to this command, on this Mac. What the command does with them (sending them to an AI tool or a server, for instance) is up to the command. Guide: Post-processing command.
The statements elsewhere on this site about what stays on your Mac describe pepito without such commands. Each command runs without asking you, with pepito's permissions.
2. Version
Requires pepito 26.61 or later.
This page describes the contract from that version. It changes the contract of the transcription command
(PEPITO_AUDIO_PATH now names the recording's audio and the converted WAV is in
PEPITO_INPUT_PATH; PEPITO_SOURCE_AUDIO_PATH is gone) and of the LLM command (empty
working folder instead of /). From then on, variables, values of PEPITO_TASK and
values of PEPITO_REASON are added, never removed or renamed: a command tolerates a value it does
not know. recording.json is readable but is not part of the contract; the stable way to read a
recording is the get_recording MCP tool.
3. How a command is called
Command line
pepito runs the line you set with /bin/sh -c, with the PATH of your login shell
(pepito does not read your shell profile on each run). pepito adds no argument: the line is yours, with the
arguments you write. Parameters come as environment variables, which the shell expands. pepito does not check
the line before running it: a missing or non-executable file shows up as exit code 127 or 126. A command is
set when its line is not empty.
Environment
- The command inherits the environment of pepito, with the
PATHof your login shell. -
The
PEPITO_namespace belongs to pepito. AnyPEPITO_*variable inherited from pepito's own environment is removed before pepito sets its own, so a variable that is not in this contract is absent for the command. A script that wants a setting of its own names it outside that namespace (WHISPER_MODEL, for example). -
All variables are computed when the command starts (when it leaves the queue, if there is one), from the
recording's
recording.jsonread at that moment. Paths are absolute and valid at that moment; a command that wants the current state reads it again through MCP. If that file cannot be read then (the recording was deleted while waiting, or the file is damaged), the run fails before starting: pepito never starts a command for a recording withoutPEPITO_RECORDING_ID. - A variable that does not apply is not set, never set to an empty value.
Working folder
The current directory of the command is an empty working folder, specific to the run (for the LLM command, to each call), never the recording's folder. Everything the command writes to its working folder is deleted when it ends, including by a process it left running; anything meant to last is written elsewhere.
Standard input
/dev/null for the transcription and post-processing commands; the filled-in prompt for the LLM command.
Result
- Exit code 0 is success, any other code a failure. A non-zero code takes precedence over any check of the output.
- The message of a failure is followed by the end of standard error (the last 20 lines, 2,000 characters at most, with the command line removed), or "The command exited with code N" when it is empty. Exit code 126 is reported as "Command not executable" and 127 as "Command not found", followed by the end of standard error.
- After exit code 0, an empty or whitespace-only useful output is a failure: "The command produced no transcription" (transcription command), "The LLM command returned an empty response" (LLM command), followed by the end of standard error. The post-processing command has no useful output.
- Standard output and standard error are read as UTF-8; an invalid byte becomes U+FFFD and nothing is discarded for it.
- Standard output and standard error go to pepito's log, marked private, along with the command line.
Time limit
Fixed per command (table below), counted from the moment the command starts, not from the moment it is queued. When it is exceeded, the run fails with "Timed out (N min)". There is no setting for it.
Stopping
The command runs in its own process group. On cancel, time limit or when pepito quits, pepito sends SIGTERM to the group, then SIGKILL after 5 seconds.
Queues
The transcription and post-processing commands each have a queue: one run at a time, in arrival order, every run of the command goes through it (the Test button included), and a queue is emptied when pepito quits. The LLM command has none: the calls of different recordings run in parallel. The three commands can run at the same time; one line set for two commands gives two simultaneous runs.
Test
Each command can be tried from its group in Settings: "Test" for the transcription and post-processing commands,
"Check" for the LLM command. The result shows the outcome, the end of standard output and of standard error, and,
folded, the PEPITO_* variables pepito set. Closing Settings stops the test. Nothing is stored.
4. Variables
Every command receives PEPITO_TASK, the variables of the recording when a recording is concerned,
PEPITO_GUIDELINES_PATH when the file exists, and its own variables (section 5).
PEPITO_TASK
Always set; says why the command runs: transcription; summary, title,
tags or check; post_processing. An executable shared by two commands branches on it.
With tags (Auto-Tag), pepito expects the chosen tags, one per line, or NONE.
Variables of the recording
The same for the three commands, as soon as a recording is concerned. All paths are absolute.
| Variable | Value | Set |
|---|---|---|
PEPITO_RECORDING_ID | The recording's id, the one the MCP tools take. | Always, when a recording is concerned. |
PEPITO_BASE_PATH | The recording's folder. Do not append an extension. | Same. |
PEPITO_METADATA_PATH | Its recording.json. | Same. |
PEPITO_AUDIO_PATH | The recording's audio (audio.m4a, audio.mp3). | When the file exists at launch. |
PEPITO_SRT_PATH | The current transcript. | When the file exists at launch. |
PEPITO_SUMMARY_PATH | The current minutes. | When the minutes succeeded and the file exists. |
PEPITO_NOTES_PATH | The notes. | When the file exists at launch. |
-
During a transcription,
PEPITO_SRT_PATHandPEPITO_SUMMARY_PATHare the files from before the run, which its result is going to replace or make out of date. - Paths read from
recording.jsonare relative to the recording's folder (the minutes' path starts with../../).
PEPITO_GUIDELINES_PATH
The absolute path of GUIDELINES.md, your guidelines, at the root of the recordings folder (the one of the
recording concerned; the folder set in Settings when no recording is). Set for the three commands, recording or not,
when the file exists at launch. The recordings folder itself is not exposed: other recordings and the tag catalog
are reached through the MCP tools.
Without a recording
The "Check" button of the LLM command (check) and the Test button of the transcription command concern no
recording: no variable of the recording is set. The absence of PEPITO_RECORDING_ID is the signal.
PEPITO_TASK, the command's own variables and PEPITO_GUIDELINES_PATH remain.
What is not shared
- No MCP variable. A command that wants MCP goes through the configuration of the AI tool it starts, which you made with the "Connect an AI Tool…" assistant.
- No language variable outside the transcription command: the language is in
recording.json. PEPITO_REASONbelongs to the post-processing command.
5. The three contracts side by side
| Transcription command | LLM command | Post-processing command | |
|---|---|---|---|
| Role | Produces the transcript; replaces the Apple engine | Answers a prompt | Side effect after a processing |
| Runs | At the transcription step, when the recording's engine is Command | At each call of the LLM provider: minutes, title suggestion, Auto-Tag, Check | At the end of each processing without failure or cancellation; manual rerun |
| stdin | /dev/null | The filled-in prompt | /dev/null |
| Working folder | One per run; pepito puts the converted WAV in it and waits for the SRT there | One per call; pepito puts nothing in it | One per run; pepito puts nothing in it |
PEPITO_TASK | transcription | summary, title, tags, check | post_processing |
| Variables of the recording | Yes; none in the Test | Yes; none for check | Yes (always a recording) |
PEPITO_GUIDELINES_PATH | If the file exists | Same | Same |
| Own variables | PEPITO_INPUT_PATH, PEPITO_OUTPUT_PATH, PEPITO_LANGUAGE, PEPITO_LANGUAGE_CODE | None | PEPITO_REASON |
| Useful output | An SRT file in PEPITO_OUTPUT_PATH, stored byte for byte; standard output is not the transcript | Standard output, trimmed of leading and trailing whitespace, nothing else | None |
| Empty output | "The command produced no transcription" | "The LLM command returned an empty response" | Not applicable |
| Time limit | 10 minutes plus a quarter of the converted WAV's duration | 10 minutes per call (summary, title, tags); 1 minute for check | 20 minutes |
| Queue | Yes, one run at a time | None; parallel calls | Yes, one run at a time |
| Test | "Test": a sentence read by macOS in the default transcription language, no recording | "Check": check, prompt "Reply with OK", no recording | "Test on": one of the last 10 eligible recordings, PEPITO_REASON=manual |
| On failure | The transcription step fails, with the error shown | The minutes fail with the error; an alert for a title suggestion; the log for Auto-Tag | A notification |
Transcription command: own variables
| Variable | Value |
|---|---|
PEPITO_INPUT_PATH | The WAV (PCM 16-bit, mono, 16 kHz) converted by pepito, in the working folder. |
PEPITO_OUTPUT_PATH | The SRT file to write, in the working folder, ending in .srt. |
PEPITO_LANGUAGE | BCP-47 tag with region (fr-FR), or auto. |
PEPITO_LANGUAGE_CODE | ISO 639-1 code (fr), or auto. |
Post-processing command: own variable
PEPITO_REASON, why the run starts (recording, import_audio, manual, ...):
values on Post-processing command.
6. LLM command
In Settings, Summary, choose "LLM command" as the provider. This page is the first public documentation of that provider.
Contract
- Standard input: the filled-in prompt of the task. The command can ignore it and work from the files (section 4).
-
Useful output: standard output, trimmed of leading and trailing whitespace, nothing else; an empty output is a failure.
For
tags, one tag per line, orNONE. - No queue: the minutes, title and tags of different recordings run in parallel, as with the other LLM providers.
-
For agents. The working folder is new at each call. An agent that keeps one session per current
directory therefore creates one session per call; with Claude Code, add
--no-session-persistence. pepito adds nothing to the line.
Deployment with MDM
Preference domain: fr.sodadi.pepito. Keys:
llmProvider(string):customScriptselects the LLM command.llmCommand(string): the command line, run by/bin/sh -c. When it is absent, pepito falls back to the oldercustomScriptPath(an absolute path), read between single quotes.
The value is not locked, as for the two other commands: a user can change the provider and the line in Settings. If you need to guarantee that prompts go only to your command, control it outside pepito as well.
7. Guides by role
- Transcription command: the whisper.cpp example, offline preparation, other tools, MDM keys.
- Post-processing command: when it runs, the reasons, MDM keys.