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