oh-my-opencode 1.0.1 → 1.0.2

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/index.js CHANGED
@@ -2586,13 +2586,42 @@ function log(message, data) {
2586
2586
  fs.appendFileSync(logFile, logEntry);
2587
2587
  } catch {}
2588
2588
  }
2589
+ // src/shared/deep-merge.ts
2590
+ var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
2591
+ var MAX_DEPTH = 50;
2592
+ function isPlainObject(value) {
2593
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
2594
+ }
2595
+ function deepMerge(base, override, depth = 0) {
2596
+ if (!base && !override)
2597
+ return;
2598
+ if (!base)
2599
+ return override;
2600
+ if (!override)
2601
+ return base;
2602
+ if (depth > MAX_DEPTH)
2603
+ return override ?? base;
2604
+ const result = { ...base };
2605
+ for (const key of Object.keys(override)) {
2606
+ if (DANGEROUS_KEYS.has(key))
2607
+ continue;
2608
+ const baseValue = base[key];
2609
+ const overrideValue = override[key];
2610
+ if (overrideValue === undefined)
2611
+ continue;
2612
+ if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {
2613
+ result[key] = deepMerge(baseValue, overrideValue, depth + 1);
2614
+ } else {
2615
+ result[key] = overrideValue;
2616
+ }
2617
+ }
2618
+ return result;
2619
+ }
2620
+
2589
2621
  // src/shared/snake-case.ts
2590
2622
  function camelToSnake(str) {
2591
2623
  return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
2592
2624
  }
2593
- function isPlainObject(value) {
2594
- return typeof value === "object" && value !== null && !Array.isArray(value);
2595
- }
2596
2625
  function objectToSnakeCase(obj, deep = true) {
2597
2626
  const result = {};
2598
2627
  for (const [key, value] of Object.entries(obj)) {
@@ -2665,36 +2694,22 @@ function isHookDisabled(config, hookType) {
2665
2694
  }
2666
2695
  return false;
2667
2696
  }
2668
- // src/shared/deep-merge.ts
2669
- var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
2670
- var MAX_DEPTH = 50;
2671
- function isPlainObject2(value) {
2672
- return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
2697
+ // src/shared/file-utils.ts
2698
+ import { lstatSync, readlinkSync } from "fs";
2699
+ import { resolve } from "path";
2700
+ function isMarkdownFile(entry) {
2701
+ return !entry.name.startsWith(".") && entry.name.endsWith(".md") && entry.isFile();
2673
2702
  }
2674
- function deepMerge(base, override, depth = 0) {
2675
- if (!base && !override)
2676
- return;
2677
- if (!base)
2678
- return override;
2679
- if (!override)
2680
- return base;
2681
- if (depth > MAX_DEPTH)
2682
- return override ?? base;
2683
- const result = { ...base };
2684
- for (const key of Object.keys(override)) {
2685
- if (DANGEROUS_KEYS.has(key))
2686
- continue;
2687
- const baseValue = base[key];
2688
- const overrideValue = override[key];
2689
- if (overrideValue === undefined)
2690
- continue;
2691
- if (isPlainObject2(baseValue) && isPlainObject2(overrideValue)) {
2692
- result[key] = deepMerge(baseValue, overrideValue, depth + 1);
2693
- } else {
2694
- result[key] = overrideValue;
2703
+ function resolveSymlink(filePath) {
2704
+ try {
2705
+ const stats = lstatSync(filePath, { throwIfNoEntry: false });
2706
+ if (stats?.isSymbolicLink()) {
2707
+ return resolve(filePath, "..", readlinkSync(filePath));
2695
2708
  }
2709
+ return filePath;
2710
+ } catch {
2711
+ return filePath;
2696
2712
  }
2697
- return result;
2698
2713
  }
2699
2714
  // src/agents/utils.ts
2700
2715
  var allBuiltinAgents = {
@@ -4042,7 +4057,7 @@ function createGrepOutputTruncatorHook(ctx) {
4042
4057
  }
4043
4058
  // src/hooks/directory-agents-injector/index.ts
4044
4059
  import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
4045
- import { dirname as dirname2, join as join9, resolve } from "path";
4060
+ import { dirname as dirname2, join as join9, resolve as resolve2 } from "path";
4046
4061
 
4047
4062
  // src/hooks/directory-agents-injector/storage.ts
4048
4063
  import {
@@ -4108,7 +4123,7 @@ function createDirectoryAgentsInjectorHook(ctx) {
4108
4123
  return null;
4109
4124
  if (title.startsWith("/"))
4110
4125
  return title;
4111
- return resolve(ctx.directory, title);
4126
+ return resolve2(ctx.directory, title);
4112
4127
  }
4113
4128
  function findAgentsMdUp(startDir) {
4114
4129
  const found = [];
@@ -4183,7 +4198,7 @@ ${content}`;
4183
4198
  }
4184
4199
  // src/hooks/directory-readme-injector/index.ts
4185
4200
  import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
4186
- import { dirname as dirname3, join as join12, resolve as resolve2 } from "path";
4201
+ import { dirname as dirname3, join as join12, resolve as resolve3 } from "path";
4187
4202
 
4188
4203
  // src/hooks/directory-readme-injector/storage.ts
4189
4204
  import {
@@ -4249,7 +4264,7 @@ function createDirectoryReadmeInjectorHook(ctx) {
4249
4264
  return null;
4250
4265
  if (title.startsWith("/"))
4251
4266
  return title;
4252
- return resolve2(ctx.directory, title);
4267
+ return resolve3(ctx.directory, title);
4253
4268
  }
4254
4269
  function findReadmeMdUp(startDir) {
4255
4270
  const found = [];
@@ -5974,7 +5989,7 @@ ${result.message}`;
5974
5989
  // src/hooks/rules-injector/index.ts
5975
5990
  import { readFileSync as readFileSync9 } from "fs";
5976
5991
  import { homedir as homedir7 } from "os";
5977
- import { relative as relative3, resolve as resolve3 } from "path";
5992
+ import { relative as relative3, resolve as resolve4 } from "path";
5978
5993
 
5979
5994
  // src/hooks/rules-injector/finder.ts
5980
5995
  import {
@@ -6331,7 +6346,7 @@ function createRulesInjectorHook(ctx) {
6331
6346
  return null;
6332
6347
  if (title.startsWith("/"))
6333
6348
  return title;
6334
- return resolve3(ctx.directory, title);
6349
+ return resolve4(ctx.directory, title);
6335
6350
  }
6336
6351
  const toolExecuteAfter = async (input, output) => {
6337
6352
  if (!TRACKED_TOOLS.includes(input.tool.toLowerCase()))
@@ -6927,8 +6942,8 @@ function startCallbackServer(timeoutMs = 5 * 60 * 1000) {
6927
6942
  });
6928
6943
  const actualPort = server.port;
6929
6944
  const waitForCallback = () => {
6930
- return new Promise((resolve4, reject) => {
6931
- resolveCallback = resolve4;
6945
+ return new Promise((resolve5, reject) => {
6946
+ resolveCallback = resolve5;
6932
6947
  rejectCallback = reject;
6933
6948
  timeoutId = setTimeout(() => {
6934
6949
  cleanup();
@@ -7874,7 +7889,7 @@ async function attemptFetch(options) {
7874
7889
  if (attempt < maxPermissionRetries) {
7875
7890
  const delay = calculateRetryDelay2(attempt);
7876
7891
  debugLog6(`[RETRY] GCP permission error, retry ${attempt + 1}/${maxPermissionRetries} after ${delay}ms`);
7877
- await new Promise((resolve4) => setTimeout(resolve4, delay));
7892
+ await new Promise((resolve5) => setTimeout(resolve5, delay));
7878
7893
  continue;
7879
7894
  }
7880
7895
  debugLog6(`[RETRY] GCP permission error, max retries exceeded`);
@@ -8189,9 +8204,6 @@ async function createGoogleAntigravityAuthPlugin({
8189
8204
  import { existsSync as existsSync19, readdirSync as readdirSync4, readFileSync as readFileSync11 } from "fs";
8190
8205
  import { homedir as homedir9 } from "os";
8191
8206
  import { join as join24, basename } from "path";
8192
- function isMarkdownFile(entry) {
8193
- return !entry.name.startsWith(".") && entry.name.endsWith(".md") && entry.isFile();
8194
- }
8195
8207
  function loadCommandsFromDir(commandsDir, scope) {
8196
8208
  if (!existsSync19(commandsDir)) {
8197
8209
  return [];
@@ -8263,9 +8275,9 @@ function loadOpencodeProjectCommands() {
8263
8275
  return commandsToRecord(commands);
8264
8276
  }
8265
8277
  // src/features/claude-code-skill-loader/loader.ts
8266
- import { existsSync as existsSync20, readdirSync as readdirSync5, readFileSync as readFileSync12, lstatSync, readlinkSync } from "fs";
8278
+ import { existsSync as existsSync20, readdirSync as readdirSync5, readFileSync as readFileSync12 } from "fs";
8267
8279
  import { homedir as homedir10 } from "os";
8268
- import { join as join25, resolve as resolve4 } from "path";
8280
+ import { join as join25 } from "path";
8269
8281
  function loadSkillsFromDir(skillsDir, scope) {
8270
8282
  if (!existsSync20(skillsDir)) {
8271
8283
  return [];
@@ -8278,14 +8290,7 @@ function loadSkillsFromDir(skillsDir, scope) {
8278
8290
  const skillPath = join25(skillsDir, entry.name);
8279
8291
  if (!entry.isDirectory() && !entry.isSymbolicLink())
8280
8292
  continue;
8281
- let resolvedPath = skillPath;
8282
- try {
8283
- if (lstatSync(skillPath, { throwIfNoEntry: false })?.isSymbolicLink()) {
8284
- resolvedPath = resolve4(skillPath, "..", readlinkSync(skillPath));
8285
- }
8286
- } catch {
8287
- continue;
8288
- }
8293
+ const resolvedPath = resolveSymlink(skillPath);
8289
8294
  const skillMdPath = join25(resolvedPath, "SKILL.md");
8290
8295
  if (!existsSync20(skillMdPath))
8291
8296
  continue;
@@ -8352,9 +8357,6 @@ function parseToolsConfig(toolsStr) {
8352
8357
  }
8353
8358
  return result;
8354
8359
  }
8355
- function isMarkdownFile2(entry) {
8356
- return !entry.name.startsWith(".") && entry.name.endsWith(".md") && entry.isFile();
8357
- }
8358
8360
  function loadAgentsFromDir(agentsDir, scope) {
8359
8361
  if (!existsSync21(agentsDir)) {
8360
8362
  return [];
@@ -8362,7 +8364,7 @@ function loadAgentsFromDir(agentsDir, scope) {
8362
8364
  const entries = readdirSync6(agentsDir, { withFileTypes: true });
8363
8365
  const agents = [];
8364
8366
  for (const entry of entries) {
8365
- if (!isMarkdownFile2(entry))
8367
+ if (!isMarkdownFile(entry))
8366
8368
  continue;
8367
8369
  const agentPath = join26(agentsDir, entry.name);
8368
8370
  const agentName = basename2(entry.name, ".md");
@@ -10325,7 +10327,7 @@ __export(exports_util, {
10325
10327
  jsonStringifyReplacer: () => jsonStringifyReplacer,
10326
10328
  joinValues: () => joinValues,
10327
10329
  issue: () => issue,
10328
- isPlainObject: () => isPlainObject3,
10330
+ isPlainObject: () => isPlainObject2,
10329
10331
  isObject: () => isObject,
10330
10332
  hexToUint8Array: () => hexToUint8Array,
10331
10333
  getSizableOrigin: () => getSizableOrigin,
@@ -10507,7 +10509,7 @@ var allowsEval = cached(() => {
10507
10509
  return false;
10508
10510
  }
10509
10511
  });
10510
- function isPlainObject3(o) {
10512
+ function isPlainObject2(o) {
10511
10513
  if (isObject(o) === false)
10512
10514
  return false;
10513
10515
  const ctor = o.constructor;
@@ -10522,7 +10524,7 @@ function isPlainObject3(o) {
10522
10524
  return true;
10523
10525
  }
10524
10526
  function shallowClone(o) {
10525
- if (isPlainObject3(o))
10527
+ if (isPlainObject2(o))
10526
10528
  return { ...o };
10527
10529
  if (Array.isArray(o))
10528
10530
  return [...o];
@@ -10705,7 +10707,7 @@ function omit(schema, mask) {
10705
10707
  return clone(schema, def);
10706
10708
  }
10707
10709
  function extend(schema, shape) {
10708
- if (!isPlainObject3(shape)) {
10710
+ if (!isPlainObject2(shape)) {
10709
10711
  throw new Error("Invalid input to extend: expected a plain object");
10710
10712
  }
10711
10713
  const checks = schema._zod.def.checks;
@@ -10724,7 +10726,7 @@ function extend(schema, shape) {
10724
10726
  return clone(schema, def);
10725
10727
  }
10726
10728
  function safeExtend(schema, shape) {
10727
- if (!isPlainObject3(shape)) {
10729
+ if (!isPlainObject2(shape)) {
10728
10730
  throw new Error("Invalid input to safeExtend: expected a plain object");
10729
10731
  }
10730
10732
  const def = {
@@ -12874,7 +12876,7 @@ function mergeValues(a, b) {
12874
12876
  if (a instanceof Date && b instanceof Date && +a === +b) {
12875
12877
  return { valid: true, data: a };
12876
12878
  }
12877
- if (isPlainObject3(a) && isPlainObject3(b)) {
12879
+ if (isPlainObject2(a) && isPlainObject2(b)) {
12878
12880
  const bKeys = Object.keys(b);
12879
12881
  const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
12880
12882
  const newObj = { ...a, ...b };
@@ -13004,7 +13006,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
13004
13006
  $ZodType.init(inst, def);
13005
13007
  inst._zod.parse = (payload, ctx) => {
13006
13008
  const input = payload.value;
13007
- if (!isPlainObject3(input)) {
13009
+ if (!isPlainObject2(input)) {
13008
13010
  payload.issues.push({
13009
13011
  expected: "record",
13010
13012
  code: "invalid_type",
@@ -23351,11 +23353,7 @@ function discoverCommandsFromDir(commandsDir, scope) {
23351
23353
  const entries = readdirSync7(commandsDir, { withFileTypes: true });
23352
23354
  const commands = [];
23353
23355
  for (const entry of entries) {
23354
- if (entry.name.startsWith("."))
23355
- continue;
23356
- if (!entry.name.endsWith(".md"))
23357
- continue;
23358
- if (!entry.isFile())
23356
+ if (!isMarkdownFile(entry))
23359
23357
  continue;
23360
23358
  const commandPath = join32(commandsDir, entry.name);
23361
23359
  const commandName = basename3(entry.name, ".md");
@@ -23519,9 +23517,9 @@ var SkillFrontmatterSchema = exports_external.object({
23519
23517
  metadata: exports_external.record(exports_external.string(), exports_external.string()).optional()
23520
23518
  });
23521
23519
  // src/tools/skill/tools.ts
23522
- import { existsSync as existsSync30, readdirSync as readdirSync8, lstatSync as lstatSync2, readlinkSync as readlinkSync2, readFileSync as readFileSync18 } from "fs";
23520
+ import { existsSync as existsSync30, readdirSync as readdirSync8, readFileSync as readFileSync18 } from "fs";
23523
23521
  import { homedir as homedir16 } from "os";
23524
- import { join as join33, resolve as resolve7, basename as basename4 } from "path";
23522
+ import { join as join33, basename as basename4 } from "path";
23525
23523
  function parseSkillFrontmatter(data) {
23526
23524
  return {
23527
23525
  name: typeof data.name === "string" ? data.name : "",
@@ -23542,15 +23540,7 @@ function discoverSkillsFromDir(skillsDir, scope) {
23542
23540
  continue;
23543
23541
  const skillPath = join33(skillsDir, entry.name);
23544
23542
  if (entry.isDirectory() || entry.isSymbolicLink()) {
23545
- let resolvedPath = skillPath;
23546
- try {
23547
- const stats = lstatSync2(skillPath, { throwIfNoEntry: false });
23548
- if (stats?.isSymbolicLink()) {
23549
- resolvedPath = resolve7(skillPath, "..", readlinkSync2(skillPath));
23550
- }
23551
- } catch {
23552
- continue;
23553
- }
23543
+ const resolvedPath = resolveSymlink(skillPath);
23554
23544
  const skillMdPath = join33(resolvedPath, "SKILL.md");
23555
23545
  if (!existsSync30(skillMdPath))
23556
23546
  continue;
@@ -23579,17 +23569,6 @@ function discoverSkillsSync() {
23579
23569
  var availableSkills = discoverSkillsSync();
23580
23570
  var skillListForDescription = availableSkills.map((s) => `- ${s.name}: ${s.description} (${s.scope})`).join(`
23581
23571
  `);
23582
- function resolveSymlink(skillPath) {
23583
- try {
23584
- const stats = lstatSync2(skillPath, { throwIfNoEntry: false });
23585
- if (stats?.isSymbolicLink()) {
23586
- return resolve7(skillPath, "..", readlinkSync2(skillPath));
23587
- }
23588
- return skillPath;
23589
- } catch {
23590
- return skillPath;
23591
- }
23592
- }
23593
23572
  async function parseSkillMd(skillPath) {
23594
23573
  const resolvedPath = resolveSymlink(skillPath);
23595
23574
  const skillMdPath = join33(resolvedPath, "SKILL.md");
@@ -23861,7 +23840,7 @@ Use \`background_output\` tool with task_id="${task.id}" to check progress:
23861
23840
  });
23862
23841
  }
23863
23842
  function delay(ms) {
23864
- return new Promise((resolve8) => setTimeout(resolve8, ms));
23843
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
23865
23844
  }
23866
23845
  function truncateText(text, maxLength) {
23867
23846
  if (text.length <= maxLength)
@@ -1,3 +1,4 @@
1
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
1
2
  /**
2
3
  * Deep merges two objects, with override values taking precedence.
3
4
  * - Objects are recursively merged
@@ -0,0 +1,6 @@
1
+ export declare function isMarkdownFile(entry: {
2
+ name: string;
3
+ isFile: () => boolean;
4
+ }): boolean;
5
+ export declare function isSymbolicLink(filePath: string): boolean;
6
+ export declare function resolveSymlink(filePath: string): string;
@@ -8,3 +8,4 @@ export * from "./tool-name";
8
8
  export * from "./pattern-matcher";
9
9
  export * from "./hook-disabled";
10
10
  export * from "./deep-merge";
11
+ export * from "./file-utils";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
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",