Skip to content

Claude Code ​

Jue status: Read, Write, Artifact, and Confirm are all Implemented. Both project and Plugin Artifact kinds are implemented (a Marketplace aggregate index is explicitly excluded — see adapter-standardization.md); Core apply/--dry-run/--check is implemented for native project and user apply scopes; the full fixture → Canonical → Artifact → native confirmation loop (including a real headless invocation and a batch rollback) is replayable end-to-end via one command; confirm() is exported and assembled into defineExtension()/Adapter: Plugin goes through real claude plugin validate --strict; project scope honestly reports unconfirmed (an honest degradation, not a gap) since it has no equivalent native validator

Official sources: Claude Code Plugins, Plugins Reference, Skills, Sub-agents, Hooks, MCP, Memory, Headless mode

Probed against claude CLI 2.1.219 (2026-07-26).

1. Official surface ​

Claude Code supports project .claude/ configuration and distributable Plugins.

The Plugin manifest (.claude-plugin/plugin.json) is optional for --plugin-dir runtime loading: when it is omitted, Claude Code auto-discovers the default component directories by folder name and derives the Plugin name from it (the separate claude plugin validate check path instead requires a plugin.json or marketplace.json to exist — the two paths differ in strictness). A Plugin can carry skills/, commands/, agents/, hooks/ (hooks.json, shaped as {"hooks": {"<Event>": [...]}}, or inline under the manifest's hooks key), .mcp.json, .lsp.json (lspServers), workflows/, output-styles/, themes/, monitors/monitors.json, bin/, channels, and a declarative userConfig (each entry needs type/title/description, injected via ${user_config.KEY} and exported as CLAUDE_PLUGIN_OPTION_<KEY>). The manifest can also declare dependencies (an array of "<name>@<range>" strings — semver dependencies between Plugins, pulling another Artifact at install time).

The CLI lifecycle spans validate, install, enable, disable, update, list, details, init/new, uninstall/remove, prune/autoremove, tag, eval, and marketplace add/list/remove/update.

marketplace.json is a separate distribution index that can carry fields that would otherwise belong to a Plugin (for example, a Plugin without its own plugin.json can have lspServers that only exist in its marketplace entry). Reconstructing a Plugin's full fact surface on Read requires reading its marketplace entry too.

Skill, Command, and Agent components share one set of frontmatter execution fields: context: fork, agent, background, hooks, model, effort, disable-model-invocation, user-invocable, paths (path-conditional loading). These fields give a skill some agent- and hook-like behavior, making the boundary finer-grained than Jue's six atomic Capability types.

2. Intended Jue mapping ​

Canonical / FacetClaude Code
context.globalproject CLAUDE.md; user ~/.claude/CLAUDE.md
rulesproject/user .claude/rules/*.md (under the user root: ~/.claude/rules/*.md)
skills / commandsproject/user .claude/skills/*/SKILL.md and .claude/commands/*.md
agents.claude/agents/*.md (project), ~/.claude/agents/*.md (user); agents/ inside a Plugin
hooksthe hooks key in project/user .claude/settings.json, or a Plugin's hooks/hooks.json / inline manifest hooks
mcp.serversproject .mcp.json; user ~/.claude.json
target-specific settingstools.claude (lspServers, monitors, themes, output-styles, bin, workflows, channels, userConfig, dependencies)
Artifactproject-native config, or a Claude Plugin (.claude-plugin/plugin.json plus component directories, manifest optional)
Confirmclaude plugin validate <path> [--strict]; headless system/init (see §3)

3. Conversion boundary ​

  • Read must distinguish three discovery paths: .claude/ project configuration, an installed Plugin root, and in-place discovery via <skills-dir>/<name>/.claude-plugin/plugin.json (not cached, independent of plugin install).
  • A Plugin's lspServers, monitors, themes, output-styles, bin, workflows, channels, userConfig, and dependencies are Claude Code-private fields; the Adapter preserves them as-is and they never enter Canonical.
  • A Preset can materialize as a Plugin, but a Preset itself carries no Claude install state; a Plugin's dependencies (pulling another Artifact at install time) and Preset dependencies (merging assets at build time) are different semantics and are not mapped onto each other.
  • The Plugin aggregate itself (plugin.json expressing identity, version, dependencies, and component-path redirection) corresponds to Jue's Artifact, not a Capability.
  • Plugin scope, dependencies, cache, and permissions are Artifact install constraints, not Capability.
  • Scope precedence: Skill/Agent is managed/enterprise > user > project; Rule is project > user (CLAUDE.local.md is a local override); Settings is managed > CLI > local > project > user (the permissions key merges rather than overrides). MCP's local scope is written to ~/.claude.json, not .claude/settings.local.json. Jue project apply writes .mcp.json and user apply writes ~/.claude.json. A server with no scope inherits the apply scope; an explicit mismatch or local fails before writing.

Headless native confirmation path ​

bash
claude -p "<deterministic task>" --plugin-dir <path> \
  --output-format stream-json --verbose \
  --tools "" --setting-sources ""

The first system/init event reports the full plugins, plugin_errors, skills, slash_commands, agents, and mcp_servers (with status) inventory; this path is also the evidence that manifest-optional runtime auto-discovery actually works (a manifest-less directory shows up in plugins as <dir>@inline). Do not add --bare: it silently drops a Plugin's agents and mcp_servers from the inventory, leaving only built-ins. claude plugin list/claude plugin details only confirm already-installed Plugins and do not accept --plugin-dir.

--tools "" does not guarantee zero cost: it only makes tools unavailable for the turn, and if the prompt does not require a tool the model still generates a normal reply and is billed for real (verified: the same command above produced total_cost_usd: 0.0394407). Making a call actually free requires a prompt that structurally depends on a now-unavailable tool; --tools "" alone does not make the CLI short-circuit before invoking the model. Confirm the prompt is genuinely free (or budget-approved) before using this path for native verification.

--bare authentication strictly requires ANTHROPIC_API_KEY or an apiKeyHelper via --settings (it never reads OAuth/keychain), and does not isolate the Plugin surface from whatever else is installed on the machine (the plugins inventory lists the fixture alongside every other real Plugin already present). plugin_errors is absent from system/init entirely when nothing failed to load — not an empty array. Reproducible evidence lives in packages/ai-jue-adapter-claude/fixtures/README.md's "native usability verification" section and the repo-root scripts/verify-claude-native.js. The same fixture → Canonical → Artifact → native confirmation chain replays as one command runnable from a clean environment via scripts/verify-claude-mvp-gate.js — see that README's "Claude MVP Gate" section.

4. Current gaps ​

LevelStatusGap
ReadImplementedpackages/ai-jue-adapter-claude/src/read.ts
WriteImplementedpackages/ai-jue-adapter-claude/src/write.ts, driven by the Core executor
ArtifactImplementedBoth project and Plugin are implemented; a Marketplace aggregate index is explicitly excluded (not a gap)
ConfirmImplementedconfirm() is exported and assembled into defineExtension()/Adapter; Plugin goes through real plugin validate --strict (headless evidence); project scope honestly reports unconfirmed (an honest degradation, not a gap)

Define once. Adapt everywhere.