A Practical Guide to AI Coding CLIs: Startup, Permissions, and Sessions
This guide covers how to run an AI coding CLI in the terminal—using Anthropic’s Claude Code (`claude`) as the example—including install and version checks, interactive vs. non-interactive launches, permission and config layers, session resume, common workflows, and engineering checklists for individuals, teams, and CI.
1. Role and boundaries
AI coding CLIs run in the terminal. They can read files in the current project, answer questions about code, and—after you authorize them—edit files or run commands. This article uses Anthropic’s Claude Code as the example; the command is claude. Other tools may use different flags; check each tool’s help before you rely on a name.
The main difference from a web chat is direct access to your project directory. That also means the tool can see secrets, credentials, and personal data. Confirm the working directory first, and limit which files it can reach.
Treat output as unverified. Changes that touch authorization logic, database migrations, production config, or concurrency must go through code review and tests before merge.
2. Install and version check
The following uses npm and assumes Node.js is installed. Install steps change over time; follow the official documentation.
npm install -g @anthropic-ai/claude-codeclaude --versionclaude --help
After every upgrade, run claude --version, then claude --help to confirm flag names. Pin one version across the team so results do not drift between machines.
3. Interactive and non-interactive startup
1. Interactive sessions
Interactive mode fits complex features, multi-round review, and step-by-step debugging. Start from the project directory:
cd /path/to/your-projectclaude
Inside the session, ask for a read-only analysis before any edits:
Please read the src/auth directory and explain which files the login flow goes through. Do not modify any files yet.
The first time you start in a directory, the tool asks whether to trust it. Before you confirm, check for .env, private keys, or other credentials. Trust only repositories you control.
Context lasts until the session ends or is cleared. On long tasks, have the tool write a progress summary after each stage and save that summary to a file.
2. Non-interactive calls
Non-interactive mode passes the task with -p. The tool prints output and exits:
claude -p "List functions in src/auth that lack unit tests. Output only the list; do not modify files"
--output-format commonly accepts text and json. Use json when scripts parse the result.
claude -p "List functions in src/auth that lack tests" --output-format json
Non-interactive calls fit scripts and CI. This example sets a timeout and checks the exit code:
#!/usr/bin/env bashset -utimeout 300 claude -p "Check whether these changes contain hardcoded secrets; output only suspicious locations" \--output-format json > review.jsonstatus=$?if [ "$status" -eq 124 ]; thenecho "AI check timed out and was killed" >&2exit 1elif [ "$status" -ne 0 ]; thenecho "AI check failed with exit code $status" >&2exit "$status"fi
timeout returns 124 on timeout. Other non-zero values mean the tool failed. Treat timeout and execution failure separately; exact codes depend on your installed version.
You can also pipe content:
git diff main...HEAD | claude -p "Find unhandled exceptions in this change and list them by severity"
Piped content is sent to the tool. If the diff may contain secrets or personal data, redact it first, or confirm your organization allows sending that content.
3. Version and help
--version and --help do not start a project task, run quickly, and do not read project files. When troubleshooting, use them first, then check config and permissions.
4. Permissions, configuration, and session resume
1. Permission policy
Permissions are the security boundary. A practical policy:
| Action | Suggested policy | When to require human confirmation |
|---|---|---|
| Read project files | Allow, but exclude secret and credential paths | Directory contains .env, private keys, or customer data |
| Edit files | Allow only on a dedicated branch | Auth, payments, or permission-related code |
| Run shell commands | Allowlist tests and build commands only | Deleting files, installing dependencies, network access |
| External services and extensions | Connect only to reviewed internal services | First connection to a new service |
| Directory trust | Trust only your own repositories | Third-party code or downloaded archives |
| Audit trail | Keep session logs and change summaries | — |
In settings.json you can deny reads of sensitive files. Syntax is version-specific; treat this as an illustration only:
{"permissions": {"deny": ["Read(./.env)", "Read(./secrets/**)"]}}
2. Config files and precedence
Typical locations:
- User config:
~/.claude/settings.json(current user only). - Shared project config:
.claude/settings.json(can be committed for the team). - Local project config:
.claude/settings.local.json(machine-only; add to.gitignore). - Enterprise-managed policy: usually highest precedence.
Per official docs, CLI flags override project and user config. Verify precedence on your version. If a permission does not apply as expected, look for a higher-priority override.
Do not put API keys in config files. Use environment variables such as ANTHROPIC_API_KEY, and inject them from a secrets manager in CI.
3. Session resume
Continue the most recent session:
claude -c
Resume a specific session:
claude -r
Without arguments, -r typically lists resumable sessions. Confirm with claude --help.
When resuming: keep separate sessions for separate tasks in the same project; if context is too long, quality may drop—start a new session from a saved summary; session logs may contain sensitive code, so decide what to keep before deleting.
If resume fails:
- Confirm the current directory matches the session’s original directory.
- Confirm the session id is spelled correctly.
- If the session cannot be found, start a new one and paste the last summary.
- If it keeps failing, check whether local session files were cleaned up or moved.
5. Use cases
Each of these needs a clear input, a checkable output, and a human confirmation point.
| Scenario | Input | Output | Human confirmation | Failure handling |
|---|---|---|---|---|
| Project understanding | Path and question | Module relationships and startup flow | Check key claims against the code | Narrow the scope; ask per directory |
| Code generation | Requirements and API contract | Draft code | Review logic; run tests | Ask for a plan before any code |
| Test assistance | Target files | Cases or a test plan | Check that assertions are meaningful | Keep only passing, useful tests |
| Incident debugging | Error logs and related code | Likely causes and files | Reproduce locally | Add log context and retry |
| Docs | Code and API definitions | Draft API notes | Compare with the real interface | Mark uncertain fields |
| Automated checks | Diff content | Risk list (JSON) | Review false positives and misses | Block and alert on timeout or bad format |
Three examples:
Summarize exceptions in a log:
cat logs/app-error.log | claude -p "Summarize the earliest exceptions in time order and suggest likely file locations. Do not modify code"
Scan staged changes for sensitive data:
git diff --cached | timeout 300 claude -p "Check whether the index contains secrets or personal data; output only locations and types" --output-format json
Plan tests before writing files:
Design a unit-test plan for src/utils/date.ts. List cases and edge conditions. Do not create files until I confirm.
6. Engineering checklists
1. Individual developers
- Required: Confirm the working directory before every run.
- Required: Do not let the tool read
.envor private keys. - Required: After edits, run tests and inspect the diff.
- Optional: Keep fixed prompts for common read-only tasks.
- Optional: Periodically delete session logs you do not need.
2. Teams
- Required: Put shared permission rules in
.claude/settings.jsonand commit them. - Required: Gitignore
settings.local.json. - Required: Pin the tool version; validate upgrades in a test repo.
- Required: Review AI-generated code.
- Optional: Maintain a prompt template library.
- Optional: Keep session summaries and change lists per task.
3. CI pipelines
- Required: Set
timeouton every non-interactive call. - Required: Check exit codes; distinguish timeout from failure.
- Required: Pin
jsonoutput; fail the job if parsing fails. - Required: Inject API keys from a secrets manager, never from the script.
- Required: Run checks read-only; do not let the tool push code.
- Optional: Post check results as merge-request comments.
4. Failure handling
- Timeout: Shrink the input or split the task.
- Non-zero exit: Inspect stderr; check version, network, and keys.
- JSON parse failure: Require valid JSON only in the prompt, and print raw output before parsing.
- Permission denied: Inspect rules and directory trust; do not widen permissions just to pass.
- Network drop: Retry once; if it still fails, log and stop—do not continue without a result.
- Output disagrees with the code: Trust code and tests; record the gap and fix the prompt.
