Repository navigation
feat(cli): 0012 DeterministicCliSidecar — gimp-agent doctor/probe/exit codes - #37
Ryan-AI-Studios wants to merge 23 commits into
Conversation
Add uv dev toolchain (ruff, basedpyright, pytest), project CI with Node-24-ready Actions, gitignore for local agent/conductor governance, offline smoke tests, and docs/planner-handoff.md for cold-start planners. Includes small gimp_mcp_server typing/format fixes for the new gate.
Document 0001 bootstrap complete, 0002 quality stabilization as next, and the full path through 0028 final product polish.
Full product ruff/format green; scripts layout; setup-uv@v9.0.0; lint.yml retired; planner-handoff policy. Ledger: 83598dee-78b5-4c0a-8975-96a7b5cd15c4
…th jail Track 0003: Class A/B exec gates, AF_INET 127.0.0.1, session auth, path jail, audit. CI green. Codex final PASS WITH DEFERRED P3.
…mapping Visible composite snapshots (dup+merge), image_index, ToolResult structuredContent mapping, temp policy, fail-closed selection/PNG validation. Codex final PASS WITH DEFERRED P3.
* feat(export): add gimp_mcp_export host module + offline alpha tests * fix(export): alpha-preserving merge-on-dup + file-*-export + verify tool * docs: Issue 16 alpha export defaults, install gimp_mcp_export.py * fix(export): recursive alpha preflight + structured MCP errors IR1-01: walk layer groups recursively in preflight/verify_alpha IR1-02: return structured export error dicts from MCP export_image IR1-04: fail-closed when preserve_alpha and drawable unset IR1-05: greps, type-4 PNG fixture, structured-error source tests * fix(export): codex P1/P2 — no silent format fallback, fail-closed RGBA8, batch metadata * fix(export): format README; drop accidental conductor review from tree Keep conductor/ gitignored local-only. Ruff-format README code fences for CI. * docs(0005): mark AlphaExportCorrectness complete in planner handoff Issue 16 closed: merge-on-dup export, IHDR ALPHA_LOST, verify_alpha_channel. Next product track: 0006 StateManifestOrientation (placeholder plan). --------- Co-authored-by: Ryan <rbourgoin@gmail.com>
Schema-versioned orient_workspace state-manifest v1; host finalize; recursive layers; provisional handles; image_index metadata hygiene. Codex engineering PASS WITH DEFERRED P3 (live matrix).
Ledger: f13ebc80-dc77-4722-831e-68b1858c6a0f
…select_* (#6) Stable handle registry: gimp_mcp_handles, process-unique session_epoch, generation tombstones, structural bumps, select_image/select_layers. Codex PASS WITH DEFERRED P3.
Next product track is 0008-CoordinateModelAndExif (placeholder). PR #6 / main@33df2b5 delivered generation registry, STALE_HANDLE, select_*. Ledger: 211b63de-c672-4bfe-9143-007559ba8877 Co-authored-by: Ryan <rbourgoin@gmail.com>
…#8) * feat(0008): CoordinateModelAndExif — coords, mapping, normalize, map_* Ship gimp_mcp_coords as 7th plug-in file (preview/layer math, ordered ORIENTATION_OPS, declaration validate, half-even rounding). Enrich mapping metadata on three paths (build_mapping_metadata + plugin bitmap flatten + server ToolResult pass-through). Add normalize_image_orientation (default assume_pixels_upright; trust_tag opt-in; direct rotate/flip; both EXIF tags; METADATA_WRITE_FAILED; self gen-bump). Session _orientation_normalized synced with gen prune. Host map_* x4. Capability coordinate_exif_normalized true. Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3 * fix(0008): undo pixel ops when normalize set_metadata fails Call image.undo() after the undo group ends if metadata write fails and trust_tag pixel ops ran, so the canvas is not left rotated with a stale tag. Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3 * fix(0008): undo on mid-op normalize exceptions (ops_started) Ensure trust_tag pixel ops that raise after partial transform call image.undo() after undo_group_end, not only the metadata-false path. Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3 * fix(0008): fail-closed gboolean ops, invalid EXIF honesty, plan tests - Check image.flip/rotate and undo_group_* for explicit False - Keep present-but-invalid orientation for honesty; clamp for manifest - plan_normalize_ops offline behavioral tests; README install count Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3 * fix(0008): fail-closed undo_group_end (no success on False) Do not swallow undo_group_end gboolean False; re-raise body errors after end so generation is never bumped on group-close failure. Ledger: a184eb50-f0d4-42c6-b069-1061eef57ad3 --------- Co-authored-by: Ryan <rbourgoin@gmail.com>
PR #8 / main@8970ad2; Codex PASS WITH DEFERRED P3; next=0009. Co-authored-by: Ryan <rbourgoin@gmail.com>
…kpoints, confirm_destructive (#10) * feat(0009): gimp_mcp_policy + codes + tests + install Ship 8th plug-in file for labels/paths/sidecar/integrity hash; POLICY_DENIED/CONFIRM_REQUIRED/CHECKPOINT_* codes; offline tests; pyproject + README install lists. Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4 * feat(0009): Source_Immutable, confirm_destructive, checkpoints - ensure_source_immutable with parasite group + central mutable resolve - confirm_destructive on live flatten/merge/rotate free-angle/resize fill - checkpoint_create/restore with jailed paths + integrity sidecar - orient tattoo/protected; capabilities source_immutable_policy + checkpoints - MCP tools + protocol/README agent intake order Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4 * fix(0009): tighten confirm-scope wiring tests and orient-snapshot honesty Pin free-angle / will_flatten branch structure for confirm_destructive. Document include_orient_snapshot=true as note-only (no embedded dump). Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4 * fix(0009): address Codex P1/P2 — bool coerce, idempotent ensure, XCF partial - Use export.coerce_bool for confirm_destructive / allow_source_mutation / overwrite - Skip working copies on re-ensure (session set + name suffix); no gen bump on no-op - Save checkpoint XCF via .partial then os.replace; check PDB status + non-empty - Document allow_source_mutation as raw-TCP recovery only (not MCP mutators) Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4 * fix(0009): strict coerce_bool + safer working-name skip + restore bools - coerce_bool fail-closed for non-scalar JSON (list/dict → default) - Name-based working skip only when policy group already has children - checkpoint_restore close_prior/verify_hash use coerce_bool Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4 * fix(0009): durable Source_Immutable deny via group ancestry + hydrate _assert_mutable also denies descendants of parasite-marked group. Hydrate protected set on ensure, open_image, orient, checkpoint_restore. Strict coerce_bool non-scalar fail-closed already in export. Ledger: 3a04bc4b-8616-4512-9529-40c0f0c9f4d4 --------- Co-authored-by: Ryan <rbourgoin@gmail.com>
…stMCP (#12) * 0010: high-level MCP surface (~18 tools) on real FastMCP Migrate from mcp.server.fastmcp shim to real fastmcp.FastMCP with include_tags + ToolAnnotations. Default surface is 18 HL tools; GIMP_MCP_ADVANCED_TOOLS=1 exposes full advanced surface. Ledger: 5272272a-d519-4e72-9635-d27e3267c1fb * fix(0010): handle-first save/export/verify/close + by_color layer_id Wire plugin mutators through _resolve_image_from_params so HL handle params cannot silently target image 0. Fail closed on explicit layer_id for select_by_color. Strengthen offline handle tests; PROTOCOL design names. Ledger: 5272272a-d519-4e72-9635-d27e3267c1fb * fix(0010): fail-closed prior handle on restore; honest composite index checkpoint_restore close_prior with invalid handle returns STALE/FOREIGN instead of silent skip. Derive open-list image_index after handle resolve for composite mapping. Align create_selection layer_handle docs; tests. Ledger: 5272272a-d519-4e72-9635-d27e3267c1fb --------- Co-authored-by: Ryan <rbourgoin@gmail.com>
Ledger: 5272272a-d519-4e72-9635-d27e3267c1fb Co-authored-by: Ryan <rbourgoin@gmail.com>
…st_id audit (#14) * feat(0011): structured error envelope v1 + request_id audit correlation Implement product error envelope, single-line ToolError wire, CODE matrix (PARTIAL_MUTATION, CONNECTION_FAILED), host/plugin split audit files, and request_id correlation (contextvars host, threading.local plugin). - export_image raises ToolError on ALPHA_LOST (H1; details preserved) - _jail_path_or_raise re-raises SecurityError (H5) - send_command params copy + _request_id; CONNECTION_FAILED on transport - @with_structured_error on all MCP tools; structured_errors capability - docs: PROTOCOL recovery table, SECURITY audit/traceback policy, README Ledger: 6dc55b22-8287-44cf-a6d3-1fbbfb37327a * fix(0011): call_api ToolError path + affected_handles on INTERNAL (M5) Ledger: 6dc55b22-8287-44cf-a6d3-1fbbfb37327a * fix(0011): parse_tool_error_text handles message containing ' | ' Codex P1: rfind alone selected the pipe inside JSON error.message when the human message also contained the delimiter. Try every ' | ' candidate from the right until a valid envelope parses. Regression test added. Ledger: 6dc55b22-8287-44cf-a6d3-1fbbfb37327a --------- Co-authored-by: Ryan <rbourgoin@gmail.com>
…#15) Ledger: 6dc55b22-8287-44cf-a6d3-1fbbfb37327a Co-authored-by: Ryan <rbourgoin@gmail.com>
Ship host package gimp_agent/ with entrypoint gimp-agent: - argparse CLI: doctor [--strict], probe [--timeout], version, codes - CODE_* / CLI-local → exit 0-12 map + reverse table - path discovery (env/PATH/App Paths/install dirs + GIMP 3.* semver) - doctor ordered checks; probe auth JSON get_gimp_info - JSON envelope (--json / GIMP_AGENT_JSON); offline tests - docs: README CLI section; protocol full exit table
Document non-strict doctor (exit 0 + ok:false) and probe TIMEOUT→9. Add offline tests for non-strict doctor and TimeoutError path. Remove dead stderr branch in jsonio.emit (human mode stays stdout).
|
Opened against upstream by mistake; product PR belongs on Ryan-AI-Studios/gimp-mcp. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (49)
WalkthroughThe change adds secure authenticated MCP transport, workspace and export safeguards, stable handles, state manifests, visible-composite snapshots, a diagnostic CLI, updated tooling, documentation, and offline tests. ChangesGIMP MCP platform
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Implements conductor track 0012-DeterministicCliSidecar: product
gimp-agentCLI sidecar with deterministic exit codes, JSON envelopes, doctor/probe diagnostics, and path discovery.Deliverables
gimp_agent/(argparse only; no click/typer)doctor [--json] [--strict],probe [--json] [--timeout],version,codesCODE_*→ 0–12 (+ CLI-localCLI_USAGE/GIMP_NOT_FOUND/PLUGIN_NOT_FOUND; generic exit 1)packages = [\"gimp_agent\"]+ existingpy-modules;gimp-agentscript; ruff/basedpyright coverageget_gimp_info; doctor TCP is connect-only; fullEXPECTED_PLUGIN_FILES(7 files)bin/shim noteReview
--json, probe success require, version rc, env JSON, NaN JSON) → Codex final PASSTest plan
uv run ruff check .uv run basedpyrightuv run pytest tests/test_gimp_agent_cli.py -q(38)uv run pytest -m \"not integration and not slow\"uv run gimp-agent codes --json/--json codes/GIMP_AGENT_JSON=1Out of scope (later tracks)
BatchProcedure (0019), recipes (0015), atomic save (0013), install scripts (0018)
Summary by CodeRabbit
New Features
gimp-agentcommand-line utility for diagnostics, connectivity checks, version information, and standardized exit codes.Improvements
Documentation
Tests