opencode-extended-sidebar 0.2.90 → 0.2.91

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 (108) hide show
  1. package/.oesignore +17 -17
  2. package/CHANGELOG.md +96 -95
  3. package/LICENSE +21 -21
  4. package/README.md +150 -235
  5. package/oes.json +13 -11
  6. package/package.json +100 -100
  7. package/scripts/install-git-hooks.mjs +29 -29
  8. package/src/pware.oc.core/constants/index.ts +18 -18
  9. package/src/pware.oc.core/constants/pware.oc.core.constants.eventKind.ts +29 -29
  10. package/src/pware.oc.core/constants/pware.oc.core.constants.eventName.ts +15 -13
  11. package/src/pware.oc.core/constants/pware.oc.core.constants.eventType.ts +241 -241
  12. package/src/pware.oc.core/constants/pware.oc.core.constants.myWork.ts +55 -55
  13. package/src/pware.oc.core/constants/pware.oc.core.constants.partType.ts +65 -65
  14. package/src/pware.oc.core/constants/pware.oc.core.constants.phase.ts +58 -58
  15. package/src/pware.oc.core/constants/pware.oc.core.constants.pulse.ts +63 -63
  16. package/src/pware.oc.core/constants/pware.oc.core.constants.rowKind.ts +34 -34
  17. package/src/pware.oc.core/constants/pware.oc.core.constants.status.ts +74 -74
  18. package/src/pware.oc.core/constants/pware.oc.core.constants.toolName.ts +69 -69
  19. package/src/pware.oc.core/git/index.ts +7 -7
  20. package/src/pware.oc.core/git/pware.oc.core.git.ts +237 -237
  21. package/src/pware.oc.core/git/pware.oc.core.gitignore.ts +87 -87
  22. package/src/pware.oc.core/index.ts +19 -18
  23. package/src/pware.oc.core/pware.oc.core.bus.ts +42 -42
  24. package/src/pware.oc.core/pware.oc.core.cache.ts +48 -48
  25. package/src/pware.oc.core/pware.oc.core.clipboard.ts +97 -97
  26. package/src/pware.oc.core/pware.oc.core.debug.ts +280 -280
  27. package/src/pware.oc.core/pware.oc.core.events.ts +79 -79
  28. package/src/pware.oc.core/pware.oc.core.glyph.ts +135 -135
  29. package/src/pware.oc.core/pware.oc.core.layout.ts +234 -234
  30. package/src/pware.oc.core/pware.oc.core.oes.ts +99 -89
  31. package/src/pware.oc.core/pware.oc.core.paths.ts +240 -240
  32. package/src/pware.oc.core/pware.oc.core.preview.ts +74 -74
  33. package/src/pware.oc.core/pware.oc.core.pulse.ts +726 -726
  34. package/src/pware.oc.core/pware.oc.core.runtimeConfig.ts +41 -0
  35. package/src/pware.oc.core/pware.oc.core.sqlite.ts +164 -175
  36. package/src/pware.oc.core/pware.oc.core.sqliteGateway.ts +89 -0
  37. package/src/pware.oc.core/pware.oc.core.status.ts +214 -214
  38. package/src/pware.oc.core/pware.oc.core.timing.ts +63 -63
  39. package/src/pware.oc.core/pware.oc.core.width.ts +215 -215
  40. package/src/pware.oc.omo/constants/index.ts +15 -15
  41. package/src/pware.oc.omo/constants/pware.oc.omo.constants.backgroundTask.ts +18 -18
  42. package/src/pware.oc.omo/constants/pware.oc.omo.constants.boulderStatus.ts +49 -49
  43. package/src/pware.oc.omo/constants/pware.oc.omo.constants.docKind.ts +29 -29
  44. package/src/pware.oc.omo/constants/pware.oc.omo.constants.eventName.ts +11 -11
  45. package/src/pware.oc.omo/constants/pware.oc.omo.constants.planStatus.ts +60 -60
  46. package/src/pware.oc.omo/constants/pware.oc.omo.constants.reviewStatus.ts +49 -49
  47. package/src/pware.oc.omo/constants/pware.oc.omo.constants.startWork.ts +25 -25
  48. package/src/pware.oc.omo/constants/pware.oc.omo.constants.verdict.ts +38 -38
  49. package/src/pware.oc.omo/index.ts +7 -7
  50. package/src/pware.oc.omo/resolver/index.ts +19 -19
  51. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approval.ts +179 -179
  52. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalGroup.ts +116 -116
  53. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalState.ts +34 -34
  54. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.boulder.ts +503 -503
  55. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.config.ts +40 -40
  56. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.doc.ts +269 -269
  57. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.draftFile.ts +18 -18
  58. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.notepadsFile.ts +18 -18
  59. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.plan.ts +155 -155
  60. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.planFile.ts +363 -361
  61. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.proofFile.ts +18 -18
  62. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.rulesFile.ts +11 -11
  63. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.runContinuationFile.ts +14 -14
  64. package/src/pware.oc.opencode/constants/index.ts +10 -10
  65. package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.eventName.ts +15 -15
  66. package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.fileTouch.ts +18 -18
  67. package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.questionKind.ts +45 -45
  68. package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.sessionStatus.ts +58 -58
  69. package/src/pware.oc.opencode/index.ts +8 -8
  70. package/src/pware.oc.opencode/pware.oc.opencode.events.ts +182 -182
  71. package/src/pware.oc.opencode/pware.oc.opencode.files.ts +399 -399
  72. package/src/pware.oc.opencode/resolver/index.ts +223 -170
  73. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.file.ts +150 -162
  74. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.question.ts +149 -185
  75. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.session.ts +248 -211
  76. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.todo.ts +22 -26
  77. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.tool.ts +224 -236
  78. package/src/pware.oc.perf/index.ts +14 -14
  79. package/src/pware.oc.perf/pware.oc.perf.asciichart.d.ts +15 -15
  80. package/src/pware.oc.perf/pware.oc.perf.charts.ts +284 -284
  81. package/src/pware.oc.perf/pware.oc.perf.reader.ts +962 -927
  82. package/src/pware.oc.perf/pware.oc.perf.realtime.ts +88 -88
  83. package/src/pware.oc.perf/pware.oc.perf.realtimeBlock.ts +118 -118
  84. package/src/pware.oc.perf/pware.oc.perf.realtimeCpuRam.ts +79 -79
  85. package/src/pware.oc.perf/pware.oc.perf.realtimeSampler.ts +71 -71
  86. package/src/pware.oc.perf/pware.oc.perf.realtimeTimeline.ts +214 -214
  87. package/src/pware.oc.perf/pware.oc.perf.self.ts +179 -179
  88. package/src/pware.oc.perf/pware.oc.perf.view.tsx +463 -462
  89. package/src/pware.oc.runtime/index.ts +13 -13
  90. package/src/pware.oc.runtime/pware.oc.runtime.monitor.ts +142 -142
  91. package/src/pware.oc.runtime/pware.oc.runtime.mywork-enrich.ts +87 -79
  92. package/src/pware.oc.runtime/pware.oc.runtime.mywork.ts +282 -253
  93. package/src/pware.oc.runtime/pware.oc.runtime.omoRead.ts +37 -0
  94. package/src/pware.oc.runtime/pware.oc.runtime.questions.ts +83 -95
  95. package/src/pware.oc.runtime/pware.oc.runtime.snapshotClient.ts +130 -129
  96. package/src/pware.oc.runtime/pware.oc.runtime.source.ts +105 -105
  97. package/src/pware.oc.runtime/pware.oc.runtime.worker.ts +44 -43
  98. package/src/pware.oc.runtime/resolver/index.ts +268 -224
  99. package/src/pware.oc.runtime/resolver/pware.oc.runtime.resolver.delegate.ts +146 -146
  100. package/src/pware.oc.ui/index.ts +12 -12
  101. package/src/pware.oc.ui/pware.oc.ui.chrome.tsx +381 -339
  102. package/src/pware.oc.ui/pware.oc.ui.glyphs.tsx +144 -144
  103. package/src/pware.oc.ui/pware.oc.ui.host.tsx +111 -111
  104. package/src/pware.oc.ui/pware.oc.ui.live.tsx +82 -82
  105. package/src/pware.oc.ui/pware.oc.ui.menudialogs.tsx +843 -843
  106. package/src/pware.oc.ui/pware.oc.ui.sections.tsx +552 -526
  107. package/src/pware.oc.ui/pware.oc.ui.sidebar.tsx +1718 -1629
  108. package/src/pware.oc.ui.tsx +98 -98
@@ -1,88 +1,88 @@
1
- /**
2
- * pware.oc.perf.realtime
3
- *
4
- * Real-time metric samples from the live stream. One `StatRealtimeSnapshot`
5
- * carries the leaf series for every category the OES realtime chart renders
6
- * (Tokens / Cache / CPU·RAM / Network); sums are derived via `sumSeries`.
7
- * `StatRealtimeSnapshotHistory` is that sample retained in the rolling RAM
8
- * history (see `pware.oc.perf.realtimeTimeline.ts`). Pure and host-free.
9
- */
10
- import { REALTIME_WINDOW_MS } from "../pware.oc.core/pware.oc.core.timing.js"
11
-
12
- /** Token series — tok/s. `out` is visible output; `reasoning` is hidden thinking. */
13
- export type StatRealtimeTokensSeries = {
14
- in: number | null
15
- out: number | null
16
- reasoning: number | null
17
- }
18
-
19
- /** Token-cache series — tok/s served from / written to cache. */
20
- export type StatRealtimeCacheSeries = {
21
- read: number | null
22
- write: number | null
23
- }
24
-
25
- /** CPU/RAM series — cpu as %, ram as MB. */
26
- export type StatRealtimeCpuRamSeries = {
27
- cpu: number | null
28
- ram: number | null
29
- }
30
-
31
- /**
32
- * Network series — kbit/s, estimated from the token flow (≈ `NETWORK_BYTES_PER_TOKEN`
33
- * per token), not a real socket meter (model traffic lives in the server process).
34
- * Network convention: `in` is data the machine receives (model output + reasoning),
35
- * `out` is data the machine sends (input + cache). Null when idle.
36
- */
37
- export type StatRealtimeNetworkSeries = {
38
- in: number | null
39
- out: number | null
40
- }
41
-
42
- /** Rough bytes-per-token used to turn a token rate into a kbit/s estimate. */
43
- export const NETWORK_BYTES_PER_TOKEN = 4
44
-
45
- /** Token rate (tok/s) → kbit/s at `NETWORK_BYTES_PER_TOKEN`. Null stays null. */
46
- export function tokenRateToKbit(tokPerSec: number | null): number | null {
47
- if (tokPerSec == null) return null
48
- return (tokPerSec * NETWORK_BYTES_PER_TOKEN * 8) / 1000
49
- }
50
-
51
- /** One point-in-time realtime sample across all categories. Rates are null when idle. */
52
- export type StatRealtimeSnapshot = {
53
- at: number
54
- tokens: StatRealtimeTokensSeries
55
- cache: StatRealtimeCacheSeries
56
- cpuRam: StatRealtimeCpuRamSeries
57
- network: StatRealtimeNetworkSeries
58
- }
59
-
60
- /** A realtime sample retained in the rolling history — the same shape as a snapshot. */
61
- export type StatRealtimeSnapshotHistory = StatRealtimeSnapshot
62
-
63
- /** Sum two nullable rates: null only when both are null. */
64
- export function sumSeries(a: number | null, b: number | null): number | null {
65
- if (a == null && b == null) return null
66
- return (a ?? 0) + (b ?? 0)
67
- }
68
-
69
- /** An idle sample at `at` — every series null. */
70
- export function emptyStatRealtimeSnapshot(at = Date.now()): StatRealtimeSnapshot {
71
- return {
72
- at,
73
- tokens: { in: null, out: null, reasoning: null },
74
- cache: { read: null, write: null },
75
- cpuRam: { cpu: null, ram: null },
76
- network: { in: null, out: null },
77
- }
78
- }
79
-
80
- /** Append a sample and drop entries older than the window (immutable). */
81
- export function pushStatRealtimeHistory(
82
- history: readonly StatRealtimeSnapshotHistory[],
83
- snapshot: StatRealtimeSnapshotHistory,
84
- windowMs = REALTIME_WINDOW_MS,
85
- ): StatRealtimeSnapshotHistory[] {
86
- const next = [...history, snapshot]
87
- return next.filter((s) => snapshot.at - s.at <= windowMs)
88
- }
1
+ /**
2
+ * pware.oc.perf.realtime
3
+ *
4
+ * Real-time metric samples from the live stream. One `StatRealtimeSnapshot`
5
+ * carries the leaf series for every category the OES realtime chart renders
6
+ * (Tokens / Cache / CPU·RAM / Network); sums are derived via `sumSeries`.
7
+ * `StatRealtimeSnapshotHistory` is that sample retained in the rolling RAM
8
+ * history (see `pware.oc.perf.realtimeTimeline.ts`). Pure and host-free.
9
+ */
10
+ import { REALTIME_WINDOW_MS } from "../pware.oc.core/pware.oc.core.timing.js"
11
+
12
+ /** Token series — tok/s. `out` is visible output; `reasoning` is hidden thinking. */
13
+ export type StatRealtimeTokensSeries = {
14
+ in: number | null
15
+ out: number | null
16
+ reasoning: number | null
17
+ }
18
+
19
+ /** Token-cache series — tok/s served from / written to cache. */
20
+ export type StatRealtimeCacheSeries = {
21
+ read: number | null
22
+ write: number | null
23
+ }
24
+
25
+ /** CPU/RAM series — cpu as %, ram as MB. */
26
+ export type StatRealtimeCpuRamSeries = {
27
+ cpu: number | null
28
+ ram: number | null
29
+ }
30
+
31
+ /**
32
+ * Network series — kbit/s, estimated from the token flow (≈ `NETWORK_BYTES_PER_TOKEN`
33
+ * per token), not a real socket meter (model traffic lives in the server process).
34
+ * Network convention: `in` is data the machine receives (model output + reasoning),
35
+ * `out` is data the machine sends (input + cache). Null when idle.
36
+ */
37
+ export type StatRealtimeNetworkSeries = {
38
+ in: number | null
39
+ out: number | null
40
+ }
41
+
42
+ /** Rough bytes-per-token used to turn a token rate into a kbit/s estimate. */
43
+ export const NETWORK_BYTES_PER_TOKEN = 4
44
+
45
+ /** Token rate (tok/s) → kbit/s at `NETWORK_BYTES_PER_TOKEN`. Null stays null. */
46
+ export function tokenRateToKbit(tokPerSec: number | null): number | null {
47
+ if (tokPerSec == null) return null
48
+ return (tokPerSec * NETWORK_BYTES_PER_TOKEN * 8) / 1000
49
+ }
50
+
51
+ /** One point-in-time realtime sample across all categories. Rates are null when idle. */
52
+ export type StatRealtimeSnapshot = {
53
+ at: number
54
+ tokens: StatRealtimeTokensSeries
55
+ cache: StatRealtimeCacheSeries
56
+ cpuRam: StatRealtimeCpuRamSeries
57
+ network: StatRealtimeNetworkSeries
58
+ }
59
+
60
+ /** A realtime sample retained in the rolling history — the same shape as a snapshot. */
61
+ export type StatRealtimeSnapshotHistory = StatRealtimeSnapshot
62
+
63
+ /** Sum two nullable rates: null only when both are null. */
64
+ export function sumSeries(a: number | null, b: number | null): number | null {
65
+ if (a == null && b == null) return null
66
+ return (a ?? 0) + (b ?? 0)
67
+ }
68
+
69
+ /** An idle sample at `at` — every series null. */
70
+ export function emptyStatRealtimeSnapshot(at = Date.now()): StatRealtimeSnapshot {
71
+ return {
72
+ at,
73
+ tokens: { in: null, out: null, reasoning: null },
74
+ cache: { read: null, write: null },
75
+ cpuRam: { cpu: null, ram: null },
76
+ network: { in: null, out: null },
77
+ }
78
+ }
79
+
80
+ /** Append a sample and drop entries older than the window (immutable). */
81
+ export function pushStatRealtimeHistory(
82
+ history: readonly StatRealtimeSnapshotHistory[],
83
+ snapshot: StatRealtimeSnapshotHistory,
84
+ windowMs = REALTIME_WINDOW_MS,
85
+ ): StatRealtimeSnapshotHistory[] {
86
+ const next = [...history, snapshot]
87
+ return next.filter((s) => snapshot.at - s.at <= windowMs)
88
+ }
@@ -1,118 +1,118 @@
1
- /**
2
- * pware.oc.perf.realtimeBlock
3
- *
4
- * The static definition of the OES realtime widget: which category tabs exist,
5
- * which selector rows each tab offers, and how each row reads its series from a
6
- * `StatRealtimeSnapshot`. This is a pure, host-free model — the TUI layer
7
- * renders it and owns the runtime state (active tab, fullscreen).
8
- */
9
- import { sumSeries, type StatRealtimeSnapshot, type StatRealtimeSnapshotHistory } from "./pware.oc.perf.realtime.js"
10
-
11
- /** A selector row's series key — unique within its tab. */
12
- export type StatRealtimeSeriesKey =
13
- | "avg"
14
- | "sum"
15
- | "in"
16
- | "out"
17
- | "reasoning"
18
- | "read"
19
- | "write"
20
- | "cpu"
21
- | "ram"
22
- | "tok/s"
23
-
24
- /** One selector row: its key, label, unit, and how to read the series from a sample. */
25
- export type StatRealtimeRowTab = {
26
- key: StatRealtimeSeriesKey
27
- label: string
28
- unit: string
29
- read: (snap: StatRealtimeSnapshot) => number | null
30
- }
31
-
32
- /** A category tab id. */
33
- export type StatRealtimeTabId = "tokens" | "cache" | "cpu-ram" | "network"
34
- /** One category tab: its id, label, unit, and selector rows. */
35
- export type StatRealtimeTab = {
36
- id: StatRealtimeTabId
37
- label: string
38
- unit: string
39
- rows: readonly StatRealtimeRowTab[]
40
- }
41
-
42
- /** The whole realtime widget definition: the tabs the selector offers. */
43
- export type StatRealtimeBlock = {
44
- tabs: readonly StatRealtimeTab[]
45
- }
46
-
47
- /** Extract one selector row's series across history as a chartable `number[]` (null → 0). */
48
- export function seriesValues(
49
- history: readonly StatRealtimeSnapshotHistory[],
50
- read: (snap: StatRealtimeSnapshot) => number | null,
51
- ): number[] {
52
- return history.map((s) => read(s) ?? 0)
53
- }
54
-
55
- /** The tab for `id`, or the first tab if `id` is unknown. */
56
- export function realtimeTab(
57
- tabs: readonly StatRealtimeTab[],
58
- id: StatRealtimeTabId,
59
- ): StatRealtimeTab {
60
- return tabs.find((t) => t.id === id) ?? tabs[0]!
61
- }
62
-
63
- /** The selector row for `key` on `tab`, or the tab's first row if `key` is missing. */
64
- export function realtimeRow(
65
- tab: StatRealtimeTab,
66
- key: StatRealtimeSeriesKey,
67
- ): StatRealtimeRowTab {
68
- return tab.rows.find((r) => r.key === key) ?? tab.rows[0]!
69
- }
70
-
71
- /** The default OES realtime block. Network is estimated from the token flow (kbit/s). */
72
- export const STAT_REALTIME_BLOCK: StatRealtimeBlock = {
73
- tabs: [
74
- {
75
- id: "tokens",
76
- label: "Tok",
77
- unit: "tok/s",
78
- rows: [
79
- // avg is the OES bar's old live reading — the chart smooths this series.
80
- { key: "avg", label: "avg", unit: "tok/s", read: (s) => sumSeries(s.tokens.in, s.tokens.out) },
81
- { key: "sum", label: "sum", unit: "tok/s", read: (s) => sumSeries(s.tokens.in, s.tokens.out) },
82
- { key: "in", label: "in", unit: "tok/s", read: (s) => s.tokens.in },
83
- { key: "out", label: "out", unit: "tok/s", read: (s) => s.tokens.out },
84
- // tok/s duplicates sum (in+out) — kept as the bar's old label per UX.
85
- { key: "tok/s", label: "tok/s", unit: "tok/s", read: (s) => sumSeries(s.tokens.in, s.tokens.out) },
86
- ],
87
- },
88
- {
89
- id: "cache",
90
- label: "Cache",
91
- unit: "tok/s",
92
- rows: [
93
- { key: "sum", label: "sum", unit: "tok/s", read: (s) => sumSeries(s.cache.read, s.cache.write) },
94
- { key: "read", label: "read", unit: "tok/s", read: (s) => s.cache.read },
95
- { key: "write", label: "write", unit: "tok/s", read: (s) => s.cache.write },
96
- ],
97
- },
98
- {
99
- id: "cpu-ram",
100
- label: "Proc",
101
- unit: "%/MB",
102
- rows: [
103
- { key: "cpu", label: "cpu", unit: "%", read: (s) => s.cpuRam.cpu },
104
- { key: "ram", label: "ram", unit: "MB", read: (s) => s.cpuRam.ram },
105
- ],
106
- },
107
- {
108
- id: "network",
109
- label: "Net",
110
- unit: "kbit/s",
111
- rows: [
112
- { key: "in", label: "in", unit: "kbit/s", read: (s) => s.network.in },
113
- { key: "out", label: "out", unit: "kbit/s", read: (s) => s.network.out },
114
- { key: "sum", label: "sum", unit: "kbit/s", read: (s) => sumSeries(s.network.in, s.network.out) },
115
- ],
116
- },
117
- ],
118
- }
1
+ /**
2
+ * pware.oc.perf.realtimeBlock
3
+ *
4
+ * The static definition of the OES realtime widget: which category tabs exist,
5
+ * which selector rows each tab offers, and how each row reads its series from a
6
+ * `StatRealtimeSnapshot`. This is a pure, host-free model — the TUI layer
7
+ * renders it and owns the runtime state (active tab, fullscreen).
8
+ */
9
+ import { sumSeries, type StatRealtimeSnapshot, type StatRealtimeSnapshotHistory } from "./pware.oc.perf.realtime.js"
10
+
11
+ /** A selector row's series key — unique within its tab. */
12
+ export type StatRealtimeSeriesKey =
13
+ | "avg"
14
+ | "sum"
15
+ | "in"
16
+ | "out"
17
+ | "reasoning"
18
+ | "read"
19
+ | "write"
20
+ | "cpu"
21
+ | "ram"
22
+ | "tok/s"
23
+
24
+ /** One selector row: its key, label, unit, and how to read the series from a sample. */
25
+ export type StatRealtimeRowTab = {
26
+ key: StatRealtimeSeriesKey
27
+ label: string
28
+ unit: string
29
+ read: (snap: StatRealtimeSnapshot) => number | null
30
+ }
31
+
32
+ /** A category tab id. */
33
+ export type StatRealtimeTabId = "tokens" | "cache" | "cpu-ram" | "network"
34
+ /** One category tab: its id, label, unit, and selector rows. */
35
+ export type StatRealtimeTab = {
36
+ id: StatRealtimeTabId
37
+ label: string
38
+ unit: string
39
+ rows: readonly StatRealtimeRowTab[]
40
+ }
41
+
42
+ /** The whole realtime widget definition: the tabs the selector offers. */
43
+ export type StatRealtimeBlock = {
44
+ tabs: readonly StatRealtimeTab[]
45
+ }
46
+
47
+ /** Extract one selector row's series across history as a chartable `number[]` (null → 0). */
48
+ export function seriesValues(
49
+ history: readonly StatRealtimeSnapshotHistory[],
50
+ read: (snap: StatRealtimeSnapshot) => number | null,
51
+ ): number[] {
52
+ return history.map((s) => read(s) ?? 0)
53
+ }
54
+
55
+ /** The tab for `id`, or the first tab if `id` is unknown. */
56
+ export function realtimeTab(
57
+ tabs: readonly StatRealtimeTab[],
58
+ id: StatRealtimeTabId,
59
+ ): StatRealtimeTab {
60
+ return tabs.find((t) => t.id === id) ?? tabs[0]!
61
+ }
62
+
63
+ /** The selector row for `key` on `tab`, or the tab's first row if `key` is missing. */
64
+ export function realtimeRow(
65
+ tab: StatRealtimeTab,
66
+ key: StatRealtimeSeriesKey,
67
+ ): StatRealtimeRowTab {
68
+ return tab.rows.find((r) => r.key === key) ?? tab.rows[0]!
69
+ }
70
+
71
+ /** The default OES realtime block. Network is estimated from the token flow (kbit/s). */
72
+ export const STAT_REALTIME_BLOCK: StatRealtimeBlock = {
73
+ tabs: [
74
+ {
75
+ id: "tokens",
76
+ label: "Tok",
77
+ unit: "tok/s",
78
+ rows: [
79
+ // avg is the OES bar's old live reading — the chart smooths this series.
80
+ { key: "avg", label: "avg", unit: "tok/s", read: (s) => sumSeries(s.tokens.in, s.tokens.out) },
81
+ { key: "sum", label: "sum", unit: "tok/s", read: (s) => sumSeries(s.tokens.in, s.tokens.out) },
82
+ { key: "in", label: "in", unit: "tok/s", read: (s) => s.tokens.in },
83
+ { key: "out", label: "out", unit: "tok/s", read: (s) => s.tokens.out },
84
+ // tok/s duplicates sum (in+out) — kept as the bar's old label per UX.
85
+ { key: "tok/s", label: "tok/s", unit: "tok/s", read: (s) => sumSeries(s.tokens.in, s.tokens.out) },
86
+ ],
87
+ },
88
+ {
89
+ id: "cache",
90
+ label: "Cache",
91
+ unit: "tok/s",
92
+ rows: [
93
+ { key: "sum", label: "sum", unit: "tok/s", read: (s) => sumSeries(s.cache.read, s.cache.write) },
94
+ { key: "read", label: "read", unit: "tok/s", read: (s) => s.cache.read },
95
+ { key: "write", label: "write", unit: "tok/s", read: (s) => s.cache.write },
96
+ ],
97
+ },
98
+ {
99
+ id: "cpu-ram",
100
+ label: "Proc",
101
+ unit: "%/MB",
102
+ rows: [
103
+ { key: "cpu", label: "cpu", unit: "%", read: (s) => s.cpuRam.cpu },
104
+ { key: "ram", label: "ram", unit: "MB", read: (s) => s.cpuRam.ram },
105
+ ],
106
+ },
107
+ {
108
+ id: "network",
109
+ label: "Net",
110
+ unit: "kbit/s",
111
+ rows: [
112
+ { key: "in", label: "in", unit: "kbit/s", read: (s) => s.network.in },
113
+ { key: "out", label: "out", unit: "kbit/s", read: (s) => s.network.out },
114
+ { key: "sum", label: "sum", unit: "kbit/s", read: (s) => sumSeries(s.network.in, s.network.out) },
115
+ ],
116
+ },
117
+ ],
118
+ }
@@ -1,79 +1,79 @@
1
- /**
2
- * pware.oc.perf.realtimeCpuRam
3
- *
4
- * Process-level CPU/RAM reading for the OES realtime block. CPU% is the
5
- * OpenCode process's load across all cores; RAM is its resident set. Both come
6
- * from Node/Bun built-ins (`process.cpuUsage`, `process.memoryUsage`,
7
- * `os.cpus`), so they work identically on Linux, macOS and Windows with no
8
- * dependencies. The sampling math is pure and exported for tests; the host
9
- * read helpers (`readCpuRam`, `cpuCores`) are thin edges the UI tick calls.
10
- */
11
- import os from "node:os"
12
-
13
- /** A raw CPU/RAM reading: cumulative CPU µs (user/system) + resident bytes. */
14
- export type CpuRamReading = {
15
- user: number
16
- system: number
17
- rss: number
18
- }
19
-
20
- /** One raw reading from the host: process CPU µs since start + resident bytes. Never throws. */
21
- export function readCpuRam(): CpuRamReading {
22
- try {
23
- const cpu = process.cpuUsage()
24
- return { user: cpu.user, system: cpu.system, rss: process.memoryUsage().rss }
25
- } catch {
26
- return { user: 0, system: 0, rss: 0 }
27
- }
28
- }
29
-
30
- /** Logical CPU count — divides CPU% so a full core is never above 100. */
31
- export function cpuCores(): number {
32
- return os.cpus().length
33
- }
34
-
35
- /** A reading stamped with when it was taken. */
36
- export type CpuRamStampedReading = CpuRamReading & { at: number }
37
-
38
- /** Process CPU% over an interval, relative to `cores` cores. Null when unmeasurable. */
39
- export function cpuPercent(
40
- prev: CpuRamReading,
41
- next: CpuRamReading,
42
- wallMs: number,
43
- cores: number,
44
- ): number | null {
45
- if (wallMs <= 0 || cores <= 0) return null
46
- const usedMs = (next.user - prev.user + next.system - prev.system) / 1000
47
- return (usedMs / wallMs / cores) * 100
48
- }
49
-
50
- /**
51
- * CPU% across a rolling window of stamped readings (oldest first): the delta
52
- * between the newest and the first reading still inside the window, over their
53
- * wall span. Null while fewer than two readings fit. This is what damps the
54
- * fine sampling cadence into a stable utilisation number.
55
- */
56
- export function cpuPercentOverWindow(
57
- readings: readonly CpuRamStampedReading[],
58
- cores: number,
59
- windowMs: number,
60
- ): number | null {
61
- if (cores <= 0 || windowMs <= 0 || readings.length < 2) return null
62
- const last = readings[readings.length - 1]!
63
- const minAt = last.at - windowMs
64
- let first = readings[0]!
65
- for (let i = 0; i < readings.length; i += 1) {
66
- if (readings[i]!.at >= minAt) {
67
- first = readings[i]!
68
- break
69
- }
70
- }
71
- const wall = last.at - first.at
72
- if (wall <= 0) return null
73
- return cpuPercent(first, last, wall, cores)
74
- }
75
-
76
- /** Resident bytes → MB. */
77
- export function ramMb(rssBytes: number): number {
78
- return rssBytes / (1024 * 1024)
79
- }
1
+ /**
2
+ * pware.oc.perf.realtimeCpuRam
3
+ *
4
+ * Process-level CPU/RAM reading for the OES realtime block. CPU% is the
5
+ * OpenCode process's load across all cores; RAM is its resident set. Both come
6
+ * from Node/Bun built-ins (`process.cpuUsage`, `process.memoryUsage`,
7
+ * `os.cpus`), so they work identically on Linux, macOS and Windows with no
8
+ * dependencies. The sampling math is pure and exported for tests; the host
9
+ * read helpers (`readCpuRam`, `cpuCores`) are thin edges the UI tick calls.
10
+ */
11
+ import os from "node:os"
12
+
13
+ /** A raw CPU/RAM reading: cumulative CPU µs (user/system) + resident bytes. */
14
+ export type CpuRamReading = {
15
+ user: number
16
+ system: number
17
+ rss: number
18
+ }
19
+
20
+ /** One raw reading from the host: process CPU µs since start + resident bytes. Never throws. */
21
+ export function readCpuRam(): CpuRamReading {
22
+ try {
23
+ const cpu = process.cpuUsage()
24
+ return { user: cpu.user, system: cpu.system, rss: process.memoryUsage().rss }
25
+ } catch {
26
+ return { user: 0, system: 0, rss: 0 }
27
+ }
28
+ }
29
+
30
+ /** Logical CPU count — divides CPU% so a full core is never above 100. */
31
+ export function cpuCores(): number {
32
+ return os.cpus().length
33
+ }
34
+
35
+ /** A reading stamped with when it was taken. */
36
+ export type CpuRamStampedReading = CpuRamReading & { at: number }
37
+
38
+ /** Process CPU% over an interval, relative to `cores` cores. Null when unmeasurable. */
39
+ export function cpuPercent(
40
+ prev: CpuRamReading,
41
+ next: CpuRamReading,
42
+ wallMs: number,
43
+ cores: number,
44
+ ): number | null {
45
+ if (wallMs <= 0 || cores <= 0) return null
46
+ const usedMs = (next.user - prev.user + next.system - prev.system) / 1000
47
+ return (usedMs / wallMs / cores) * 100
48
+ }
49
+
50
+ /**
51
+ * CPU% across a rolling window of stamped readings (oldest first): the delta
52
+ * between the newest and the first reading still inside the window, over their
53
+ * wall span. Null while fewer than two readings fit. This is what damps the
54
+ * fine sampling cadence into a stable utilisation number.
55
+ */
56
+ export function cpuPercentOverWindow(
57
+ readings: readonly CpuRamStampedReading[],
58
+ cores: number,
59
+ windowMs: number,
60
+ ): number | null {
61
+ if (cores <= 0 || windowMs <= 0 || readings.length < 2) return null
62
+ const last = readings[readings.length - 1]!
63
+ const minAt = last.at - windowMs
64
+ let first = readings[0]!
65
+ for (let i = 0; i < readings.length; i += 1) {
66
+ if (readings[i]!.at >= minAt) {
67
+ first = readings[i]!
68
+ break
69
+ }
70
+ }
71
+ const wall = last.at - first.at
72
+ if (wall <= 0) return null
73
+ return cpuPercent(first, last, wall, cores)
74
+ }
75
+
76
+ /** Resident bytes → MB. */
77
+ export function ramMb(rssBytes: number): number {
78
+ return rssBytes / (1024 * 1024)
79
+ }