SIGN IN SIGN UP

test: [ENG-3025] add command-level tests for Curate continuation orchestration

Closes the four-round-carryover finding by pinning the load-bearing
orchestration invariants. Three consecutive review rounds had each
introduced a subtle behavioral change in the emitter / orchestration
surface caught only by manual interactive verification:

  abd82ba — deferred unlink until after dispatch
  316ece0 — switched cleanup-failure from warnings[] to errors[]
  60b613d — made text-mode iterate companion errors[] on the done branch

Each would have been caught by a small command-level test with stubbed
seams. Adding both the seams and the tests.

Refactor (src/oclif/commands/curate/index.ts):
- Extract the dispatch path into a protected dispatchContinuation()
  method that wraps withDaemonRetry + continueSession. Throws on
  daemon-error so the caller can map to a daemon-error envelope AND
  skip the post-success unlink — that ordering is the load-bearing
  invariant.
- Extract loadCurateResponseFile, deleteCurateResponseFile,
  peekCurateSession, and resolveProjectRoot calls into protected
  methods so a TestableCurate subclass can inject in-memory doubles.
- Switch the removed-flag check from process.argv.slice(2) to
  this.argv so testable subclasses scope to their own argv (mocha's
  --timeout was leaking into the curate flag parser otherwise).

New test file (test/commands/curate/index.test.ts) — 13 tests pinning:

  flag combinations:
    - --response + --response-file together
    - --delete-response-file without --response-file
    - continuation-only flags on kickoff (no --session)
  pre-dispatch local validation:
    - whitespace payload → empty-response, no dispatch
    - invalid JSON → invalid-response-format, no dispatch
    - unknown session → unknown-session, no unlink
    - --response-file read error → response-file-read-error, no dispatch
  daemon-error path preserves the response file (regression abd82ba):
    - dispatch throws → daemon-error envelope, NO unlink call fired
  cleanup-failure-post-success → done with appended errors[] (316ece0):
    - done + unlink throws → ok=true, status=done, errors[0].kind=response-file-delete-error
    - failed + unlink throws → existing errors preserved, cleanup appended
    - done + unlink succeeds → clean done envelope (no companion errors)
  text-mode emitter surfaces companion errors on done (60b613d):
    - text-mode done + cleanup error → both ✓ and ⚠ lines surface
    - text-mode done + writer warnings → existing behavior unchanged

Pattern follows test/commands/status.test.ts: TestableCurate subclasses
Curate, overrides protected seams via constructor-injected behavior
callbacks, captures stdout via sinon.stub(process.stdout, 'write')
because writeJsonResponse bypasses this.log.

Full suite: 8890 passing (13 new, 1 added earlier this session).
N
Nguyễn Thuận Phát committed
176906890867bf2ba64af589414a858809d42f7b
Parent: 60b613d