项目文件夹

文件
Ali Khokhar 5305bd7e08 Remove obsolete init and server alias commands (#1220)
## Problem

FCC still publishes `fcc-init` and the `free-claude-code` server alias
from an obsolete installation flow. Configuration creation now belongs
to the Admin UI, while `fcc-server` owns startup and legacy migration.

## Changes

| Before | After |
| --- | --- |
| The package installs six console commands. | The package installs only
`fcc-server`, `fcc-claude`, `fcc-codex`, and `fcc-pi`. |
| `fcc-init` duplicates configuration creation outside the Admin UI. |
The Admin UI exclusively creates managed configuration, and server
startup retains legacy migration. |
| Smoke contracts and architecture describe the retired commands. |
Smoke contracts and architecture describe the supported command surface.
|
| Installer safety lists contain unexplained retired names. | Installer
safety lists document why retired names remain detectable during updates
and uninstall. |
| The package version is `4.11.4`. | The package version is `4.11.5`. |

<!-- greptile_comment -->

<details open><summary><h3>Greptile Summary</h3></summary>

This PR retires the obsolete initialization command and server alias.
The main changes are:

- Removes `fcc-init` and `free-claude-code` from package scripts.
- Moves fresh configuration creation exclusively to the Admin UI.
- Keeps legacy environment migration in `fcc-server` startup.
- Updates smoke coverage, installer comments, documentation, and package
metadata.
</details>

<h3>Confidence Score: 4/5</h3>

The CLI removal needs a compatible release version or temporary aliases
before merging.

Existing automation can lose `fcc-init` and `free-claude-code` after a
patch upgrade. Fresh installs can still start the server and create
configuration through the Admin UI.

pyproject.toml and uv.lock; legacy configuration migration remains
before settings loading.

<details><summary><h3><a href="https://www.greptile.com/trex"><img
alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="20" align="absmiddle"></a> T-Rex Logs</h3></summary>

**What T-Rex did**
- I reproduced the patch upgrade path by installing base revision
d37b34b02f in an isolated Python 3.14
environment and verified that fcc-init --version and free-claude-code
--version reported 4.11.4 with exit code 0. After upgrading to head
revision 9a65f654f5e06c0ca96a31d3ad03db8c63d8dec7, the installed version
changed to 4.11.5 and both entrypoints disappeared, with subsequent
invocations yielding command-not-found errors (exit code 127).
- Local smoke tests and server migrations completed successfully: the
CLI local smoke test exited with code 0, the installed-entrypoints
checks passed, and the server migrated to a healthy state with the
health endpoint responding.

<a
href="https://app.greptile.com/trex/runs/15196662/artifacts"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=4"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"><img
alt="View all artifacts"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"></picture></a>

<sub><a href="https://www.greptile.com/trex"><img alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="14" align="absmiddle"></a> Ran code and verified through
T-Rex</sub>
</details>

<details open><summary><h3>Important Files Changed</h3></summary>

| Filename | Overview |
|----------|----------|
| pyproject.toml | Removes two public console commands while applying a
patch version bump. |
| src/free_claude_code/cli/commands.py | Removes template-based
initialization while preserving startup migration. |
| src/free_claude_code/cli/entrypoints.py | Removes the retired
initialization entrypoint and retains server version handling. |
| smoke/lib/child_process.py | Removes the init helper and renames the
server helper consistently. |
| scripts/install.sh | Keeps retired names in process detection for safe
upgrades. |
| scripts/uninstall.sh | Keeps retired names in removal checks for older
installations. |
| uv.lock | Tracks the patch version that must change if the command
removal remains breaking. |

</details>

<a
href="https://app.greptile.com/api/ide/codex?prompt=IMPORTANT%3A%20Work%20in%20the%20repository%20%22alishahryar1%2Ffree-claude-code%22%20on%20the%20existing%20branch%20%22remove-obsolete-cli-commands%22.%20Checkout%20that%20branch%20%E2%80%94%20do%20NOT%20create%20a%20new%20branch%20or%20open%20a%20new%20PR.%20Push%20your%20changes%20to%20%22remove-obsolete-cli-commands%22.%0A%0AFix%20the%20following%201%20code%20review%20issue.%20Work%20through%20them%20one%20at%20a%20time%2C%20proposing%20concise%20fixes.%0A%0A---%0A%0A%23%23%23%20Issue%201%20of%201%0Apyproject.toml%3A7%0A**Breaking%20Commands%20Ship%20as%20Patch**%0A%0AUpgrading%20from%204.11.4%20removes%20the%20published%20%60fcc-init%60%20and%20%60free-claude-code%60%20commands%2C%20so%20existing%20scripts%20fail%20with%20%E2%80%9Ccommand%20not%20found.%E2%80%9D%20The%20repository%20policy%20classifies%20incompatible%20CLI%20removals%20as%20major%20changes%3B%20keep%20compatibility%20aliases%20for%204.x%20or%20publish%20this%20removal%20as%205.0.0.%0A%0A&repo=alishahryar1%2Ffree-claude-code&pr=1220&platform=github"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodexDark.svg?v=6"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"><img
alt="Fix All in Codex"
src="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"></picture></a>

<sub>Reviews (1): Last reviewed commit: ["Remove obsolete CLI entry
points"](https://github.com/alishahryar1/free-claude-code/commit/9a65f654f5e06c0ca96a31d3ad03db8c63d8dec7)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=45848525)</sub>

> Greptile also left **1 inline comment** on this PR.

<!-- /greptile_comment -->
2026-07-20 21:55:49 -07:00
..

Product E2E Smoke Tests

smoke/ is local-only. It can launch subprocesses, call real providers, touch local model servers, and optionally send/delete bot messages. Hermetic contracts belong under tests/ and must stay green with plain uv run pytest.

Taxonomy

  • smoke/prereq/: liveness checks that prove the server, routes, auth, CLI scripts, provider pings, local /models, and bot permissions are reachable. These are prerequisites only.
  • smoke/product/: end-to-end product scenarios. Feature smoke coverage comes from these tests, not from route/header/provider pings.
  • smoke/features.py: source-of-truth feature map: feature -> subfeature -> scenario -> env -> expected behavior -> failure class.

Required Local Commands

uv run pytest smoke --collect-only -q
uv run pytest smoke -n 0 -s --tb=short

The second command skips everything unless FCC_LIVE_SMOKE=1 is set, but still writes skip entries to .smoke-results/.

Product Smoke Run

$env:FCC_LIVE_SMOKE = "1"
uv run pytest smoke -n 0 -s --tb=short

Provider smoke scenarios can run providers in parallel while preserving sequential execution within each provider:

$env:FCC_LIVE_SMOKE = "1"
$env:FCC_SMOKE_TARGETS = "providers"
uv run pytest smoke -n auto --dist=loadgroup -s --tb=short

Provider product E2E runs once per configured provider, independent of MODEL, MODEL_FABLE, MODEL_OPUS, MODEL_SONNET, and MODEL_HAIKU. Defaults come from the provider catalog/docs and can be overridden with FCC_SMOKE_MODEL_<PROVIDER>, for example FCC_SMOKE_MODEL_DEEPSEEK=deepseek-v4-pro (or deepseek-v4-flash). If no provider smoke model is configured, live product smoke fails as missing_env unless you explicitly set FCC_ALLOW_NO_PROVIDER_SMOKE=1.

Targets

Default targets do not send real bot messages or load voice backends:

Target Product scenarios Required environment
api messages, count_tokens full payload, errors, /stop, optimizations configured provider only for streaming messages
auth canonical bearer auth, conflicting legacy headers, invalid/missing auth none; test sets an isolated token
cli server entrypoint, Claude CLI adaptive thinking, session cleanup Claude CLI binary and provider only for real CLI
clients VS Code and JetBrains protocol payloads configured provider
config env precedence, removed-env migration, proxy/timeouts none
extensibility provider runtime and platform factory construction none
messaging fake Discord/Telegram full flow, literal clear scopes, trees, persistence, voice cancel none
providers multi-turn text, adaptive thinking history, tools, disconnect, errors configured providers, optional FCC_SMOKE_MODEL_*
tools forced tool_use and tool_result continuation tool-capable configured provider
rate_limit disconnect cleanup and follow-up request configured provider
lmstudio local /models plus OpenAI-chat-backed Messages through proxy running LM Studio server
llamacpp local /models plus OpenAI-chat-backed Messages through proxy running llama-server
ollama local /v1/models plus OpenAI-chat-backed Messages through proxy running Ollama server

Heavy/side-effectful targets are opt-in:

Target Product scenarios Required environment
nvidia_nim_cli Claude Code CLI feature matrix across NIM models NVIDIA_NIM_API_KEY, Claude CLI
openrouter_free_cli Claude Code CLI feature matrix across OpenRouter free models OPENROUTER_API_KEY, Claude CLI
telegram getMe, send, edit, delete, optional manual inbound token and chat/user ID
discord channel access, send, edit, delete, optional manual inbound token and channel ID
voice generated WAV through local Whisper or NVIDIA NIM transcription VOICE_NOTE_ENABLED=true, FCC_SMOKE_RUN_VOICE=1

Examples

$env:FCC_LIVE_SMOKE = "1"
$env:FCC_SMOKE_PROVIDER_MATRIX = "open_router,nvidia_nim,deepseek,lmstudio,llamacpp,ollama"
uv run pytest smoke/product -n 0 -s --tb=short
$env:FCC_LIVE_SMOKE = "1"
$env:FCC_SMOKE_TARGETS = "ollama"
$env:OLLAMA_BASE_URL = "http://localhost:11434"
uv run pytest smoke/prereq smoke/product -n 0 -s --tb=short
$env:FCC_LIVE_SMOKE = "1"
$env:FCC_SMOKE_TARGETS = "telegram,discord,voice"
$env:FCC_SMOKE_RUN_VOICE = "1"
uv run pytest smoke/product -n 0 -s --tb=short
$env:FCC_LIVE_SMOKE = "1"
$env:FCC_SMOKE_TARGETS = "nvidia_nim_cli"
$env:FCC_SMOKE_NIM_MODELS = "z-ai/glm-5.2,moonshotai/kimi-k2.6,minimaxai/minimax-m2.7,nvidia/nemotron-3-super-120b-a12b,deepseek-ai/deepseek-v4-pro,deepseek-ai/deepseek-v4-flash"
uv run pytest smoke/product -n 0 -s --tb=short
$env:FCC_LIVE_SMOKE = "1"
$env:FCC_SMOKE_TARGETS = "openrouter_free_cli"
$env:FCC_SMOKE_OPENROUTER_FREE_MODELS = "nvidia/nemotron-3-super-120b-a12b:free,openai/gpt-oss-120b:free,poolside/laguna-m.1:free"
uv run pytest smoke/product -n 0 -s --tb=short
$env:FCC_LIVE_SMOKE = "1"
$env:FCC_SMOKE_TARGETS = "messaging,config,extensibility"
uv run pytest smoke/product -n 0 -s --tb=short

Environment

  • FCC_ENV_FILE: explicit dotenv path for startup/config scenarios.
  • FCC_LIVE_SMOKE=1: enables live smoke execution.
  • FCC_ALLOW_NO_PROVIDER_SMOKE=1: permits no-provider live smoke for harness work.
  • FCC_SMOKE_TARGETS: comma-separated targets, or all.
  • FCC_SMOKE_PROVIDER_MATRIX: comma-separated provider prefixes to require.
  • FCC_SMOKE_MODEL_NVIDIA_NIM, FCC_SMOKE_MODEL_OPEN_ROUTER, FCC_SMOKE_MODEL_MISTRAL, FCC_SMOKE_MODEL_MISTRAL_REASONING, FCC_SMOKE_MODEL_MISTRAL_CODESTRAL, FCC_SMOKE_MODEL_DEEPSEEK, FCC_SMOKE_MODEL_KIMI, FCC_SMOKE_MODEL_KIMI_CODE, FCC_SMOKE_MODEL_WAFER, FCC_SMOKE_MODEL_MINIMAX, FCC_SMOKE_MODEL_OPENCODE, FCC_SMOKE_MODEL_OPENCODE_GO, FCC_SMOKE_MODEL_BEDROCK, FCC_SMOKE_MODEL_ZAI, FCC_SMOKE_MODEL_FIREWORKS, FCC_SMOKE_MODEL_CLOUDFLARE, FCC_SMOKE_MODEL_GEMINI, FCC_SMOKE_MODEL_GROQ, FCC_SMOKE_MODEL_CEREBRAS, FCC_SMOKE_MODEL_OLLAMA_CLOUD, FCC_SMOKE_MODEL_LMSTUDIO, FCC_SMOKE_MODEL_LLAMACPP, FCC_SMOKE_MODEL_OLLAMA: optional per-provider smoke model overrides. Values may include the provider prefix or just the model name for that provider.
  • FCC_SMOKE_MODEL_MISTRAL_REASONING: optional override for the dedicated Mistral native reasoning smoke, default mistral/mistral-medium-3-5.
  • FCC_SMOKE_NIM_MODELS: optional comma-separated NVIDIA NIM CLI matrix models that replace the default characterization set.
  • FCC_SMOKE_NIM_EXTRA_MODELS: optional comma-separated NVIDIA NIM CLI matrix models appended to the default or replacement set.
  • FCC_SMOKE_OPENROUTER_FREE_MODELS: optional comma-separated OpenRouter free CLI matrix models that replace the default characterization set.
  • FCC_SMOKE_OPENROUTER_FREE_EXTRA_MODELS: optional comma-separated OpenRouter free CLI matrix models appended to the default or replacement set.
  • FCC_SMOKE_TIMEOUT_S: per-request/subprocess timeout, default 45.
  • FCC_SMOKE_CLAUDE_BIN: Claude CLI executable name, default claude.
  • FCC_SMOKE_TELEGRAM_CHAT_ID: Telegram chat/user ID for send/edit/delete.
  • FCC_SMOKE_DISCORD_CHANNEL_ID: Discord channel ID for send/edit/delete.
  • FCC_SMOKE_INTERACTIVE=1: enables manual inbound Telegram/Discord checks.
  • FCC_SMOKE_RUN_VOICE=1: allows voice transcription backends to load/run.

Windows / nested uv run

Run smoke the same way you run tests (uv run pytest smoke from the repo). Child processes use the same Python interpreter as the test runner, not nested uv run, so Windows does not try to replace fcc-server.exe while it is locked.

Failure Classes

Smoke artifacts are written to .smoke-results/ and redact env values whose names contain KEY, TOKEN, SECRET, WEBHOOK, or AUTH.

  • missing_env: required credentials, binary, provider config, local provider server/model, or opt-in flag is absent.
  • upstream_unavailable: a real provider or bot API is not reachable.
  • probe_timeout: the smoke driver reached the target, but the CLI/probe did not complete within the smoke timeout.
  • product_failure: the app accepted the scenario but returned the wrong shape, crashed, leaked state, or violated the product contract.
  • harness_bug: the smoke test or driver made an invalid assumption.
  • target_disabled: skipped because FCC_SMOKE_TARGETS intentionally selected a different target.

product_failure and harness_bug are failures. missing_env, upstream_unavailable, and probe_timeout are skips except when the user explicitly selected a provider in FCC_SMOKE_PROVIDER_MATRIX; selected-but-missing providers fail.