* Executes a Template or Capture choice and returns a structured * ChoiceOutcome (used by the URI x-callback handler). Mirrors * execute's envelope (one-page preflight + prompt-draft scope) so behaviour * is identical to the legacy void path; the only addition is surfacing the
( choice: ITemplateChoice | ICaptureChoice, )
| 191 | * which is reported as `error` — never silently as success. |
| 192 | */ |
| 193 | async executeWithOutcome( |
| 194 | choice: ITemplateChoice | ICaptureChoice, |
| 195 | ): Promise<ChoiceOutcome> { |
| 196 | this.pendingAbort = null; |
| 197 | this.pendingResult = null; |
| 198 | this.beginExecutionContext(); |
| 199 | const originLeaf = getOpenFileOriginLeaf(this.app); |
| 200 | const promptDraftStore = InputPromptDraftStore.getInstance(); |
| 201 | promptDraftStore.beginExecutionScope(); |
| 202 | try { |
| 203 | await this.runOnePagePreflightIfEnabled(choice); |
| 204 | |
| 205 | if (choice.type === "Template") { |
| 206 | await this.onChooseTemplateType(choice as ITemplateChoice, originLeaf); |
| 207 | } else { |
| 208 | await this.onChooseCaptureType(choice as ICaptureChoice, originLeaf); |
| 209 | } |
| 210 | |
| 211 | if (this.pendingAbort) { |
| 212 | promptDraftStore.rollbackExecutionScope(); |
| 213 | const abort = this.consumeAbortSignal(); |
| 214 | const isUser = abort instanceof UserCancelError; |
| 215 | return { |
| 216 | status: "cancelled", |
| 217 | cancelKind: isUser ? "user" : "aborted", |
| 218 | // Only surface the message for an involuntary abort (e.g. the |
| 219 | // non-interactive prompt guards). A user dismissal keeps its stable |
| 220 | // "cancelled by user" text and leaks no internals. |
| 221 | reason: isUser ? undefined : abort?.message, |
| 222 | }; |
| 223 | } |
| 224 | |
| 225 | promptDraftStore.commitExecutionScope(); |
| 226 | const result = this.pendingResult; |
| 227 | this.pendingResult = null; |
| 228 | // No success recorded and no abort => the engine swallowed a failure. |
| 229 | return result ?? { status: "error" }; |
| 230 | } catch (error) { |
| 231 | promptDraftStore.rollbackExecutionScope(); |
| 232 | if (error instanceof UserCancelError) { |
| 233 | // Stable user-facing text; no internal message surfaced. |
| 234 | return { status: "cancelled", cancelKind: "user" }; |
| 235 | } |
| 236 | if (error instanceof MacroAbortError) { |
| 237 | return { status: "cancelled", cancelKind: "aborted", reason: error.message }; |
| 238 | } |
| 239 | reportError(error, "Error executing choice from URI"); |
| 240 | return { status: "error" }; |
| 241 | } finally { |
| 242 | this.endExecutionContext(); |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | private async runOnePagePreflightIfEnabled(choice: IChoice): Promise<void> { |
| 247 | // One-page preflight honoring per-choice override. |
no test coverage detected