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.
- package/.oesignore +17 -17
- package/CHANGELOG.md +96 -95
- package/LICENSE +21 -21
- package/README.md +150 -235
- package/oes.json +13 -11
- package/package.json +100 -100
- package/scripts/install-git-hooks.mjs +29 -29
- package/src/pware.oc.core/constants/index.ts +18 -18
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventKind.ts +29 -29
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventName.ts +15 -13
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventType.ts +241 -241
- package/src/pware.oc.core/constants/pware.oc.core.constants.myWork.ts +55 -55
- package/src/pware.oc.core/constants/pware.oc.core.constants.partType.ts +65 -65
- package/src/pware.oc.core/constants/pware.oc.core.constants.phase.ts +58 -58
- package/src/pware.oc.core/constants/pware.oc.core.constants.pulse.ts +63 -63
- package/src/pware.oc.core/constants/pware.oc.core.constants.rowKind.ts +34 -34
- package/src/pware.oc.core/constants/pware.oc.core.constants.status.ts +74 -74
- package/src/pware.oc.core/constants/pware.oc.core.constants.toolName.ts +69 -69
- package/src/pware.oc.core/git/index.ts +7 -7
- package/src/pware.oc.core/git/pware.oc.core.git.ts +237 -237
- package/src/pware.oc.core/git/pware.oc.core.gitignore.ts +87 -87
- package/src/pware.oc.core/index.ts +19 -18
- package/src/pware.oc.core/pware.oc.core.bus.ts +42 -42
- package/src/pware.oc.core/pware.oc.core.cache.ts +48 -48
- package/src/pware.oc.core/pware.oc.core.clipboard.ts +97 -97
- package/src/pware.oc.core/pware.oc.core.debug.ts +280 -280
- package/src/pware.oc.core/pware.oc.core.events.ts +79 -79
- package/src/pware.oc.core/pware.oc.core.glyph.ts +135 -135
- package/src/pware.oc.core/pware.oc.core.layout.ts +234 -234
- package/src/pware.oc.core/pware.oc.core.oes.ts +99 -89
- package/src/pware.oc.core/pware.oc.core.paths.ts +240 -240
- package/src/pware.oc.core/pware.oc.core.preview.ts +74 -74
- package/src/pware.oc.core/pware.oc.core.pulse.ts +726 -726
- package/src/pware.oc.core/pware.oc.core.runtimeConfig.ts +41 -0
- package/src/pware.oc.core/pware.oc.core.sqlite.ts +164 -175
- package/src/pware.oc.core/pware.oc.core.sqliteGateway.ts +89 -0
- package/src/pware.oc.core/pware.oc.core.status.ts +214 -214
- package/src/pware.oc.core/pware.oc.core.timing.ts +63 -63
- package/src/pware.oc.core/pware.oc.core.width.ts +215 -215
- package/src/pware.oc.omo/constants/index.ts +15 -15
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.backgroundTask.ts +18 -18
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.boulderStatus.ts +49 -49
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.docKind.ts +29 -29
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.eventName.ts +11 -11
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.planStatus.ts +60 -60
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.reviewStatus.ts +49 -49
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.startWork.ts +25 -25
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.verdict.ts +38 -38
- package/src/pware.oc.omo/index.ts +7 -7
- package/src/pware.oc.omo/resolver/index.ts +19 -19
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approval.ts +179 -179
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalGroup.ts +116 -116
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalState.ts +34 -34
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.boulder.ts +503 -503
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.config.ts +40 -40
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.doc.ts +269 -269
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.draftFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.notepadsFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.plan.ts +155 -155
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.planFile.ts +363 -361
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.proofFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.rulesFile.ts +11 -11
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.runContinuationFile.ts +14 -14
- package/src/pware.oc.opencode/constants/index.ts +10 -10
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.eventName.ts +15 -15
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.fileTouch.ts +18 -18
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.questionKind.ts +45 -45
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.sessionStatus.ts +58 -58
- package/src/pware.oc.opencode/index.ts +8 -8
- package/src/pware.oc.opencode/pware.oc.opencode.events.ts +182 -182
- package/src/pware.oc.opencode/pware.oc.opencode.files.ts +399 -399
- package/src/pware.oc.opencode/resolver/index.ts +223 -170
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.file.ts +150 -162
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.question.ts +149 -185
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.session.ts +248 -211
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.todo.ts +22 -26
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.tool.ts +224 -236
- package/src/pware.oc.perf/index.ts +14 -14
- package/src/pware.oc.perf/pware.oc.perf.asciichart.d.ts +15 -15
- package/src/pware.oc.perf/pware.oc.perf.charts.ts +284 -284
- package/src/pware.oc.perf/pware.oc.perf.reader.ts +962 -927
- package/src/pware.oc.perf/pware.oc.perf.realtime.ts +88 -88
- package/src/pware.oc.perf/pware.oc.perf.realtimeBlock.ts +118 -118
- package/src/pware.oc.perf/pware.oc.perf.realtimeCpuRam.ts +79 -79
- package/src/pware.oc.perf/pware.oc.perf.realtimeSampler.ts +71 -71
- package/src/pware.oc.perf/pware.oc.perf.realtimeTimeline.ts +214 -214
- package/src/pware.oc.perf/pware.oc.perf.self.ts +179 -179
- package/src/pware.oc.perf/pware.oc.perf.view.tsx +463 -462
- package/src/pware.oc.runtime/index.ts +13 -13
- package/src/pware.oc.runtime/pware.oc.runtime.monitor.ts +142 -142
- package/src/pware.oc.runtime/pware.oc.runtime.mywork-enrich.ts +87 -79
- package/src/pware.oc.runtime/pware.oc.runtime.mywork.ts +282 -253
- package/src/pware.oc.runtime/pware.oc.runtime.omoRead.ts +37 -0
- package/src/pware.oc.runtime/pware.oc.runtime.questions.ts +83 -95
- package/src/pware.oc.runtime/pware.oc.runtime.snapshotClient.ts +130 -129
- package/src/pware.oc.runtime/pware.oc.runtime.source.ts +105 -105
- package/src/pware.oc.runtime/pware.oc.runtime.worker.ts +44 -43
- package/src/pware.oc.runtime/resolver/index.ts +268 -224
- package/src/pware.oc.runtime/resolver/pware.oc.runtime.resolver.delegate.ts +146 -146
- package/src/pware.oc.ui/index.ts +12 -12
- package/src/pware.oc.ui/pware.oc.ui.chrome.tsx +381 -339
- package/src/pware.oc.ui/pware.oc.ui.glyphs.tsx +144 -144
- package/src/pware.oc.ui/pware.oc.ui.host.tsx +111 -111
- package/src/pware.oc.ui/pware.oc.ui.live.tsx +82 -82
- package/src/pware.oc.ui/pware.oc.ui.menudialogs.tsx +843 -843
- package/src/pware.oc.ui/pware.oc.ui.sections.tsx +552 -526
- package/src/pware.oc.ui/pware.oc.ui.sidebar.tsx +1718 -1629
- 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
|
+
}
|