@pinta-ai/pinta-opencode 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.
@@ -0,0 +1,53 @@
1
+ import { buildOtlpPayload } from "./core/otlp.js";
2
+ /**
3
+ * Maps opencode hook payloads to OTLP spans (verified payload shapes — SPEC §5).
4
+ * Tool spans are built from tool.execute.before/after (richer: args, output,
5
+ * exit) rather than the event bus; `event` covers lifecycle + turn boundaries.
6
+ */
7
+ export class Telemetry {
8
+ transport;
9
+ trace;
10
+ config;
11
+ constructor(transport, trace, config) {
12
+ this.transport = transport;
13
+ this.trace = trace;
14
+ this.config = config;
15
+ }
16
+ async emit(name, sessionId, fields, guard) {
17
+ const traceId = this.trace.currentTrace(sessionId);
18
+ const payload = buildOtlpPayload({ name, traceId, fields, guard, serviceVersion: this.config.serviceVersion });
19
+ await this.transport.send(payload);
20
+ }
21
+ /** Lifecycle span from the `event` hook. Flushes the retry buffer on turn-END. */
22
+ async lifecycle(ev) {
23
+ const props = ev.properties ?? {};
24
+ const sessionId = typeof props.sessionID === "string" ? props.sessionID : undefined;
25
+ await this.emit(`opencode.event.${ev.type ?? "unknown"}`, sessionId, {
26
+ kind: "event",
27
+ event_type: ev.type,
28
+ session_id: sessionId,
29
+ ...props,
30
+ });
31
+ if (ev.type === "session.idle")
32
+ await this.transport.flush();
33
+ }
34
+ /** Tool span from `tool.execute.before`, carrying the guard decision. */
35
+ async toolBefore(input, args, guard) {
36
+ await this.emit("opencode.tool.before", input.sessionID, { kind: "tool.before", tool: input.tool, session_id: input.sessionID, call_id: input.callID, args }, guard);
37
+ }
38
+ /** Tool result span from `tool.execute.after`, incl. exit code / truncation. */
39
+ async toolAfter(input, output) {
40
+ const meta = output.metadata ?? {};
41
+ await this.emit("opencode.tool.after", input.sessionID, {
42
+ kind: "tool.after",
43
+ tool: input.tool,
44
+ session_id: input.sessionID,
45
+ call_id: input.callID,
46
+ title: output.title,
47
+ output: output.output,
48
+ exit: meta.exit,
49
+ truncated: meta.truncated,
50
+ });
51
+ }
52
+ }
53
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAsBlD;;;;GAIG;AACH,MAAM,OAAO,SAAS;IAEV;IACA;IACA;IAHV,YACU,SAAoB,EACpB,KAAmB,EACnB,MAAsB;QAFtB,cAAS,GAAT,SAAS,CAAW;QACpB,UAAK,GAAL,KAAK,CAAc;QACnB,WAAM,GAAN,MAAM,CAAgB;IAC7B,CAAC;IAEI,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,SAA6B,EAAE,MAA+B,EAAE,KAA0B;QACzH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;QAC/G,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,kFAAkF;IAClF,KAAK,CAAC,SAAS,CAAC,EAAiB;QAC/B,MAAM,KAAK,GAAG,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACpF,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,IAAI,IAAI,SAAS,EAAE,EAAE,SAAS,EAAE;YACnE,IAAI,EAAE,OAAO;YACb,UAAU,EAAE,EAAE,CAAC,IAAI;YACnB,UAAU,EAAE,SAAS;YACrB,GAAG,KAAK;SACT,CAAC,CAAC;QACH,IAAI,EAAE,CAAC,IAAI,KAAK,cAAc;YAAE,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IAC/D,CAAC;IAED,yEAAyE;IACzE,KAAK,CAAC,UAAU,CAAC,KAAsB,EAAE,IAAa,EAAE,KAAyB;QAC/E,MAAM,IAAI,CAAC,IAAI,CACb,sBAAsB,EACtB,KAAK,CAAC,SAAS,EACf,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EACnG,KAAK,CACN,CAAC;IACJ,CAAC;IAED,gFAAgF;IAChF,KAAK,CAAC,SAAS,CAAC,KAAsB,EAAE,MAAuB;QAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAC,SAAS,EAAE;YACtD,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,OAAO,EAAE,KAAK,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@pinta-ai/pinta-opencode",
3
+ "version": "0.1.0",
4
+ "description": "OTLP forwarder + guard for opencode (in-process plugin)",
5
+ "type": "module",
6
+ "main": "dist/plugin.js",
7
+ "exports": {
8
+ ".": "./dist/plugin.js"
9
+ },
10
+ "license": "PolyForm-Noncommercial-1.0.0",
11
+ "engines": {
12
+ "opencode": ">=1.15.0"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "LICENSE",
17
+ "README.md",
18
+ "CHANGELOG.md"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+ssh://git@github.com/pinta-ai/pinta-opencode.git"
23
+ },
24
+ "homepage": "https://github.com/pinta-ai/pinta-opencode#readme",
25
+ "bugs": {
26
+ "url": "https://github.com/pinta-ai/pinta-opencode/issues"
27
+ },
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "dev": "tsc --watch",
31
+ "test": "vitest run",
32
+ "test:watch": "vitest",
33
+ "prepublishOnly": "npm run build"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^22.0.0",
37
+ "typescript": "^5.7.0",
38
+ "vitest": "^2.1.0"
39
+ }
40
+ }