cd /news/ai-tools/command-code-1-58-0-taken-apart-the-… · home topics ai-tools article
[ARTICLE · art-134712] src=gist.github.com ↗ pub= topic=ai-tools verified=true sentiment=↓ negative

Command Code 1.58.0 taken apart: the taste subsystem end to end, every system prompt, tools, wire protocol, telemetry

A developer's teardown of the command-code@1.58.0 npm package found that its marketed "taste-1" feature is not a "meta neuro-symbolic AI model with continuous reinforcement learning" but a prompt sent to whichever ordinary model the user has selected, with output written to a markdown file prepended to later prompts. The analysis of dist/cli.mjs also found taste learning defaults to on, mines up to 200 git commits without applying the package's own secret-filename filter, and uploads code to vendor servers for processing despite in-product privacy text saying learning data is stored locally.

by read25 min views1 publishedSep 19, 2026

Everything recovered from reading the published command-code npm package: the taste subsystem end to end, every system prompt, the tool catalogue, the wire protocol, the model catalogue, and the telemetry.

Read as shipped on 19 September 2026, pinned to one version. Later releases may differ.

| package | command-code@1.58.0 | | file | dist/cli.mjs , 2,635,431 bytes | | sha256 | aab2bec800371953112d18472bb7383992ef264cca22558bdcda77e7d0dc0f14 |

Line numbers below refer to dist/cli.mjs after npx prettier --parser babel, which produces 115,067 lines. See reproducing this.

  1. taste-1 is marketed as a "meta neuro-symbolic AI model with continuous reinforcement learning." No such model exists in the package. Taste is a prompt sent to whichever ordinary model you have selected, and the output is a markdown file that gets prepended to later prompts.
  2. Taste feeds on three sources: your git history, your live conversation, and your saved transcripts from Claude Code, Codex and Cursor.
  3. The git path mines up to 200 commits and applies no secret-filename filter, although the package ships one and uses it in six other places. See below .
  4. Taste learning defaults to on.
  5. The in-product privacy text says taste "stores learning data in your project and on your local machine only." Storage is local. Processing happens on the vendor's servers and your code is uploaded to reach it.

From commandcode.ai/docs/taste, archived 2026-09-07, 2026-03-13, 2025-12-09:

Taste is powered by our meta neuro-symbolic AI model taste-1 with continuous reinforcement learning (RL). We combine reasoning with neural intuition to create an invisible architecture of your choices, structures, patterns and tooling preferences.

Bullets on the same page: "Meta Neuro-Symbolic AI model taste-1 enforces the invisible logic of your choices" and "Reflective Context Engineering of a self-aware RL feedback loop to build skills." The page embeds an architecture diagram at /docs/mns.png whose alt text is meta neuro-symbolic ai model taste-1.

The string taste-1 occurs five times in the shipped bundle, across four locations:

Location Line Kind
FAQ string (twice in one string) 9371 marketing copy
/taste help text 64741 marketing copy
billing text 64749 pricing label
TUI status bar 97801 UI string literal

There is no model ID, routing entry or catalogue record named taste-1. The same bundle carries about eighty real model IDs with context windows and provider routing. The runtime occurrence is:

y = Boolean(o && byokProviderId({ model: o })) ? "" : " · taste-1",

The badge is appended when you are not using your own API key. Supply your own provider key and it disappears while taste behaves identically.

The billing text at line 64749 reads: "Premium requests: Any request that uses a premium model (like taste-1) during your coding session." Calling it a premium model is what sets the rate.

runTasteLearningAgent (55352), extractAllSignals (55392), compileTasteContext (55686).

git show --format= -U3 --diff-algorithm=histogram -b --ignore-blank-lines -M <hash>

Caps recovered from the constants:

Constant Value Meaning
maxCommits 200 commits cloned and scanned
Bx 50 maximum signals extracted
Wx 50 maximum commits with usable diffs
Hx 10 commit batch size
Gx 5 diff concurrency
Vx 5 grouped patterns kept per commit
zx 200 maximum lines per side of a hunk
Jx /Yx 3 / 5 snippet line budget

Each surviving hunk goes through buildSnippet2 (55612), which emits your source verbatim:

Snippet:
  <context line, indented two spaces>
→ <changed line, verbatim>
  <context line, indented two spaces>

compileTasteContext concatenates these under two headings, quoted verbatim:

## Correction Diffs — What Wrong→Right Looks Like

It appends the instruction block quoted below and posts the result to https://api.commandcode.ai/alpha/generate.

It also accepts a GitHub URL or owner/repo and will git clone --depth 200 --single-branch a public repository to mine it.

The package ships a sensitive-filename denylist (68900):

.env   .env.*   *.pem   *.key   *.crt   .npmrc   .pypirc   .netrc
id_rsa   id_rsa.*   id_ed25519   id_ed25519.*   id_ecdsa   id_ecdsa.*
credentials   credentials.*

hasSensitiveBasename() consumes that list at six call sites:

Line Call site
17640 isGuardedWritePath , tool write guarding
17728 path-safety set
17773 path-safety check
74588 telemetry file list filter
74600 IDE active-file filter
74606 IDE file list filter

The taste extractor is not among them. The only filter applied while mining diffs is isNoiseFile (called once, at 55556; list at 77172):

package-lock.json   pnpm-lock.yaml   yarn.lock   CHANGELOG.*
.versionbot/   *.min.js   *.min.css   dist/   *.map

That is a relevance filter, which excludes lockfiles and build output because they make poor style signals. It excludes no secret-bearing filename.

Two details make this worse than a missing check on the working tree:

  1. Taste reads history, not HEAD. It runsgit show across up to 200 commits. A.env or private key that was committed once and deleted later is still inside that range. Removing a secret from the current tree does not remove it from what taste reads.
  2. .gitignore is irrelevant here. Ignoring a file today does nothing about the commit that added it before it was ignored, which is the common way secrets enter a repository at all.

So a repository that ever committed a .env, *.pem, id_rsa or credentials file will have those hunks extracted verbatim by buildSnippet2 and uploaded to api.commandcode.ai with everything else, on a feature that is enabled by default.

The filter is applied to six paths and missing from the one path that ships historical file contents off the machine.

createLearner / runLearningLoop (72820 onward), system prompt mS at 72872.

Your conversation messages are JSON-serialized and sent to the model:

`Current taste structure:\n${m}\n\n` +
`Previously analyzed conversation (context only — already processed in earlier passes, ` +
`do NOT learn from it again):\n${JSON.stringify(k, null, 2)}\n\n` +
`NEW messages to analyze (learn ONLY from these):\n${JSON.stringify(C, null, 2)}`

stripInjectedMetaForLearning and stripReasoningPartsForLearning remove injected metadata and reasoning blocks first. The loop runs up to dS = 20 model turns, with a window of uS = 20 messages, calling read_taste_file, write_taste_file and edit_taste_file to write results.

The model reaches this path through the taste tool, described to the model at 20801 as:

Record or update the user's coding preferences and taste. Use this whenever the user states a preference or asks you to remember something.

The base system prompt instructs the model to call it (73838):

TO RECORD OR UPDATE A PREFERENCE, USE THE taste TOOL: When the user states a preference or asks you to remember/save something ("prefer X over Y", "always do Z", "save this to my taste"), call the taste tool with the instruction in the user's words.

The model decides when your conversation gets mined during a normal session.

createSessionImporter (40333), agent table uC:

[ { agent: "claude-code", find: findClaudeCodeSessions, extract: extractClaudeCodePrompts },
  { agent: "codex",       find: findCodexSessions,      extract: extractCodexPrompts },
  { agent: "cursor",      find: findCursorSessions,     extract: extractCursorPrompts } ]

Locations read from disk:

Agent Path
Claude Code ~/.claude/projects/<encoded-project-dir>/*.jsonl
Codex ~/.codex/sessions/** rollout files
Cursor Cursor transcripts directory, <id>/<id>.jsonl

extractClaudeCodePrompts pulls every entry with type === "user" and a string message.content, which is your prompt text. The same shape applies to the Codex and Cursor extractors. The prompts are batched by splitPromptsIntoLearnBatches and each batch is sent through learn() to /alpha/generate.

The UI string for this, at 64521, is:

Learn taste from sessions with other coding agents (Claude Code, Cursor, etc)

and at 86541:

Learn from your previous sessions - updates your taste profile

Command Code reads your saved conversations with competing coding agents and uploads them to its own API.

Location Contents
.commandcode/taste/taste.md project taste, category headings, bullets with confidence scores
.commandcode/taste/<category>/taste.md a category once it exceeds 5 learnings
~/.commandcode/taste/ global taste, -g flag
commandcode.ai/<username>/taste remote taste packages, npx taste push

Remote package upload is a multipart POST built by prepareUpload (56570), with fields name, description, type, isPublic, overwrite and file parts files[taste.md] and files[<category>/taste.md]. Endpoints: /beta/taste/packages/:namespace and /alpha/taste/:projectSlug.

Taste reaches the model through the system prompt rather than the request body. The taste field in the /alpha/generate body is always null on the model-client path; the content is injected by renderTasteSection2 into the cached system section instead.

getTasteLearningSettings (19650 onward):

const s = n.tasteLearning ?? !0,          // global default: ON
      i = resolveProjectOverride(r, o),
      a = i?.value;
return { global: s, project: a, effective: a ?? s };

Taste learning is on unless turned off. Controls:

Control Effect
/taste in session, orcmd taste disable toggle taste learning
tasteLearning: false in~/.commandcode/config.json global off
project shared or local settings per-project override
DO_NOT_TRACK=1 disables telemetry and fingerprinting, not taste
CMD_ZDR zero data retention header, s title generation and taste onboarding

The onboarding scan is gated behind checkOnboardingConditions and presents a banner with a skip option, so the transcript import is offered rather than silent. Taking no action leaves it enabled.

Line 55706. ${a} interpolates for <author> when an author is targeted.

## Instructions for Taste Learning

You are analyzing code change patterns from a real repository${a}. Based on the correction diffs above, generate deeply personal and opinionated coding taste.

**Critical guidelines:**

1. **Be specific, not generic.** Instead of "Use TypeScript", write "Use branded types for IDs and explicit return types on every function. Prefer `readonly` arrays and objects by default."

2. **Extract the WHY from patterns.** If you see verbose names being replaced with concise ones, don't just say "use short names" — say "Prefer concise variable names that derive meaning from context rather than encoding type information."

3. **Look for recurring themes.** If multiple substitutions show the same pattern (e.g., nested if→guard clauses), that's a strong taste signal worth capturing.

4. **Make it actionable.** Every taste entry should be specific enough that another developer could follow it and produce code that looks like it belongs in this repository.

5. **Prioritize quality corrections** — these are the purest taste signals (wrong→right pairs with explicit WHY context from commit messages).

6. **Capture anti-patterns too.** If you see code being removed in refactors, note what the developer avoids: "Never nest deeper than 2 levels — flatten with early returns."

7. **Don't repeat generic tool preferences** like "Use pnpm" or "Use TypeScript" unless the substitutions show something specific about HOW they use those tools.

8. **Prioritize opinionated preferences.** The goal is taste that makes someone's code distinctly theirs — not industry best practices.

Write the taste entries to the taste.md file using the standard format with confidence scores.

Header prepended to the diffs, line 55692:


Repository: ${n}
${s}Commits analyzed: ${o}
Signals extracted: ${t.length}

This analysis was generated by examining actual code changes (diffs, substitutions, refactoring patterns) rather than static file contents. Every signal below comes from real commits.

Line 72872, used as the system parameter.

You are the taste-learning agent for Command Code. Review the NEW messages and the user's current taste files, then record DURABLE, generalizable preferences the user revealed — coding style, tooling, workflow, and communication preferences — not one-off task details.

Learn ONLY from the NEW messages. The previously analyzed conversation was already mined by earlier passes — it is provided so you can resolve references, never to be re-learned. Do NOT re-record a preference that already exists in the taste files, and do NOT raise or lower an existing learning's confidence unless the NEW messages themselves contain fresh evidence for it. Seeing the same preference again in the previously analyzed context is not evidence.

Use the tools to update taste files. A taste file path MUST be either "taste.md" (the root file) or "{category}/taste.md" (a single category folder) — never any other name or nesting:
- write_taste_file to create/replace a file.
- edit_taste_file to amend an existing file.
- read_taste_file to inspect a file before editing.

Record each learning as a markdown bullet ending in a confidence score, e.g.
  - Prefers tabs over spaces. Confidence: 0.9
Only record clear, repeated, or explicitly-stated preferences. Prefer amending existing files over creating near-duplicates. When the new messages reveal nothing durable, make no tool calls and reply "no changes".

Line 73841, injected into the system prompt of every session that has taste enabled.

<taste_guidance>
IMPORTANT - Taste System (Learned Preferences):

WHAT IS TASTE:
Taste is a system of continuously learned preferences that captures how the user wants code written in this specific project. These preferences are learned automatically from past interactions and corrections, covering areas like:
- Technology choices (e.g., "Use TypeScript", "Use Commander.js for CLIs")
- Code style (e.g., "Use const instead of let", "Use object parameters for functions with 2+ params")
- Workflow patterns (e.g., "Always run tests before committing")
- Project-specific conventions

WHERE TASTE IS STORED:
All taste preferences are stored in the .commandcode/taste/ directory in the project root:
- Main file: .commandcode/taste/taste.md - Contains all learnings organized by category headings (# Category Name)
- Category files: .commandcode/taste/{category}/taste.md - When a category grows beyond 5 learnings, it's moved to its own subdirectory

HOW TASTE IS ORGANIZED:
The main taste.md file contains category sections with H1 headings (# Category Name). Each category can be in two states:

1. INLINE (≤5 learnings): Category heading followed by bullet points with learnings
   Example:
   - Use const instead of let for non-reassigned variables. Confidence: 0.90
   - Use object parameters for functions with 2+ params. Confidence: 0.85

2. REFERENCED (>5 learnings): Category heading with a reference link to category file
   Example:
   See [cli/taste.md](./cli/taste.md)

WHY TASTE MATTERS:
These preferences represent the user's actual requirements learned from real interactions. When a user corrects you (e.g., "use TypeScript not JavaScript", "use Commander.js for CLIs"), that correction is captured as taste. Following taste prevents you from making the same mistakes repeatedly and ensures consistency across the project.

HOW TO USE TASTE:
1. Your learned preferences are provided in the <taste> section below
2. BEFORE starting ANY work, carefully read the taste content
3. If you see a category reference like "See [category/taste.md]", you MUST use read_file to read .commandcode/taste/{category}/taste.md to get the full preferences
4. Apply ALL relevant preferences to your work - these are REQUIREMENTS, not suggestions
5. If working on a specific domain (e.g., CLI, TypeScript, testing), check if there's a category for it and read the full preferences
6. Taste preferences override general best practices - if taste says "Use X", you use X even if you would normally prefer Y

CRITICAL RULES:
- When you see "See [cli/taste.md]" for a CLI task, IMMEDIATELY read .commandcode/taste/cli/taste.md before writing any code
- NEVER ignore taste preferences - they represent explicit user requirements
- If a taste preference conflicts with the user's current request, follow the current request (it may be updating the preference)
- The same applies to any other domain-specific category - ALWAYS read referenced taste files before starting work in that domain
- **NEVER EDIT OR WRITE TO TASTE FILES**: Do not use edit_file or write_file on any files in .commandcode/taste/ or ~/.commandcode/taste/. These files are managed automatically by the learning system. You can READ them, but never modify them.
</taste_guidance>

Line 35886, populated, and 35887, empty.

<taste>
Below is the complete content of the .commandcode/taste/taste.md file.
This shows you what preferences are available and which categories might have additional details in separate files.
If you see references like "See [category/taste.md]", you MUST read that file using read_file to get the full preferences.

--- Content of .commandcode/taste/taste.md ---

${t}

--- End of .commandcode/taste/taste.md ---
</taste>
<taste>
No preferences learned yet for this project. The .commandcode/taste/taste.md file is empty or doesn't exist yet. Preferences will be learned automatically as you work.
</taste>

Line 20801, with its one parameter at 20808.

Record or update the user's coding preferences and taste. Use this whenever the user states a preference or asks you to remember something.
The preference or taste change to record, in the user's words.

Line 64741, the text behind /taste.

Taste is powered by the meta neuro-symbolic AI model taste-1 with continuous reinforcement learning (RL). It combines reasoning with neural intuition to learn your coding preferences.

How taste works:
- Learns from you — every accept, reject, and edit becomes a signal
- Thinks like you — learns patterns and micro-decisions you'd never document
- Grows with you — continuous learning loop that never goes stale

Enable taste: Use /taste in a session or run npx taste from the command line.

Taste packages (three types):
- Project: Stored in .commandcode/taste/ — learnings unique to this codebase
- Global: Stored in ~/.commandcode/taste/ — personal taste across all projects (use -g flag)
- Remote: Stored at commandcode.ai/username/taste — team sharing, backup, sync across machines

Privacy: Taste processing runs on your codebase and stores learning data locally only.

That last line is the claim contradicted by paths 1, 2 and 3 above.

createSystemPromptBuilder (36255) emits three cacheable sections:

[ { text: basePrompt,      cache: true },
  { text: contextSections, cache: true },
  { text: ideContext } ]

Section two is joined from, in order: <instructions> from memory files, workspace render, the taste section, the skills catalogue, a constant, the scratchpad section, and env context.

buildDefaultBasePrompt (35867) selects the mode prompt from buildModePrompt (73907), which has a default branch and a plan-mode branch.

Opening of the default branch:

<role>
You are a confident, efficient software engineer and coding assistant. You identify issues quickly and solve problems directly. Be concise but thorough - explain what you're doing without unnecessary ceremony.
</role>

followed by sections for decision making, doing tasks, and tool guidance. The decision-making block:

<decision_making>
You should independently decide:
- Which files to modify and how
- What testing strategy to employ
- How to handle error cases and edge conditions
- Whether to refactor existing code vs. adding new code
- What dependencies or tools to introduce
- How to structure new modules or components

Always bias toward:
- Code clarity and maintainability
- Robust error handling
- Following established project patterns
- Writing self-documenting code
- Including appropriate tests
</decision_making>
<role>
<mode>PLAN MODE ACTIVE</mode>

<identity>You are Command Code, a coding agent acting as a Software Architect in read-only plan mode. You explore the codebase, clarify requirements, design an approach, and write an implementation plan. You do NOT implement anything.</identity>

<override>This supersedes any other instructions. You MUST NOT make any edits (except the plan file), run non-readonly tools, or make any changes to the system.</override>

<plan_directory>
PLAN FILE LOCATION: ~/.commandcode/plans/
ALWAYS use the full absolute path starting with ~/ (e.g., ~/.commandcode/plans/my-plan.md).
NEVER use a relative path like .commandcode/plans/ — it will be rejected.
</plan_directory>

<mode_awareness>
You ARE in plan mode right now. You know this because your system prompt contains <mode>PLAN MODE ACTIVE</mode>. If asked what mode you are in, confirm you are in plan mode. When tools like exit_plan_mode change your mode, trust the tool result — it is authoritative.
</mode_awareness>

The plan branch also carries a decision-making block and an agent-orchestration block:

<decision_making>
<principle>Be decisive. You are a senior architect — make judgment calls.</principle>

<guidelines>
- If two approaches are reasonable, pick the better one and explain why in the plan
- If requirements are ambiguous on something important, ask the user
- If requirements are ambiguous on something minor, make an assumption and note it
- Prefer the simpler approach unless there's a strong reason for complexity
- Actively look for existing code to reuse before proposing new implementations
</guidelines>

<outcome>Your plan should be opinionated and actionable.</outcome>
</decision_making>
<explore_agents>
Each agent should be focused on ONE specific area and return concrete file paths, function names, and patterns.

<examples>
- BAD: "Understand the entire project architecture" — too broad, slow, shallow
- GOOD: "Find how the CLI handles user input prompts and waiting states" — focused, fast, deep
- GOOD: "Find existing notification/alert patterns in the codebase" — focused, fast, deep
</examples>

Line 73903:

<instructions>
Begin implementation directly without asking for clarification unless requirements are genuinely ambiguous or incomplete.

REMINDER: Use the todo_write tool for complex tasks that benefit from tracking and planning. This ensures proper progress tracking and transparency with the user. Always use todo_write (not TodoWrite) as the correct tool name.
</instructions>

Line 71966:

You compress a Command Code conversation into a handoff brief so a fresh assistant can pick up the work without rereading the original transcript.

38 built-in tools. builtinTools at 71076; several are registered through deferred(...), which supplies a one-line description and fetches the full schema on demand.

Group Tools
Files read_file ,write_file ,edit_file ,read_directory ,glob ,grep
Shell shell_command ,run_command ,powershell ,shell_output ,shell_tasks ,kill_shell
Agents agent ,task ,agent_output ,task_create ,task_update ,task_list ,task_get ,task_stop ,task_output
Planning todo_write ,exit_plan_mode ,plan_review
Web web_search ,web_fetch (server-side, metered)
Skills activate_skill ,search_tools /tool_search
Taste taste ,read_taste_file ,write_taste_file ,edit_taste_file
Other vision ,ask_user_question ,monitor_command ,monitor_events ,schedule_wakeup ,cron_create ,cron_delete

Tools serialize as {name, description, input_schema}. tool_search is renamed to search_tools in transit by toWireToolName (37569). defangMonitorOutput wraps monitor output in an UNTRUSTED_MONITOR_OUTPUT marker. Writes into the taste directory are denied by isTasteDirWrite.

Seven Agent Skills ship as markdown under dist/bundled/: agent-browser, command-code-knowledge, config, design, loop, mod-builder, skill-builder.

resolveApiBaseUrl (2632), table at 62528.

Env URL
prod https://api.commandcode.ai
staging https://staging-api.commandcode.ai
local http://localhost:9090

Selection: --local / --staging argv, then COMMANDCODE_API_ENV, else prod. COMMANDCODE_API_URL overrides everything only when COMMANDCODE_SANDBOX=true, which is the supported way to point the client at your own server.

One opaque bearer token with a user_ prefix, in ~/.commandcode/auth.json, mode 0600. The token carries no expiry and the client performs no refresh, request signing or proof of work. Validated against GET /alpha/whoami.

Constants at 72706.

Header Required
Authorization: Bearer user_… yes
Content-Type: application/json yes
x-command-code-version yes on /alpha/generate
x-cli-environment ,x-session-id ,x-project-slug ,x-taste-learning ,x-oss-primary-provider ,traceparent ,User-Agent no
x-cmd-zdr: 1 whenCMD_ZDR is set no
x-cmd-provider-deepseek-internal: 1 whenCMD_PROVIDER_DEEPSEEK_INTERNAL=1 no
x-oauth-token /x-oauth-provider no

Omitting x-command-code-version, or sending an unparseable value, returns 403 "Your Command Code CLI is out of date." Tested live: 1.58.0, 1.57.0, 1.0.0 and 99.0.0 all pass, garbage and absence both fail. The gate checks that the header is present and version-shaped, not that it is recent.

Endpoint Purpose
/alpha/whoami validate key, identity
/alpha/generate inference, streaming
/alpha/agent/generate sub-agent generation
/alpha/learn taste learning
/alpha/taste/:projectSlug (+/update ) remote taste
/beta/taste/packages/… taste package registry
/alpha/web-search ,/alpha/web-fetch server-side tools, metered
/alpha/billing/credits ,/alpha/billing/subscriptions ,/alpha/usage/summary billing
/alpha/fingerprint/record machine fingerprint
/alpha/lifecycle-events telemetry
/alpha/sandbox/start ,/alpha/sandbox/stream remote sandbox
/alpha/share/{create,append,delete} session sharing

Built at 37946. Every config field is required; the server returns full zod paths on a bad body.

{
  "config": {
    "workingDir": "/abs/path", "date": "2026-09-19", "environment": "cli",
    "structure": [], "isGitRepo": false,
    "currentBranch": "", "mainBranch": "", "gitStatus": "", "recentCommits": []
  },
  "memory": null, "taste": null, "skills": null,
  "permissionMode": "standard",            // standard | auto-accept | plan
  "threadId": "<uuid, optional>",
  "mode": "agent",                         // optional, enum-validated when present:
                                           // agent|learning|custom-agent|custom-agent-create
                                           // |title-gen|tool-desc|compact|vision
  "promptCache": true,
  "params": {
    "model": "deepseek/deepseek-v4-pro",
    "messages": [ /* Vercel AI SDK ModelMessage */ ],
    "tools":   [ { "name", "description", "input_schema" } ],   // Anthropic shape
    "system":  [ { "type":"text", "text":"…",
                   "cache_control": {"type":"ephemeral"} } ],   // Anthropic blocks
    "max_tokens": 64000, "stream": true,
    "temperature": 0.0,                    // optional
    "reasoning_effort": "high"             // optional
  }
}

The dialect is mixed: messages follow the Vercel AI SDK, while tools and system follow Anthropic. toWireMessages (37572) maps tool_use to {type:"tool-call", toolCallId, toolName, input}, tool_result into a separate role:"tool" message, thinking to reasoning, and images to data: URLs.

NDJSON, one JSON object per line, with no data: prefix and no [DONE] terminator. Consumed by consumeStream (37731).

type Payload
text-delta {text}
reasoning-start /reasoning-delta /reasoning-end {text} on delta
tool-call {toolCallId, toolName, input, providerExecuted?}
tool-result {toolCallId, toolName, output, isError?}
provider-metadata {providerMetadata:{anthropic:{usage:{cache_creation:…}}}}
finish {finishReason, rawFinishReason, totalUsage:{…}, systemPromptTokens}
error {error: string | {message, statusCode, isRetryable}}
abort none

A stream that ends with no finish event is treated as truncated and raises a retryable 502. rawFinishReason === "_turn" makes the client re-issue and continue.

About eighty models, all routed through /alpha/generate. Upstream routing shows in ID prefixes such as baseten:, novita:, anthropic: and openai:. The service resells Baseten, Novita and first-party APIs.

Family Examples
DeepSeek deepseek/deepseek-v4-pro ,-v4-flash ,-v4-flash-fast ,-v4-flash-vision-exp ,-v4.1-flash
Moonshot moonshotai/Kimi-K3 ,Kimi-K2.7-Code ,-Code-Highspeed ,Kimi-K2.6 ,Kimi-K2.5
Z.ai zai-org/GLM-5.3 ,GLM-5.2 ,GLM-5.2-Fast ,GLM-5.1 ,GLM-5
MiniMax MiniMaxAI/MiniMax-M3 ,-M2.7 ,-M2.5
Qwen Qwen/Qwen3.8-Max ,3.8-Flash ,3.8-27B ,3.8-Omni-Flash ,3.7-* ,3.6-*
OpenAI gpt-6-astra ,gpt-5.6-{luna,sol,terra} ,gpt-5.5 ,gpt-5.4 ,gpt-5.3-codex
Anthropic claude-opus-5 ,claude-sonnet-5 ,claude-fable-5 ,claude-opus-4-8/4-7/4-6 ,claude-haiku-4-5
google/gemini-3.8-flash down togemini-3.1-flash-lite
xAI xai/grok-4.6 ,grok-4.5
Other meta/muse-spark-1.* ,tencent/Hy3 ,stepfun/Step-3.7-Flash ,xiaomi/mimo-v2.5 ,nvidia/nemotron-3-ultra-550b-a55b ,sakana/fugu-ultra ,thinkingmachines/inkling ,meituan/LongCat-2.0 ,poolside/laguna-s-2.1

Eight models carry badge: "free", most with hidden: true. All of them return 403 "the free … tier has been retired" when called.

Background requests billed to the user, on fixed models (63536):

Feature Model
title generation deepseek/deepseek-v4-flash
compaction deepseek/deepseek-v4.1-flash
tool descriptions deepseek/deepseek-v4-flash
taste onboarding deepseek/deepseek-v4-flash
branch summarization deepseek/deepseek-v4-pro
vision xiaomi/mimo-v2.5

applyPremiumCreditsFallback silently switches to moonshotai/Kimi-K2.5 when premium requests run out, with the message "Auto switched model to Kimi K2. Plan Premium requests used."

gatherRawSignals / buildMachineFingerprint / recordCliFingerprint (44694 to 44836). Runs once per process in the background, POST /alpha/fingerprint/record, only when an auth key exists.

Salted SHA-256 of: /etc/machine-id or /var/lib/dbus/machine-id, every MAC address, OS username, hostname, and git email.

Plaintext: platform, arch, osRelease, cpuModel, cpuCount, memGiB, isContainer, timezone.

A stable thumbmark derives from machine ID plus sorted MACs, falling back to hostname plus CPU model.

The salt is a constant shipped in the package:

Fb = "command-code:device-fingerprint:v1"

function hashSignal(e) {
  const t = e.trim();
  if (t) return E("sha256").update(Fb).update("\0").update(t.toLowerCase()).digest("hex");
}

Because the salt is published, testing a candidate value against an observed hash costs one sha256 call. A git email is guessable and a MAC address space is enumerable, so the hashing pseudonymizes these values against a casual reader rather than against anyone holding the package.

Disable with DO_NOT_TRACK=1 or "telemetry": false in ~/.commandcode/config.json.

The published package also hardcodes (62785) three Axiom ingest tokens for the command_code_cli_tracing dataset at https://api.axiom.co/v1/traces, and an OTLP token for https://ingestion.claicode.com/v1/inference-events. A redaction list strips apikey, api_key, token, secret and authorization from span attributes. The token values are in the public package and are deliberately not reproduced here.

~/.commandcode/:

File Mode Contents
auth.json 0600 vendor user_ API key and user ID
credentials.json 0600 BYOK provider keys and OAuth tokens
providers.json 0644 custom provider declarations
config.json global config, telemetry ,tasteLearning
settings.json ,settings.local.json settings and hooks
mcp.json ,projects/*/mcp.json MCP servers
keybindings.json key rebinding
plans/ ,skills/ ,taste/ plan output, user skills, global taste
telemetry-install-id install UUID

providers.json accepts an arbitrary baseURL in three dialects, openai-completions (default), openai-responses and anthropic-messages, so the whole CLI runs against any endpoint with no patching:

{ "provider": { "mine": {
    "api": "openai-completions",
    "baseURL": "http://localhost:8080/v1",
    "apiKey": "$MY_KEY",
    "models": { "some-model": { "contextWindow": 200000 } } } } }

The parser rejects literal secrets in providers.json and accepts only "$ENV_VAR", "{env:VAR}" or "!command" references. npm: provider packages are not loaded.

npm pack command-code@1.58.0

curl -s https://unpkg.com/command-code@1.58.0/dist/cli.mjs | shasum -a 256

npx prettier --parser babel cli.mjs > cli.pretty.mjs    # 115,067 lines

Greps that land on the claims above:

grep -n 'taste-1' cli.pretty.mjs                          # 4 locations, 0 model ids
grep -n 'runTasteLearningAgent' cli.pretty.mjs            # git history path
grep -n 'Instructions for Taste Learning' cli.pretty.mjs  # the mining prompt
grep -n 'taste-learning agent for Command Code' cli.pretty.mjs  # conversation path
grep -n 'findClaudeCodeSessions\|findCodexSessions\|findCursorSessions' cli.pretty.mjs
grep -n 'hasSensitiveBasename' cli.pretty.mjs             # 6 sites, none in taste
grep -n 'isNoiseFile' cli.pretty.mjs                      # the only taste filter
grep -n 'tasteLearning ?? !0' cli.pretty.mjs              # default on
grep -n 'buildMachineFingerprint' cli.pretty.mjs

Quotations from vendor material are reproduced for identification and commentary. Archive links are given so the originals can be read in full.

This documents what the package does. Whether the gap between the marketing and the implementation is deliberate is not something a bundle read can establish, so this sticks to what the code shows.

Corrections welcome. Anything here that a counter-grep contradicts gets fixed.

Shorter writeup focused on taste-1 alone: https://gist.github.com/safzanpirani/5bd7a77ce304edb16f768982bb26bcc0

── more in #ai-tools 4 stories · sorted by recency
── more on @command-code 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/command-code-1-58-0-…] indexed:0 read:25min 2026-09-19 ·