Skip to content

feat(retexture): --ai-model picks Meshy N1; its texture defaults follow the model [ENG-5144] - #39

Merged
AltaMills merged 5 commits into
mainfrom
arkjiaqixiong/eng-5144-meshy-n1
Nov 3, 2026
Merged

AltaMills merged 5 commits into
mainfrom
arkjiaqixiong/eng-5144-meshy-n1

Conversation

@AltaMills

@AltaMills AltaMills commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Meshy N1 (ai_model: "meshy-n1") makes a 2K base color texture from reference images only, for 10 credits. It takes either one --image-style-url, read as the front view, or 1–4 --multiview-image-urls, front first and the rest in any order.

Before this change, N1 could only be picked through --data, and the CLI's retexture defaults (enable_pbr: true, texture_resolution: "4k", meshy-7 pinned on multi-view) turned every such request into a 400.

Release only after Meshy N1 is live for every API user. Until then, the API refuses meshy-n1 for callers it has not enabled.

Changes

  • New flag: retexture create --ai-model latest|meshy-7|meshy-6|meshy-n1.

    • meshy-5 is not offered, since it is retired.
    • meshy-6-lite stays reachable only through --data, as before. Its 2K limit clashes with the 4K default, and that default is unchanged here.
  • Defaults for meshy-n1: enable_pbr: false and texture_resolution: "2k", with no meshy-7 pin on multi-view.

    • They apply whether N1 comes from the flag or from --data (the flag wins, the same precedence the merged payload uses).
    • Every other model keeps its defaults: PBR on, 4K, and meshy-7 on multi-view.
  • Refused before the POST with N1 (exit 2), whether set by flag or by --data:

    • a text prompt;
    • enable_pbr: true;
    • 4k / 8k, or hd_texture: true;
    • remove_lighting.

    With no reference image, the CLI says N1 needs one.

  • Also refused locally: --ai-model latest|meshy-6 together with --multiview-image-urls.

  • Stricter than the API on purpose: a prompt beside one image (v1 drops it) and hd_texture: true beside an explicit "2k" (the API runs at 2k). The other N1 refusals are 400s on the API too.

  • Not refused locally: only the inputs above are checked before the create. A --data multiview_image_urls with 5 views, an empty, numeric or null element goes to the API as given, which answers it. With an expired OAuth login the CLI refreshes the token first, so one token request precedes a local refusal.

  • Face limit: the CLI does not check it. The skill points to meshy inspect faces and the limit in the API docs.

  • Docs:

    • D-088 in docs/decisions.md records why N1 flips the defaults rather than the defaults changing for every model;
    • an example block in docs/usage.md;
    • a bullet in skills/meshy-cli/SKILL.md.

    No version bump, publish or tag.

Failures the tests guard

tests/retexture.test.ts runs the built CLI against a loopback API and checks the POST body. The new tests failed on main first. The loopback API answers every create with 200, so these tests prove the request body and the CLI's own refusals, not what the backend does with them.

  • F1 / F2: N1 inherits PBR on or 4K, so every N1 request gets a 400.
  • F3: the multi-view meshy-7 pin replaces an N1 pick, so a Meshy 7 task runs and is billed.
  • F4: views are reordered or dropped, so the wrong image is read as the front view (checked with 1, 2 and 4 views).
  • F5: N1 picked through --data keeps the Meshy 7 defaults.
  • F6: N1 with a text prompt and no image is sent, or refused without saying that an image is needed.
  • F7: a prompt next to an image in --data is sent, and the API drops it silently.
  • F8: an explicit PBR, 4K, 8K, hd_texture or remove_lighting request with N1, by flag or by --data, is sent or quietly rewritten.
  • F9: other models lose PBR, 4K or the meshy-7 multi-view pin (checked with no flag, meshy-7, meshy-6 and latest).
  • F10: --ai-model accepts meshy-5 or a typo and spends a request on it.
  • F11: latest or meshy-6 with multi-view is sent.
  • F12: the flag no longer beats ai_model in --data, or the defaults do not follow the model that wins.
  • F13: with an expired OAuth login, a refused N1 request skips the refresh or sends a create: the login is refreshed once and saved, then the CLI exits 2 with no create sent.

How to test

pnpm install --frozen-lockfile && pnpm typecheck && pnpm test && pnpm build   # 595 pass locally (the wait/SIGINT timing tests can flake under heavy machine load; they pass on their own)

Against an API where Meshy N1 is enabled for the caller:

meshy retexture create --input-task-id <id> --ai-model meshy-n1 --image-style-url ./front.png --format json
meshy retexture create --input-task-id <id> --ai-model meshy-n1 --multiview-image-urls ./front.png,./back.png --format json

Expected POST body: ai_model: "meshy-n1", enable_pbr: false, texture_resolution: "2k", and the views in the order given.

Not verified end to end against a live API from this branch.

Linear: ENG-5144.

🤖 Generated with Claude Code

AltaMills and others added 5 commits November 2, 2026 10:53
…ow the model [ENG-5144]

Meshy N1 (ai_model "meshy-n1") makes a 2K base color texture from
reference images only: one --image-style-url (read as the front view)
or 1-4 --multiview-image-urls, front first. Before this change it was
reachable only through --data, and every such request drew a 400: the
CLI's retexture defaults sent enable_pbr true and texture_resolution 4k,
and N1 takes neither.

- New --ai-model on `retexture create`: latest | meshy-7 | meshy-6 |
  meshy-n1, a commander choice list like the Smart Topology flag. The
  retired meshy-5 is not offered; meshy-6-lite stays --data only, as
  before, since it refuses the 4k default too.
- For meshy-n1 the defaults layer sends enable_pbr false and
  texture_resolution 2k and pins no model, so N1 with multi-view stays
  N1. Every other model keeps PBR on, 4k and the meshy-7 multi-view pin.
  The model is read from the flag, else --data, the same precedence as
  the merged payload, so N1 picked through --data gets the N1 defaults.
- Explicit asks N1 cannot honour are refused before the POST (exit 2): a
  text prompt, enable_pbr true, 4k/8k, hd_texture true, remove_lighting.
  A request without a reference image says N1 needs one. This follows
  the CLI's rule for documented API refusals (D-076), and runs on the
  merged payload so --data meets the same checks (D-078, D-083). The
  asks are not rewritten to 2k / no PBR: a quiet downgrade would return
  something other than what was asked for.
- --ai-model latest or meshy-6 with --multiview-image-urls is refused
  locally; an ai_model in --data beside multi-view stays the server's
  call, like the pin it overrides.

Docs: decision D-088, docs/usage.md, the bundled skill (N1 costs 10
credits; the face limit is 5,000,000).

Tests: tests/retexture.test.ts drives the built CLI against a loopback
API and asserts the POST body (failure list F1-F12 in its header).
`pnpm typecheck`, `pnpm test` (594 pass) and `pnpm build` pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… refusal [ENG-5144]

Review follow-up on Meshy N1 (ENG-5144), non-blocking:

- A test: with an expired OAuth profile, a meshy-n1 request the CLI refuses
  (--enable-pbr true) refreshes the login once and saves the new token, then
  exits 2 before any create is sent.
- The hd_texture refusal's comment says it is the CLI's own rule: the API
  takes an explicit texture_resolution over hd_texture.
- The test file says its loopback API answers every create with 200, so the
  tests prove the request body and the CLI's refusals, not backend behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uts [ENG-5144]

Review follow-up on Meshy N1 (ENG-5144). Comments no longer present the CLI's
own refusals as API 400s:

- hd_texture true is a 400 on N1 only without a texture_resolution; beside an
  explicit "2k" the API runs at 2k, so refusing it is the CLI's rule.
- The API does not take "exactly one style input": views beside a prompt or
  an image are a 400, but v1 clears a prompt beside one image. The CLI refuses
  every combination so no flag is dropped without a word.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…NG-5144]

main now seals secrets in the credential store (ENG-5285), so the N1
expired-login test reads the saved access token with openStoredProfile, as
the other refresh tests do, instead of parsing the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AltaMills
AltaMills merged commit 5091d17 into main Nov 3, 2026
7 checks passed
AltaMills added a commit that referenced this pull request Nov 3, 2026
Version 0.8.2 for the release: Meshy N1 (`--ai-model meshy-n1`) on
retexture, #39.

Checked locally on this branch: `pnpm typecheck`, `pnpm test` (618 pass,
0 fail), `pnpm build`, and `node dist/index.js --version` prints 0.8.2.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <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