@vite-plugin-opencode-assistant/shared 1.0.57 → 1.0.58

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/es/constants.d.ts CHANGED
@@ -109,4 +109,11 @@ export declare const DEFAULT_CONFIG: {
109
109
  } | undefined;
110
110
  language: OpenCodeLanguage | undefined;
111
111
  settings: OpenCodeSettings | undefined;
112
+ logFiles: Array<{
113
+ name: string;
114
+ path: string;
115
+ description: string;
116
+ watchExisting?: boolean;
117
+ maxBufferSize?: number;
118
+ }> | undefined;
112
119
  };
package/es/constants.mjs CHANGED
@@ -54,7 +54,9 @@ const DEFAULT_CONFIG = {
54
54
  splitMode: void 0,
55
55
  // OpenCode 内部配置默认值
56
56
  language: void 0,
57
- settings: void 0
57
+ settings: void 0,
58
+ // 日志文件配置
59
+ logFiles: void 0
58
60
  };
59
61
  export {
60
62
  AUTO_OPEN_DELAY,
@@ -0,0 +1,53 @@
1
+ export interface FileLogEntry {
2
+ level: "info" | "warn" | "error";
3
+ message: string;
4
+ timestamp: string;
5
+ source: string;
6
+ }
7
+ export interface FileLogBufferOptions {
8
+ name: string;
9
+ filePath: string;
10
+ maxBufferSize?: number;
11
+ watchExisting?: boolean;
12
+ }
13
+ declare class FileLogBuffer {
14
+ private buffer;
15
+ private maxSize;
16
+ private name;
17
+ private filePath;
18
+ private lastPosition;
19
+ private watcher;
20
+ private enabled;
21
+ constructor(options: FileLogBufferOptions);
22
+ start(projectRoot?: string): void;
23
+ stop(): void;
24
+ private resolvePath;
25
+ private readNewLogs;
26
+ private processLogContent;
27
+ private detectLogLevel;
28
+ addEntry(entry: FileLogEntry): void;
29
+ getLogs(options?: {
30
+ level?: FileLogEntry["level"] | FileLogEntry["level"][];
31
+ limit?: number;
32
+ since?: string;
33
+ }): FileLogEntry[];
34
+ clear(): void;
35
+ size(): number;
36
+ setEnabled(enabled: boolean): void;
37
+ isEnabled(): boolean;
38
+ getName(): string;
39
+ getFilePath(): string;
40
+ }
41
+ export declare class ServiceLogWatcher {
42
+ private buffers;
43
+ private projectRoot;
44
+ setProjectRoot(root: string): void;
45
+ addLogFile(options: FileLogBufferOptions): void;
46
+ removeLogFile(name: string): void;
47
+ getBuffer(name: string): FileLogBuffer | undefined;
48
+ getAllBuffers(): Map<string, FileLogBuffer>;
49
+ stopAll(): void;
50
+ getLogFileNames(): string[];
51
+ }
52
+ export declare function getServiceLogWatcher(): ServiceLogWatcher;
53
+ export {};
@@ -0,0 +1,193 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import fs from "fs";
5
+ import path from "path";
6
+ import { createLogger } from "./logger.mjs";
7
+ const log = createLogger("FileLogWatcher");
8
+ class FileLogBuffer {
9
+ constructor(options) {
10
+ __publicField(this, "buffer", []);
11
+ __publicField(this, "maxSize");
12
+ __publicField(this, "name");
13
+ __publicField(this, "filePath");
14
+ __publicField(this, "lastPosition", 0);
15
+ __publicField(this, "watcher", null);
16
+ __publicField(this, "enabled", false);
17
+ var _a;
18
+ this.name = options.name;
19
+ this.filePath = options.filePath;
20
+ this.maxSize = (_a = options.maxBufferSize) != null ? _a : 200;
21
+ this.enabled = true;
22
+ }
23
+ start(projectRoot) {
24
+ const resolvedPath = this.resolvePath(projectRoot);
25
+ if (!fs.existsSync(resolvedPath)) {
26
+ log.debug(`Log file does not exist: ${resolvedPath}`);
27
+ return;
28
+ }
29
+ const stat = fs.statSync(resolvedPath);
30
+ this.lastPosition = stat.size;
31
+ this.watcher = fs.watch(resolvedPath, (eventType) => {
32
+ if (eventType === "change") {
33
+ this.readNewLogs(resolvedPath);
34
+ }
35
+ });
36
+ this.watcher.on("error", (err) => {
37
+ log.error(`Error watching file ${resolvedPath}`, { error: err });
38
+ });
39
+ log.info(`Started watching log file: ${resolvedPath}`);
40
+ }
41
+ stop() {
42
+ if (this.watcher) {
43
+ this.watcher.close();
44
+ this.watcher = null;
45
+ log.debug(`Stopped watching log file: ${this.filePath}`);
46
+ }
47
+ }
48
+ resolvePath(projectRoot) {
49
+ if (path.isAbsolute(this.filePath)) {
50
+ return this.filePath;
51
+ }
52
+ if (projectRoot) {
53
+ return path.resolve(projectRoot, this.filePath);
54
+ }
55
+ return path.resolve(process.cwd(), this.filePath);
56
+ }
57
+ readNewLogs(filePath) {
58
+ try {
59
+ const stat = fs.statSync(filePath);
60
+ if (stat.size <= this.lastPosition) {
61
+ return;
62
+ }
63
+ const fd = fs.openSync(filePath, "r");
64
+ const buffer = Buffer.alloc(stat.size - this.lastPosition);
65
+ fs.readSync(fd, buffer, 0, buffer.length, this.lastPosition);
66
+ fs.closeSync(fd);
67
+ this.lastPosition = stat.size;
68
+ const content = buffer.toString("utf-8").trim();
69
+ if (content) {
70
+ this.processLogContent(content);
71
+ }
72
+ } catch (err) {
73
+ log.error(`Error reading log file ${filePath}`, { error: err });
74
+ }
75
+ }
76
+ processLogContent(content) {
77
+ const lines = content.split("\n");
78
+ for (const line of lines) {
79
+ if (!line.trim()) continue;
80
+ this.addEntry({
81
+ level: this.detectLogLevel(line),
82
+ message: line,
83
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
84
+ source: `file:${this.name}`
85
+ });
86
+ }
87
+ }
88
+ detectLogLevel(line) {
89
+ const lowerLine = line.toLowerCase();
90
+ if (lowerLine.includes("error") || lowerLine.includes("err") || lowerLine.includes("fatal")) {
91
+ return "error";
92
+ }
93
+ if (lowerLine.includes("warn") || lowerLine.includes("warning")) {
94
+ return "warn";
95
+ }
96
+ return "info";
97
+ }
98
+ addEntry(entry) {
99
+ if (!this.enabled) return;
100
+ if (this.buffer.length >= this.maxSize) {
101
+ this.buffer.shift();
102
+ }
103
+ this.buffer.push(entry);
104
+ }
105
+ getLogs(options = {}) {
106
+ let logs = [...this.buffer];
107
+ if (options.level) {
108
+ const levels = Array.isArray(options.level) ? options.level : [options.level];
109
+ logs = logs.filter((log2) => levels.includes(log2.level));
110
+ }
111
+ if (options.since) {
112
+ const sinceDate = new Date(options.since);
113
+ logs = logs.filter((log2) => new Date(log2.timestamp) >= sinceDate);
114
+ }
115
+ if (options.limit && options.limit > 0) {
116
+ logs = logs.slice(-options.limit);
117
+ }
118
+ return logs;
119
+ }
120
+ clear() {
121
+ this.buffer = [];
122
+ }
123
+ size() {
124
+ return this.buffer.length;
125
+ }
126
+ setEnabled(enabled) {
127
+ this.enabled = enabled;
128
+ }
129
+ isEnabled() {
130
+ return this.enabled;
131
+ }
132
+ getName() {
133
+ return this.name;
134
+ }
135
+ getFilePath() {
136
+ return this.filePath;
137
+ }
138
+ }
139
+ class ServiceLogWatcher {
140
+ constructor() {
141
+ __publicField(this, "buffers", /* @__PURE__ */ new Map());
142
+ __publicField(this, "projectRoot", null);
143
+ }
144
+ setProjectRoot(root) {
145
+ this.projectRoot = root;
146
+ }
147
+ addLogFile(options) {
148
+ var _a;
149
+ if (this.buffers.has(options.name)) {
150
+ log.warn(`Log file "${options.name}" already exists, skipping`);
151
+ return;
152
+ }
153
+ const buffer = new FileLogBuffer(options);
154
+ buffer.start((_a = this.projectRoot) != null ? _a : void 0);
155
+ this.buffers.set(options.name, buffer);
156
+ log.info(`Added log file watcher: ${options.name} -> ${options.filePath}`);
157
+ }
158
+ removeLogFile(name) {
159
+ const buffer = this.buffers.get(name);
160
+ if (buffer) {
161
+ buffer.stop();
162
+ this.buffers.delete(name);
163
+ log.info(`Removed log file watcher: ${name}`);
164
+ }
165
+ }
166
+ getBuffer(name) {
167
+ return this.buffers.get(name);
168
+ }
169
+ getAllBuffers() {
170
+ return this.buffers;
171
+ }
172
+ stopAll() {
173
+ for (const [name, buffer] of this.buffers) {
174
+ buffer.stop();
175
+ log.debug(`Stopped log file watcher: ${name}`);
176
+ }
177
+ this.buffers.clear();
178
+ }
179
+ getLogFileNames() {
180
+ return Array.from(this.buffers.keys());
181
+ }
182
+ }
183
+ let globalWatcher = null;
184
+ function getServiceLogWatcher() {
185
+ if (!globalWatcher) {
186
+ globalWatcher = new ServiceLogWatcher();
187
+ }
188
+ return globalWatcher;
189
+ }
190
+ export {
191
+ ServiceLogWatcher,
192
+ getServiceLogWatcher
193
+ };
package/es/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./constants";
2
+ export * from "./file-log-watcher";
2
3
  export * from "./logger";
3
4
  export * from "./process-logger";
4
5
  export * from "./types";
package/es/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./constants.mjs";
2
+ export * from "./file-log-watcher.mjs";
2
3
  export * from "./logger.mjs";
3
4
  export * from "./process-logger.mjs";
4
5
  export * from "./types.mjs";
package/es/types.d.ts CHANGED
@@ -84,6 +84,21 @@ export interface SplitModeOptions {
84
84
  /** 面板位置,默认 'right' */
85
85
  position?: "left" | "right";
86
86
  }
87
+ /**
88
+ * 日志文件配置
89
+ */
90
+ export interface LogFileConfig {
91
+ /** 日志文件的唯一标识符,用于工具调用时指定 */
92
+ name: string;
93
+ /** 日志文件路径(绝对路径或相对于项目根目录的相对路径) */
94
+ path: string;
95
+ /** 工具描述,告诉 Agent 何时使用此工具查看日志 */
96
+ description: string;
97
+ /** 是否监控已存在的文件内容,默认 false(只监控新增内容) */
98
+ watchExisting?: boolean;
99
+ /** 日志缓冲区最大条数,默认 200 */
100
+ maxBufferSize?: number;
101
+ }
87
102
  /**
88
103
  * OpenCode Vite 插件配置选项
89
104
  */
@@ -116,6 +131,8 @@ export interface OpenCodeOptions {
116
131
  language?: OpenCodeLanguage;
117
132
  /** OpenCode 内部设置,直接映射到 localStorage settings.v3 */
118
133
  settings?: OpenCodeSettings;
134
+ /** 自定义日志文件配置,为 Agent 提供查看外部服务日志的能力 */
135
+ logFiles?: LogFileConfig[];
119
136
  }
120
137
  /**
121
138
  * OpenCode Web 服务启动选项
@@ -137,6 +154,8 @@ export interface WebOptions {
137
154
  contextApiUrl?: string;
138
155
  /** 进程日志 API URL */
139
156
  logsApiUrl?: string;
157
+ /** 日志文件配置(JSON 字符串) */
158
+ logFilesJson?: string;
140
159
  }
141
160
  /**
142
161
  * 挂件注入配置选项
package/lib/constants.cjs CHANGED
@@ -108,7 +108,9 @@ const DEFAULT_CONFIG = {
108
108
  splitMode: void 0,
109
109
  // OpenCode 内部配置默认值
110
110
  language: void 0,
111
- settings: void 0
111
+ settings: void 0,
112
+ // 日志文件配置
113
+ logFiles: void 0
112
114
  };
113
115
  // Annotate the CommonJS export names for ESM import in node:
114
116
  0 && (module.exports = {
@@ -109,4 +109,11 @@ export declare const DEFAULT_CONFIG: {
109
109
  } | undefined;
110
110
  language: OpenCodeLanguage | undefined;
111
111
  settings: OpenCodeSettings | undefined;
112
+ logFiles: Array<{
113
+ name: string;
114
+ path: string;
115
+ description: string;
116
+ watchExisting?: boolean;
117
+ maxBufferSize?: number;
118
+ }> | undefined;
112
119
  };
@@ -0,0 +1,226 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
30
+ var file_log_watcher_exports = {};
31
+ __export(file_log_watcher_exports, {
32
+ ServiceLogWatcher: () => ServiceLogWatcher,
33
+ getServiceLogWatcher: () => getServiceLogWatcher
34
+ });
35
+ module.exports = __toCommonJS(file_log_watcher_exports);
36
+ var import_fs = __toESM(require("fs"));
37
+ var import_path = __toESM(require("path"));
38
+ var import_logger = require("./logger.cjs");
39
+ const log = (0, import_logger.createLogger)("FileLogWatcher");
40
+ class FileLogBuffer {
41
+ constructor(options) {
42
+ __publicField(this, "buffer", []);
43
+ __publicField(this, "maxSize");
44
+ __publicField(this, "name");
45
+ __publicField(this, "filePath");
46
+ __publicField(this, "lastPosition", 0);
47
+ __publicField(this, "watcher", null);
48
+ __publicField(this, "enabled", false);
49
+ var _a;
50
+ this.name = options.name;
51
+ this.filePath = options.filePath;
52
+ this.maxSize = (_a = options.maxBufferSize) != null ? _a : 200;
53
+ this.enabled = true;
54
+ }
55
+ start(projectRoot) {
56
+ const resolvedPath = this.resolvePath(projectRoot);
57
+ if (!import_fs.default.existsSync(resolvedPath)) {
58
+ log.debug(`Log file does not exist: ${resolvedPath}`);
59
+ return;
60
+ }
61
+ const stat = import_fs.default.statSync(resolvedPath);
62
+ this.lastPosition = stat.size;
63
+ this.watcher = import_fs.default.watch(resolvedPath, (eventType) => {
64
+ if (eventType === "change") {
65
+ this.readNewLogs(resolvedPath);
66
+ }
67
+ });
68
+ this.watcher.on("error", (err) => {
69
+ log.error(`Error watching file ${resolvedPath}`, { error: err });
70
+ });
71
+ log.info(`Started watching log file: ${resolvedPath}`);
72
+ }
73
+ stop() {
74
+ if (this.watcher) {
75
+ this.watcher.close();
76
+ this.watcher = null;
77
+ log.debug(`Stopped watching log file: ${this.filePath}`);
78
+ }
79
+ }
80
+ resolvePath(projectRoot) {
81
+ if (import_path.default.isAbsolute(this.filePath)) {
82
+ return this.filePath;
83
+ }
84
+ if (projectRoot) {
85
+ return import_path.default.resolve(projectRoot, this.filePath);
86
+ }
87
+ return import_path.default.resolve(process.cwd(), this.filePath);
88
+ }
89
+ readNewLogs(filePath) {
90
+ try {
91
+ const stat = import_fs.default.statSync(filePath);
92
+ if (stat.size <= this.lastPosition) {
93
+ return;
94
+ }
95
+ const fd = import_fs.default.openSync(filePath, "r");
96
+ const buffer = Buffer.alloc(stat.size - this.lastPosition);
97
+ import_fs.default.readSync(fd, buffer, 0, buffer.length, this.lastPosition);
98
+ import_fs.default.closeSync(fd);
99
+ this.lastPosition = stat.size;
100
+ const content = buffer.toString("utf-8").trim();
101
+ if (content) {
102
+ this.processLogContent(content);
103
+ }
104
+ } catch (err) {
105
+ log.error(`Error reading log file ${filePath}`, { error: err });
106
+ }
107
+ }
108
+ processLogContent(content) {
109
+ const lines = content.split("\n");
110
+ for (const line of lines) {
111
+ if (!line.trim()) continue;
112
+ this.addEntry({
113
+ level: this.detectLogLevel(line),
114
+ message: line,
115
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
116
+ source: `file:${this.name}`
117
+ });
118
+ }
119
+ }
120
+ detectLogLevel(line) {
121
+ const lowerLine = line.toLowerCase();
122
+ if (lowerLine.includes("error") || lowerLine.includes("err") || lowerLine.includes("fatal")) {
123
+ return "error";
124
+ }
125
+ if (lowerLine.includes("warn") || lowerLine.includes("warning")) {
126
+ return "warn";
127
+ }
128
+ return "info";
129
+ }
130
+ addEntry(entry) {
131
+ if (!this.enabled) return;
132
+ if (this.buffer.length >= this.maxSize) {
133
+ this.buffer.shift();
134
+ }
135
+ this.buffer.push(entry);
136
+ }
137
+ getLogs(options = {}) {
138
+ let logs = [...this.buffer];
139
+ if (options.level) {
140
+ const levels = Array.isArray(options.level) ? options.level : [options.level];
141
+ logs = logs.filter((log2) => levels.includes(log2.level));
142
+ }
143
+ if (options.since) {
144
+ const sinceDate = new Date(options.since);
145
+ logs = logs.filter((log2) => new Date(log2.timestamp) >= sinceDate);
146
+ }
147
+ if (options.limit && options.limit > 0) {
148
+ logs = logs.slice(-options.limit);
149
+ }
150
+ return logs;
151
+ }
152
+ clear() {
153
+ this.buffer = [];
154
+ }
155
+ size() {
156
+ return this.buffer.length;
157
+ }
158
+ setEnabled(enabled) {
159
+ this.enabled = enabled;
160
+ }
161
+ isEnabled() {
162
+ return this.enabled;
163
+ }
164
+ getName() {
165
+ return this.name;
166
+ }
167
+ getFilePath() {
168
+ return this.filePath;
169
+ }
170
+ }
171
+ class ServiceLogWatcher {
172
+ constructor() {
173
+ __publicField(this, "buffers", /* @__PURE__ */ new Map());
174
+ __publicField(this, "projectRoot", null);
175
+ }
176
+ setProjectRoot(root) {
177
+ this.projectRoot = root;
178
+ }
179
+ addLogFile(options) {
180
+ var _a;
181
+ if (this.buffers.has(options.name)) {
182
+ log.warn(`Log file "${options.name}" already exists, skipping`);
183
+ return;
184
+ }
185
+ const buffer = new FileLogBuffer(options);
186
+ buffer.start((_a = this.projectRoot) != null ? _a : void 0);
187
+ this.buffers.set(options.name, buffer);
188
+ log.info(`Added log file watcher: ${options.name} -> ${options.filePath}`);
189
+ }
190
+ removeLogFile(name) {
191
+ const buffer = this.buffers.get(name);
192
+ if (buffer) {
193
+ buffer.stop();
194
+ this.buffers.delete(name);
195
+ log.info(`Removed log file watcher: ${name}`);
196
+ }
197
+ }
198
+ getBuffer(name) {
199
+ return this.buffers.get(name);
200
+ }
201
+ getAllBuffers() {
202
+ return this.buffers;
203
+ }
204
+ stopAll() {
205
+ for (const [name, buffer] of this.buffers) {
206
+ buffer.stop();
207
+ log.debug(`Stopped log file watcher: ${name}`);
208
+ }
209
+ this.buffers.clear();
210
+ }
211
+ getLogFileNames() {
212
+ return Array.from(this.buffers.keys());
213
+ }
214
+ }
215
+ let globalWatcher = null;
216
+ function getServiceLogWatcher() {
217
+ if (!globalWatcher) {
218
+ globalWatcher = new ServiceLogWatcher();
219
+ }
220
+ return globalWatcher;
221
+ }
222
+ // Annotate the CommonJS export names for ESM import in node:
223
+ 0 && (module.exports = {
224
+ ServiceLogWatcher,
225
+ getServiceLogWatcher
226
+ });
@@ -0,0 +1,53 @@
1
+ export interface FileLogEntry {
2
+ level: "info" | "warn" | "error";
3
+ message: string;
4
+ timestamp: string;
5
+ source: string;
6
+ }
7
+ export interface FileLogBufferOptions {
8
+ name: string;
9
+ filePath: string;
10
+ maxBufferSize?: number;
11
+ watchExisting?: boolean;
12
+ }
13
+ declare class FileLogBuffer {
14
+ private buffer;
15
+ private maxSize;
16
+ private name;
17
+ private filePath;
18
+ private lastPosition;
19
+ private watcher;
20
+ private enabled;
21
+ constructor(options: FileLogBufferOptions);
22
+ start(projectRoot?: string): void;
23
+ stop(): void;
24
+ private resolvePath;
25
+ private readNewLogs;
26
+ private processLogContent;
27
+ private detectLogLevel;
28
+ addEntry(entry: FileLogEntry): void;
29
+ getLogs(options?: {
30
+ level?: FileLogEntry["level"] | FileLogEntry["level"][];
31
+ limit?: number;
32
+ since?: string;
33
+ }): FileLogEntry[];
34
+ clear(): void;
35
+ size(): number;
36
+ setEnabled(enabled: boolean): void;
37
+ isEnabled(): boolean;
38
+ getName(): string;
39
+ getFilePath(): string;
40
+ }
41
+ export declare class ServiceLogWatcher {
42
+ private buffers;
43
+ private projectRoot;
44
+ setProjectRoot(root: string): void;
45
+ addLogFile(options: FileLogBufferOptions): void;
46
+ removeLogFile(name: string): void;
47
+ getBuffer(name: string): FileLogBuffer | undefined;
48
+ getAllBuffers(): Map<string, FileLogBuffer>;
49
+ stopAll(): void;
50
+ getLogFileNames(): string[];
51
+ }
52
+ export declare function getServiceLogWatcher(): ServiceLogWatcher;
53
+ export {};
package/lib/index.cjs CHANGED
@@ -15,6 +15,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
15
15
  var lib_exports = {};
16
16
  module.exports = __toCommonJS(lib_exports);
17
17
  __reExport(lib_exports, require("./constants.cjs"), module.exports);
18
+ __reExport(lib_exports, require("./file-log-watcher.cjs"), module.exports);
18
19
  __reExport(lib_exports, require("./logger.cjs"), module.exports);
19
20
  __reExport(lib_exports, require("./process-logger.cjs"), module.exports);
20
21
  __reExport(lib_exports, require("./types.cjs"), module.exports);
@@ -22,6 +23,7 @@ __reExport(lib_exports, require("./utils.cjs"), module.exports);
22
23
  // Annotate the CommonJS export names for ESM import in node:
23
24
  0 && (module.exports = {
24
25
  ...require("./constants.cjs"),
26
+ ...require("./file-log-watcher.cjs"),
25
27
  ...require("./logger.cjs"),
26
28
  ...require("./process-logger.cjs"),
27
29
  ...require("./types.cjs"),
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./constants";
2
+ export * from "./file-log-watcher";
2
3
  export * from "./logger";
3
4
  export * from "./process-logger";
4
5
  export * from "./types";
package/lib/types.d.ts CHANGED
@@ -84,6 +84,21 @@ export interface SplitModeOptions {
84
84
  /** 面板位置,默认 'right' */
85
85
  position?: "left" | "right";
86
86
  }
87
+ /**
88
+ * 日志文件配置
89
+ */
90
+ export interface LogFileConfig {
91
+ /** 日志文件的唯一标识符,用于工具调用时指定 */
92
+ name: string;
93
+ /** 日志文件路径(绝对路径或相对于项目根目录的相对路径) */
94
+ path: string;
95
+ /** 工具描述,告诉 Agent 何时使用此工具查看日志 */
96
+ description: string;
97
+ /** 是否监控已存在的文件内容,默认 false(只监控新增内容) */
98
+ watchExisting?: boolean;
99
+ /** 日志缓冲区最大条数,默认 200 */
100
+ maxBufferSize?: number;
101
+ }
87
102
  /**
88
103
  * OpenCode Vite 插件配置选项
89
104
  */
@@ -116,6 +131,8 @@ export interface OpenCodeOptions {
116
131
  language?: OpenCodeLanguage;
117
132
  /** OpenCode 内部设置,直接映射到 localStorage settings.v3 */
118
133
  settings?: OpenCodeSettings;
134
+ /** 自定义日志文件配置,为 Agent 提供查看外部服务日志的能力 */
135
+ logFiles?: LogFileConfig[];
119
136
  }
120
137
  /**
121
138
  * OpenCode Web 服务启动选项
@@ -137,6 +154,8 @@ export interface WebOptions {
137
154
  contextApiUrl?: string;
138
155
  /** 进程日志 API URL */
139
156
  logsApiUrl?: string;
157
+ /** 日志文件配置(JSON 字符串) */
158
+ logFilesJson?: string;
140
159
  }
141
160
  /**
142
161
  * 挂件注入配置选项
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vite-plugin-opencode-assistant/shared",
3
- "version": "1.0.57",
3
+ "version": "1.0.58",
4
4
  "type": "module",
5
5
  "main": "lib/index.cjs",
6
6
  "module": "es/index.mjs",