opencode-logger 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/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # opencode-logger
2
+
3
+ This small package is intended to be used as [Opencode](https://opencode.ai) plugin.
4
+
5
+ See [plugins documentation](https://opencode.ai/docs/plugins/).
6
+
7
+ This plugin handles logging of all supported [events](https://opencode.ai/docs/plugins/#events).
8
+
9
+ Events are logged as [jsonl](https://jsonlines.org/) to the
10
+
11
+ ```bash
12
+ <project-root>/logs/opencode/log.jsonl
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ In your project open (or set) your `opencode.json` or `opencode.jsonc` file
18
+ and add:
19
+
20
+ ```jsonc
21
+ {
22
+ "$schema": "https://opencode.ai/config.json",
23
+ "plugin": ["opencode-logger"]
24
+ }
25
+ ```
26
+
27
+
package/bunfig.toml ADDED
@@ -0,0 +1,3 @@
1
+ [test]
2
+
3
+ root = "./src/__tests__"
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Directory where logs will be stored relative to the project root.
3
+ */
4
+ export declare const LOG_DIRECTORY = "logs/opencode";
5
+ /**
6
+ * Filename for the log file.
7
+ */
8
+ export declare const LOG_FILENAME = "log.jsonl";
9
+ /**
10
+ * List of event types supported by the logger plugin.
11
+ * These events correspond to various lifecycle hooks and actions within the Opencode environment.
12
+ */
13
+ export declare const SUPPORTED_EVENTS: readonly ["command.executed", "file.edited", "file.watcher.updated", "installation.updated", "lsp.client.diagnostics", "lsp.updated", "message.part.removed", "message.part.updated", "message.removed", "message.updated", "permission.replied", "permission.updated", "server.connected", "session.created", "session.compacted", "session.deleted", "session.diff", "session.error", "session.idle", "session.status", "session.updated", "todo.updated", "tool.execute.after", "tool.execute.before", "tui.prompt.append", "tui.command.execute", "tui.toast.show"];
14
+ /**
15
+ * Type definition derived from the supported events constant.
16
+ */
17
+ export type SupportedEvent = (typeof SUPPORTED_EVENTS)[number];
18
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,gBAAgB,yiBA4BnB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Directory where logs will be stored relative to the project root.
3
+ */
4
+ export const LOG_DIRECTORY = "logs/opencode";
5
+ /**
6
+ * Filename for the log file.
7
+ */
8
+ export const LOG_FILENAME = "log.jsonl";
9
+ /**
10
+ * List of event types supported by the logger plugin.
11
+ * These events correspond to various lifecycle hooks and actions within the Opencode environment.
12
+ */
13
+ export const SUPPORTED_EVENTS = [
14
+ "command.executed",
15
+ "file.edited",
16
+ "file.watcher.updated",
17
+ "installation.updated",
18
+ "lsp.client.diagnostics",
19
+ "lsp.updated",
20
+ "message.part.removed",
21
+ "message.part.updated",
22
+ "message.removed",
23
+ "message.updated",
24
+ "permission.replied",
25
+ "permission.updated",
26
+ "server.connected",
27
+ "session.created",
28
+ "session.compacted",
29
+ "session.deleted",
30
+ "session.diff",
31
+ "session.error",
32
+ "session.idle",
33
+ "session.status",
34
+ "session.updated",
35
+ "todo.updated",
36
+ "tool.execute.after",
37
+ "tool.execute.before",
38
+ "tui.prompt.append",
39
+ "tui.command.execute",
40
+ "tui.toast.show",
41
+ ];
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Interface representing a single log entry in the log file.
3
+ */
4
+ export interface LogEntry {
5
+ /** ISO 8601 timestamp of when the event occurred. */
6
+ timestamp: string;
7
+ /** The type of event being logged (e.g., "session.created", "tool.execute.before"). */
8
+ eventType: string;
9
+ /** The data payload associated with the event. */
10
+ payload: unknown;
11
+ }
12
+ /**
13
+ * Handles initialization of the log directory and writing log entries to the file system.
14
+ */
15
+ export declare class FileLogger {
16
+ private logFilePath;
17
+ /**
18
+ * Creates a new instance of FileLogger.
19
+ * @param projectRoot - The absolute path to the root of the project.
20
+ */
21
+ constructor(projectRoot: string);
22
+ /**
23
+ * Initializes the logger by ensuring the log directory exists.
24
+ * This method should be called before attempting to log any events.
25
+ */
26
+ init(): Promise<void>;
27
+ /**
28
+ * Logs an event and its payload to the log file in JSONL format.
29
+ * @param eventType - The type of event to log.
30
+ * @param payload - The data associated with the event.
31
+ */
32
+ log(eventType: string, payload: unknown): Promise<void>;
33
+ }
34
+ //# sourceMappingURL=file-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-logger.d.ts","sourceRoot":"","sources":["../src/file-logger.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,OAAO,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,UAAU;IACtB,OAAO,CAAC,WAAW,CAAS;IAE5B;;;OAGG;gBACS,WAAW,EAAE,MAAM;IAI/B;;;OAGG;IACG,IAAI;IAWV;;;;OAIG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;CAe7C"}
@@ -0,0 +1,48 @@
1
+ import { appendFile, mkdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { LOG_DIRECTORY, LOG_FILENAME } from "./constants.js";
4
+ /**
5
+ * Handles initialization of the log directory and writing log entries to the file system.
6
+ */
7
+ export class FileLogger {
8
+ logFilePath;
9
+ /**
10
+ * Creates a new instance of FileLogger.
11
+ * @param projectRoot - The absolute path to the root of the project.
12
+ */
13
+ constructor(projectRoot) {
14
+ this.logFilePath = join(projectRoot, LOG_DIRECTORY, LOG_FILENAME);
15
+ }
16
+ /**
17
+ * Initializes the logger by ensuring the log directory exists.
18
+ * This method should be called before attempting to log any events.
19
+ */
20
+ async init() {
21
+ try {
22
+ const dirPath = join(this.logFilePath, "..");
23
+ await mkdir(dirPath, { recursive: true });
24
+ }
25
+ catch (error) {
26
+ console.error(`[Opencode Logger] Failed to create log directory: ${error}`);
27
+ }
28
+ }
29
+ /**
30
+ * Logs an event and its payload to the log file in JSONL format.
31
+ * @param eventType - The type of event to log.
32
+ * @param payload - The data associated with the event.
33
+ */
34
+ async log(eventType, payload) {
35
+ const entry = {
36
+ timestamp: new Date().toISOString(),
37
+ eventType,
38
+ payload,
39
+ };
40
+ const line = `${JSON.stringify(entry)}\n`;
41
+ try {
42
+ await appendFile(this.logFilePath, line, "utf-8");
43
+ }
44
+ catch (error) {
45
+ console.error(`[Opencode Logger] Failed to write to log file: ${error}`);
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,10 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ /**
3
+ * The main Opencode Logger plugin entry point.
4
+ * Initializes the file logger and registers hooks for supported events.
5
+ *
6
+ * @param ctx - The plugin context provided by Opencode, containing project details.
7
+ * @returns A promise that resolves to the plugin hooks configuration.
8
+ */
9
+ export declare const loggerPlugin: Plugin;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;AAIzD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,MAwB1B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ import { SUPPORTED_EVENTS } from "./constants.js";
2
+ import { FileLogger } from "./file-logger.js";
3
+ /**
4
+ * The main Opencode Logger plugin entry point.
5
+ * Initializes the file logger and registers hooks for supported events.
6
+ *
7
+ * @param ctx - The plugin context provided by Opencode, containing project details.
8
+ * @returns A promise that resolves to the plugin hooks configuration.
9
+ */
10
+ export const loggerPlugin = async (ctx) => {
11
+ // ctx.directory is the project root in the context of the running plugin usually,
12
+ // but let's be safe and check if we need to resolve it.
13
+ // Based on the docs: directory: The current working directory.
14
+ const logger = new FileLogger(ctx.directory);
15
+ await logger.init();
16
+ console.log("Opencode Logger Plugin initialized!");
17
+ const hooks = {
18
+ event: async ({ event }) => {
19
+ if (SUPPORTED_EVENTS.includes(event.type)) {
20
+ await logger.log(event.type, event);
21
+ }
22
+ },
23
+ "tool.execute.before": async (input, output) => {
24
+ await logger.log("tool.execute.before", { input, output });
25
+ },
26
+ "tool.execute.after": async (input, output) => {
27
+ await logger.log("tool.execute.after", { input, output });
28
+ },
29
+ };
30
+ return hooks;
31
+ };
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "opencode-logger",
3
+ "main": "dist/index.js",
4
+ "types": "dist/index.d.ts",
5
+ "version": "0.1.0",
6
+ "devDependencies": {
7
+ "@biomejs/biome": "2.3.11",
8
+ "@types/bun": "latest",
9
+ "husky": "^9.1.7",
10
+ "lint-staged": "^16.2.7"
11
+ },
12
+ "peerDependencies": {
13
+ "typescript": "^5"
14
+ },
15
+ "private": false,
16
+ "scripts": {
17
+ "build-dist": "bunx tsc",
18
+ "lint": "bunx biome lint --write ./src",
19
+ "format": "bunx biome format --write",
20
+ "forlint": "bun lint && bun format",
21
+ "typecheck": "tsc --noEmit --pretty",
22
+ "prepare": "husky"
23
+ },
24
+ "type": "module",
25
+ "lint-staged": {
26
+ "*.{js, ts}": [
27
+ "bun forlint"
28
+ ],
29
+ "*.{ts,json}": [
30
+ "bun format"
31
+ ]
32
+ },
33
+ "dependencies": {
34
+ "@opencode-ai/plugin": "^1.1.25"
35
+ }
36
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["ESNext"],
4
+ "target": "ESNext",
5
+ "module": "NodeNext",
6
+ "moduleDetection": "auto",
7
+ "moduleResolution": "nodenext",
8
+ "verbatimModuleSyntax": true,
9
+
10
+ "strict": true,
11
+ "skipLibCheck": true,
12
+ "noFallthroughCasesInSwitch": true,
13
+ "noUncheckedIndexedAccess": true,
14
+ "noImplicitOverride": true,
15
+
16
+ "noUnusedLocals": true,
17
+ "noUnusedParameters": true,
18
+ "noPropertyAccessFromIndexSignature": true,
19
+
20
+ "outDir": "./dist",
21
+ "rootDir": "./src",
22
+ "baseUrl": ".",
23
+ "paths": {
24
+ "@/*": ["src/*"]
25
+ },
26
+ "declaration": true,
27
+ "declarationMap": true
28
+ },
29
+ "include": ["src/**/*.ts"]
30
+ }