oh-my-opencode 0.1.9 → 0.1.11
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/dist/hooks/comment-checker/detector.d.ts +1 -0
- package/dist/index.js +194 -31
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { CommentInfo } from "./types";
|
|
2
|
+
export declare function warmupCommonLanguages(): void;
|
|
2
3
|
export declare function isSupportedFile(filePath: string): boolean;
|
|
3
4
|
export declare function detectComments(filePath: string, content: string, includeDocstrings?: boolean): Promise<CommentInfo[]>;
|
package/dist/index.js
CHANGED
|
@@ -4122,6 +4122,149 @@ function getLanguageByExtension(filePath) {
|
|
|
4122
4122
|
}
|
|
4123
4123
|
|
|
4124
4124
|
// src/hooks/comment-checker/detector.ts
|
|
4125
|
+
import * as fs2 from "fs";
|
|
4126
|
+
var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
4127
|
+
var DEBUG_FILE = "/tmp/comment-checker-debug.log";
|
|
4128
|
+
function debugLog(...args2) {
|
|
4129
|
+
if (DEBUG) {
|
|
4130
|
+
const msg = `[${new Date().toISOString()}] [comment-checker:detector] ${args2.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
|
|
4131
|
+
`;
|
|
4132
|
+
fs2.appendFileSync(DEBUG_FILE, msg);
|
|
4133
|
+
}
|
|
4134
|
+
}
|
|
4135
|
+
var parserClass = null;
|
|
4136
|
+
var parserInitPromise = null;
|
|
4137
|
+
var languageCache = new Map;
|
|
4138
|
+
var LANGUAGE_NAME_MAP = {
|
|
4139
|
+
golang: "go",
|
|
4140
|
+
csharp: "c_sharp",
|
|
4141
|
+
cpp: "cpp"
|
|
4142
|
+
};
|
|
4143
|
+
var COMMON_LANGUAGES = [
|
|
4144
|
+
"python",
|
|
4145
|
+
"typescript",
|
|
4146
|
+
"javascript",
|
|
4147
|
+
"tsx",
|
|
4148
|
+
"go",
|
|
4149
|
+
"rust",
|
|
4150
|
+
"java"
|
|
4151
|
+
];
|
|
4152
|
+
async function initParserClass() {
|
|
4153
|
+
if (parserClass)
|
|
4154
|
+
return;
|
|
4155
|
+
if (parserInitPromise) {
|
|
4156
|
+
await parserInitPromise;
|
|
4157
|
+
return;
|
|
4158
|
+
}
|
|
4159
|
+
parserInitPromise = (async () => {
|
|
4160
|
+
debugLog("importing web-tree-sitter...");
|
|
4161
|
+
parserClass = (await Promise.resolve().then(() => __toESM(require_tree_sitter(), 1))).default;
|
|
4162
|
+
const treeSitterWasmPath = __require.resolve("/home/runner/work/oh-my-opencode/oh-my-opencode/node_modules/web-tree-sitter/tree-sitter.wasm");
|
|
4163
|
+
debugLog("wasm path:", treeSitterWasmPath);
|
|
4164
|
+
await parserClass.init({
|
|
4165
|
+
locateFile: () => treeSitterWasmPath
|
|
4166
|
+
});
|
|
4167
|
+
debugLog("Parser class initialized");
|
|
4168
|
+
})();
|
|
4169
|
+
await parserInitPromise;
|
|
4170
|
+
}
|
|
4171
|
+
async function getParser() {
|
|
4172
|
+
await initParserClass();
|
|
4173
|
+
return new parserClass;
|
|
4174
|
+
}
|
|
4175
|
+
async function loadLanguageWasm(langName) {
|
|
4176
|
+
const mappedLang = LANGUAGE_NAME_MAP[langName] || langName;
|
|
4177
|
+
try {
|
|
4178
|
+
const wasmModule = await import(`tree-sitter-wasms/out/tree-sitter-${langName}.wasm`);
|
|
4179
|
+
return wasmModule.default;
|
|
4180
|
+
} catch {
|
|
4181
|
+
if (mappedLang !== langName) {
|
|
4182
|
+
try {
|
|
4183
|
+
const wasmModule = await import(`tree-sitter-wasms/out/tree-sitter-${mappedLang}.wasm`);
|
|
4184
|
+
return wasmModule.default;
|
|
4185
|
+
} catch {
|
|
4186
|
+
return null;
|
|
4187
|
+
}
|
|
4188
|
+
}
|
|
4189
|
+
return null;
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4192
|
+
async function getLanguage(langName) {
|
|
4193
|
+
const cached = languageCache.get(langName);
|
|
4194
|
+
if (cached) {
|
|
4195
|
+
if (cached.initPromise) {
|
|
4196
|
+
await cached.initPromise;
|
|
4197
|
+
}
|
|
4198
|
+
cached.lastUsedAt = Date.now();
|
|
4199
|
+
debugLog("using cached language:", langName);
|
|
4200
|
+
return cached.language;
|
|
4201
|
+
}
|
|
4202
|
+
debugLog("loading language wasm:", langName);
|
|
4203
|
+
const initPromise2 = (async () => {
|
|
4204
|
+
await initParserClass();
|
|
4205
|
+
const wasmPath = await loadLanguageWasm(langName);
|
|
4206
|
+
if (!wasmPath) {
|
|
4207
|
+
debugLog("failed to load language wasm:", langName);
|
|
4208
|
+
return null;
|
|
4209
|
+
}
|
|
4210
|
+
return await parserClass.Language.load(wasmPath);
|
|
4211
|
+
})();
|
|
4212
|
+
languageCache.set(langName, {
|
|
4213
|
+
language: null,
|
|
4214
|
+
initPromise: initPromise2,
|
|
4215
|
+
isInitializing: true,
|
|
4216
|
+
lastUsedAt: Date.now()
|
|
4217
|
+
});
|
|
4218
|
+
const language = await initPromise2;
|
|
4219
|
+
const managed = languageCache.get(langName);
|
|
4220
|
+
if (managed) {
|
|
4221
|
+
managed.language = language;
|
|
4222
|
+
managed.initPromise = undefined;
|
|
4223
|
+
managed.isInitializing = false;
|
|
4224
|
+
}
|
|
4225
|
+
debugLog("language loaded and cached:", langName);
|
|
4226
|
+
return language;
|
|
4227
|
+
}
|
|
4228
|
+
function warmupLanguage(langName) {
|
|
4229
|
+
if (languageCache.has(langName))
|
|
4230
|
+
return;
|
|
4231
|
+
debugLog("warming up language (background):", langName);
|
|
4232
|
+
const initPromise2 = (async () => {
|
|
4233
|
+
await initParserClass();
|
|
4234
|
+
const wasmPath = await loadLanguageWasm(langName);
|
|
4235
|
+
if (!wasmPath)
|
|
4236
|
+
return null;
|
|
4237
|
+
return await parserClass.Language.load(wasmPath);
|
|
4238
|
+
})();
|
|
4239
|
+
languageCache.set(langName, {
|
|
4240
|
+
language: null,
|
|
4241
|
+
initPromise: initPromise2,
|
|
4242
|
+
isInitializing: true,
|
|
4243
|
+
lastUsedAt: Date.now()
|
|
4244
|
+
});
|
|
4245
|
+
initPromise2.then((language) => {
|
|
4246
|
+
const managed = languageCache.get(langName);
|
|
4247
|
+
if (managed) {
|
|
4248
|
+
managed.language = language;
|
|
4249
|
+
managed.initPromise = undefined;
|
|
4250
|
+
managed.isInitializing = false;
|
|
4251
|
+
debugLog("warmup complete:", langName);
|
|
4252
|
+
}
|
|
4253
|
+
}).catch((err2) => {
|
|
4254
|
+
debugLog("warmup failed:", langName, err2);
|
|
4255
|
+
languageCache.delete(langName);
|
|
4256
|
+
});
|
|
4257
|
+
}
|
|
4258
|
+
function warmupCommonLanguages() {
|
|
4259
|
+
debugLog("starting background warmup for common languages...");
|
|
4260
|
+
initParserClass().then(() => {
|
|
4261
|
+
for (const lang of COMMON_LANGUAGES) {
|
|
4262
|
+
warmupLanguage(lang);
|
|
4263
|
+
}
|
|
4264
|
+
}).catch((err2) => {
|
|
4265
|
+
debugLog("warmup initialization failed:", err2);
|
|
4266
|
+
});
|
|
4267
|
+
}
|
|
4125
4268
|
function isSupportedFile(filePath) {
|
|
4126
4269
|
return getLanguageByExtension(filePath) !== null;
|
|
4127
4270
|
}
|
|
@@ -4145,40 +4288,24 @@ function determineCommentType(text, nodeType) {
|
|
|
4145
4288
|
return "line";
|
|
4146
4289
|
}
|
|
4147
4290
|
async function detectComments(filePath, content, includeDocstrings = true) {
|
|
4291
|
+
debugLog("detectComments called:", { filePath, contentLength: content.length });
|
|
4148
4292
|
const langName = getLanguageByExtension(filePath);
|
|
4149
4293
|
if (!langName) {
|
|
4294
|
+
debugLog("unsupported language for:", filePath);
|
|
4150
4295
|
return [];
|
|
4151
4296
|
}
|
|
4152
4297
|
const queryPattern = QUERY_TEMPLATES[langName];
|
|
4153
4298
|
if (!queryPattern) {
|
|
4299
|
+
debugLog("no query pattern for:", langName);
|
|
4154
4300
|
return [];
|
|
4155
4301
|
}
|
|
4156
4302
|
try {
|
|
4157
|
-
const
|
|
4158
|
-
const
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
const parser = new Parser2;
|
|
4163
|
-
let wasmPath;
|
|
4164
|
-
try {
|
|
4165
|
-
const wasmModule = await import(`tree-sitter-wasms/out/tree-sitter-${langName}.wasm`);
|
|
4166
|
-
wasmPath = wasmModule.default;
|
|
4167
|
-
} catch {
|
|
4168
|
-
const languageMap = {
|
|
4169
|
-
golang: "go",
|
|
4170
|
-
csharp: "c_sharp",
|
|
4171
|
-
cpp: "cpp"
|
|
4172
|
-
};
|
|
4173
|
-
const mappedLang = languageMap[langName] || langName;
|
|
4174
|
-
try {
|
|
4175
|
-
const wasmModule = await import(`tree-sitter-wasms/out/tree-sitter-${mappedLang}.wasm`);
|
|
4176
|
-
wasmPath = wasmModule.default;
|
|
4177
|
-
} catch {
|
|
4178
|
-
return [];
|
|
4179
|
-
}
|
|
4303
|
+
const parser = await getParser();
|
|
4304
|
+
const language = await getLanguage(langName);
|
|
4305
|
+
if (!language) {
|
|
4306
|
+
debugLog("language not available:", langName);
|
|
4307
|
+
return [];
|
|
4180
4308
|
}
|
|
4181
|
-
const language = await Parser2.Language.load(wasmPath);
|
|
4182
4309
|
parser.setLanguage(language);
|
|
4183
4310
|
const tree = parser.parse(content);
|
|
4184
4311
|
const comments = [];
|
|
@@ -4230,8 +4357,10 @@ async function detectComments(filePath, content, includeDocstrings = true) {
|
|
|
4230
4357
|
}
|
|
4231
4358
|
}
|
|
4232
4359
|
comments.sort((a, b) => a.lineNumber - b.lineNumber);
|
|
4360
|
+
debugLog("detected comments:", comments.length);
|
|
4233
4361
|
return comments;
|
|
4234
|
-
} catch {
|
|
4362
|
+
} catch (err2) {
|
|
4363
|
+
debugLog("detectComments failed:", err2);
|
|
4235
4364
|
return [];
|
|
4236
4365
|
}
|
|
4237
4366
|
}
|
|
@@ -4343,6 +4472,16 @@ function formatHookMessage(fileCommentsList) {
|
|
|
4343
4472
|
`;
|
|
4344
4473
|
}
|
|
4345
4474
|
// src/hooks/comment-checker/index.ts
|
|
4475
|
+
import * as fs3 from "fs";
|
|
4476
|
+
var DEBUG2 = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
4477
|
+
var DEBUG_FILE2 = "/tmp/comment-checker-debug.log";
|
|
4478
|
+
function debugLog2(...args2) {
|
|
4479
|
+
if (DEBUG2) {
|
|
4480
|
+
const msg = `[${new Date().toISOString()}] [comment-checker:hook] ${args2.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
|
|
4481
|
+
`;
|
|
4482
|
+
fs3.appendFileSync(DEBUG_FILE2, msg);
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4346
4485
|
var pendingCalls = new Map;
|
|
4347
4486
|
var PENDING_CALL_TTL = 60000;
|
|
4348
4487
|
function cleanupOldPendingCalls() {
|
|
@@ -4355,20 +4494,28 @@ function cleanupOldPendingCalls() {
|
|
|
4355
4494
|
}
|
|
4356
4495
|
setInterval(cleanupOldPendingCalls, 1e4);
|
|
4357
4496
|
function createCommentCheckerHooks() {
|
|
4497
|
+
debugLog2("createCommentCheckerHooks called");
|
|
4498
|
+
warmupCommonLanguages();
|
|
4358
4499
|
return {
|
|
4359
4500
|
"tool.execute.before": async (input, output) => {
|
|
4501
|
+
debugLog2("tool.execute.before:", { tool: input.tool, callID: input.callID, args: output.args });
|
|
4360
4502
|
const toolLower = input.tool.toLowerCase();
|
|
4361
4503
|
if (toolLower !== "write" && toolLower !== "edit" && toolLower !== "multiedit") {
|
|
4504
|
+
debugLog2("skipping non-write/edit tool:", toolLower);
|
|
4362
4505
|
return;
|
|
4363
4506
|
}
|
|
4364
|
-
const filePath = output.args.filePath ?? output.args.file_path;
|
|
4507
|
+
const filePath = output.args.filePath ?? output.args.file_path ?? output.args.path;
|
|
4365
4508
|
const content = output.args.content;
|
|
4509
|
+
debugLog2("extracted filePath:", filePath);
|
|
4366
4510
|
if (!filePath) {
|
|
4511
|
+
debugLog2("no filePath found");
|
|
4367
4512
|
return;
|
|
4368
4513
|
}
|
|
4369
4514
|
if (!isSupportedFile(filePath)) {
|
|
4515
|
+
debugLog2("unsupported file:", filePath);
|
|
4370
4516
|
return;
|
|
4371
4517
|
}
|
|
4518
|
+
debugLog2("registering pendingCall:", { callID: input.callID, filePath, tool: toolLower });
|
|
4372
4519
|
pendingCalls.set(input.callID, {
|
|
4373
4520
|
filePath,
|
|
4374
4521
|
content,
|
|
@@ -4378,25 +4525,38 @@ function createCommentCheckerHooks() {
|
|
|
4378
4525
|
});
|
|
4379
4526
|
},
|
|
4380
4527
|
"tool.execute.after": async (input, output) => {
|
|
4528
|
+
debugLog2("tool.execute.after:", { tool: input.tool, callID: input.callID });
|
|
4381
4529
|
const pendingCall = pendingCalls.get(input.callID);
|
|
4382
4530
|
if (!pendingCall) {
|
|
4531
|
+
debugLog2("no pendingCall found for:", input.callID);
|
|
4383
4532
|
return;
|
|
4384
4533
|
}
|
|
4385
4534
|
pendingCalls.delete(input.callID);
|
|
4386
|
-
|
|
4535
|
+
debugLog2("processing pendingCall:", pendingCall);
|
|
4536
|
+
const outputLower = output.output.toLowerCase();
|
|
4537
|
+
const isToolFailure = outputLower.includes("error:") || outputLower.includes("failed to") || outputLower.includes("could not") || outputLower.startsWith("error");
|
|
4538
|
+
if (isToolFailure) {
|
|
4539
|
+
debugLog2("skipping due to tool failure in output");
|
|
4387
4540
|
return;
|
|
4388
4541
|
}
|
|
4389
4542
|
try {
|
|
4390
4543
|
let content;
|
|
4391
4544
|
if (pendingCall.content) {
|
|
4392
4545
|
content = pendingCall.content;
|
|
4546
|
+
debugLog2("using content from args");
|
|
4393
4547
|
} else {
|
|
4548
|
+
debugLog2("reading file:", pendingCall.filePath);
|
|
4394
4549
|
const file = Bun.file(pendingCall.filePath);
|
|
4395
4550
|
content = await file.text();
|
|
4551
|
+
debugLog2("file content length:", content.length);
|
|
4396
4552
|
}
|
|
4553
|
+
debugLog2("calling detectComments...");
|
|
4397
4554
|
const rawComments = await detectComments(pendingCall.filePath, content);
|
|
4555
|
+
debugLog2("raw comments:", rawComments.length);
|
|
4398
4556
|
const filteredComments = applyFilters(rawComments);
|
|
4557
|
+
debugLog2("filtered comments:", filteredComments.length);
|
|
4399
4558
|
if (filteredComments.length === 0) {
|
|
4559
|
+
debugLog2("no comments after filtering");
|
|
4400
4560
|
return;
|
|
4401
4561
|
}
|
|
4402
4562
|
const fileComments = [
|
|
@@ -4406,10 +4566,13 @@ function createCommentCheckerHooks() {
|
|
|
4406
4566
|
}
|
|
4407
4567
|
];
|
|
4408
4568
|
const message = formatHookMessage(fileComments);
|
|
4569
|
+
debugLog2("appending message to output");
|
|
4409
4570
|
output.output += `
|
|
4410
4571
|
|
|
4411
4572
|
${message}`;
|
|
4412
|
-
} catch {
|
|
4573
|
+
} catch (err2) {
|
|
4574
|
+
debugLog2("tool.execute.after failed:", err2);
|
|
4575
|
+
}
|
|
4413
4576
|
}
|
|
4414
4577
|
};
|
|
4415
4578
|
}
|
|
@@ -18954,7 +19117,7 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
|
|
|
18954
19117
|
agents: AgentOverridesSchema.optional()
|
|
18955
19118
|
});
|
|
18956
19119
|
// src/index.ts
|
|
18957
|
-
import * as
|
|
19120
|
+
import * as fs4 from "fs";
|
|
18958
19121
|
import * as path from "path";
|
|
18959
19122
|
function loadPluginConfig(directory) {
|
|
18960
19123
|
const configPaths = [
|
|
@@ -18963,8 +19126,8 @@ function loadPluginConfig(directory) {
|
|
|
18963
19126
|
];
|
|
18964
19127
|
for (const configPath of configPaths) {
|
|
18965
19128
|
try {
|
|
18966
|
-
if (
|
|
18967
|
-
const content =
|
|
19129
|
+
if (fs4.existsSync(configPath)) {
|
|
19130
|
+
const content = fs4.readFileSync(configPath, "utf-8");
|
|
18968
19131
|
const rawConfig = JSON.parse(content);
|
|
18969
19132
|
const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
18970
19133
|
if (!result.success) {
|