@mtayfur/opencode-prompt-enhancer 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mtayfur/opencode-prompt-enhancer",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "OpenCode plugin that rewrites rough drafts into stronger prompts.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -16,8 +16,7 @@ const MAX_CHANGED_FILES = 25
16
16
  const MAX_PROMPT_PREVIEW_LENGTH = 250
17
17
  const ENHANCEMENT_TIMEOUT_MS = 60_000
18
18
  const ENHANCEMENT_ANIMATION_INTERVAL_MS = 250
19
- const PROGRESS_TOAST_DURATION_MS = 2_000
20
- const RESULT_TOAST_DURATION_MS = 2_000
19
+ const TOAST_DURATION_MS = 3_000
21
20
  const ENHANCEMENT_CANCELED_MESSAGE = "Prompt enhancement canceled."
22
21
  const ENHANCEMENT_ANIMATION_FRAMES = [
23
22
  "Enhancing prompt",
@@ -36,6 +35,11 @@ type ModelRef = {
36
35
  type Api = Parameters<TuiPlugin>[0]
37
36
  type ActiveEnhancement = {
38
37
  controller: AbortController
38
+ stopAnimation?: () => void
39
+ handle: PromptHandle
40
+ originalPrompt?: TuiPromptInfo
41
+ input: string
42
+ canceled?: boolean
39
43
  }
40
44
 
41
45
  type PluginState = {
@@ -244,6 +248,25 @@ async function restorePrompt(
244
248
  return true
245
249
  }
246
250
 
251
+ async function cancelActiveEnhancement(
252
+ api: Api,
253
+ state: PluginState,
254
+ signal: AbortSignal,
255
+ ): Promise<boolean> {
256
+ const active = state.activeEnhancement
257
+ if (!state.enhancing || !active) return false
258
+
259
+ active.canceled = true
260
+ active.stopAnimation?.()
261
+ active.controller.abort(new Error(ENHANCEMENT_CANCELED_MESSAGE))
262
+
263
+ if (active.originalPrompt) {
264
+ return restorePrompt(api, state, active.handle, active.originalPrompt, signal)
265
+ }
266
+
267
+ return writePrompt(api, state, active.handle, active.input, signal)
268
+ }
269
+
247
270
  function startEnhancementAnimation(
248
271
  api: Api,
249
272
  state: PluginState,
@@ -311,8 +334,6 @@ function gatherContext(api: Api): string {
311
334
  const files = diff.slice(0, MAX_CHANGED_FILES).map((f) => ` @${f.file}`)
312
335
  sections.push(`Files changed in session:\n${files.join("\n")}`)
313
336
  }
314
-
315
-
316
337
  }
317
338
 
318
339
  return sections.join("\n\n")
@@ -435,12 +456,17 @@ function openEnhanceDialog(
435
456
  variant: "info",
436
457
  title: TOAST_TITLE,
437
458
  message: "Enhancing prompt...",
438
- duration: PROGRESS_TOAST_DURATION_MS,
459
+ duration: TOAST_DURATION_MS,
439
460
  })
440
461
 
441
462
  const enhancementController = new AbortController()
442
463
  const onLifecycleAbort = () => enhancementController.abort(signal.reason)
443
- state.activeEnhancement = { controller: enhancementController }
464
+ state.activeEnhancement = {
465
+ controller: enhancementController,
466
+ handle,
467
+ originalPrompt,
468
+ input,
469
+ }
444
470
  if (signal.aborted) {
445
471
  enhancementController.abort(signal.reason)
446
472
  } else {
@@ -461,6 +487,9 @@ function openEnhanceDialog(
461
487
  }
462
488
 
463
489
  stopAnimation = startEnhancementAnimation(api, state, handle, originalPrompt)
490
+ if (state.activeEnhancement) {
491
+ state.activeEnhancement.stopAnimation = stopAnimation
492
+ }
464
493
 
465
494
  const enhanced = await enhanceWithModel(api, options, input, enhancementController.signal)
466
495
  if (signal.aborted) return
@@ -490,13 +519,19 @@ function openEnhanceDialog(
490
519
  variant: "success",
491
520
  title: "Prompt enhanced",
492
521
  message: "Enhanced prompt added to input.",
493
- duration: RESULT_TOAST_DURATION_MS,
522
+ duration: TOAST_DURATION_MS,
494
523
  })
495
524
  } catch (error) {
496
525
  if (signal.aborted) return
497
526
 
498
527
  stopAnimation()
499
528
 
529
+ const canceled = enhancementController.signal.aborted && !signal.aborted
530
+ if (canceled && state.activeEnhancement?.canceled) {
531
+ // cancelActiveEnhancement already stopped the animation and restored the prompt.
532
+ return
533
+ }
534
+
500
535
  let restored = true
501
536
  if (originalPrompt) {
502
537
  try {
@@ -512,8 +547,6 @@ function openEnhanceDialog(
512
547
  restored = false
513
548
  }
514
549
  }
515
-
516
- const canceled = enhancementController.signal.aborted && !signal.aborted
517
550
  const baseMessage = canceled
518
551
  ? ENHANCEMENT_CANCELED_MESSAGE
519
552
  : error instanceof Error
@@ -545,7 +578,26 @@ function revertEnhancement(
545
578
  signal: AbortSignal,
546
579
  ): void {
547
580
  if (state.enhancing && state.activeEnhancement) {
548
- state.activeEnhancement.controller.abort(new Error(ENHANCEMENT_CANCELED_MESSAGE))
581
+ void (async () => {
582
+ try {
583
+ const restored = await cancelActiveEnhancement(api, state, signal)
584
+ if (!restored) {
585
+ api.ui.toast({ variant: "warning", title: TOAST_TITLE, message: "Prompt changed while canceling." })
586
+ return
587
+ }
588
+
589
+ api.ui.toast({
590
+ variant: "info",
591
+ title: TOAST_TITLE,
592
+ message: "Enhancement canceled. Original prompt restored.",
593
+ duration: TOAST_DURATION_MS,
594
+ })
595
+ } catch (error) {
596
+ if (signal.aborted) return
597
+ const message = error instanceof Error ? error.message : "Cancel failed."
598
+ api.ui.toast({ variant: "error", title: TOAST_TITLE, message })
599
+ }
600
+ })()
549
601
  return
550
602
  }
551
603
 
@@ -600,7 +652,7 @@ function revertEnhancement(
600
652
  variant: "success",
601
653
  title: TOAST_TITLE,
602
654
  message: "Reverted to original prompt.",
603
- duration: RESULT_TOAST_DURATION_MS,
655
+ duration: TOAST_DURATION_MS,
604
656
  })
605
657
  } catch (error) {
606
658
  if (signal.aborted) return