oc-plugin-smoke-test 0.0.1 → 0.0.2

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.
Files changed (2) hide show
  1. package/index.tsx +200 -44
  2. package/package.json +1 -1
package/index.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  /** @jsxImportSource @opentui/solid */
2
2
  import { useKeyboard, useTerminalDimensions } from "@opentui/solid"
3
3
  import { RGBA, VignetteEffect } from "@opentui/core"
4
- import type { TuiApi, TuiKeybindSet, TuiPluginInit, TuiPluginInput } from "@opencode-ai/plugin/tui"
4
+ import type { TuiApi, TuiKeybindSet, TuiPluginInit, TuiPluginInput, TuiSlotPlugin } from "@opencode-ai/plugin/tui"
5
5
 
6
6
  const tabs = ["overview", "counter", "help"]
7
7
  const bind = {
@@ -89,24 +89,33 @@ const ui = {
89
89
 
90
90
  type Color = RGBA | string
91
91
 
92
- const tone = (api: TuiApi) => {
93
- const map = api.theme.current as Record<string, unknown>
94
- const get = (name: string, fallback: string): Color => {
95
- const value = map[name]
96
- if (typeof value === "string") return value
97
- if (value && typeof value === "object") return value as RGBA
98
- return fallback
99
- }
92
+ const cash = new Intl.NumberFormat("en-US", {
93
+ style: "currency",
94
+ currency: "USD",
95
+ })
96
+
97
+ const ink = (map: Record<string, unknown>, name: string, fallback: string): Color => {
98
+ const value = map[name]
99
+ if (typeof value === "string") return value
100
+ if (value && typeof value === "object") return value as RGBA
101
+ return fallback
102
+ }
103
+
104
+ const look = (map: Record<string, unknown>) => {
100
105
  return {
101
- panel: get("backgroundPanel", ui.panel),
102
- border: get("border", ui.border),
103
- text: get("text", ui.text),
104
- muted: get("textMuted", ui.muted),
105
- accent: get("primary", ui.accent),
106
- selected: get("selectedListItemText", ui.text),
106
+ panel: ink(map, "backgroundPanel", ui.panel),
107
+ border: ink(map, "border", ui.border),
108
+ text: ink(map, "text", ui.text),
109
+ muted: ink(map, "textMuted", ui.muted),
110
+ accent: ink(map, "primary", ui.accent),
111
+ selected: ink(map, "selectedListItemText", ui.text),
107
112
  }
108
113
  }
109
114
 
115
+ const tone = (api: TuiApi) => {
116
+ return look(api.theme.current as Record<string, unknown>)
117
+ }
118
+
110
119
  type Skin = {
111
120
  panel: Color
112
121
  border: Color
@@ -598,17 +607,12 @@ const Modal = (props: { api: TuiApi; input: Cfg; route: Route; keys: Keys; param
598
607
  )
599
608
  }
600
609
 
601
- const slot = (input: Cfg) => ({
610
+ const slot = (input: Cfg): TuiSlotPlugin => ({
602
611
  id: "workspace-smoke",
603
612
  slots: {
604
613
  home_logo(ctx) {
605
614
  const map = ctx.theme.current as Record<string, unknown>
606
- const get = (name: string, fallback: string) => {
607
- const value = map[name]
608
- if (typeof value === "string") return value
609
- if (value && typeof value === "object") return value as RGBA
610
- return fallback
611
- }
615
+ const skin = look(map)
612
616
  const art = [
613
617
  " $$\\",
614
618
  " $$ |",
@@ -619,39 +623,75 @@ const slot = (input: Cfg) => ({
619
623
  "$$$$$$$ |$$ | $$ | $$ |\\$$$$$$ |$$ | \\$$\\ \\$$$$$$$\\",
620
624
  "\\_______/ \\__| \\__| \\__| \\______/ \\__| \\__| \\_______|",
621
625
  ]
622
- const ink = [
623
- get("primary", ui.accent),
624
- get("textMuted", ui.muted),
625
- get("info", ui.accent),
626
- get("text", ui.text),
627
- get("success", ui.accent),
628
- get("warning", ui.accent),
629
- get("secondary", ui.accent),
630
- get("error", ui.accent),
626
+ const fill = [
627
+ skin.accent,
628
+ skin.muted,
629
+ ink(map, "info", ui.accent),
630
+ skin.text,
631
+ ink(map, "success", ui.accent),
632
+ ink(map, "warning", ui.accent),
633
+ ink(map, "secondary", ui.accent),
634
+ ink(map, "error", ui.accent),
631
635
  ]
632
636
 
633
637
  return (
634
638
  <box flexDirection="column">
635
639
  {art.map((line, i) => (
636
- <text fg={ink[i]}>{line}</text>
640
+ <text fg={fill[i]}>{line}</text>
637
641
  ))}
638
642
  </box>
639
643
  )
640
644
  },
645
+ home_tips(ctx, value) {
646
+ if (!value.show_tips) return null
647
+ const skin = look(ctx.theme.current as Record<string, unknown>)
648
+
649
+ return (
650
+ <box height={4} minHeight={0} width="100%" maxWidth={75} alignItems="center" paddingTop={3} flexShrink={1}>
651
+ <text fg={skin.muted}>
652
+ <span style={{ fg: skin.accent }}>{input.label}</span> replaces the built-in home tips slot
653
+ </text>
654
+ </box>
655
+ )
656
+ },
657
+ home_below_tips(ctx, value) {
658
+ const skin = look(ctx.theme.current as Record<string, unknown>)
659
+ const text = value.first_time_user
660
+ ? "first-time user state"
661
+ : value.tips_hidden
662
+ ? "tips are hidden"
663
+ : "extra content below tips"
664
+
665
+ return (
666
+ <box width="100%" maxWidth={75} alignItems="center" paddingTop={1} flexShrink={0}>
667
+ <box
668
+ border
669
+ borderColor={skin.border}
670
+ backgroundColor={skin.panel}
671
+ paddingTop={1}
672
+ paddingBottom={1}
673
+ paddingLeft={2}
674
+ paddingRight={2}
675
+ width="100%"
676
+ >
677
+ <text fg={skin.muted}>
678
+ <span style={{ fg: skin.accent }}>{input.label}</span> {text}
679
+ </text>
680
+ <text fg={skin.muted}>
681
+ NPM Version
682
+ </text>
683
+ </box>
684
+ </box>
685
+ )
686
+ },
641
687
  sidebar_top(ctx, value) {
642
- const map = ctx.theme.current as Record<string, unknown>
643
- const get = (name: string, fallback: string) => {
644
- const item = map[name]
645
- if (typeof item === "string") return item
646
- if (item && typeof item === "object") return item as RGBA
647
- return fallback
648
- }
688
+ const skin = look(ctx.theme.current as Record<string, unknown>)
649
689
 
650
690
  return (
651
691
  <box
652
692
  border
653
- borderColor={get("border", ui.border)}
654
- backgroundColor={get("backgroundPanel", ui.panel)}
693
+ borderColor={skin.border}
694
+ backgroundColor={skin.panel}
655
695
  paddingTop={1}
656
696
  paddingBottom={1}
657
697
  paddingLeft={2}
@@ -659,11 +699,127 @@ const slot = (input: Cfg) => ({
659
699
  flexDirection="column"
660
700
  gap={1}
661
701
  >
662
- <text fg={get("primary", ui.accent)}>
702
+ <text fg={skin.accent}>
663
703
  <b>{input.label}</b>
664
704
  </text>
665
- <text fg={get("text", ui.text)}>sidebar slot active</text>
666
- <text fg={get("textMuted", ui.muted)}>session {value.session_id.slice(0, 8)}</text>
705
+ <text fg={skin.text}>sidebar slot active</text>
706
+ <text fg={skin.muted}>session {value.session_id.slice(0, 8)}</text>
707
+ </box>
708
+ )
709
+ },
710
+ sidebar_title(ctx, value) {
711
+ const skin = look(ctx.theme.current as Record<string, unknown>)
712
+
713
+ return (
714
+ <box paddingRight={1} flexDirection="column" gap={1}>
715
+ <box flexDirection="row" justifyContent="space-between">
716
+ <text fg={skin.text}>
717
+ <b>{value.title}</b>
718
+ </text>
719
+ <text fg={skin.accent}>plugin</text>
720
+ </box>
721
+ <text fg={skin.muted}>session {value.session_id.slice(0, 8)}</text>
722
+ {value.share_url ? <text fg={skin.muted}>{value.share_url}</text> : null}
723
+ </box>
724
+ )
725
+ },
726
+ sidebar_context(ctx, value) {
727
+ const skin = look(ctx.theme.current as Record<string, unknown>)
728
+ const used = value.percentage === null ? "n/a" : `${value.percentage}%`
729
+ const bar =
730
+ value.percentage === null ? "" : "■".repeat(Math.max(1, Math.min(10, Math.round(value.percentage / 10))))
731
+
732
+ return (
733
+ <box
734
+ border
735
+ borderColor={skin.border}
736
+ backgroundColor={skin.panel}
737
+ paddingTop={1}
738
+ paddingBottom={1}
739
+ paddingLeft={2}
740
+ paddingRight={2}
741
+ flexDirection="column"
742
+ gap={1}
743
+ >
744
+ <box flexDirection="row" justifyContent="space-between">
745
+ <text fg={skin.text}>
746
+ <b>Context</b>
747
+ </text>
748
+ <text fg={skin.accent}>slot</text>
749
+ </box>
750
+ <text fg={skin.text}>{value.tokens.toLocaleString()} tokens</text>
751
+ <text fg={skin.muted}>{bar ? `${used} · ${bar}` : used}</text>
752
+ <text fg={skin.muted}>{cash.format(value.cost)} spent</text>
753
+ </box>
754
+ )
755
+ },
756
+ sidebar_files(ctx, value) {
757
+ if (!value.items.length) return null
758
+ const map = ctx.theme.current as Record<string, unknown>
759
+ const skin = look(map)
760
+ const add = ink(map, "diffAdded", "#7bd389")
761
+ const del = ink(map, "diffRemoved", "#ff8e8e")
762
+ const list = value.items.slice(0, 3)
763
+
764
+ return (
765
+ <box
766
+ border
767
+ borderColor={skin.border}
768
+ backgroundColor={skin.panel}
769
+ paddingTop={1}
770
+ paddingBottom={1}
771
+ paddingLeft={2}
772
+ paddingRight={2}
773
+ flexDirection="column"
774
+ gap={1}
775
+ >
776
+ <box flexDirection="row" justifyContent="space-between">
777
+ <text fg={skin.text}>
778
+ <b>Working Tree</b>
779
+ </text>
780
+ <text fg={skin.accent}>{value.items.length}</text>
781
+ </box>
782
+ {list.map((item) => (
783
+ <box flexDirection="row" gap={1} justifyContent="space-between">
784
+ <text fg={skin.muted} wrapMode="none">
785
+ {item.file}
786
+ </text>
787
+ <text fg={skin.text}>
788
+ {item.additions ? <span style={{ fg: add }}>+{item.additions}</span> : null}
789
+ {item.deletions ? <span style={{ fg: del }}> -{item.deletions}</span> : null}
790
+ </text>
791
+ </box>
792
+ ))}
793
+ {value.items.length > list.length ? (
794
+ <text fg={skin.muted}>+{value.items.length - list.length} more file(s)</text>
795
+ ) : null}
796
+ </box>
797
+ )
798
+ },
799
+ sidebar_bottom(ctx, value) {
800
+ const skin = look(ctx.theme.current as Record<string, unknown>)
801
+
802
+ return (
803
+ <box
804
+ border
805
+ borderColor={skin.border}
806
+ backgroundColor={skin.panel}
807
+ paddingTop={1}
808
+ paddingBottom={1}
809
+ paddingLeft={2}
810
+ paddingRight={2}
811
+ flexDirection="column"
812
+ gap={1}
813
+ >
814
+ <text fg={skin.accent}>
815
+ <b>{input.label} footer slot</b>
816
+ </text>
817
+ <text fg={skin.muted}>
818
+ append demo after {value.show_getting_started ? "welcome card" : "default footer"}
819
+ </text>
820
+ <text fg={skin.text}>
821
+ {value.directory_name} · {value.version}
822
+ </text>
667
823
  </box>
668
824
  )
669
825
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oc-plugin-smoke-test",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.tsx"