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 +70 -91
- package/dist/shared/deep-merge.d.ts +1 -0
- package/dist/shared/file-utils.d.ts +6 -0
- package/dist/shared/index.d.ts +1 -0
- package/package.json +1 -1
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/
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
function
|
|
2672
|
-
return
|
|
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
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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((
|
|
6931
|
-
resolveCallback =
|
|
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((
|
|
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
|
|
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
|
|
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
|
-
|
|
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 (!
|
|
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: () =>
|
|
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
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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 (!
|
|
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
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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((
|
|
23843
|
+
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
23865
23844
|
}
|
|
23866
23845
|
function truncateText(text, maxLength) {
|
|
23867
23846
|
if (text.length <= maxLength)
|
package/dist/shared/index.d.ts
CHANGED