Skip to content

Instantly share code, notes, and snippets.

@codejake
Created July 28, 2026 03:40
Show Gist options
  • Select an option

  • Save codejake/446c3b58398f534c31aecfd340f242d2 to your computer and use it in GitHub Desktop.

Select an option

Save codejake/446c3b58398f534c31aecfd340f242d2 to your computer and use it in GitHub Desktop.
Codex-generated fm cheat sheet

fm cheat sheet

fm is the command-line interface for Apple Foundation Models, built into macOS 27 for local prompting, structured generation, image understanding, interactive chat, and automation.

Warning

The default system model runs on-device. --model pcc sends the request to Apple's Private Cloud Compute service and requires a network connection. Do not pass secrets to PCC unless that is appropriate for the data.

Model output is untrusted input. Validate structured results and require human review before deleting files, sending messages, changing infrastructure, or taking other consequential actions.

Quick start

# Verify that the model is usable
fm available

# Ask the default on-device model
fm respond 'Explain this shell error in plain English: permission denied'

# Start a conversation
fm chat --instructions 'Be concise and ask before making assumptions.'

# Use the larger Private Cloud Compute model
fm respond --model pcc 'Compare these two architecture options: ...'

# See the exact options installed on this Mac
fm --help
fm respond --help
fm schema object --help

Requirements

  • macOS 27; fm is preinstalled.
  • The default system model is on-device.
  • The pcc model uses Private Cloud Compute, requires connectivity, and has usage limits.

Check both availability and PCC quota before relying on a model in automation:

fm available
fm available --model pcc
fm quota-usage --model pcc

Good defaults

For one-off private work, start with the on-device model:

fm respond \
  --instructions 'Answer concisely. Separate facts from uncertainty.' \
  'Why might this launch daemon repeatedly restart?'

For scripts, prefer non-streaming, structured, repeatable output:

fm respond \
  --no-stream \
  --greedy \
  --schema ./result.schema.json \
  --instructions 'Return only the requested structured result.' \
  'Analyze the supplied data.'

--greedy reduces sampling variability, but it does not make an answer guaranteed or factual.

Models

Model Select with Best fit Important difference
On-device system model Default or --model system Private, offline, low-latency work No request quota; 4,096-token session context
Private Cloud Compute model --model pcc More complex tasks and larger inputs Requires a network connection; usage limits; 32K context

Use fm count-tokens before sending a large prompt:

fm count-tokens 'A prompt to measure'
fm count-tokens --quiet 'A prompt to measure'

The prompt, instructions, transcript, and generated response share the available context. Leave room for the answer.

Core commands

Goal Command
Generate one response fm respond 'Prompt'
Hold an interactive conversation fm chat
Count input tokens fm count-tokens 'Text'
Build a generation schema fm schema object ...
Check model availability fm available
Check PCC quota fm quota-usage --model pcc
Run a local Chat Completions server fm serve --host 127.0.0.1 --port 8080
Get command-specific help fm <command> --help

Useful respond options

Option Purpose
-i, --instructions <text> Set persistent instructions for the response
--text <text> Add a text segment to the prompt
--image <path> Add an image
--schema <file-or-JSON> Constrain the response to a JSON schema
--resume <file> Continue from a saved transcript
--save-transcript <file> Save the resulting transcript
--no-stream Wait and print the complete result; useful in scripts
-g, --greedy Use greedy sampling for less variable output
-v, --verbose Print diagnostic detail
--model system|pcc Select the on-device or PCC model

Real-world recipes

Summarize the clipboard locally

pbpaste | fm respond \
  --instructions 'Summarize in five bullets. Preserve dates, owners, and decisions.'

Piping avoids placing the clipboard contents directly in shell history. The default model keeps processing on-device.

Turn meeting notes into an action list

fm respond \
  --instructions 'Extract decisions, action items, owners, and deadlines. Mark missing owners or dates as unknown.' \
  < meeting-notes.md

Do not let the model invent missing assignments; explicitly requesting unknown makes review easier.

Draft a commit message from the staged diff

git diff --cached --no-ext-diff | fm respond \
  --instructions 'Write one imperative Git subject under 72 characters, then an optional concise body. Output only the commit message.'

Review the result before committing. The staged diff may contain credentials or customer data; keep the default on-device model for sensitive repositories.

Explain the suspicious part of a log

tail -n 250 ./service.log | fm respond \
  --instructions 'Act as an incident responder. Identify the earliest likely cause, distinguish it from follow-on errors, quote relevant timestamps, and give three safe checks.'

Bound the input with tail or another filter so logs do not consume the entire context window.

Understand a screenshot

fm respond \
  --image ./Screenshot.png \
  'Describe the visible error, likely cause, and the safest next diagnostic step.'

For a harder visual task, add --model pcc after checking that sending the screenshot to PCC is acceptable.

Generate accessible alt text

fm respond \
  --image ./product-dashboard.png \
  --instructions 'Write factual alt text under 160 characters. Do not infer identities or hidden meaning.' \
  'Describe this image for a screen-reader user.'

Verify names, numbers, and chart conclusions against the image.

Extract predictable JSON

Create a schema:

fm schema object \
  --name IncidentSummary \
  --string severity \
    --description 'One of: low, medium, high, critical' \
  --string probable_cause \
  --string evidence --array \
  --string next_checks --array \
  > /tmp/incident-summary.schema.json

Generate and validate a result:

tail -n 250 ./service.log | fm respond \
  --no-stream \
  --greedy \
  --schema /tmp/incident-summary.schema.json \
  --instructions 'Analyze the log supplied on standard input. Do not invent absent evidence.' \
  | tee /tmp/incident-summary.json \
  | jq -e .

A valid schema guarantees shape, not truth. Check values before acting on them.

Classify files without moving anything

fm schema object \
  --name FileTriage \
  --string final_files --array \
  --string draft_files --array \
  > ./file-triage.schema.json

printf '%s\n' ./* | fm respond \
  --no-stream \
  --schema ./file-triage.schema.json \
  --instructions 'Classify the supplied names as likely final or draft. Return only names present in the input.' \
  > ./triage-result.json

First print the proposed actions:

jq -r '.draft_files[] | "WOULD ARCHIVE: \(.)"' ./triage-result.json

Only write a separate move or deletion step after validating that every returned path is inside the intended directory. Never evaluate model output as shell code.

Save and resume a focused session

fm respond \
  --instructions 'Help diagnose this incident. Track confirmed facts separately from hypotheses.' \
  --save-transcript ./incident-session.json \
  'The API began returning 503 errors at 14:32.'

fm respond \
  --resume ./incident-session.json \
  --save-transcript ./incident-session.json \
  'New evidence: database connections are healthy.'

For an interactive session:

fm chat --instructions 'Coach me through this migration one reversible step at a time.'

Inside fm chat, /save saves the conversation and /model switches models. Use fm chat --continue to continue the most recent saved session.

Start a local Chat Completions endpoint

fm serve --host 127.0.0.1 --port 8080

Bind to 127.0.0.1 unless remote access is intentionally configured and protected. Run fm serve --help for the installed server's connection details and supported options.

Structured generation

fm schema object starts a property with --string, --integer, --double, or --boolean. Modifiers such as --description, --optional, and --array apply to the property immediately before them.

fm schema object \
  --name DeploymentReview \
  --boolean approved \
  --string blockers --array \
  --double confidence --optional \
  --string owner.name \
  > deployment-review.schema.json

Dot notation such as owner.name creates nested objects. Inspect fm schema object --help because the property grammar is easier to understand from the complete built-in help.

Prompting practices that hold up in scripts

  • Put stable rules in --instructions; put the current task and data in the prompt.
  • Ask the model to use unknown rather than guess.
  • Bound large inputs and check them with fm count-tokens.
  • Use a schema instead of parsing prose with regular expressions.
  • Use --no-stream when capturing a complete response.
  • Use --greedy when repeatability matters, then still test representative cases.
  • Treat files, webpages, logs, and email as untrusted prompt content; they may contain prompt-injection text.
  • Never pass model output to eval, sh -c, or an unreviewed destructive command.

Troubleshooting

fm is not found

sw_vers -productVersion
command -v fm

The Apple fm command requires macOS 27 and is normally available as a system command.

A model is unavailable

fm available --model system
fm available --model pcc

Check Apple Intelligence availability for the system model. PCC additionally requires connectivity and available quota:

fm quota-usage --model pcc

The response stops or loses earlier context

fm count-tokens --quiet < long-prompt.txt

Shorten the input, remove repeated context, or use PCC when its larger context and privacy boundary are appropriate.

Automation is hard to parse

Use all three:

fm respond --no-stream --greedy --schema ./result.schema.json '...'

Then validate the result with jq -e and enforce application-level rules.

Useful links

#cheatsheets #macOS #AppleIntelligence #FoundationModels #CLI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment