Skip to content

feat: add mxcli catalog search and show commands#218

Open
dionesiusap wants to merge 10 commits intomendixlabs:mainfrom
dionesiusap:feature/213-catalog-search
Open

feat: add mxcli catalog search and show commands#218
dionesiusap wants to merge 10 commits intomendixlabs:mainfrom
dionesiusap:feature/213-catalog-search

Conversation

@dionesiusap
Copy link
Copy Markdown

Adds mxcli catalog search and mxcli catalog show commands for discovering services registered in Mendix Catalog (catalog.mendix.com).

Summary

Users can now search the Mendix Catalog programmatically via CLI:

# Authenticate once
mxcli auth login

# Search for services
mxcli catalog search "customer" --service-type OData --production-only

# View detailed endpoint metadata
mxcli catalog show a7f3c2d1-4b5e-6c7f-8d9e-0a1b2c3d4e5f

# JSON output for scripting
mxcli catalog search "api" --json | jq '.[] | .name'

Changes

  • New commands: mxcli catalog search <query> and mxcli catalog show <uuid>
  • Filters: --service-type, --production-only, --owned-only, --limit, --offset
  • Output modes: Table (default) and JSON (--json)
  • Authentication: Reuses existing internal/auth infrastructure (PAT tokens)
  • Documentation: Skills, CLI help, proposal, and disambiguation warnings added
  • Tests: Unit tests for client, types, and command layers

Disambiguation

Added prominent warnings to distinguish between:

  • Mendix Catalog (this feature) - external service registry at catalog.mendix.com
  • MDL CATALOG keyword (existing) - local project metadata tables (SELECT ... FROM CATALOG.entities)

See issue comment for details: #213 (comment)

Testing

  • make build passes
  • make test passes (all unit tests)
  • make lint passes
  • Manual testing against real Catalog API
  • Agentic Code testing completed

Closes #213

dionesiusap and others added 10 commits April 16, 2026 14:30
Implements Phase 1 of Catalog integration (mendixlabs#213): read-only search
and discovery of services registered in Mendix Catalog.

New command:
  mxcli catalog search <query> [flags]

Features:
- Search with query term (required positional argument)
- Filter by service type (OData, REST, SOAP)
- Filter by environment (production-only flag)
- Filter by ownership (owned-only flag)
- Pagination support (limit, offset)
- Dual output formats (table or JSON)
- Table output: 7 columns, ~120 chars wide
- Short UUIDs (first 8 chars) in table, full UUIDs in JSON

Files added:
- internal/catalog/types.go - API request/response structs
- internal/catalog/client.go - HTTP client for catalog.mendix.com
- cmd/mxcli/cmd_catalog.go - Cobra command definitions

Reuses existing internal/auth infrastructure for PAT authentication.
catalog.mendix.com already whitelisted in internal/auth/scheme.go.

Phase 2 (client creation from Catalog) deferred pending architecture
discussion on executor network access.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Comprehensive proposal for mxcli Catalog integration covering:
- Phase 1: Search and discovery (implemented in this PR)
- Phase 2: Client creation from Catalog (architecture TBD)
- API analysis and endpoint details
- Three architectural options for executor integration
- Trade-offs and design decisions

References issue mendixlabs#213.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Automatic formatting changes from go fmt.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
API returns owner objects {name, email, uuid}, not strings.
Discovered during manual testing against real Catalog API.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Owner is an object, not a string.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Phase 1 now includes both search and show commands.
Client creation remains in Phase 2 (architecture TBD).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements 'mxcli catalog show <uuid>' for detailed endpoint inspection
and changes search output to show full UUIDs instead of shortened.

Changes:
- Show full UUID (36 chars) in search table output
- Users can copy UUID directly for use with show command
- Add catalog show command with human-readable and JSON output
- Display entities, actions, security scheme, environment

New types:
- EndpointDetails, ServiceVersion, Contract, Document
- Entity, Attribute, Association
- Action, Parameter, ReturnType
- SecurityScheme, SecurityType, Role
- EnvironmentWithApp (nested Application in endpoint response)

New client method:
- GetEndpoint(ctx, uuid) - Calls GET /endpoints/{uuid}

Updated documentation:
- Skills file reflects full UUID in table
- Proposal updated with full UUID rationale
- Table width now ~155 chars with full UUIDs

Tested against real Catalog API.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add prominent warnings in:
- catalog-search.md skill: clarify this is the external service registry
- browse-integrations.md skill: clarify this is MDL CATALOG for local queries
- cmd_catalog.go: add disambiguation note in CLI help text
- PROPOSAL_catalog_integration.md: add terminology note at top

This prevents confusion between:
1. Mendix Catalog (catalog.mendix.com) - external service registry, CLI commands
2. MDL CATALOG keyword - local project metadata tables, SQL queries

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add command-level tests for catalog search and show:
- Test authentication requirement (no auth errors)
- Test required arguments (query for search, uuid for show)
- Tests validate error messages guide users to 'mxcli auth login'

Catalog client and types tests were already present in the codebase.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

AI Code Review

What Looks Good

This PR implements mxcli catalog search and mxcli catalog show commands for discovering services in the external Mendix Catalog service (catalog.mendix.com). The implementation is clean, well-tested, and properly documented.

Strengths:

  • Clear disambiguation: Excellent documentation distinguishing between:
    • Mendix Catalog (external service registry) → CLI: mxcli catalog search/show
    • MDL CATALOG keyword (local project metadata) → MDL: SELECT ... FROM CATALOG.entities
  • Authentication reuse: Properly leverages existing internal/auth infrastructure for PAT tokens
  • Output flexibility: Provides both human-readable table output and JSON output for scripting
  • Pagination: Implements --limit and --offset with sensible defaults (max 100)
  • Error handling: Clear guidance for authentication failures ("Run: mxcli auth login")
  • Comprehensive testing: Unit tests for client, types, and command layers using proper mocks (no time.Sleep)
  • Documentation: New skill file, updated disambiguation notes, CHANGELOG entry, and detailed proposal

Code Quality:

  • Follows existing patterns from cmd/mxcli/cmd_auth.go
  • Proper HTTP client management with context cancellation
  • Clean separation of concerns (types, client, command layers)
  • No silent side effects on typos - requires explicit arguments
  • Method receivers not applicable (CLI command layer)

Recommendation

APPROVE - This PR is ready for merging. It implements a valuable feature for discovering Mendix Catalog services programmatically while maintaining clean separation from existing MDL functionality. The implementation follows project conventions, includes thorough testing, and provides excellent documentation with clear disambiguation between the two different "catalog" concepts.

No changes are needed before merging.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@ako
Copy link
Copy Markdown
Collaborator

ako commented Apr 17, 2026

Review

Overall: well-structured feature with clean separation, but bundled with too much noise (go fmt, 819-line proposal, merge conflict). The actual feature code is solid — httptest-based tests, proper auth reuse, good disambiguation between MDL CATALOG and Mendix Catalog.

What I like

  • Clean package separation. internal/catalog/ for API client + types, cmd/mxcli/cmd_catalog.go for Cobra wiring. The client is reusable; the CLI layer is thin.
  • httptest-based tests. client_test.go mocks the Catalog API with httptest.NewServer, verifies query params, and tests both search and endpoint-detail responses. Good pattern.
  • Disambiguation is handled proactively. The help text, the skill doc, and the PR description all clearly distinguish mxcli catalog search (external service registry) from MDL CATALOG (local metadata tables). This will prevent real user confusion.
  • Auth reuse. auth.ClientFor(ctx, profile) wraps the PAT token injection cleanly. Error paths check for ErrNoCredential and ErrUnauthenticated with actionable messages ("Run: mxcli auth login").
  • Types are thorough. 197 lines covering SearchResponse, EndpointDetails, ServiceVersion, Contract, Entity, Action, SecurityScheme — well-mapped to the real API response shape.

Concerns

  1. go fmt noise — again. 11 files of whitespace realignment (ast_entity.go, ast_microflow.go, ast_rest.go, model/types.go, sdk/agenteditor/types.go, sdk/mpr/parser_customblob.go, sdk/mpr/writer_rest.go, etc.). Same files as PRs feat: Support local file metadata for OData clients #210, feat: add typed error system for executor #222, feat: dispatch registry, backend interfaces, and MockBackend #224. These are now conflicting across multiple open PRs. Please land them once in a dedicated PR and stop including them in feature PRs.

  2. 819-line proposal doc bundled with implementation. docs/11-proposals/PROPOSAL_catalog_integration.md is valuable design documentation, but it inflates the PR stats (2035+ additions) and should have been a separate pre-PR to get design alignment before building. Not blocking — the code is already written — but per CLAUDE.md checklist, proposals and features should be separate PRs.

  3. UUID is concatenated directly into the URL without validation (client.go:99):

    reqURL := c.baseURL + "/endpoints/" + uuid

    If someone passes a crafted string with path separators, it modifies the URL path. Low risk (CLI input, server rejects bad UUIDs) but a url.PathEscape(uuid) or UUID format check would be cleaner. The example in the help text shows partial UUIDs (a7f3c2d1) — does the API support prefix matching, or is that misleading?

  4. Auth error handling uses type assertions, not errors.As. Two places do _, ok := err.(*auth.ErrNoCredential). Given the project is moving toward typed errors with errors.As/errors.Is (feat: add typed error system for executor #222), this should follow the same pattern: var target *auth.ErrNoCredential; if errors.As(err, &target) { ... }. Wrapping layers could break the type assertion.

  5. No build-and-test CI run. Only the review check shows. And the PR has merge conflicts (CONFLICTING/DIRTY). Both need resolution before merge.

  6. Missing: no MDL integration path. The mxcli catalog search command exists only as a Cobra CLI command — there's no MDL statement (SEARCH CATALOG 'query') and no executor integration. This means the feature isn't accessible from the REPL, scripts, or the LSP. Intentional as Phase 1? Worth noting in the PR what the planned MDL surface is, if any.

Minor

  • outputTable uses text/tabwriter directly instead of the project's TableResult pattern used everywhere else in the executor. Not a big deal for a CLI-only command, but inconsistent.
  • The --limit flag defaults to 20 with max 100 per the API, but there's no client-side validation that limit <= 100. The API will reject it, but the error message won't be user-friendly.
  • The skill doc at .claude/skills/mendix/catalog-search.md is 169 lines — quite detailed for a two-command feature. Good for LLM discoverability though.

Verdict

Approve the feature code after (1) go fmt noise is removed, (3) UUID is escaped, (4) error handling uses errors.As, and (5) CI is green + conflicts resolved. (2) and (6) are observations, not blockers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Catalog Integration: Search and Discovery

2 participants