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 Parser2 = (await Promise.resolve().then(() => __toESM(require_tree_sitter(), 1))).default;
4158
- const treeSitterWasmPath = __require.resolve("/home/runner/work/oh-my-opencode/oh-my-opencode/node_modules/web-tree-sitter/tree-sitter.wasm");
4159
- await Parser2.init({
4160
- locateFile: () => treeSitterWasmPath
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
- if (output.output.toLowerCase().includes("error")) {
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 fs2 from "fs";
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 (fs2.existsSync(configPath)) {
18967
- const content = fs2.readFileSync(configPath, "utf-8");
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
Binary file