@vite-plugin-opencode-assistant/opencode 1.0.58 → 1.0.59

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.
@@ -1,75 +1,122 @@
1
- import { t as h } from "./tool.js";
2
- import { c as v } from "./logger.js";
3
- const o = {};
4
- var y = Object.defineProperty, E = (s, e, t) => e in s ? y(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, n = (s, e, t) => E(s, typeof e != "symbol" ? e + "" : e, t);
5
- const a = v("FileLogWatcher");
6
- class F {
7
- constructor(e) {
8
- n(this, "buffer", []), n(this, "maxSize"), n(this, "name"), n(this, "filePath"), n(this, "lastPosition", 0), n(this, "watcher", null), n(this, "enabled", !1);
9
- var t;
10
- this.name = e.name, this.filePath = e.filePath, this.maxSize = (t = e.maxBufferSize) != null ? t : 200, this.enabled = !0;
11
- }
12
- start(e) {
13
- const t = this.resolvePath(e);
14
- if (!o.existsSync(t)) {
15
- a.debug(`Log file does not exist: ${t}`);
1
+ import { tool } from "@opencode-ai/plugin";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { c as createLogger } from "./logger.js";
5
+ var __defProp = Object.defineProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
+ const log$1 = createLogger("FileLogWatcher");
9
+ class FileLogBuffer {
10
+ constructor(options) {
11
+ __publicField(this, "buffer", []);
12
+ __publicField(this, "maxSize");
13
+ __publicField(this, "name");
14
+ __publicField(this, "filePath");
15
+ __publicField(this, "lastPosition", 0);
16
+ __publicField(this, "watcher", null);
17
+ __publicField(this, "enabled", false);
18
+ var _a;
19
+ this.name = options.name;
20
+ this.filePath = options.filePath;
21
+ this.maxSize = (_a = options.maxBufferSize) != null ? _a : 200;
22
+ this.enabled = true;
23
+ }
24
+ start(projectRoot) {
25
+ const resolvedPath = this.resolvePath(projectRoot);
26
+ if (!fs.existsSync(resolvedPath)) {
27
+ log$1.debug(`Log file does not exist: ${resolvedPath}`);
16
28
  return;
17
29
  }
18
- const i = o.statSync(t);
19
- this.lastPosition = i.size, this.watcher = o.watch(t, (r) => {
20
- r === "change" && this.readNewLogs(t);
21
- }), this.watcher.on("error", (r) => {
22
- a.error(`Error watching file ${t}`, { error: r });
23
- }), a.info(`Started watching log file: ${t}`);
30
+ const stat = fs.statSync(resolvedPath);
31
+ this.lastPosition = stat.size;
32
+ this.watcher = fs.watch(resolvedPath, (eventType) => {
33
+ if (eventType === "change") {
34
+ this.readNewLogs(resolvedPath);
35
+ }
36
+ });
37
+ this.watcher.on("error", (err) => {
38
+ log$1.error(`Error watching file ${resolvedPath}`, { error: err });
39
+ });
40
+ log$1.info(`Started watching log file: ${resolvedPath}`);
24
41
  }
25
42
  stop() {
26
- this.watcher && (this.watcher.close(), this.watcher = null, a.debug(`Stopped watching log file: ${this.filePath}`));
43
+ if (this.watcher) {
44
+ this.watcher.close();
45
+ this.watcher = null;
46
+ log$1.debug(`Stopped watching log file: ${this.filePath}`);
47
+ }
27
48
  }
28
- resolvePath(e) {
29
- return o.isAbsolute(this.filePath) ? this.filePath : e ? o.resolve(e, this.filePath) : o.resolve(process.cwd(), this.filePath);
49
+ resolvePath(projectRoot) {
50
+ if (path.isAbsolute(this.filePath)) {
51
+ return this.filePath;
52
+ }
53
+ if (projectRoot) {
54
+ return path.resolve(projectRoot, this.filePath);
55
+ }
56
+ return path.resolve(process.cwd(), this.filePath);
30
57
  }
31
- readNewLogs(e) {
58
+ readNewLogs(filePath) {
32
59
  try {
33
- const t = o.statSync(e);
34
- if (t.size <= this.lastPosition)
60
+ const stat = fs.statSync(filePath);
61
+ if (stat.size <= this.lastPosition) {
35
62
  return;
36
- const i = o.openSync(e, "r"), r = Buffer.alloc(t.size - this.lastPosition);
37
- o.readSync(i, r, 0, r.length, this.lastPosition), o.closeSync(i), this.lastPosition = t.size;
38
- const f = r.toString("utf-8").trim();
39
- f && this.processLogContent(f);
40
- } catch (t) {
41
- a.error(`Error reading log file ${e}`, { error: t });
63
+ }
64
+ const fd = fs.openSync(filePath, "r");
65
+ const buffer = Buffer.alloc(stat.size - this.lastPosition);
66
+ fs.readSync(fd, buffer, 0, buffer.length, this.lastPosition);
67
+ fs.closeSync(fd);
68
+ this.lastPosition = stat.size;
69
+ const content = buffer.toString("utf-8").trim();
70
+ if (content) {
71
+ this.processLogContent(content);
72
+ }
73
+ } catch (err) {
74
+ log$1.error(`Error reading log file ${filePath}`, { error: err });
42
75
  }
43
76
  }
44
- processLogContent(e) {
45
- const t = e.split(`
46
- `);
47
- for (const i of t)
48
- i.trim() && this.addEntry({
49
- level: this.detectLogLevel(i),
50
- message: i,
77
+ processLogContent(content) {
78
+ const lines = content.split("\n");
79
+ for (const line of lines) {
80
+ if (!line.trim()) continue;
81
+ this.addEntry({
82
+ level: this.detectLogLevel(line),
83
+ message: line,
51
84
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
52
85
  source: `file:${this.name}`
53
86
  });
87
+ }
54
88
  }
55
- detectLogLevel(e) {
56
- const t = e.toLowerCase();
57
- return t.includes("error") || t.includes("err") || t.includes("fatal") ? "error" : t.includes("warn") || t.includes("warning") ? "warn" : "info";
89
+ detectLogLevel(line) {
90
+ const lowerLine = line.toLowerCase();
91
+ if (lowerLine.includes("error") || lowerLine.includes("err") || lowerLine.includes("fatal")) {
92
+ return "error";
93
+ }
94
+ if (lowerLine.includes("warn") || lowerLine.includes("warning")) {
95
+ return "warn";
96
+ }
97
+ return "info";
58
98
  }
59
- addEntry(e) {
60
- this.enabled && (this.buffer.length >= this.maxSize && this.buffer.shift(), this.buffer.push(e));
99
+ addEntry(entry) {
100
+ if (!this.enabled) return;
101
+ if (this.buffer.length >= this.maxSize) {
102
+ this.buffer.shift();
103
+ }
104
+ this.buffer.push(entry);
61
105
  }
62
- getLogs(e = {}) {
63
- let t = [...this.buffer];
64
- if (e.level) {
65
- const i = Array.isArray(e.level) ? e.level : [e.level];
66
- t = t.filter((r) => i.includes(r.level));
106
+ getLogs(options = {}) {
107
+ let logs = [...this.buffer];
108
+ if (options.level) {
109
+ const levels = Array.isArray(options.level) ? options.level : [options.level];
110
+ logs = logs.filter((log2) => levels.includes(log2.level));
111
+ }
112
+ if (options.since) {
113
+ const sinceDate = new Date(options.since);
114
+ logs = logs.filter((log2) => new Date(log2.timestamp) >= sinceDate);
67
115
  }
68
- if (e.since) {
69
- const i = new Date(e.since);
70
- t = t.filter((r) => new Date(r.timestamp) >= i);
116
+ if (options.limit && options.limit > 0) {
117
+ logs = logs.slice(-options.limit);
71
118
  }
72
- return e.limit && e.limit > 0 && (t = t.slice(-e.limit)), t;
119
+ return logs;
73
120
  }
74
121
  clear() {
75
122
  this.buffer = [];
@@ -77,8 +124,8 @@ class F {
77
124
  size() {
78
125
  return this.buffer.length;
79
126
  }
80
- setEnabled(e) {
81
- this.enabled = e;
127
+ setEnabled(enabled) {
128
+ this.enabled = enabled;
82
129
  }
83
130
  isEnabled() {
84
131
  return this.enabled;
@@ -90,123 +137,151 @@ class F {
90
137
  return this.filePath;
91
138
  }
92
139
  }
93
- class z {
140
+ class ServiceLogWatcher {
94
141
  constructor() {
95
- n(this, "buffers", /* @__PURE__ */ new Map()), n(this, "projectRoot", null);
142
+ __publicField(this, "buffers", /* @__PURE__ */ new Map());
143
+ __publicField(this, "projectRoot", null);
96
144
  }
97
- setProjectRoot(e) {
98
- this.projectRoot = e;
145
+ setProjectRoot(root) {
146
+ this.projectRoot = root;
99
147
  }
100
- addLogFile(e) {
101
- var t;
102
- if (this.buffers.has(e.name)) {
103
- a.warn(`Log file "${e.name}" already exists, skipping`);
148
+ addLogFile(options) {
149
+ var _a;
150
+ if (this.buffers.has(options.name)) {
151
+ log$1.warn(`Log file "${options.name}" already exists, skipping`);
104
152
  return;
105
153
  }
106
- const i = new F(e);
107
- i.start((t = this.projectRoot) != null ? t : void 0), this.buffers.set(e.name, i), a.info(`Added log file watcher: ${e.name} -> ${e.filePath}`);
154
+ const buffer = new FileLogBuffer(options);
155
+ buffer.start((_a = this.projectRoot) != null ? _a : void 0);
156
+ this.buffers.set(options.name, buffer);
157
+ log$1.info(`Added log file watcher: ${options.name} -> ${options.filePath}`);
108
158
  }
109
- removeLogFile(e) {
110
- const t = this.buffers.get(e);
111
- t && (t.stop(), this.buffers.delete(e), a.info(`Removed log file watcher: ${e}`));
159
+ removeLogFile(name) {
160
+ const buffer = this.buffers.get(name);
161
+ if (buffer) {
162
+ buffer.stop();
163
+ this.buffers.delete(name);
164
+ log$1.info(`Removed log file watcher: ${name}`);
165
+ }
112
166
  }
113
- getBuffer(e) {
114
- return this.buffers.get(e);
167
+ getBuffer(name) {
168
+ return this.buffers.get(name);
115
169
  }
116
170
  getAllBuffers() {
117
171
  return this.buffers;
118
172
  }
119
173
  stopAll() {
120
- for (const [e, t] of this.buffers)
121
- t.stop(), a.debug(`Stopped log file watcher: ${e}`);
174
+ for (const [name, buffer] of this.buffers) {
175
+ buffer.stop();
176
+ log$1.debug(`Stopped log file watcher: ${name}`);
177
+ }
122
178
  this.buffers.clear();
123
179
  }
124
180
  getLogFileNames() {
125
181
  return Array.from(this.buffers.keys());
126
182
  }
127
183
  }
128
- let d = null;
129
- function N() {
130
- return d || (d = new z()), d;
184
+ let globalWatcher = null;
185
+ function getServiceLogWatcher() {
186
+ if (!globalWatcher) {
187
+ globalWatcher = new ServiceLogWatcher();
188
+ }
189
+ return globalWatcher;
131
190
  }
132
- const l = v("ServiceLogsPlugin"), B = async () => {
133
- l.debug("ServiceLogsPlugin loading...");
134
- const s = process.env.OPENCODE_LOG_FILES_JSON;
135
- if (l.debug("Log files JSON from env:", { logFilesJson: s ? "set" : "not set" }), !s)
136
- return l.debug("OPENCODE_LOG_FILES_JSON is not set, service logs plugin will not register tools"), {};
137
- let e;
191
+ const log = createLogger("ServiceLogsPlugin");
192
+ const ServiceLogsPlugin = async () => {
193
+ log.debug("ServiceLogsPlugin loading...");
194
+ const logFilesJson = process.env.OPENCODE_LOG_FILES_JSON;
195
+ log.debug("Log files JSON from env:", { logFilesJson: logFilesJson ? "set" : "not set" });
196
+ if (!logFilesJson) {
197
+ log.debug("OPENCODE_LOG_FILES_JSON is not set, service logs plugin will not register tools");
198
+ return {};
199
+ }
200
+ let logFiles;
138
201
  try {
139
- e = JSON.parse(s), l.debug("Parsed log files config", { count: e.length });
140
- } catch (r) {
141
- return l.error("Failed to parse OPENCODE_LOG_FILES_JSON", { error: r }), {};
142
- }
143
- if (!e || e.length === 0)
144
- return l.debug("No log files configured, plugin will not register any tools"), {};
145
- const t = N();
146
- t.setProjectRoot(process.cwd());
147
- for (const r of e)
148
- t.addLogFile({
149
- name: r.name,
150
- filePath: r.path,
151
- maxBufferSize: r.maxBufferSize,
152
- watchExisting: r.watchExisting
153
- }), l.debug(`Added log file watcher: ${r.name} -> ${r.path}`);
154
- const i = {};
155
- for (const r of e) {
156
- const f = `get_${r.name}_logs`, L = `获取 ${r.name} 的日志。
202
+ logFiles = JSON.parse(logFilesJson);
203
+ log.debug("Parsed log files config", { count: logFiles.length });
204
+ } catch (e) {
205
+ log.error("Failed to parse OPENCODE_LOG_FILES_JSON", { error: e });
206
+ return {};
207
+ }
208
+ if (!logFiles || logFiles.length === 0) {
209
+ log.debug("No log files configured, plugin will not register any tools");
210
+ return {};
211
+ }
212
+ const watcher = getServiceLogWatcher();
213
+ watcher.setProjectRoot(process.cwd());
214
+ for (const logFileConfig of logFiles) {
215
+ watcher.addLogFile({
216
+ name: logFileConfig.name,
217
+ filePath: logFileConfig.path,
218
+ maxBufferSize: logFileConfig.maxBufferSize,
219
+ watchExisting: logFileConfig.watchExisting
220
+ });
221
+ log.debug(`Added log file watcher: ${logFileConfig.name} -> ${logFileConfig.path}`);
222
+ }
223
+ const tools = {};
224
+ for (const logFileConfig of logFiles) {
225
+ const toolName = `get_${logFileConfig.name}_logs`;
226
+ const description = `获取 ${logFileConfig.name} 的日志。
157
227
 
158
228
  **何时使用此工具**:
159
- ${r.description}
229
+ ${logFileConfig.description}
160
230
 
161
231
  **日志内容**:
162
- - 来自日志文件 ${r.path} 的实时日志
163
- - 最多保留 ${r.maxBufferSize ?? 200} 条日志`, S = h({
164
- description: L,
232
+ - 来自日志文件 ${logFileConfig.path} 的实时日志
233
+ - 最多保留 ${logFileConfig.maxBufferSize ?? 200} 条日志`;
234
+ const getLogsTool = tool({
235
+ description,
165
236
  args: {
166
- level: h.schema.string().optional().describe(
237
+ level: tool.schema.string().optional().describe(
167
238
  "日志级别过滤:error(错误)、warn(警告)、info(信息)。多个用逗号分隔,如 'error,warn'"
168
239
  ),
169
- limit: h.schema.number().int().min(1).max(200).optional().default(50).describe("返回条数,默认 50,最大 200"),
170
- since: h.schema.string().optional().describe("起始时间(ISO 格式),获取此时间之后的日志")
240
+ limit: tool.schema.number().int().min(1).max(200).optional().default(50).describe("返回条数,默认 50,最大 200"),
241
+ since: tool.schema.string().optional().describe("起始时间(ISO 格式),获取此时间之后的日志")
171
242
  },
172
- async execute(m, b) {
173
- const { level: w, limit: p, since: P } = m;
174
- l.debug(`${f} called`, {
175
- args: m,
176
- sessionID: b.sessionID,
177
- directory: b.directory
243
+ async execute(args, context) {
244
+ const { level, limit, since } = args;
245
+ log.debug(`${toolName} called`, {
246
+ args,
247
+ sessionID: context.sessionID,
248
+ directory: context.directory
178
249
  });
179
- const g = t.getBuffer(r.name);
180
- if (!g)
181
- return `日志文件 "${r.name}" 未找到。请检查配置。`;
182
- const u = g.getLogs({
183
- level: w ? w.split(",").map((c) => c.trim()) : void 0,
184
- limit: p,
185
- since: P
250
+ const buffer = watcher.getBuffer(logFileConfig.name);
251
+ if (!buffer) {
252
+ return `日志文件 "${logFileConfig.name}" 未找到。请检查配置。`;
253
+ }
254
+ const logs = buffer.getLogs({
255
+ level: level ? level.split(",").map((l) => l.trim()) : void 0,
256
+ limit,
257
+ since
186
258
  });
187
- if (u.length === 0)
188
- return `当前没有符合条件的日志(缓冲区共 ${g.size()} 条)。
259
+ if (logs.length === 0) {
260
+ return `当前没有符合条件的日志(缓冲区共 ${buffer.size()} 条)。
189
261
 
190
262
  建议:
191
263
  - 不指定参数获取所有日志
192
264
  - 使用 level=error,warn 获取错误和警告`;
193
- const $ = u.map((c) => {
194
- const _ = new Date(c.timestamp).toLocaleTimeString(), O = c.level === "error" ? "❌" : c.level === "warn" ? "⚠️" : "ℹ️";
195
- return `${_} ${O} ${c.message}`;
196
- }).join(`
197
- `);
198
- return `${r.name} 日志(${u.length}/${g.size()} 条):
265
+ }
266
+ const formattedLogs = logs.map((entry) => {
267
+ const time = new Date(entry.timestamp).toLocaleTimeString();
268
+ const levelIcon = entry.level === "error" ? "❌" : entry.level === "warn" ? "⚠️" : "ℹ️";
269
+ return `${time} ${levelIcon} ${entry.message}`;
270
+ }).join("\n");
271
+ return `${logFileConfig.name} 日志(${logs.length}/${buffer.size()} 条):
199
272
 
200
- ${$}`;
273
+ ${formattedLogs}`;
201
274
  }
202
275
  });
203
- i[f] = S, l.debug(`Registered tool: ${f}`);
276
+ tools[toolName] = getLogsTool;
277
+ log.debug(`Registered tool: ${toolName}`);
204
278
  }
205
- return l.debug(`Plugin initialized with ${Object.keys(i).length} log tools`), {
206
- tool: i
279
+ log.debug(`Plugin initialized with ${Object.keys(tools).length} log tools`);
280
+ return {
281
+ tool: tools
207
282
  };
208
283
  };
209
284
  export {
210
- B as ServiceLogsPlugin,
211
- B as default
285
+ ServiceLogsPlugin,
286
+ ServiceLogsPlugin as default
212
287
  };
@@ -1,12 +1,17 @@
1
- import { t as n } from "./tool.js";
2
- import { c as p } from "./logger.js";
3
- const e = p("OpenCodePluginViteLogs"), b = async () => {
4
- e.info("ViteLogsPlugin loading...");
5
- const l = process.env.OPENCODE_VITE_LOGS_API_URL;
6
- return e.debug("Vite Logs API URL:", { logsApiUrl: l }), l ? (e.info("Plugin initialized successfully"), {
7
- tool: {
8
- get_vite_dev_logs: n({
9
- description: `获取 Vite 开发服务器的运行日志。
1
+ import { tool } from "@opencode-ai/plugin";
2
+ import { c as createLogger } from "./logger.js";
3
+ const log = createLogger("OpenCodePluginViteLogs");
4
+ const ViteLogsPlugin = async () => {
5
+ log.info("ViteLogsPlugin loading...");
6
+ const logsApiUrl = process.env.OPENCODE_VITE_LOGS_API_URL;
7
+ log.debug("Vite Logs API URL:", { logsApiUrl });
8
+ if (!logsApiUrl) {
9
+ log.warn("OPENCODE_VITE_LOGS_API_URL is not set, vite logs plugin will not work");
10
+ return {};
11
+ }
12
+ log.info("Plugin initialized successfully");
13
+ const getViteDevLogsTool = tool({
14
+ description: `获取 Vite 开发服务器的运行日志。
10
15
 
11
16
  **何时使用此工具**:
12
17
  - 用户报告"页面没更新"、"热更新不工作"、"HMR 失效"时
@@ -22,60 +27,74 @@ const e = p("OpenCodePluginViteLogs"), b = async () => {
22
27
  - 插件运行日志
23
28
 
24
29
  日志保存在内存缓冲区(最近 500 条)。`,
25
- args: {
26
- level: n.schema.string().optional().describe(
27
- "日志级别过滤:error(错误)、warn(警告)、info(信息)、debug(调试)、log(普通)。多个用逗号分隔,如 'error,warn'"
28
- ),
29
- limit: n.schema.number().int().min(1).max(200).optional().default(50).describe("返回条数,默认 50,最大 200"),
30
- source: n.schema.string().optional().describe("来源过滤:console(控制台)、opencode-stdout(服务输出)、opencode-stderr(服务错误)")
31
- },
32
- async execute(a, i) {
33
- const { level: c, limit: g, source: u } = a;
34
- e.debug("get_vite_dev_logs called", {
35
- args: a,
36
- sessionID: i.sessionID,
37
- directory: i.directory
38
- });
39
- try {
40
- const r = new URL(l);
41
- c && r.searchParams.set("level", c), g && r.searchParams.set("limit", String(g)), u && r.searchParams.set("source", u), e.debug("Fetching logs from", { url: r.toString() });
42
- const t = await fetch(r.toString(), {
43
- method: "GET",
44
- headers: { Accept: "application/json" },
45
- signal: i.abort
46
- });
47
- if (!t.ok) {
48
- const o = await t.text();
49
- return e.error("Failed to fetch logs", { status: t.status, error: o }), `获取日志失败: HTTP ${t.status} - ${o}`;
50
- }
51
- const s = await t.json();
52
- if (e.debug("Logs fetched successfully", {
53
- count: s.logs.length,
54
- total: s.meta.total
55
- }), s.logs.length === 0)
56
- return `当前没有符合条件的日志(缓冲区共 ${s.meta.total} 条)。
30
+ args: {
31
+ level: tool.schema.string().optional().describe(
32
+ "日志级别过滤:error(错误)、warn(警告)、info(信息)、debug(调试)、log(普通)。多个用逗号分隔,如 'error,warn'"
33
+ ),
34
+ limit: tool.schema.number().int().min(1).max(200).optional().default(50).describe("返回条数,默认 50,最大 200"),
35
+ source: tool.schema.string().optional().describe("来源过滤:console(控制台)、opencode-stdout(服务输出)、opencode-stderr(服务错误)")
36
+ },
37
+ async execute(args, context) {
38
+ const { level, limit, source } = args;
39
+ log.debug("get_vite_dev_logs called", {
40
+ args,
41
+ sessionID: context.sessionID,
42
+ directory: context.directory
43
+ });
44
+ try {
45
+ const url = new URL(logsApiUrl);
46
+ if (level) url.searchParams.set("level", level);
47
+ if (limit) url.searchParams.set("limit", String(limit));
48
+ if (source) url.searchParams.set("source", source);
49
+ log.debug("Fetching logs from", { url: url.toString() });
50
+ const response = await fetch(url.toString(), {
51
+ method: "GET",
52
+ headers: { Accept: "application/json" },
53
+ signal: context.abort
54
+ });
55
+ if (!response.ok) {
56
+ const errorText = await response.text();
57
+ log.error("Failed to fetch logs", { status: response.status, error: errorText });
58
+ return `获取日志失败: HTTP ${response.status} - ${errorText}`;
59
+ }
60
+ const data = await response.json();
61
+ log.debug("Logs fetched successfully", {
62
+ count: data.logs.length,
63
+ total: data.meta.total
64
+ });
65
+ if (data.logs.length === 0) {
66
+ return `当前没有符合条件的日志(缓冲区共 ${data.meta.total} 条)。
57
67
 
58
68
  建议:
59
69
  - 不指定参数获取所有日志
60
70
  - 使用 level=error,warn 获取错误和警告`;
61
- const d = s.logs.map((o) => {
62
- const m = new Date(o.timestamp).toLocaleTimeString(), f = o.level === "error" ? "❌" : o.level === "warn" ? "⚠️" : o.level === "info" ? "ℹ️" : "";
63
- return `${m} ${f} ${o.message}`;
64
- }).join(`
65
- `);
66
- return `Vite 开发服务器日志(${s.meta.returned}/${s.meta.total} 条):
71
+ }
72
+ const formattedLogs = data.logs.map((entry) => {
73
+ const time = new Date(entry.timestamp).toLocaleTimeString();
74
+ const levelIcon = entry.level === "error" ? "❌" : entry.level === "warn" ? "⚠️" : entry.level === "info" ? "ℹ️" : "";
75
+ return `${time} ${levelIcon} ${entry.message}`;
76
+ }).join("\n");
77
+ return `Vite 开发服务器日志(${data.meta.returned}/${data.meta.total} 条):
67
78
 
68
- ${d}`;
69
- } catch (r) {
70
- const t = r;
71
- return i.abort.aborted ? (e.debug("Request aborted"), "请求已取消") : (e.error("Error fetching vite logs", { error: t }), `获取日志时发生错误: ${t.message}`);
72
- }
79
+ ${formattedLogs}`;
80
+ } catch (error) {
81
+ const err = error;
82
+ if (context.abort.aborted) {
83
+ log.debug("Request aborted");
84
+ return "请求已取消";
73
85
  }
74
- })
86
+ log.error("Error fetching vite logs", { error: err });
87
+ return `获取日志时发生错误: ${err.message}`;
88
+ }
89
+ }
90
+ });
91
+ return {
92
+ tool: {
93
+ get_vite_dev_logs: getViteDevLogsTool
75
94
  }
76
- }) : (e.warn("OPENCODE_VITE_LOGS_API_URL is not set, vite logs plugin will not work"), {});
95
+ };
77
96
  };
78
97
  export {
79
- b as ViteLogsPlugin,
80
- b as default
98
+ ViteLogsPlugin,
99
+ ViteLogsPlugin as default
81
100
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vite-plugin-opencode-assistant/opencode",
3
- "version": "1.0.58",
3
+ "version": "1.0.59",
4
4
  "type": "module",
5
5
  "main": "lib/index.cjs",
6
6
  "module": "es/index.mjs",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "execa": "^9.6.1",
25
- "@vite-plugin-opencode-assistant/shared": "1.0.58"
25
+ "@vite-plugin-opencode-assistant/shared": "1.0.59"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@opencode-ai/plugin": "^1.3.15",