Skip to content

feat: add --field option to field add content-relationship and field edit#123

Merged
angeloashmore merged 6 commits intoaa/remote-modelingfrom
aa/field-selection
Apr 14, 2026
Merged

feat: add --field option to field add content-relationship and field edit#123
angeloashmore merged 6 commits intoaa/remote-modelingfrom
aa/field-selection

Conversation

@angeloashmore
Copy link
Copy Markdown
Member

@angeloashmore angeloashmore commented Apr 13, 2026

Resolves: #103

Description

Add a repeatable --field flag to field add content-relationship and field edit for specifying which fields to fetch from related documents.

Fields are validated against the production custom type model via the Custom Types API. Supports dot notation for nested selection through groups and content relationship fields, matching the editor's type builder behavior.

Checklist

  • A comprehensive Linear ticket, providing sufficient context and details to facilitate the review of the PR, is linked to the PR.
  • If my changes require tests, I added them.
  • If my changes affect backward compatibility, it has been discussed.
  • If my changes require an update to the CONTRIBUTING.md guide, I updated it.

Preview

How to QA 1

# Add a content relationship with field selection
prismic field add content-relationship my_cr \
  --to-type blog \
  --custom-type author \
  --field name \
  --field bio

# Edit an existing content relationship to add field selection
prismic field edit my_cr \
  --from-type blog \
  --field name

# Nested selection through groups and CR fields
prismic field add content-relationship my_cr \
  --to-type blog \
  --custom-type author \
  --field name \
  --field social.twitter \
  --field related_author.title

Note

Medium Risk
Adds new CLI behavior that fetches and validates remote custom type schemas and mutates the stored customtypes config shape; incorrect resolution/validation could break content relationship configuration. Scope is limited to the field add/edit commands and covered by new tests.

Overview
Adds a repeatable --field option to prismic field add content-relationship and prismic field edit to define which fields are fetched from related documents.

Introduces resolveFieldSelection() in models.ts to validate dot-path selections against the target custom type (including traversal through groups and one nested content relationship) and emit the nested selection structure the Prismic API expects; both commands now fetch the target custom type via the Custom Types API and error if --field is used without exactly one allowed --custom-type.

Adds test coverage for adding/editing a content relationship with field selection.

Reviewed by Cursor Bugbot for commit 3f34759. Bugbot is set up for automated code reviews on this repo. Configure here.

Footnotes

  1. Please use these labels when submitting a review:
    ❓ #ask: Ask a question.
    💡 #idea: Suggest an idea.
    ⚠️ #issue: Strongly suggest a change.
    🎉 #nice: Share a compliment.

…ield edit`

Add a repeatable `--field` flag for specifying which fields to fetch from
related documents. Fields are validated against the production custom type
model via the Custom Types API.

Supports dot notation for nested selection:
- `--field title` for top-level fields
- `--field group.name` for group sub-fields
- `--field cr.name` for CR target type fields
- `--field group.cr.group.leaf` for full depth

Closes #103

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace 7 call sites that fetch all custom types just to find one by ID
with the single-type `GET /customtypes/{id}` endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e3d785e. Configure here.

angeloashmore and others added 4 commits April 13, 2026 20:09
…unction

Replace 7 functions (157 lines) with a single recursive `resolveFields`
function and named `ResolvedField` type, reducing to 3 functions (107 lines).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@angeloashmore angeloashmore merged commit ddd0555 into aa/remote-modeling Apr 14, 2026
23 of 35 checks passed
@angeloashmore angeloashmore deleted the aa/field-selection branch April 14, 2026 18:30
angeloashmore added a commit that referenced this pull request Apr 15, 2026
…slices (#83)

* feat: add remote modeling commands for custom types, page types, and slices

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: correct Custom Types API URLs and slice command messages

The insert/update endpoints were using incorrect paths (e.g. `customtypes`
instead of `customtypes/insert`), causing 401 errors on write operations.
Also fixes copy-paste errors in slice command output messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add e2e tests for custom-type, page-type, and slice commands

Covers create, list, view, remove for all three command groups, plus
slice-specific connect, disconnect, add-variation, and remove-variation.
All tests verify state against the Custom Types API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add default slice zone to page type and fix test types

Page types need a slice zone in Main tab by default. Replace `as any`
casts in slice connect/disconnect tests with proper types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add field management commands for remote modeling

Adds `field add`, `field list`, and `field remove` commands that operate
on custom types and slices via the Custom Types API, along with per-type
`field add <type>` subcommands for all supported field types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add missing primary field to test slice builder

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add field edit command for remote modeling

Adds `prismic field edit` to modify existing field properties (label,
placeholder, type-specific options) on slices and custom types via the
API. Extracts shared `resolveFieldContainer` from `resolveModel` for
reuse across field-edit and field-remove.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: move sync logic into Adapter and sync after modeling commands

Consolidates sync logic (syncModels, syncSlices, syncCustomTypes) into
the Adapter class so all modeling commands can sync local files after
remote changes. This ensures local models stay up-to-date after any
create, remove, or field mutation command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: replace syncModels with granular adapter methods

Move adapter sync into resolveModel/resolveFieldContainer so field
commands no longer depend on the adapter directly. Type/slice CRUD
commands now call specific adapter methods (create/update/delete)
instead of a full sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: unify `page-type` and `custom-type` into single `type` command (#104)

* feat: unify `page-type` and `custom-type` into single `type` command

Consolidates the separate `page-type` and `custom-type` top-level
commands into a single `type` command with a `--format` flag on create.

- `prismic type create <name> --format page` for page types
- `prismic type create <name>` defaults to custom format
- `prismic type list` shows all types with format in output
- `prismic type view/remove` work regardless of format
- Field targeting simplified: `--to-type`/`--from-type` replace
  `--to-page-type`/`--to-custom-type`/`--from-page-type`/`--from-custom-type`

Closes #96

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use "content type" in command descriptions for clarity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add `type edit` command (#106)

Closes #91

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add `slice edit` and `slice edit-variation` commands (#107)

* feat: add `slice edit` and `slice edit-variation` commands

Adds two new subcommands for editing slice and variation metadata after
creation. Also adds E2E tests for the recently added `type edit` command.

Closes #92

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add local fallback for `type edit` adapter call

Wraps adapter.updateCustomType in try/catch with createCustomType
fallback, matching the pattern used in other commands. Prevents crash
when the local customtypes/ directory doesn't contain the edited type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove --repeatable/--single flags from `type edit`

The Custom Types API does not support updating the repeatable property;
it must be changed from the writing room UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove --description from `slice edit-variation`

Edit commands should only expose options that the corresponding create
command exposes. `slice add-variation` does not accept --description.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add tab management commands (#108)

* feat: add `type add-tab`, `type edit-tab`, and `type remove-tab` commands

Adds tab management commands for content types:
- `add-tab` creates a new tab, optionally with a slice zone
- `edit-tab` renames a tab and/or adds/removes a slice zone
- `remove-tab` deletes a tab (guards against removing the last one)

Closes #94

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: validate mutually exclusive --with-slice-zone and --without-slice-zone flags

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: rename `--in` flag to `--from-slice`/`--from-type` (#110)

* refactor: rename `--in` flag to `--from-slice`/`--from-type`

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update tests to use renamed flags

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: show fields inline in `view` commands and remove `field list` (#111)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add `field view` command (#112)

* feat: add `field view` command

Add a command to inspect a single field's full configuration,
including label, placeholder, constraints, and type-specific settings.

Resolves #93

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: use compact buildSlice pattern in field-view tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: consolidate link-related field types (#114)

* feat: consolidate link-related field types

Merge `link-to-media` into `link` with a new `--allow` option that
accepts `document`, `media`, or `web`. Omitting `--allow` creates a
generic link. Keep `content-relationship` separate.

Update descriptions on `link` and `content-relationship` so agents
can tell when to use each one.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: validate --allow option and restore field-edit subtype guards

Validate that --allow is one of document, media, or web. Restore
subtype guards in field-edit so content-relationship fields can't
receive link-only options and vice versa.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: allow all Link options regardless of select value

Remove the select-based guard in field-edit so link fields with
select: "document" can still be edited with link-specific options
like --allow-target-blank and --allow-text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: improve `content-relationship` help text (#115)

* feat: improve `content-relationship` help text

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: drop FIELD CONSTRAINTS section from content-relationship help

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add a consistent table formatter for tabular output (#116)

* feat: add a consistent table formatter for tabular output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add header support to formatTable and add headers to list commands

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: avoid blank line in `preview list` when only simulator URL exists

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: rename preview list header from LABEL to NAME

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: replace name-based model specifiers with IDs (#117)

* feat: replace name-based model specifiers with IDs

Slice commands now resolve by `id` instead of `name`, content type
commands resolve by `id` instead of `label`, and variation commands
resolve by `id` instead of `name`.

Closes #105

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: rename `currentId` to `id` in slice-edit-variation

The "current" prefix was a holdover from name-based specifiers where
names could change. IDs are immutable, so the prefix is unnecessary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: add `getCustomType` and `getSlice` client functions (#124)

* refactor: add `getCustomType` and `getSlice` client functions

Replace the `getCustomTypes().find()` and `getSlices().find()` patterns
with dedicated single-resource fetch functions that set contextual error
messages on `NotFoundRequestError`. Add a central handler in the root
router to print those messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: give `NotFoundRequestError` a user-friendly default message

Overrides the raw "fetch failed: <url>" message with "Not found." so
unhandled 404s from any endpoint still produce a clean message when
caught by the root error handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: include URL in default NotFoundRequestError message

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add `--field` option to `field add content-relationship` and `field edit` (#123)

* feat: add `--field` option to `field add content-relationship` and `field edit`

Add a repeatable `--field` flag for specifying which fields to fetch from
related documents. Fields are validated against the production custom type
model via the Custom Types API.

Supports dot notation for nested selection:
- `--field title` for top-level fields
- `--field group.name` for group sub-fields
- `--field cr.name` for CR target type fields
- `--field group.cr.group.leaf` for full depth

Closes #103

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: use `getCustomType` instead of `getCustomTypes` + find

Replace 7 call sites that fetch all custom types just to find one by ID
with the single-type `GET /customtypes/{id}` endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: simplify field selection resolution with single recursive function

Replace 7 functions (157 lines) with a single recursive `resolveFields`
function and named `ResolvedField` type, reducing to 3 functions (107 lines).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove unnatural phrasing from JSDoc comment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: simplify test custom type construction to use default fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: handle type removal when documents exist (#127)

Show a clear error message when attempting to remove a type that has
associated documents, guiding users to delete the documents first.

Closes #99

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add field reorder command (#129)

* feat: add field reorder command

Adds `prismic field reorder` to move a field before or after another
field. Supports cross-tab moves in custom types (destination tab is
determined by the anchor field) and dot-notation for group fields.

Resolves #100

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: simplify test model setup in field-reorder tests

Use buildSlice()/buildCustomType() with property assignment instead of
verbose override objects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add `--screenshot` option to `slice add-variation` and `slice edit-variation` (#128)

* feat: add `--screenshot` option to `slice add-variation` and `slice edit-variation`

Upload a screenshot image (local file or URL) to Prismic's S3 via the
ACL provider, storing the resulting imgix URL in the variation's
`imageUrl` field.

Closes #95

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address PR review feedback for screenshot upload

- Use GET with auth headers (Authorization, Repository) for ACL provider
- Match response schema from slice-machine: { values: { url, fields }, imgixEndpoint }
- Support PRISMIC_HOST via getAclProviderUrl() helper
- Use request() instead of fetch() for S3 upload
- Fix buffer pooling issue by slicing to owned ArrayBuffer
- Build supported extensions list from MIME_TYPES
- Add local file path test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: use response.blob() and URL for path construction

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: accept Blob in uploadScreenshot and validate file type

Separate file resolution (readURLFile) from upload logic so
uploadScreenshot only deals with Blobs. Add UnsupportedFileTypeError
for MIME type validation, fix getExtension edge case, and remove
dead imports.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add local screenshot file test for slice edit-variation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address PR review feedback for screenshot upload

Rename MIME_TYPE_EXTENSIONS to SUPPORTED_IMAGE_MIME_TYPES to clarify
intent. Use regex check for HTTP URLs instead of URL.canParse to avoid
misidentifying Windows absolute paths as URLs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: misc fixes for remote modeling branch

- Remove unnecessary type parameters from request calls
- Fix field-edit to reference field.config instead of config
- Fix sync watch to generate types once after both syncs
- Use getCustomType in type-view instead of filtering list
- Fix error message to show variationId instead of variation object

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve nested field lookup and missing existence check

- Use root field ID for custom type tab lookup in resolveFieldContainer
  so dot-separated IDs (e.g. "my_group.subtitle") find the correct tab
- Add field existence check in field-edit to throw a clean CommandError
  instead of a TypeError when the field doesn't exist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: join field IDs before fallback check in error message

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: allow adding placeholder to fields that lack one and remove unused --tab from SOURCE_OPTIONS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant