@rejacky/opencode-insights 0.1.0
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/DEVELOPMENT.md +97 -0
- package/LICENSE +21 -0
- package/README.md +211 -0
- package/dist/capture-gQauLsdn.d.ts +48 -0
- package/dist/chunk-G7E4J6OW.js +257 -0
- package/dist/chunk-G7E4J6OW.js.map +1 -0
- package/dist/chunk-WF6BN2SB.js +462 -0
- package/dist/chunk-WF6BN2SB.js.map +1 -0
- package/dist/cli.d.ts +89 -0
- package/dist/cli.js +1360 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +111 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/tui.d.ts +11 -0
- package/dist/tui.js +234 -0
- package/dist/tui.js.map +1 -0
- package/package.json +68 -0
package/dist/tui.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import {
|
|
2
|
+
applySubagentEvent,
|
|
3
|
+
createMetricsState,
|
|
4
|
+
createSubagentState,
|
|
5
|
+
getSubagentSidebarModel,
|
|
6
|
+
recordAssistantDelta,
|
|
7
|
+
recordAssistantMessage,
|
|
8
|
+
recordToolActivity,
|
|
9
|
+
renderMetricsText,
|
|
10
|
+
renderSubagentFooter
|
|
11
|
+
} from "./chunk-WF6BN2SB.js";
|
|
12
|
+
|
|
13
|
+
// src/tui.tsx
|
|
14
|
+
import { createTextAttributes, StyledText } from "@opentui/core";
|
|
15
|
+
import { onCleanup } from "solid-js";
|
|
16
|
+
import { jsx } from "@opentui/solid/jsx-runtime";
|
|
17
|
+
function isSessionID(value) {
|
|
18
|
+
return typeof value === "string" && value.startsWith("ses");
|
|
19
|
+
}
|
|
20
|
+
function PromptRight(props) {
|
|
21
|
+
let text;
|
|
22
|
+
const sync = () => {
|
|
23
|
+
if (!text) return;
|
|
24
|
+
text.content = props.text();
|
|
25
|
+
props.api.renderer.requestRender();
|
|
26
|
+
};
|
|
27
|
+
const unsubscribe = props.subscribe(sync);
|
|
28
|
+
onCleanup(unsubscribe);
|
|
29
|
+
return /* @__PURE__ */ jsx(
|
|
30
|
+
"text",
|
|
31
|
+
{
|
|
32
|
+
ref: (ref) => {
|
|
33
|
+
text = ref;
|
|
34
|
+
sync();
|
|
35
|
+
},
|
|
36
|
+
fg: props.api.theme.current.textMuted,
|
|
37
|
+
children: props.text()
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
function ReactiveText(props) {
|
|
42
|
+
let text;
|
|
43
|
+
const sync = () => {
|
|
44
|
+
if (!text) return;
|
|
45
|
+
text.content = props.text();
|
|
46
|
+
props.api.renderer.requestRender();
|
|
47
|
+
};
|
|
48
|
+
const unsubscribe = props.subscribe(sync);
|
|
49
|
+
onCleanup(unsubscribe);
|
|
50
|
+
return /* @__PURE__ */ jsx(
|
|
51
|
+
"text",
|
|
52
|
+
{
|
|
53
|
+
ref: (ref) => {
|
|
54
|
+
text = ref;
|
|
55
|
+
sync();
|
|
56
|
+
},
|
|
57
|
+
fg: props.api.theme.current.textMuted,
|
|
58
|
+
children: props.text()
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
function SubagentSidebar(props) {
|
|
63
|
+
let text;
|
|
64
|
+
const titleAttributes = createTextAttributes({ bold: true });
|
|
65
|
+
const sync = () => {
|
|
66
|
+
if (!text) return;
|
|
67
|
+
text.content = renderSubagentStyledSidebar(props.state, props.sessionID, props.api, titleAttributes);
|
|
68
|
+
props.api.renderer.requestRender();
|
|
69
|
+
};
|
|
70
|
+
const unsubscribe = props.subscribe(sync);
|
|
71
|
+
const timer = setInterval(sync, 1e3);
|
|
72
|
+
onCleanup(() => {
|
|
73
|
+
unsubscribe();
|
|
74
|
+
clearInterval(timer);
|
|
75
|
+
});
|
|
76
|
+
return /* @__PURE__ */ jsx(
|
|
77
|
+
"text",
|
|
78
|
+
{
|
|
79
|
+
ref: (ref) => {
|
|
80
|
+
text = ref;
|
|
81
|
+
sync();
|
|
82
|
+
},
|
|
83
|
+
fg: props.api.theme.current.textMuted,
|
|
84
|
+
children: ""
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function renderSubagentStyledSidebar(state, sessionID, api, titleAttributes) {
|
|
89
|
+
const model = getSubagentSidebarModel(state, sessionID);
|
|
90
|
+
if (!model) return "";
|
|
91
|
+
const chunks = [
|
|
92
|
+
textChunk(`${model.title}
|
|
93
|
+
`, api.theme.current.text, titleAttributes),
|
|
94
|
+
textChunk(`${model.summary}
|
|
95
|
+
`, api.theme.current.textMuted)
|
|
96
|
+
];
|
|
97
|
+
for (const [index, row] of model.rows.entries()) {
|
|
98
|
+
if (index > 0) chunks.push(textChunk("\n", api.theme.current.textMuted));
|
|
99
|
+
chunks.push(textChunk(`${row.title}
|
|
100
|
+
`, api.theme.current.text));
|
|
101
|
+
chunks.push(textChunk(row.subtitle, api.theme.current.textMuted));
|
|
102
|
+
}
|
|
103
|
+
return new StyledText(chunks);
|
|
104
|
+
}
|
|
105
|
+
function textChunk(text, fg, attributes) {
|
|
106
|
+
return {
|
|
107
|
+
__isChunk: true,
|
|
108
|
+
text,
|
|
109
|
+
...fg === void 0 ? {} : { fg },
|
|
110
|
+
...attributes === void 0 ? {} : { attributes }
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
var tui = async (api) => {
|
|
114
|
+
const metrics = createMetricsState();
|
|
115
|
+
const subagents = createSubagentState();
|
|
116
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
117
|
+
const bump = () => {
|
|
118
|
+
for (const listener of listeners) listener();
|
|
119
|
+
};
|
|
120
|
+
const subscribe = (listener) => {
|
|
121
|
+
listeners.add(listener);
|
|
122
|
+
return () => listeners.delete(listener);
|
|
123
|
+
};
|
|
124
|
+
const offDelta = api.event.on("message.part.delta", (evt) => {
|
|
125
|
+
if (evt.properties.field !== "text") return;
|
|
126
|
+
recordAssistantDelta(metrics, {
|
|
127
|
+
sessionID: evt.properties.sessionID,
|
|
128
|
+
messageID: evt.properties.messageID,
|
|
129
|
+
delta: evt.properties.delta,
|
|
130
|
+
at: Date.now()
|
|
131
|
+
});
|
|
132
|
+
bump();
|
|
133
|
+
});
|
|
134
|
+
const offMessage = api.event.on("message.updated", (evt) => {
|
|
135
|
+
const info = evt.properties.info;
|
|
136
|
+
if (applySubagentEvent(subagents, evt)) bump();
|
|
137
|
+
if (info.role !== "assistant") return;
|
|
138
|
+
const messageInput = {
|
|
139
|
+
sessionID: info.sessionID ?? evt.properties.sessionID,
|
|
140
|
+
messageID: info.id,
|
|
141
|
+
createdAt: info.time.created,
|
|
142
|
+
outputTokens: info.tokens.output,
|
|
143
|
+
reasoningTokens: info.tokens.reasoning
|
|
144
|
+
};
|
|
145
|
+
if (typeof info.time.completed === "number") messageInput.completedAt = info.time.completed;
|
|
146
|
+
if (typeof info.finish === "string") messageInput.finish = info.finish;
|
|
147
|
+
recordAssistantMessage(metrics, messageInput);
|
|
148
|
+
bump();
|
|
149
|
+
});
|
|
150
|
+
const offPart = api.event.on("message.part.updated", (evt) => {
|
|
151
|
+
const part = evt.properties.part;
|
|
152
|
+
if (part.type === "tool") {
|
|
153
|
+
recordToolActivity(metrics, part.sessionID ?? evt.properties.sessionID, part.messageID, Date.now());
|
|
154
|
+
}
|
|
155
|
+
applySubagentEvent(subagents, evt);
|
|
156
|
+
bump();
|
|
157
|
+
});
|
|
158
|
+
const offSessionCreated = api.event.on("session.created", (evt) => {
|
|
159
|
+
if (applySubagentEvent(subagents, evt)) bump();
|
|
160
|
+
});
|
|
161
|
+
const offSessionUpdated = api.event.on("session.updated", (evt) => {
|
|
162
|
+
if (applySubagentEvent(subagents, evt)) bump();
|
|
163
|
+
});
|
|
164
|
+
const offSessionStatus = api.event.on("session.status", (evt) => {
|
|
165
|
+
if (applySubagentEvent(subagents, evt)) bump();
|
|
166
|
+
});
|
|
167
|
+
const offSessionIdle = api.event.on("session.idle", (evt) => {
|
|
168
|
+
if (applySubagentEvent(subagents, evt)) bump();
|
|
169
|
+
});
|
|
170
|
+
const offSessionError = api.event.on("session.error", (evt) => {
|
|
171
|
+
if (applySubagentEvent(subagents, evt)) bump();
|
|
172
|
+
});
|
|
173
|
+
const offSlots = api.slots.register({
|
|
174
|
+
slots: {
|
|
175
|
+
session_prompt_right: (_ctx, props) => /* @__PURE__ */ jsx(
|
|
176
|
+
PromptRight,
|
|
177
|
+
{
|
|
178
|
+
api,
|
|
179
|
+
sessionID: props.session_id,
|
|
180
|
+
subscribe,
|
|
181
|
+
text: () => {
|
|
182
|
+
if (!isSessionID(props.session_id)) return "";
|
|
183
|
+
const status = api.state.session.status(props.session_id);
|
|
184
|
+
return renderMetricsText(metrics, props.session_id, { idle: status?.type === "idle" });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
),
|
|
188
|
+
home_prompt_right: () => /* @__PURE__ */ jsx(
|
|
189
|
+
PromptRight,
|
|
190
|
+
{
|
|
191
|
+
api,
|
|
192
|
+
sessionID: "",
|
|
193
|
+
subscribe,
|
|
194
|
+
text: () => ""
|
|
195
|
+
}
|
|
196
|
+
),
|
|
197
|
+
sidebar_content: (_ctx, props) => /* @__PURE__ */ jsx(
|
|
198
|
+
SubagentSidebar,
|
|
199
|
+
{
|
|
200
|
+
api,
|
|
201
|
+
sessionID: props.session_id,
|
|
202
|
+
state: subagents,
|
|
203
|
+
subscribe
|
|
204
|
+
}
|
|
205
|
+
),
|
|
206
|
+
sidebar_footer: (_ctx, props) => /* @__PURE__ */ jsx(
|
|
207
|
+
ReactiveText,
|
|
208
|
+
{
|
|
209
|
+
api,
|
|
210
|
+
subscribe,
|
|
211
|
+
text: () => renderSubagentFooter(subagents, props.session_id)
|
|
212
|
+
}
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
api.lifecycle.onDispose(() => {
|
|
217
|
+
offDelta();
|
|
218
|
+
offMessage();
|
|
219
|
+
offPart();
|
|
220
|
+
offSessionCreated();
|
|
221
|
+
offSessionUpdated();
|
|
222
|
+
offSessionStatus();
|
|
223
|
+
offSessionIdle();
|
|
224
|
+
offSessionError();
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
var id = "opencode-insights-tui";
|
|
228
|
+
var tui_default = { id, tui };
|
|
229
|
+
export {
|
|
230
|
+
tui_default as default,
|
|
231
|
+
id,
|
|
232
|
+
tui
|
|
233
|
+
};
|
|
234
|
+
//# sourceMappingURL=tui.js.map
|
package/dist/tui.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tui.tsx"],"sourcesContent":["/** @jsxImportSource @opentui/solid */\nimport { createTextAttributes, StyledText, type TextChunk, type TextRenderable } from \"@opentui/core\";\nimport type { TuiPlugin, TuiPluginApi, TuiPluginModule } from \"@opencode-ai/plugin/tui\";\nimport { onCleanup } from \"solid-js\";\nimport {\n createMetricsState,\n recordAssistantDelta,\n recordAssistantMessage,\n recordToolActivity,\n renderMetricsText\n} from \"./metrics.js\";\nimport {\n applySubagentEvent,\n createSubagentState,\n getSubagentSidebarModel,\n renderSubagentFooter,\n type SubagentState\n} from \"./subagents.js\";\n\ntype Listener = () => void;\n\nfunction isSessionID(value: string | undefined): value is string {\n return typeof value === \"string\" && value.startsWith(\"ses\");\n}\n\nfunction PromptRight(props: {\n api: TuiPluginApi;\n sessionID: string;\n text: () => string;\n subscribe: (listener: Listener) => () => void;\n}) {\n let text: TextRenderable | undefined;\n\n const sync = () => {\n if (!text) return;\n text.content = props.text();\n props.api.renderer.requestRender();\n };\n\n const unsubscribe = props.subscribe(sync);\n onCleanup(unsubscribe);\n\n return (\n <text\n ref={(ref: TextRenderable) => {\n text = ref;\n sync();\n }}\n fg={props.api.theme.current.textMuted}\n >\n {props.text()}\n </text>\n );\n}\n\nfunction ReactiveText(props: {\n api: TuiPluginApi;\n text: () => string;\n subscribe: (listener: Listener) => () => void;\n}) {\n let text: TextRenderable | undefined;\n\n const sync = () => {\n if (!text) return;\n text.content = props.text();\n props.api.renderer.requestRender();\n };\n\n const unsubscribe = props.subscribe(sync);\n onCleanup(unsubscribe);\n\n return (\n <text\n ref={(ref: TextRenderable) => {\n text = ref;\n sync();\n }}\n fg={props.api.theme.current.textMuted}\n >\n {props.text()}\n </text>\n );\n}\n\nfunction SubagentSidebar(props: {\n api: TuiPluginApi;\n sessionID: string;\n state: SubagentState;\n subscribe: (listener: Listener) => () => void;\n}) {\n let text: TextRenderable | undefined;\n const titleAttributes = createTextAttributes({ bold: true });\n\n const sync = () => {\n if (!text) return;\n text.content = renderSubagentStyledSidebar(props.state, props.sessionID, props.api, titleAttributes);\n props.api.renderer.requestRender();\n };\n\n const unsubscribe = props.subscribe(sync);\n const timer = setInterval(sync, 1_000);\n onCleanup(() => {\n unsubscribe();\n clearInterval(timer);\n });\n\n return (\n <text\n ref={(ref: TextRenderable) => {\n text = ref;\n sync();\n }}\n fg={props.api.theme.current.textMuted}\n >\n {\"\"}\n </text>\n );\n}\n\nfunction renderSubagentStyledSidebar(\n state: SubagentState,\n sessionID: string,\n api: TuiPluginApi,\n titleAttributes: number\n) {\n const model = getSubagentSidebarModel(state, sessionID);\n if (!model) return \"\";\n\n const chunks: TextChunk[] = [\n textChunk(`${model.title}\\n`, api.theme.current.text, titleAttributes),\n textChunk(`${model.summary}\\n`, api.theme.current.textMuted)\n ];\n\n for (const [index, row] of model.rows.entries()) {\n if (index > 0) chunks.push(textChunk(\"\\n\", api.theme.current.textMuted));\n chunks.push(textChunk(`${row.title}\\n`, api.theme.current.text));\n chunks.push(textChunk(row.subtitle, api.theme.current.textMuted));\n }\n\n return new StyledText(chunks);\n}\n\nfunction textChunk(text: string, fg?: TextChunk[\"fg\"], attributes?: number): TextChunk {\n return {\n __isChunk: true,\n text,\n ...(fg === undefined ? {} : { fg }),\n ...(attributes === undefined ? {} : { attributes })\n };\n}\n\nconst tui: TuiPlugin = async (api) => {\n const metrics = createMetricsState();\n const subagents = createSubagentState();\n const listeners = new Set<Listener>();\n const bump = () => {\n for (const listener of listeners) listener();\n };\n const subscribe = (listener: Listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n\n const offDelta = api.event.on(\"message.part.delta\", (evt) => {\n if (evt.properties.field !== \"text\") return;\n recordAssistantDelta(metrics, {\n sessionID: evt.properties.sessionID,\n messageID: evt.properties.messageID,\n delta: evt.properties.delta,\n at: Date.now()\n });\n bump();\n });\n\n const offMessage = api.event.on(\"message.updated\", (evt) => {\n const info = evt.properties.info;\n if (applySubagentEvent(subagents, evt)) bump();\n if (info.role !== \"assistant\") return;\n\n const messageInput: {\n sessionID: string;\n messageID: string;\n createdAt: number;\n completedAt?: number;\n outputTokens?: number;\n reasoningTokens?: number;\n finish?: string;\n } = {\n sessionID: info.sessionID ?? evt.properties.sessionID,\n messageID: info.id,\n createdAt: info.time.created,\n outputTokens: info.tokens.output,\n reasoningTokens: info.tokens.reasoning\n };\n if (typeof info.time.completed === \"number\") messageInput.completedAt = info.time.completed;\n if (typeof info.finish === \"string\") messageInput.finish = info.finish;\n recordAssistantMessage(metrics, messageInput);\n bump();\n });\n\n const offPart = api.event.on(\"message.part.updated\", (evt) => {\n const part = evt.properties.part;\n if (part.type === \"tool\") {\n recordToolActivity(metrics, part.sessionID ?? evt.properties.sessionID, part.messageID, Date.now());\n }\n applySubagentEvent(subagents, evt);\n bump();\n });\n\n const offSessionCreated = api.event.on(\"session.created\", (evt) => {\n if (applySubagentEvent(subagents, evt)) bump();\n });\n\n const offSessionUpdated = api.event.on(\"session.updated\", (evt) => {\n if (applySubagentEvent(subagents, evt)) bump();\n });\n\n const offSessionStatus = api.event.on(\"session.status\", (evt) => {\n if (applySubagentEvent(subagents, evt)) bump();\n });\n\n const offSessionIdle = api.event.on(\"session.idle\", (evt) => {\n if (applySubagentEvent(subagents, evt)) bump();\n });\n\n const offSessionError = api.event.on(\"session.error\", (evt) => {\n if (applySubagentEvent(subagents, evt)) bump();\n });\n\n const offSlots = api.slots.register({\n slots: {\n session_prompt_right: (_ctx, props) => (\n <PromptRight\n api={api}\n sessionID={props.session_id}\n subscribe={subscribe}\n text={() => {\n if (!isSessionID(props.session_id)) return \"\";\n const status = api.state.session.status(props.session_id);\n return renderMetricsText(metrics, props.session_id, { idle: status?.type === \"idle\" });\n }}\n />\n ),\n home_prompt_right: () => (\n <PromptRight\n api={api}\n sessionID=\"\"\n subscribe={subscribe}\n text={() => \"\"}\n />\n ),\n sidebar_content: (_ctx, props) => (\n <SubagentSidebar\n api={api}\n sessionID={props.session_id}\n state={subagents}\n subscribe={subscribe}\n />\n ),\n sidebar_footer: (_ctx, props) => (\n <ReactiveText\n api={api}\n subscribe={subscribe}\n text={() => renderSubagentFooter(subagents, props.session_id)}\n />\n )\n }\n });\n\n api.lifecycle.onDispose(() => {\n offDelta();\n offMessage();\n offPart();\n offSessionCreated();\n offSessionUpdated();\n offSessionStatus();\n offSessionIdle();\n offSessionError();\n });\n};\n\nconst id = \"opencode-insights-tui\";\n\nexport { id, tui };\nexport default { id, tui } satisfies TuiPluginModule;\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "@rejacky/opencode-insights",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "OpenCode plugin for local request capture, TPS metrics, and subagent status visibility.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"author": "opencode-insights contributors",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"bin": {
|
|
11
|
+
"opencode-insights": "./dist/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./tui": {
|
|
19
|
+
"types": "./dist/tui.d.ts",
|
|
20
|
+
"import": "./dist/tui.js"
|
|
21
|
+
},
|
|
22
|
+
"./cli": {
|
|
23
|
+
"types": "./dist/cli.d.ts",
|
|
24
|
+
"import": "./dist/cli.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md",
|
|
30
|
+
"DEVELOPMENT.md"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"verify": "npm run typecheck && npm run test && npm run build",
|
|
37
|
+
"prepack": "npm run build",
|
|
38
|
+
"prepublishOnly": "npm run verify"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"opencode",
|
|
42
|
+
"plugin",
|
|
43
|
+
"llm",
|
|
44
|
+
"sqlite",
|
|
45
|
+
"tps",
|
|
46
|
+
"subagent"
|
|
47
|
+
],
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=22.13"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@opencode-ai/plugin": ">=1.15.0 <2",
|
|
54
|
+
"@opentui/core": ">=0.4.0 <0.5",
|
|
55
|
+
"@opentui/solid": ">=0.4.0 <0.5",
|
|
56
|
+
"solid-js": "1.9.12"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@opencode-ai/plugin": "^1.17.13",
|
|
60
|
+
"@opentui/core": "^0.4.3",
|
|
61
|
+
"@opentui/solid": "^0.4.3",
|
|
62
|
+
"@types/node": "^24.12.2",
|
|
63
|
+
"solid-js": "1.9.12",
|
|
64
|
+
"tsup": "^8.5.1",
|
|
65
|
+
"typescript": "^6.0.3",
|
|
66
|
+
"vitest": "^4.1.10"
|
|
67
|
+
}
|
|
68
|
+
}
|