@cesarus777/opencode-cgp 0.4.1 → 0.4.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.
- package/CHANGELOG.md +8 -0
- package/README.md +7 -7
- package/dist/cli.js +415 -180
- package/dist/core.js +88 -59
- package/dist/index.js +710 -166
- package/dist/tui.js +3 -2
- package/dist/types/archive.d.ts +40 -0
- package/dist/types/core.d.ts +1 -1
- package/dist/types/dashboard/controller.d.ts +1 -0
- package/dist/types/dashboard/inventory.d.ts +1 -1
- package/dist/types/dashboard/terminal.d.ts +6 -0
- package/dist/types/dashboard/terminalview.d.ts +2 -0
- package/dist/types/dashboard/view.d.ts +1 -1
- package/dist/types/history.d.ts +39 -2
- package/dist/types/historyserver.d.ts +2 -1
- package/dist/types/modelanalytics.d.ts +11 -0
- package/dist/types/modelanalyticsserver.d.ts +2 -1
- package/package.json +2 -1
package/dist/tui.js
CHANGED
|
@@ -2070,6 +2070,7 @@ function agentLines(row2, width) {
|
|
|
2070
2070
|
const short = `${row2.freshness === "stale" ? "Last measured" : "Ctx"} ${estimate}${percent} \xB7 ${pressure === "Below threshold" ? "Threshold below" : pressure}`;
|
|
2071
2071
|
const lifecycle = compactionLabel(row2);
|
|
2072
2072
|
return [
|
|
2073
|
+
progress(valid2 && row2.utilizationPercent !== undefined ? row2.utilizationPercent / 100 : undefined, width),
|
|
2073
2074
|
...wrap(cells(full) <= width ? full : short, width),
|
|
2074
2075
|
...row2.node.status === "failed" || row2.node.status === "unknown" ? wrap(row2.node.status.toUpperCase(), width) : [],
|
|
2075
2076
|
...row2.freshness !== "fresh" ? wrap(freshnessLabel(row2) ?? "", width) : [],
|
|
@@ -2184,12 +2185,12 @@ function CompactSidebar(props) {
|
|
|
2184
2185
|
const width = () => Math.max(1, Math.min(props.width, measuredWidth()) - 4);
|
|
2185
2186
|
const [collapsed, setCollapsed] = createSignal2(new Set);
|
|
2186
2187
|
const [hideCompleted, setHideCompleted] = createSignal2(true);
|
|
2187
|
-
const [showHistory, setShowHistory] = createSignal2(
|
|
2188
|
+
const [showHistory, setShowHistory] = createSignal2(true);
|
|
2188
2189
|
const [byPressure, setByPressure] = createSignal2(true);
|
|
2189
2190
|
createEffect(() => {
|
|
2190
2191
|
props.sessionID;
|
|
2191
2192
|
setCollapsed(new Set);
|
|
2192
|
-
setShowHistory(
|
|
2193
|
+
setShowHistory(true);
|
|
2193
2194
|
});
|
|
2194
2195
|
const current = createMemo(() => props.rows.find((r) => r.node.sessionId === props.sessionID));
|
|
2195
2196
|
const trace = createMemo(() => props.state.contextTrace(current()));
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type HistoryFilter, type HistoryMetadata, type HistoryRecord, type ScanOptions } from "./history.js";
|
|
2
|
+
export interface ArchiveSnapshot {
|
|
3
|
+
revision: string;
|
|
4
|
+
metadata: HistoryMetadata;
|
|
5
|
+
records: HistoryRecord[];
|
|
6
|
+
iterateRecords?: () => Iterable<HistoryRecord>;
|
|
7
|
+
}
|
|
8
|
+
interface ArchiveOptions extends ScanOptions {
|
|
9
|
+
maxCacheBytes?: number;
|
|
10
|
+
maxCacheRecords?: number;
|
|
11
|
+
maxCacheSegments?: number;
|
|
12
|
+
}
|
|
13
|
+
/** Location-owned cache. Metadata validation assumes external writers do not restore timestamps. */
|
|
14
|
+
export declare class PerformanceArchive {
|
|
15
|
+
readonly path: string;
|
|
16
|
+
private readonly options;
|
|
17
|
+
private entries;
|
|
18
|
+
private generation;
|
|
19
|
+
private stopped;
|
|
20
|
+
private dirty;
|
|
21
|
+
private forcedGeneration;
|
|
22
|
+
private job;
|
|
23
|
+
readonly stats: {
|
|
24
|
+
readBytes: number;
|
|
25
|
+
parsedRecords: number;
|
|
26
|
+
cacheBytes: number;
|
|
27
|
+
cacheRecords: number;
|
|
28
|
+
};
|
|
29
|
+
constructor(path: string, options?: ArchiveOptions);
|
|
30
|
+
/** Writer notifications invalidate even metadata-invisible mutations. */
|
|
31
|
+
invalidate(name?: string): void;
|
|
32
|
+
dispose(): void;
|
|
33
|
+
private account;
|
|
34
|
+
private retain;
|
|
35
|
+
private validCapture;
|
|
36
|
+
private scan;
|
|
37
|
+
read(filter?: HistoryFilter): Promise<ArchiveSnapshot>;
|
|
38
|
+
private wait;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
package/dist/types/core.d.ts
CHANGED
|
@@ -8,5 +8,5 @@ export * from "./snapshot.js";
|
|
|
8
8
|
export * from "./family.js";
|
|
9
9
|
export * from "./performance.js";
|
|
10
10
|
export * from "./charts.js";
|
|
11
|
-
export
|
|
11
|
+
export { analyzeModelRequests, aggregateModels, summarizeModelRequests, type ModelAnalyticsOptions, type AnalyticsRequest, type ModelSummary, type ModelAnalyticsResult, type CompletedAnalyticsRequest, } from "./modelanalytics.js";
|
|
12
12
|
export * from "./modelseries.js";
|
|
@@ -11,6 +11,7 @@ export interface DashboardControllerOptions {
|
|
|
11
11
|
}
|
|
12
12
|
/** Shared application state; subscribers never acquire additional upstream streams. */
|
|
13
13
|
export declare class DashboardController {
|
|
14
|
+
private readonly snapshots;
|
|
14
15
|
private readonly locations;
|
|
15
16
|
private readonly cache;
|
|
16
17
|
private readonly listeners;
|
|
@@ -14,4 +14,4 @@ export interface DashboardInventory {
|
|
|
14
14
|
export declare const inventoryLimits: InventoryLimits;
|
|
15
15
|
export declare function validateInventoryLimits(limits: InventoryLimits): void;
|
|
16
16
|
/** Bounded breadth-first discovery of a whole location, without transcript reads. */
|
|
17
|
-
export declare function discoverInventory(port: Pick<DashboardPort, "location" | "listSessions">, signal: AbortSignal, limits?: InventoryLimits): Promise<DashboardInventory>;
|
|
17
|
+
export declare function discoverInventory(port: Pick<DashboardPort, "location" | "listSessions">, signal: AbortSignal, limits?: InventoryLimits, progress?: (inventory: DashboardInventory) => void): Promise<DashboardInventory>;
|
|
@@ -12,6 +12,9 @@ export interface TerminalKey {
|
|
|
12
12
|
export declare class TerminalShell {
|
|
13
13
|
readonly controller: DashboardController;
|
|
14
14
|
private readonly quit;
|
|
15
|
+
readonly work: {
|
|
16
|
+
formattedOverviewRows: number;
|
|
17
|
+
};
|
|
15
18
|
scroll: number;
|
|
16
19
|
metric: number;
|
|
17
20
|
sample: number;
|
|
@@ -27,6 +30,9 @@ export declare class TerminalShell {
|
|
|
27
30
|
private rowOffset;
|
|
28
31
|
private overviewScope;
|
|
29
32
|
private overviewPage;
|
|
33
|
+
private labelKey;
|
|
34
|
+
private labels;
|
|
35
|
+
private layouts;
|
|
30
36
|
private historyIdentity;
|
|
31
37
|
constructor(controller: DashboardController, quit: () => void);
|
|
32
38
|
private task;
|
|
@@ -3,6 +3,8 @@ export declare function diagnosticRow(row: DashboardRow): string;
|
|
|
3
3
|
export declare function overviewHeading(width: number): string[];
|
|
4
4
|
/** Stable ID suffixes when unique; position is the bounded fallback. */
|
|
5
5
|
export declare function overviewLabels(rows: readonly DashboardRow[]): string[];
|
|
6
|
+
/** Lightweight line count; identity clipping and exception text are viewport work. */
|
|
7
|
+
export declare function overviewRowHeight(row: DashboardRow, width: number, maxLines: number): number;
|
|
6
8
|
/** Each row is already cell-bounded; overview cards never wrap diagnostics. */
|
|
7
9
|
export declare function overviewRowLines(row: DashboardRow, width: number, selected: boolean, label: string, position: number, maxLines?: number): string[];
|
|
8
10
|
export declare const snapshotFields: readonly ["sessionId", "parentId", "agent", "model", "revision", "observedAt", "measurement.tokens", "measurement.at", "measurement.model", "measurement.provenance", "measurement.scope", "measurement.confidence", "measurement.requestId", "limits.input", "limits.context", "limits.output", "capacityTokens", "outputReserveTokens", "peakTokens", "policy.id", "policy.configured.type", "policy.configured.value", "policy.triggerTokens", "policy.comparison", "policy.reason", "policy.crossed", "compaction.phase", "compaction.count", "compaction.armed", "compaction.blockedReason", "compaction.lastAttempt", "compaction.lastCompleted", "compaction.cooldownUntil", "cumulativeScope", "cumulative.input", "cumulative.output", "cumulative.reasoning", "cumulative.cache.read", "cumulative.cache.write", "lastObservedActive", "performance.sessionCreatedAt", "performance.sessionOutputTokens", "performance.observedSince", "performance.at", "performance.status", "performance.partial", "performance.liveTps", "performance.averageModelTps", "performance.averageSessionTps", "performance.ttftMs", "performance.latestRequestTps", "performance.requestId", "performance.requestAgent", "performance.requestModel", "performance.requestOutputTokens", "performance.requestStartedAt", "performance.firstOutputAt", "performance.streamEndedAt", "performance.estimatedOutputTokens", "performance.modelOutputTokens", "performance.modelDurationMs", "performance.completedRequests", "performance.tokenSource"];
|
|
@@ -79,7 +79,7 @@ export type DashboardView = Immutable<{
|
|
|
79
79
|
models: DashboardModels;
|
|
80
80
|
notices: readonly string[];
|
|
81
81
|
}>;
|
|
82
|
-
/**
|
|
82
|
+
/** Copy transport objects once; already-owned immutable subtrees can be shared. */
|
|
83
83
|
export declare function immutableView<T>(value: T): T;
|
|
84
84
|
export declare function projectHistory(result: HistoryChartResult, filters: DashboardFilters): {
|
|
85
85
|
result: HistoryChartResult;
|
package/dist/types/history.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Stats } from "node:fs";
|
|
2
|
+
import { open } from "node:fs/promises";
|
|
1
3
|
import type { Identity, Config } from "./types.js";
|
|
2
4
|
import type { PerformanceSnapshot } from "./performance.js";
|
|
3
5
|
export interface HistoryRecord extends Identity {
|
|
@@ -9,12 +11,47 @@ export interface HistoryRecord extends Identity {
|
|
|
9
11
|
event?: string;
|
|
10
12
|
droppedRecords?: number;
|
|
11
13
|
}
|
|
14
|
+
export declare function segments(directory: string): Promise<{
|
|
15
|
+
bytes: number;
|
|
16
|
+
dev: number;
|
|
17
|
+
ino: number;
|
|
18
|
+
mtimeMs: number;
|
|
19
|
+
ctimeMs: number;
|
|
20
|
+
name: string;
|
|
21
|
+
time: number;
|
|
22
|
+
}[]>;
|
|
23
|
+
export declare function fileIdentity(info: Stats): {
|
|
24
|
+
bytes: number;
|
|
25
|
+
dev: number;
|
|
26
|
+
ino: number;
|
|
27
|
+
mtimeMs: number;
|
|
28
|
+
ctimeMs: number;
|
|
29
|
+
};
|
|
30
|
+
export interface ScanOptions {
|
|
31
|
+
now?: () => number;
|
|
32
|
+
yield?: () => Promise<void>;
|
|
33
|
+
chunkBytes?: number;
|
|
34
|
+
onRead?: (bytes: number) => void;
|
|
35
|
+
onParse?: () => void;
|
|
36
|
+
}
|
|
37
|
+
/** Cooperative scheduling is independent of cancellation. */
|
|
38
|
+
export declare function scanScheduler(signal?: AbortSignal, options?: ScanOptions): () => Promise<void> | undefined;
|
|
39
|
+
export declare function matchesHistory(value: HistoryRecord, filter: HistoryFilter): boolean;
|
|
40
|
+
/** Reads captured bytes only. Byte boundaries retain UTF-8 exactly, including tails. */
|
|
41
|
+
export declare function scanHistorySegment(handle: Awaited<ReturnType<typeof open>>, size: number, filter?: HistoryFilter, options?: ScanOptions, start?: number): Promise<{
|
|
42
|
+
records: HistoryRecord[];
|
|
43
|
+
malformedRecords: number;
|
|
44
|
+
boundary: number;
|
|
45
|
+
completeRecords: number;
|
|
46
|
+
completeMalformed: number;
|
|
47
|
+
}>;
|
|
12
48
|
/** Separate bounded journal; the API accepts only projected scalar measurements. */
|
|
13
49
|
export declare class PerformanceHistory {
|
|
14
50
|
readonly path: string;
|
|
15
51
|
private readonly config;
|
|
16
52
|
private readonly now;
|
|
17
53
|
private readonly report;
|
|
54
|
+
private readonly changed;
|
|
18
55
|
private pending;
|
|
19
56
|
private working;
|
|
20
57
|
private active;
|
|
@@ -23,7 +60,7 @@ export declare class PerformanceHistory {
|
|
|
23
60
|
private disabled;
|
|
24
61
|
private dropped;
|
|
25
62
|
private droppedTotal;
|
|
26
|
-
constructor(path: string, config: Config["history"], now?: () => number, report?: (event: string) => void);
|
|
63
|
+
constructor(path: string, config: Config["history"], now?: () => number, report?: (event: string) => void, changed?: (name: string) => void);
|
|
27
64
|
emit(record: HistoryRecord): void;
|
|
28
65
|
private kick;
|
|
29
66
|
private prune;
|
|
@@ -54,7 +91,7 @@ export interface HistoryMetadata {
|
|
|
54
91
|
malformedRecords: number;
|
|
55
92
|
completeness: string;
|
|
56
93
|
}
|
|
57
|
-
export declare function readPerformanceHistory(directory: string, filter?: HistoryFilter): Promise<{
|
|
94
|
+
export declare function readPerformanceHistory(directory: string, filter?: HistoryFilter, options?: ScanOptions): Promise<{
|
|
58
95
|
metadata: HistoryMetadata;
|
|
59
96
|
records: HistoryRecord[];
|
|
60
97
|
}>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { readPerformanceHistory } from "./history.js";
|
|
1
2
|
import { historyRpc } from "./rpc.js";
|
|
2
3
|
import type { RpcHandlers, RpcRegistration } from "@opencode/plugin/promise/rpc";
|
|
3
4
|
export interface HistoryRpcPort {
|
|
4
5
|
register(definition: typeof historyRpc, handlers: RpcHandlers<typeof historyRpc>): Promise<Pick<RpcRegistration<typeof historyRpc>, "dispose">>;
|
|
5
6
|
}
|
|
6
7
|
/** Read-only archive service. Clients can select an ID/time range, never a filesystem path. */
|
|
7
|
-
export declare function serveHistory(rpc: HistoryRpcPort | undefined, path: string, enabled: boolean, now?: () => number, authorize?: (sessionId: string, signal: AbortSignal) => Promise<boolean
|
|
8
|
+
export declare function serveHistory(rpc: HistoryRpcPort | undefined, path: string, enabled: boolean, now?: () => number, authorize?: (sessionId: string, signal: AbortSignal) => Promise<boolean>, reader?: typeof readPerformanceHistory): Promise<() => void>;
|
|
@@ -60,9 +60,20 @@ export interface ModelAnalyticsResult {
|
|
|
60
60
|
export declare function analyzeModelRequests(records: readonly HistoryRecord[], options: ModelAnalyticsOptions): ModelAnalyticsResult & {
|
|
61
61
|
requests: CompletedAnalyticsRequest[];
|
|
62
62
|
};
|
|
63
|
+
/** Canonical reconciliation state, shared by full and proven-prefix append paths. */
|
|
64
|
+
export declare function createModelAccumulator(options: ModelAnalyticsOptions): {
|
|
65
|
+
append: (records: readonly HistoryRecord[]) => void;
|
|
66
|
+
steps: () => Generator<void, ModelAnalyticsResult & {
|
|
67
|
+
requests: CompletedAnalyticsRequest[];
|
|
68
|
+
}>;
|
|
69
|
+
result: () => ModelAnalyticsResult & {
|
|
70
|
+
requests: CompletedAnalyticsRequest[];
|
|
71
|
+
};
|
|
72
|
+
};
|
|
63
73
|
export interface CompletedAnalyticsRequest extends AnalyticsRequest {
|
|
64
74
|
completedAt: number;
|
|
65
75
|
}
|
|
66
76
|
/** Summarize already reconciled requests, including independent metric eligibility. */
|
|
67
77
|
export declare function summarizeModelRequests(requests: readonly CompletedAnalyticsRequest[]): ModelSummary[];
|
|
78
|
+
export declare function summarizeModelRequestSteps(requests: readonly CompletedAnalyticsRequest[]): Generator<void, ModelSummary[]>;
|
|
68
79
|
export declare function aggregateModels(records: readonly HistoryRecord[], options: ModelAnalyticsOptions): ModelAnalyticsResult;
|
|
@@ -9,8 +9,9 @@ export interface AnalyticsRpcPort {
|
|
|
9
9
|
export declare function createAnalyticsService(path: string, location: string, enabled: boolean, options?: {
|
|
10
10
|
now?: () => number;
|
|
11
11
|
read?: typeof readPerformanceHistory;
|
|
12
|
+
revisioned?: boolean;
|
|
12
13
|
}): {
|
|
13
14
|
read(input: AnalyticsRead, signal: AbortSignal): Promise<AnalyticsResult>;
|
|
14
15
|
dispose(): void;
|
|
15
16
|
};
|
|
16
|
-
export declare function serveModelAnalytics(port: AnalyticsRpcPort | undefined, path: string, location: string, enabled: boolean): Promise<() => void>;
|
|
17
|
+
export declare function serveModelAnalytics(port: AnalyticsRpcPort | undefined, path: string, location: string, enabled: boolean, options?: Parameters<typeof createAnalyticsService>[3]): Promise<() => void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cesarus777/opencode-cgp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"format:check": "prettier --check src tests scripts docs README.md examples package.json tsconfig.json server.ts tui.tsx rpc.ts tsconfig.build.json .github AGENTS.md",
|
|
39
39
|
"test:tui-live": "bun scripts/tui-live.ts",
|
|
40
40
|
"bench:tui": "bun scripts/tui-bench.ts",
|
|
41
|
+
"bench:dashboard": "bun scripts/dashboard-bench.ts",
|
|
41
42
|
"build": "bun scripts/build.ts",
|
|
42
43
|
"prepack": "bun run build",
|
|
43
44
|
"prepare": "bun run build",
|