oh-my-opencode 0.1.10 → 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.
@@ -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 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
- }
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
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
- if (output.output.toLowerCase().includes("error")) {
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 fs2 from "fs";
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 (fs2.existsSync(configPath)) {
18967
- const content = fs2.readFileSync(configPath, "utf-8");
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) {
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.11",
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",