fluree-cli plugin: probe-first CLI companion with a manifest-checked contract - #1
Merged
Conversation
…cked contract New plugin teaching Claude Code to drive the fluree CLI: - skill (auto-triggering): probe-first doctrine (the binary's embedded docs are the reference; the skill deliberately carries almost no command reference so it cannot rot), destructive-op + credential + import-budget safety rails, machine-output map, Fluree AI remote choreography (device-code login the human approves at /activate). references/: workflows, remote-fluree-ai, policy correlation, troubleshooting (server-routed vs --direct divergences). - /fluree-cli:setup command: binary check/install pointers, >=4.1.3 version gate, docs-access verification, duplicate-MCP cleanup, .fluree/ gitignore hygiene. - .mcp.json: auto-connects 'fluree mcp serve --toolsets docs' (docs_search/get/examples/tree, version-exact; degrades gracefully when the binary is absent). - contract/cli-facts.json: every command path/flag the plugin's text hard-codes, validated by scripts/check-cli-contract.mjs against the fluree-cli-manifest.json release asset (fluree/db#1571). Verified against a locally built manifest: 42 commands OK — and the checker's first run caught a real error (list has no --json), already fixed. - CI: claude plugin validate --strict on every plugin, marketplace<-> plugin version-sync check, and the contract check (skips with a notice until the first fluree/db release ships the manifest asset). Marketplace entry + README row included.
aaj3f
added a commit
that referenced
this pull request
Jul 30, 2026
Response to independent review of #1; every finding verified before fixing. The three text blockers were all real against v4.1.4, the latest installable release: - SKILL.md credential rail was INVERTED: it said config list redacts on 'current versions' when redaction ships only in the first release after fluree/db#1571 — an agent on 4.1.4 would have blessed a command that dumps auth.token AND refresh_token in plaintext. Rewritten to be safe on binaries that exist: treat config list output as secret through v4.1.4; verify --reveal exists before assuming redaction. - workflows.md taught 'branch diff main dev', which does not parse (one positional + --target, defaulting to the source's parent). - The 'start here' pointer to docs get ai/claude-code is now hedged the same way the manifest pointer already was (page ships after #1571), and 'supersedes' narrowed to command-surface authority. Floor moves to 4.1.4 in lockstep with the paired solo review (auth token does not exist at 4.1.3) — SKILL, setup, README, cli-facts. CI honesty (the job could report green while running nothing): - 404 is the only skip; every other curl outcome is now ::error + fail. The skip is a ::warning with an owner and expiry (issue #2 filed). - Marketplace root now validated (the per-plugin loop never saw it); claude-code npm install pinned (2.1.220); .mcp.json syntax-checked in CI (validate --strict provably ignores it) and its nonstandard description key dropped. Checker soundness: - exit 2 (not a stack trace masquerading as 'contract violated') for unreadable/malformed inputs; commands-array guard; version fallback. - min_cli_version is now load-bearing: the checker fails when the manifest is older than the contract's floor. manifest_source is now read by CI (single source of truth for the URL). - hidden entries assert ABSENCE from the manifest (catches a hidden->visible promotion of ); checked-count counts checked commands, not list length. Contract covers the prose it missed: query --at/--policy-class, --json on the four docs subcommands, bare model, branch diff --target/--json, branch revert --json. New: the inbound-MCP section WS-4 asked for (claude mcp add --transport http against a Space's /v1/mcp?space=<id> — the Data Admin tab documents Claude Desktop only); README states the two intentional doctrine-mirror relationships and what wins where; honest failed-server description for a missing binary; .DS_Store untracked + .gitignore added; homepage in plugin.json; skill trigger scoped to terminal contexts + SDK-only check in the body. Declined with reason (recorded in the response doc): flag-VALUE validation — mcp init's --ide/--toolsets and query --format expose no possible_values in the manifest today (plain strings), so the mechanism would be vacuous; riding the 'convert --format flags to value enums' follow-up in fluree/db instead.
Response to independent review of #1; every finding verified before fixing. The three text blockers were all real against v4.1.4, the latest installable release: - SKILL.md credential rail was INVERTED: it said config list redacts on 'current versions' when redaction ships only in the first release after fluree/db#1571 — an agent on 4.1.4 would have blessed a command that dumps auth.token AND refresh_token in plaintext. Rewritten to be safe on binaries that exist: treat config list output as secret through v4.1.4; verify --reveal exists before assuming redaction. - workflows.md taught 'branch diff main dev', which does not parse (one positional + --target, defaulting to the source's parent). - The 'start here' pointer to docs get ai/claude-code is now hedged the same way the manifest pointer already was (page ships after #1571), and 'supersedes' narrowed to command-surface authority. Floor moves to 4.1.4 in lockstep with the paired solo review (auth token does not exist at 4.1.3) — SKILL, setup, README, cli-facts. CI honesty (the job could report green while running nothing): - 404 is the only skip; every other curl outcome is now ::error + fail. The skip is a ::warning with an owner and expiry (issue #2 filed). - Marketplace root now validated (the per-plugin loop never saw it); claude-code npm install pinned (2.1.220); .mcp.json syntax-checked in CI (validate --strict provably ignores it) and its nonstandard description key dropped. Checker soundness: - exit 2 (not a stack trace masquerading as 'contract violated') for unreadable/malformed inputs; commands-array guard; version fallback. - min_cli_version is now load-bearing: the checker fails when the manifest is older than the contract's floor. manifest_source is now read by CI (single source of truth for the URL). - hidden entries assert ABSENCE from the manifest (catches a hidden->visible promotion of 'fluree manifest'); checked-count counts checked commands, not list length. Contract covers the prose it missed: query --at/--policy-class, --json on the four docs subcommands, bare model, branch diff --target/--json, branch revert --json. New: the inbound-MCP section WS-4 asked for (claude mcp add --transport http against a Space's /v1/mcp?space=<id> — the Data Admin tab documents Claude Desktop only); README states the two intentional doctrine-mirror relationships and what wins where; honest failed-server description for a missing binary; .DS_Store untracked + .gitignore added; homepage in plugin.json; skill trigger scoped to terminal contexts + SDK-only check in the body. Declined with reason (recorded in the response doc): flag-VALUE validation — mcp init's --ide/--toolsets and query --format expose no possible_values in the manifest today (plain strings), so the mechanism would be vacuous; riding the 'convert --format flags to value enums' follow-up in fluree/db instead.
aaj3f
force-pushed
the
feat/fluree-cli-plugin
branch
from
July 30, 2026 21:31
74d2119 to
be22d19
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Fluree AI already hands its users' AI assistants off to the
flureeCLI (the Build-an-App prompt, the LLM-targeted served docs). This plugin is the Claude-Code-native half of that story: it packages the operating doctrine — how to drive the CLI safely — while deliberately refusing to carry command reference, which the binary itself serves version-exactly via its embedded docs. That division is what keeps the plugin from drifting: most CLI changes require zero plugin changes, and the few facts the plugin does hard-code are machine-validated in CI.What
plugins/fluree-cli/:fluree docs/--help/ the MCP docs tools before composing commands; a missing command usually means a feature-gated build), safety rails (destructive-op confirmation fordrop/branch drop,.fluree/token hygiene,auth tokenvsconfig list --reveal, explicit import budgets on shared machines, policy-correlation verification), machine-output map, and the Fluree AI remote choreography — including thatfluree auth loginblocks on the human approving a device code at the stack's/activatepage. Deep material inreferences/(workflows, remote-fluree-ai, policy, troubleshooting)./fluree-cli:setup: binary check + install pointers, the ≥ 4.1.3 version gate, docs-access verification, duplicate-MCP-registration cleanup,.fluree/gitignore hygiene..mcp.json: auto-connectsfluree mcp serve --toolsets docs(the binary's embedded, version-exact documentation asdocs_search/docs_get/docs_examples/docs_tree). Missing binary degrades gracefully.contract/cli-facts.json+scripts/check-cli-contract.mjs: every command path and flag the plugin's text mentions, validated against thefluree-cli-manifest.jsonrelease asset that fluree/db now publishes (a JSON surface description generated from the CLI's own clap definitions, so it cannot drift from the binary)..github/workflows/ci.yml):claude plugin validate --strictover every plugin in the marketplace, a marketplace↔plugin version-sync check (both verified passing locally), and the contract check — which skips with a notice until the first fluree/db release ships the manifest asset, then should be made required.Cross-repo pairing
feat/cli-ai-surface): ships the hiddenfluree manifestcommand + thefluree-cli-manifest.jsonrelease asset this repo's CI validates against, plusdocs/ai/claude-code.md— the in-binary agent guide this skill defers to.feat/cli-ai-surface): the platform half (itscli-snippetsmodule rides the same manifest rail; its Build-an-App prompt and this plugin divide labor — prompt = per-stack bootstrap, plugin = durable procedure).This PR is safe to land before either: the contract check self-skips until the manifest asset exists.
Validation
claude plugin validate --strict: ✔ both plugins and the marketplace root.check-version-sync.mjs: ✔ 2 plugins. Contract checker run against a locally built manifest from fluree/db#1571's branch: 42 commands OK — and its very first run caught a real error in my own draft (fluree listhas no--json; the skill text shipped corrected), which is the rail doing its job.Notes for reviewers
descriptionis the auto-trigger surface — worth a critical read.fluree-cli, hence/fluree-cli:setup) follows the settled decision to leave room for future platform-side plugins.min_cli_versionmessaging if the release number differs from 4.1.3-era expectations.