@vite-plugin-opencode-assistant/opencode 1.0.58 → 1.0.60
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/plugins/logger.js +211 -108
- package/es/plugins/page-context.js +33 -22
- package/es/plugins/service-logs.js +186 -179
- package/es/plugins/service-logs.mjs +13 -25
- package/es/plugins/vite-logs.js +75 -56
- package/lib/plugins/service-logs.cjs +12 -24
- package/package.json +2 -2
- package/es/plugins/tool.js +0 -9389
package/es/plugins/logger.js
CHANGED
|
@@ -1,13 +1,25 @@
|
|
|
1
|
-
const
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
const LOG_PREFIX = "[vite-plugin-opencode]";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __spreadValues = (a, b) => {
|
|
10
|
+
for (var prop in b || (b = {}))
|
|
11
|
+
if (__hasOwnProp.call(b, prop))
|
|
12
|
+
__defNormalProp(a, prop, b[prop]);
|
|
13
|
+
if (__getOwnPropSymbols)
|
|
14
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
+
if (__propIsEnum.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
}
|
|
18
|
+
return a;
|
|
19
|
+
};
|
|
20
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
21
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
22
|
+
const COLORS = {
|
|
11
23
|
reset: "\x1B[0m",
|
|
12
24
|
dim: "\x1B[2m",
|
|
13
25
|
bright: "\x1B[1m",
|
|
@@ -16,137 +28,228 @@ const s = {
|
|
|
16
28
|
yellow: "\x1B[33m",
|
|
17
29
|
magenta: "\x1B[35m",
|
|
18
30
|
cyan: "\x1B[36m"
|
|
19
|
-
}, P = {
|
|
20
|
-
0: s.cyan,
|
|
21
|
-
1: s.green,
|
|
22
|
-
2: s.yellow,
|
|
23
|
-
3: s.red,
|
|
24
|
-
4: s.reset
|
|
25
|
-
}, B = {
|
|
26
|
-
0: "DEBUG",
|
|
27
|
-
1: "INFO",
|
|
28
|
-
2: "WARN",
|
|
29
|
-
3: "ERROR",
|
|
30
|
-
4: "NONE"
|
|
31
31
|
};
|
|
32
|
-
|
|
32
|
+
const LEVEL_COLORS = {
|
|
33
|
+
[
|
|
34
|
+
0
|
|
35
|
+
/* DEBUG */
|
|
36
|
+
]: COLORS.cyan,
|
|
37
|
+
[
|
|
38
|
+
1
|
|
39
|
+
/* INFO */
|
|
40
|
+
]: COLORS.green,
|
|
41
|
+
[
|
|
42
|
+
2
|
|
43
|
+
/* WARN */
|
|
44
|
+
]: COLORS.yellow,
|
|
45
|
+
[
|
|
46
|
+
3
|
|
47
|
+
/* ERROR */
|
|
48
|
+
]: COLORS.red,
|
|
49
|
+
[
|
|
50
|
+
4
|
|
51
|
+
/* NONE */
|
|
52
|
+
]: COLORS.reset
|
|
53
|
+
};
|
|
54
|
+
const LEVEL_NAMES = {
|
|
55
|
+
[
|
|
56
|
+
0
|
|
57
|
+
/* DEBUG */
|
|
58
|
+
]: "DEBUG",
|
|
59
|
+
[
|
|
60
|
+
1
|
|
61
|
+
/* INFO */
|
|
62
|
+
]: "INFO",
|
|
63
|
+
[
|
|
64
|
+
2
|
|
65
|
+
/* WARN */
|
|
66
|
+
]: "WARN",
|
|
67
|
+
[
|
|
68
|
+
3
|
|
69
|
+
/* ERROR */
|
|
70
|
+
]: "ERROR",
|
|
71
|
+
[
|
|
72
|
+
4
|
|
73
|
+
/* NONE */
|
|
74
|
+
]: "NONE"
|
|
75
|
+
};
|
|
76
|
+
let globalConfig = {
|
|
33
77
|
level: 1
|
|
34
78
|
/* INFO */
|
|
35
79
|
};
|
|
36
|
-
function
|
|
37
|
-
const
|
|
38
|
-
|
|
80
|
+
function getTimestamp() {
|
|
81
|
+
const now = /* @__PURE__ */ new Date();
|
|
82
|
+
const hours = String(now.getHours()).padStart(2, "0");
|
|
83
|
+
const minutes = String(now.getMinutes()).padStart(2, "0");
|
|
84
|
+
const seconds = String(now.getSeconds()).padStart(2, "0");
|
|
85
|
+
const ms = String(now.getMilliseconds()).padStart(3, "0");
|
|
86
|
+
return `${hours}:${minutes}:${seconds}.${ms}`;
|
|
39
87
|
}
|
|
40
|
-
function
|
|
41
|
-
const
|
|
42
|
-
if (!
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
if (!
|
|
46
|
-
const
|
|
47
|
-
if (!
|
|
48
|
-
const [,
|
|
49
|
-
|
|
88
|
+
function getCallerInfo(depth = 3) {
|
|
89
|
+
const stack = new Error().stack;
|
|
90
|
+
if (!stack) return "";
|
|
91
|
+
const lines = stack.split("\n");
|
|
92
|
+
const targetLine = lines[depth];
|
|
93
|
+
if (!targetLine) return "";
|
|
94
|
+
const match = targetLine.match(/at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?/);
|
|
95
|
+
if (!match) return "";
|
|
96
|
+
const [, funcName, filePath, line] = match;
|
|
97
|
+
const fileName = filePath.split("/").pop() || filePath;
|
|
98
|
+
const func = funcName || "<anonymous>";
|
|
99
|
+
return `${fileName}:${line} ${func}`;
|
|
50
100
|
}
|
|
51
|
-
function
|
|
52
|
-
if (
|
|
53
|
-
if (
|
|
54
|
-
if (
|
|
55
|
-
if (typeof
|
|
56
|
-
if (typeof
|
|
57
|
-
if (
|
|
58
|
-
return `${
|
|
59
|
-
${
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
101
|
+
function formatValue(value, depth = 0) {
|
|
102
|
+
if (depth > 3) return "...";
|
|
103
|
+
if (value === null) return "null";
|
|
104
|
+
if (value === void 0) return "undefined";
|
|
105
|
+
if (typeof value === "string") return depth > 0 ? `"${value}"` : value;
|
|
106
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
107
|
+
if (value instanceof Error) {
|
|
108
|
+
return `${value.name}: ${value.message}${value.stack ? `
|
|
109
|
+
${value.stack}` : ""}`;
|
|
110
|
+
}
|
|
111
|
+
if (Array.isArray(value)) {
|
|
112
|
+
if (value.length === 0) return "[]";
|
|
113
|
+
if (value.length > 5) {
|
|
114
|
+
const items2 = value.slice(0, 3).map((v) => formatValue(v, depth + 1));
|
|
115
|
+
return `[${items2.join(", ")}, ... ${value.length - 3} more items]`;
|
|
116
|
+
}
|
|
117
|
+
const items = value.map((v) => formatValue(v, depth + 1));
|
|
118
|
+
return `[${items.join(", ")}]`;
|
|
119
|
+
}
|
|
120
|
+
if (typeof value === "object") {
|
|
121
|
+
const entries = Object.entries(value);
|
|
122
|
+
if (entries.length === 0) return "{}";
|
|
123
|
+
if (entries.length > 5) {
|
|
124
|
+
const shown = entries.slice(0, 3).map(([k, v]) => `${k}: ${formatValue(v, depth + 1)}`);
|
|
125
|
+
return `{${shown.join(", ")}, ... ${entries.length - 3} more keys}`;
|
|
126
|
+
}
|
|
127
|
+
const formatted = entries.map(([k, v]) => `${k}: ${formatValue(v, depth + 1)}`);
|
|
128
|
+
return `{${formatted.join(", ")}}`;
|
|
65
129
|
}
|
|
66
|
-
return String(
|
|
130
|
+
return String(value);
|
|
67
131
|
}
|
|
68
|
-
function
|
|
69
|
-
if (!
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
132
|
+
function formatContext(context) {
|
|
133
|
+
if (!context || Object.keys(context).length === 0) return "";
|
|
134
|
+
const parts = [];
|
|
135
|
+
if (context.module) parts.push(`[${context.module}]`);
|
|
136
|
+
if (context.operation) parts.push(`(${context.operation})`);
|
|
137
|
+
if (context.traceId) parts.push(`trace:${context.traceId}`);
|
|
138
|
+
if (context.duration !== void 0) parts.push(`${context.duration}ms`);
|
|
139
|
+
const extraKeys = Object.keys(context).filter(
|
|
140
|
+
(k) => !["module", "operation", "traceId", "duration", "error"].includes(k)
|
|
74
141
|
);
|
|
75
|
-
if (
|
|
76
|
-
const
|
|
77
|
-
|
|
142
|
+
if (extraKeys.length > 0) {
|
|
143
|
+
const extra = {};
|
|
144
|
+
extraKeys.forEach((k) => extra[k] = context[k]);
|
|
145
|
+
parts.push(formatValue(extra));
|
|
78
146
|
}
|
|
79
|
-
return
|
|
147
|
+
return parts.join(" ");
|
|
80
148
|
}
|
|
81
|
-
function
|
|
82
|
-
if (
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
149
|
+
function log(level, message, context, ...args) {
|
|
150
|
+
if (level < globalConfig.level) return;
|
|
151
|
+
const parts = [];
|
|
152
|
+
parts.push(`${COLORS.dim}[${process.pid}]${COLORS.reset}`);
|
|
153
|
+
{
|
|
154
|
+
parts.push(`${COLORS.dim}${getTimestamp()}${COLORS.reset}`);
|
|
155
|
+
}
|
|
156
|
+
const levelColor = LEVEL_COLORS[level];
|
|
157
|
+
const levelName = LEVEL_NAMES[level].padEnd(5);
|
|
158
|
+
parts.push(`${levelColor}${levelName}${COLORS.reset}`);
|
|
159
|
+
parts.push(`${COLORS.bright}${LOG_PREFIX}${COLORS.reset}`);
|
|
160
|
+
const contextStr = formatContext(context);
|
|
161
|
+
if (contextStr) {
|
|
162
|
+
parts.push(`${COLORS.magenta}${contextStr}${COLORS.reset}`);
|
|
163
|
+
}
|
|
164
|
+
parts.push(message);
|
|
165
|
+
if (level >= 2) {
|
|
166
|
+
const caller = getCallerInfo(4);
|
|
167
|
+
if (caller) {
|
|
168
|
+
parts.push(`${COLORS.dim}(${caller})${COLORS.reset}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const formattedArgs = args.map((a) => formatValue(a)).join(" ");
|
|
172
|
+
if (formattedArgs) {
|
|
173
|
+
parts.push(formattedArgs);
|
|
174
|
+
}
|
|
175
|
+
if (context == null ? void 0 : context.error) {
|
|
176
|
+
const err = context.error;
|
|
177
|
+
if (err instanceof Error) {
|
|
178
|
+
parts.push(`${COLORS.red}Error: ${err.message}${COLORS.reset}`);
|
|
179
|
+
} else {
|
|
180
|
+
parts.push(`${COLORS.red}Error: ${formatValue(err)}${COLORS.reset}`);
|
|
181
|
+
}
|
|
91
182
|
}
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
183
|
+
const output = parts.join(" ");
|
|
184
|
+
if (level >= 3) {
|
|
185
|
+
console.error(output);
|
|
186
|
+
} else if (level === 2) {
|
|
187
|
+
console.warn(output);
|
|
188
|
+
} else {
|
|
189
|
+
console.log(output);
|
|
96
190
|
}
|
|
97
|
-
const $ = o.join(" ");
|
|
98
|
-
r >= 3 ? console.error($) : r === 2 ? console.warn($) : console.log($);
|
|
99
191
|
}
|
|
100
|
-
const
|
|
101
|
-
debug(
|
|
102
|
-
|
|
192
|
+
const logger = {
|
|
193
|
+
debug(message, context, ...args) {
|
|
194
|
+
log(0, message, context, ...args);
|
|
103
195
|
},
|
|
104
|
-
info(
|
|
105
|
-
|
|
196
|
+
info(message, context, ...args) {
|
|
197
|
+
log(1, message, context, ...args);
|
|
106
198
|
},
|
|
107
|
-
warn(
|
|
108
|
-
|
|
199
|
+
warn(message, context, ...args) {
|
|
200
|
+
log(2, message, context, ...args);
|
|
109
201
|
},
|
|
110
|
-
error(
|
|
111
|
-
|
|
202
|
+
error(message, context, ...args) {
|
|
203
|
+
log(3, message, context, ...args);
|
|
112
204
|
},
|
|
113
|
-
group(
|
|
205
|
+
group(label, context) {
|
|
206
|
+
return;
|
|
114
207
|
},
|
|
115
208
|
groupEnd() {
|
|
209
|
+
return;
|
|
116
210
|
}
|
|
117
211
|
};
|
|
118
|
-
class
|
|
119
|
-
constructor(
|
|
120
|
-
|
|
212
|
+
class PerformanceTimer {
|
|
213
|
+
constructor(operation, context) {
|
|
214
|
+
__publicField(this, "startTime");
|
|
215
|
+
__publicField(this, "context");
|
|
216
|
+
__publicField(this, "operation");
|
|
217
|
+
this.operation = operation;
|
|
218
|
+
this.context = context || {};
|
|
219
|
+
this.startTime = performance.now();
|
|
220
|
+
logger.debug(`⏱️ Starting: ${operation}`, this.context);
|
|
121
221
|
}
|
|
122
|
-
end(
|
|
123
|
-
const
|
|
124
|
-
|
|
222
|
+
end(message) {
|
|
223
|
+
const duration = Math.round(performance.now() - this.startTime);
|
|
224
|
+
const msg = message || `✓ Completed: ${this.operation}`;
|
|
225
|
+
logger.debug(msg, __spreadProps(__spreadValues({}, this.context), { duration }));
|
|
226
|
+
return duration;
|
|
125
227
|
}
|
|
126
|
-
checkpoint(
|
|
127
|
-
const
|
|
128
|
-
|
|
228
|
+
checkpoint(label) {
|
|
229
|
+
const elapsed = Math.round(performance.now() - this.startTime);
|
|
230
|
+
logger.debug(` ↳ ${label}`, __spreadProps(__spreadValues({}, this.context), { duration: elapsed }));
|
|
231
|
+
return elapsed;
|
|
129
232
|
}
|
|
130
233
|
}
|
|
131
|
-
function
|
|
234
|
+
function createLogger(module) {
|
|
132
235
|
return {
|
|
133
|
-
debug(
|
|
134
|
-
|
|
236
|
+
debug(message, context, ...args) {
|
|
237
|
+
logger.debug(message, __spreadProps(__spreadValues({}, context), { module }), ...args);
|
|
135
238
|
},
|
|
136
|
-
info(
|
|
137
|
-
|
|
239
|
+
info(message, context, ...args) {
|
|
240
|
+
logger.info(message, __spreadProps(__spreadValues({}, context), { module }), ...args);
|
|
138
241
|
},
|
|
139
|
-
warn(
|
|
140
|
-
|
|
242
|
+
warn(message, context, ...args) {
|
|
243
|
+
logger.warn(message, __spreadProps(__spreadValues({}, context), { module }), ...args);
|
|
141
244
|
},
|
|
142
|
-
error(
|
|
143
|
-
|
|
245
|
+
error(message, context, ...args) {
|
|
246
|
+
logger.error(message, __spreadProps(__spreadValues({}, context), { module }), ...args);
|
|
144
247
|
},
|
|
145
|
-
timer(
|
|
146
|
-
return new
|
|
248
|
+
timer(operation, context) {
|
|
249
|
+
return new PerformanceTimer(operation, __spreadProps(__spreadValues({}, context), { module }));
|
|
147
250
|
}
|
|
148
251
|
};
|
|
149
252
|
}
|
|
150
253
|
export {
|
|
151
|
-
|
|
254
|
+
createLogger as c
|
|
152
255
|
};
|
|
@@ -1,25 +1,36 @@
|
|
|
1
|
-
import { c as
|
|
2
|
-
const
|
|
3
|
-
async function
|
|
1
|
+
import { c as createLogger } from "./logger.js";
|
|
2
|
+
const log = createLogger("OpenCodePluginPageContext");
|
|
3
|
+
async function fetchPageContext(contextApiUrl) {
|
|
4
4
|
try {
|
|
5
|
-
const
|
|
5
|
+
const response = await fetch(contextApiUrl, {
|
|
6
6
|
method: "GET",
|
|
7
7
|
headers: { "Content-Type": "application/json" }
|
|
8
8
|
});
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
if (!response.ok) {
|
|
10
|
+
log.debug("Failed to fetch page context", { status: response.status });
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return await response.json();
|
|
14
|
+
} catch (error) {
|
|
15
|
+
log.debug("Error fetching page context", { error });
|
|
16
|
+
return null;
|
|
12
17
|
}
|
|
13
18
|
}
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
const PageContextPlugin = async () => {
|
|
20
|
+
log.info("PageContextPlugin loading...");
|
|
21
|
+
const contextApiUrl = process.env.OPENCODE_CONTEXT_API_URL;
|
|
22
|
+
log.debug("Context API URL:", { contextApiUrl });
|
|
23
|
+
if (!contextApiUrl) {
|
|
24
|
+
log.warn("OPENCODE_CONTEXT_API_URL is not set, page context plugin will not work");
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
log.info("Plugin initialized successfully");
|
|
28
|
+
return {
|
|
29
|
+
"experimental.chat.system.transform": async (_input, output) => {
|
|
30
|
+
log.debug("System transform hook called");
|
|
31
|
+
const pageContext = await fetchPageContext(contextApiUrl);
|
|
32
|
+
log.debug("Page context fetched", { pageContext });
|
|
33
|
+
const systemPrompt = `
|
|
23
34
|
你是一个专业的前端开发助手,运行在 **OpenCode** 平台中,并通过 **vite-plugin-opencode-assistant** 插件集成到用户的 Vite 开发环境。
|
|
24
35
|
|
|
25
36
|
## ⚠️ 重要:页面上下文优先级规则
|
|
@@ -30,8 +41,8 @@ const l = async () => {
|
|
|
30
41
|
|
|
31
42
|
**这里的上下文为最高优先级,任何情况下都不能被覆盖**
|
|
32
43
|
|
|
33
|
-
- **页面 URL**: ${(
|
|
34
|
-
- **页面标题**: ${(
|
|
44
|
+
- **页面 URL**: ${(pageContext == null ? void 0 : pageContext.url) || "未知"}
|
|
45
|
+
- **页面标题**: ${(pageContext == null ? void 0 : pageContext.title) || "未知"}
|
|
35
46
|
|
|
36
47
|
**理解问题的优先级顺序:**
|
|
37
48
|
1. **当前页面上下文**(最高优先级) - 根据用户当前所在页面的 URL 和标题理解问题背景
|
|
@@ -104,11 +115,11 @@ const l = async () => {
|
|
|
104
115
|
4. **HTTP 请求成功判断(强制)**
|
|
105
116
|
判断请求成功时,不要只看 HTTP 状态码!HTTP 状态码 200 并不代表业务逻辑成功。必须获取接口的详细响应内容,检查响应体中的业务状态码或错误信息。在确认请求成功之前,始终解析并检查响应体的完整内容
|
|
106
117
|
`.trim();
|
|
107
|
-
|
|
118
|
+
output.system.push(systemPrompt);
|
|
108
119
|
}
|
|
109
|
-
}
|
|
120
|
+
};
|
|
110
121
|
};
|
|
111
122
|
export {
|
|
112
|
-
|
|
113
|
-
|
|
123
|
+
PageContextPlugin,
|
|
124
|
+
PageContextPlugin as default
|
|
114
125
|
};
|