oh-my-opencode 2.4.1 → 2.4.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.
|
@@ -9,6 +9,9 @@ interface ToolExecuteOutput {
|
|
|
9
9
|
output: string;
|
|
10
10
|
metadata: unknown;
|
|
11
11
|
}
|
|
12
|
+
interface ToolExecuteBeforeOutput {
|
|
13
|
+
args: unknown;
|
|
14
|
+
}
|
|
12
15
|
interface EventInput {
|
|
13
16
|
event: {
|
|
14
17
|
type: string;
|
|
@@ -16,6 +19,7 @@ interface EventInput {
|
|
|
16
19
|
};
|
|
17
20
|
}
|
|
18
21
|
export declare function createDirectoryAgentsInjectorHook(ctx: PluginInput): {
|
|
22
|
+
"tool.execute.before": (input: ToolExecuteInput, output: ToolExecuteBeforeOutput) => Promise<void>;
|
|
19
23
|
"tool.execute.after": (input: ToolExecuteInput, output: ToolExecuteOutput) => Promise<void>;
|
|
20
24
|
event: ({ event }: EventInput) => Promise<void>;
|
|
21
25
|
};
|
|
@@ -9,6 +9,9 @@ interface ToolExecuteOutput {
|
|
|
9
9
|
output: string;
|
|
10
10
|
metadata: unknown;
|
|
11
11
|
}
|
|
12
|
+
interface ToolExecuteBeforeOutput {
|
|
13
|
+
args: unknown;
|
|
14
|
+
}
|
|
12
15
|
interface EventInput {
|
|
13
16
|
event: {
|
|
14
17
|
type: string;
|
|
@@ -16,6 +19,7 @@ interface EventInput {
|
|
|
16
19
|
};
|
|
17
20
|
}
|
|
18
21
|
export declare function createDirectoryReadmeInjectorHook(ctx: PluginInput): {
|
|
22
|
+
"tool.execute.before": (input: ToolExecuteInput, output: ToolExecuteBeforeOutput) => Promise<void>;
|
|
19
23
|
"tool.execute.after": (input: ToolExecuteInput, output: ToolExecuteOutput) => Promise<void>;
|
|
20
24
|
event: ({ event }: EventInput) => Promise<void>;
|
|
21
25
|
};
|
|
@@ -9,6 +9,9 @@ interface ToolExecuteOutput {
|
|
|
9
9
|
output: string;
|
|
10
10
|
metadata: unknown;
|
|
11
11
|
}
|
|
12
|
+
interface ToolExecuteBeforeOutput {
|
|
13
|
+
args: unknown;
|
|
14
|
+
}
|
|
12
15
|
interface EventInput {
|
|
13
16
|
event: {
|
|
14
17
|
type: string;
|
|
@@ -16,6 +19,7 @@ interface EventInput {
|
|
|
16
19
|
};
|
|
17
20
|
}
|
|
18
21
|
export declare function createRulesInjectorHook(ctx: PluginInput): {
|
|
22
|
+
"tool.execute.before": (input: ToolExecuteInput, output: ToolExecuteBeforeOutput) => Promise<void>;
|
|
19
23
|
"tool.execute.after": (input: ToolExecuteInput, output: ToolExecuteOutput) => Promise<void>;
|
|
20
24
|
event: ({ event }: EventInput) => Promise<void>;
|
|
21
25
|
};
|
package/dist/index.js
CHANGED
|
@@ -3271,8 +3271,7 @@ function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, directory
|
|
|
3271
3271
|
config = { ...config, prompt: config.prompt + envContext };
|
|
3272
3272
|
}
|
|
3273
3273
|
if (override) {
|
|
3274
|
-
|
|
3275
|
-
config = mergeAgentConfig(config, restOverride);
|
|
3274
|
+
config = mergeAgentConfig(config, override);
|
|
3276
3275
|
}
|
|
3277
3276
|
result[name] = config;
|
|
3278
3277
|
}
|
|
@@ -4921,18 +4920,19 @@ function clearInjectedPaths(sessionID) {
|
|
|
4921
4920
|
// src/hooks/directory-agents-injector/index.ts
|
|
4922
4921
|
function createDirectoryAgentsInjectorHook(ctx) {
|
|
4923
4922
|
const sessionCaches = new Map;
|
|
4923
|
+
const pendingBatchReads = new Map;
|
|
4924
4924
|
function getSessionCache(sessionID) {
|
|
4925
4925
|
if (!sessionCaches.has(sessionID)) {
|
|
4926
4926
|
sessionCaches.set(sessionID, loadInjectedPaths(sessionID));
|
|
4927
4927
|
}
|
|
4928
4928
|
return sessionCaches.get(sessionID);
|
|
4929
4929
|
}
|
|
4930
|
-
function resolveFilePath2(
|
|
4931
|
-
if (!
|
|
4930
|
+
function resolveFilePath2(path4) {
|
|
4931
|
+
if (!path4)
|
|
4932
4932
|
return null;
|
|
4933
|
-
if (
|
|
4934
|
-
return
|
|
4935
|
-
return resolve2(ctx.directory,
|
|
4933
|
+
if (path4.startsWith("/"))
|
|
4934
|
+
return path4;
|
|
4935
|
+
return resolve2(ctx.directory, path4);
|
|
4936
4936
|
}
|
|
4937
4937
|
function findAgentsMdUp(startDir) {
|
|
4938
4938
|
const found = [];
|
|
@@ -4953,35 +4953,59 @@ function createDirectoryAgentsInjectorHook(ctx) {
|
|
|
4953
4953
|
}
|
|
4954
4954
|
return found.reverse();
|
|
4955
4955
|
}
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
const filePath = resolveFilePath2(output.title);
|
|
4960
|
-
if (!filePath)
|
|
4956
|
+
function processFilePathForInjection(filePath, sessionID, output) {
|
|
4957
|
+
const resolved = resolveFilePath2(filePath);
|
|
4958
|
+
if (!resolved)
|
|
4961
4959
|
return;
|
|
4962
|
-
const dir = dirname2(
|
|
4963
|
-
const cache = getSessionCache(
|
|
4960
|
+
const dir = dirname2(resolved);
|
|
4961
|
+
const cache = getSessionCache(sessionID);
|
|
4964
4962
|
const agentsPaths = findAgentsMdUp(dir);
|
|
4965
|
-
const toInject = [];
|
|
4966
4963
|
for (const agentsPath of agentsPaths) {
|
|
4967
4964
|
const agentsDir = dirname2(agentsPath);
|
|
4968
4965
|
if (cache.has(agentsDir))
|
|
4969
4966
|
continue;
|
|
4970
4967
|
try {
|
|
4971
4968
|
const content = readFileSync5(agentsPath, "utf-8");
|
|
4972
|
-
|
|
4969
|
+
output.output += `
|
|
4970
|
+
|
|
4971
|
+
[Directory Context: ${agentsPath}]
|
|
4972
|
+
${content}`;
|
|
4973
4973
|
cache.add(agentsDir);
|
|
4974
4974
|
} catch {}
|
|
4975
4975
|
}
|
|
4976
|
-
|
|
4976
|
+
saveInjectedPaths(sessionID, cache);
|
|
4977
|
+
}
|
|
4978
|
+
const toolExecuteBefore = async (input, output) => {
|
|
4979
|
+
if (input.tool.toLowerCase() !== "batch")
|
|
4977
4980
|
return;
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4981
|
+
const args = output.args;
|
|
4982
|
+
if (!args?.tool_calls)
|
|
4983
|
+
return;
|
|
4984
|
+
const readFilePaths = [];
|
|
4985
|
+
for (const call of args.tool_calls) {
|
|
4986
|
+
if (call.tool.toLowerCase() === "read" && call.parameters?.filePath) {
|
|
4987
|
+
readFilePaths.push(call.parameters.filePath);
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
if (readFilePaths.length > 0) {
|
|
4991
|
+
pendingBatchReads.set(input.callID, readFilePaths);
|
|
4992
|
+
}
|
|
4993
|
+
};
|
|
4994
|
+
const toolExecuteAfter = async (input, output) => {
|
|
4995
|
+
const toolName = input.tool.toLowerCase();
|
|
4996
|
+
if (toolName === "read") {
|
|
4997
|
+
processFilePathForInjection(output.title, input.sessionID, output);
|
|
4998
|
+
return;
|
|
4999
|
+
}
|
|
5000
|
+
if (toolName === "batch") {
|
|
5001
|
+
const filePaths = pendingBatchReads.get(input.callID);
|
|
5002
|
+
if (filePaths) {
|
|
5003
|
+
for (const filePath of filePaths) {
|
|
5004
|
+
processFilePathForInjection(filePath, input.sessionID, output);
|
|
5005
|
+
}
|
|
5006
|
+
pendingBatchReads.delete(input.callID);
|
|
5007
|
+
}
|
|
4983
5008
|
}
|
|
4984
|
-
saveInjectedPaths(input.sessionID, cache);
|
|
4985
5009
|
};
|
|
4986
5010
|
const eventHandler = async ({ event }) => {
|
|
4987
5011
|
const props = event.properties;
|
|
@@ -5001,6 +5025,7 @@ ${content}`;
|
|
|
5001
5025
|
}
|
|
5002
5026
|
};
|
|
5003
5027
|
return {
|
|
5028
|
+
"tool.execute.before": toolExecuteBefore,
|
|
5004
5029
|
"tool.execute.after": toolExecuteAfter,
|
|
5005
5030
|
event: eventHandler
|
|
5006
5031
|
};
|
|
@@ -5062,18 +5087,19 @@ function clearInjectedPaths2(sessionID) {
|
|
|
5062
5087
|
// src/hooks/directory-readme-injector/index.ts
|
|
5063
5088
|
function createDirectoryReadmeInjectorHook(ctx) {
|
|
5064
5089
|
const sessionCaches = new Map;
|
|
5090
|
+
const pendingBatchReads = new Map;
|
|
5065
5091
|
function getSessionCache(sessionID) {
|
|
5066
5092
|
if (!sessionCaches.has(sessionID)) {
|
|
5067
5093
|
sessionCaches.set(sessionID, loadInjectedPaths2(sessionID));
|
|
5068
5094
|
}
|
|
5069
5095
|
return sessionCaches.get(sessionID);
|
|
5070
5096
|
}
|
|
5071
|
-
function resolveFilePath2(
|
|
5072
|
-
if (!
|
|
5097
|
+
function resolveFilePath2(path4) {
|
|
5098
|
+
if (!path4)
|
|
5073
5099
|
return null;
|
|
5074
|
-
if (
|
|
5075
|
-
return
|
|
5076
|
-
return resolve3(ctx.directory,
|
|
5100
|
+
if (path4.startsWith("/"))
|
|
5101
|
+
return path4;
|
|
5102
|
+
return resolve3(ctx.directory, path4);
|
|
5077
5103
|
}
|
|
5078
5104
|
function findReadmeMdUp(startDir) {
|
|
5079
5105
|
const found = [];
|
|
@@ -5094,35 +5120,59 @@ function createDirectoryReadmeInjectorHook(ctx) {
|
|
|
5094
5120
|
}
|
|
5095
5121
|
return found.reverse();
|
|
5096
5122
|
}
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
const filePath = resolveFilePath2(output.title);
|
|
5101
|
-
if (!filePath)
|
|
5123
|
+
function processFilePathForInjection(filePath, sessionID, output) {
|
|
5124
|
+
const resolved = resolveFilePath2(filePath);
|
|
5125
|
+
if (!resolved)
|
|
5102
5126
|
return;
|
|
5103
|
-
const dir = dirname3(
|
|
5104
|
-
const cache = getSessionCache(
|
|
5127
|
+
const dir = dirname3(resolved);
|
|
5128
|
+
const cache = getSessionCache(sessionID);
|
|
5105
5129
|
const readmePaths = findReadmeMdUp(dir);
|
|
5106
|
-
const toInject = [];
|
|
5107
5130
|
for (const readmePath of readmePaths) {
|
|
5108
5131
|
const readmeDir = dirname3(readmePath);
|
|
5109
5132
|
if (cache.has(readmeDir))
|
|
5110
5133
|
continue;
|
|
5111
5134
|
try {
|
|
5112
5135
|
const content = readFileSync7(readmePath, "utf-8");
|
|
5113
|
-
|
|
5136
|
+
output.output += `
|
|
5137
|
+
|
|
5138
|
+
[Project README: ${readmePath}]
|
|
5139
|
+
${content}`;
|
|
5114
5140
|
cache.add(readmeDir);
|
|
5115
5141
|
} catch {}
|
|
5116
5142
|
}
|
|
5117
|
-
|
|
5143
|
+
saveInjectedPaths2(sessionID, cache);
|
|
5144
|
+
}
|
|
5145
|
+
const toolExecuteBefore = async (input, output) => {
|
|
5146
|
+
if (input.tool.toLowerCase() !== "batch")
|
|
5118
5147
|
return;
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5148
|
+
const args = output.args;
|
|
5149
|
+
if (!args?.tool_calls)
|
|
5150
|
+
return;
|
|
5151
|
+
const readFilePaths = [];
|
|
5152
|
+
for (const call of args.tool_calls) {
|
|
5153
|
+
if (call.tool.toLowerCase() === "read" && call.parameters?.filePath) {
|
|
5154
|
+
readFilePaths.push(call.parameters.filePath);
|
|
5155
|
+
}
|
|
5156
|
+
}
|
|
5157
|
+
if (readFilePaths.length > 0) {
|
|
5158
|
+
pendingBatchReads.set(input.callID, readFilePaths);
|
|
5159
|
+
}
|
|
5160
|
+
};
|
|
5161
|
+
const toolExecuteAfter = async (input, output) => {
|
|
5162
|
+
const toolName = input.tool.toLowerCase();
|
|
5163
|
+
if (toolName === "read") {
|
|
5164
|
+
processFilePathForInjection(output.title, input.sessionID, output);
|
|
5165
|
+
return;
|
|
5166
|
+
}
|
|
5167
|
+
if (toolName === "batch") {
|
|
5168
|
+
const filePaths = pendingBatchReads.get(input.callID);
|
|
5169
|
+
if (filePaths) {
|
|
5170
|
+
for (const filePath of filePaths) {
|
|
5171
|
+
processFilePathForInjection(filePath, input.sessionID, output);
|
|
5172
|
+
}
|
|
5173
|
+
pendingBatchReads.delete(input.callID);
|
|
5174
|
+
}
|
|
5124
5175
|
}
|
|
5125
|
-
saveInjectedPaths2(input.sessionID, cache);
|
|
5126
5176
|
};
|
|
5127
5177
|
const eventHandler = async ({ event }) => {
|
|
5128
5178
|
const props = event.properties;
|
|
@@ -5142,6 +5192,7 @@ ${content}`;
|
|
|
5142
5192
|
}
|
|
5143
5193
|
};
|
|
5144
5194
|
return {
|
|
5195
|
+
"tool.execute.before": toolExecuteBefore,
|
|
5145
5196
|
"tool.execute.after": toolExecuteAfter,
|
|
5146
5197
|
event: eventHandler
|
|
5147
5198
|
};
|
|
@@ -7740,29 +7791,28 @@ function clearInjectedRules(sessionID) {
|
|
|
7740
7791
|
var TRACKED_TOOLS = ["read", "write", "edit", "multiedit"];
|
|
7741
7792
|
function createRulesInjectorHook(ctx) {
|
|
7742
7793
|
const sessionCaches = new Map;
|
|
7794
|
+
const pendingBatchFiles = new Map;
|
|
7743
7795
|
function getSessionCache(sessionID) {
|
|
7744
7796
|
if (!sessionCaches.has(sessionID)) {
|
|
7745
7797
|
sessionCaches.set(sessionID, loadInjectedRules(sessionID));
|
|
7746
7798
|
}
|
|
7747
7799
|
return sessionCaches.get(sessionID);
|
|
7748
7800
|
}
|
|
7749
|
-
function resolveFilePath2(
|
|
7750
|
-
if (!
|
|
7801
|
+
function resolveFilePath2(path4) {
|
|
7802
|
+
if (!path4)
|
|
7751
7803
|
return null;
|
|
7752
|
-
if (
|
|
7753
|
-
return
|
|
7754
|
-
return resolve4(ctx.directory,
|
|
7804
|
+
if (path4.startsWith("/"))
|
|
7805
|
+
return path4;
|
|
7806
|
+
return resolve4(ctx.directory, path4);
|
|
7755
7807
|
}
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
const filePath = resolveFilePath2(output.title);
|
|
7760
|
-
if (!filePath)
|
|
7808
|
+
function processFilePathForInjection(filePath, sessionID, output) {
|
|
7809
|
+
const resolved = resolveFilePath2(filePath);
|
|
7810
|
+
if (!resolved)
|
|
7761
7811
|
return;
|
|
7762
|
-
const projectRoot = findProjectRoot(
|
|
7763
|
-
const cache2 = getSessionCache(
|
|
7812
|
+
const projectRoot = findProjectRoot(resolved);
|
|
7813
|
+
const cache2 = getSessionCache(sessionID);
|
|
7764
7814
|
const home = homedir10();
|
|
7765
|
-
const ruleFileCandidates = findRuleFiles(projectRoot, home,
|
|
7815
|
+
const ruleFileCandidates = findRuleFiles(projectRoot, home, resolved);
|
|
7766
7816
|
const toInject = [];
|
|
7767
7817
|
for (const candidate of ruleFileCandidates) {
|
|
7768
7818
|
if (isDuplicateByRealPath(candidate.realPath, cache2.realPaths))
|
|
@@ -7770,7 +7820,7 @@ function createRulesInjectorHook(ctx) {
|
|
|
7770
7820
|
try {
|
|
7771
7821
|
const rawContent = readFileSync10(candidate.path, "utf-8");
|
|
7772
7822
|
const { metadata, body } = parseRuleFrontmatter(rawContent);
|
|
7773
|
-
const matchResult = shouldApplyRule(metadata,
|
|
7823
|
+
const matchResult = shouldApplyRule(metadata, resolved, projectRoot);
|
|
7774
7824
|
if (!matchResult.applies)
|
|
7775
7825
|
continue;
|
|
7776
7826
|
const contentHash = createContentHash(body);
|
|
@@ -7797,7 +7847,46 @@ function createRulesInjectorHook(ctx) {
|
|
|
7797
7847
|
[Match: ${rule.matchReason}]
|
|
7798
7848
|
${rule.content}`;
|
|
7799
7849
|
}
|
|
7800
|
-
saveInjectedRules(
|
|
7850
|
+
saveInjectedRules(sessionID, cache2);
|
|
7851
|
+
}
|
|
7852
|
+
function extractFilePathFromToolCall(call) {
|
|
7853
|
+
const params = call.parameters;
|
|
7854
|
+
return params?.filePath ?? params?.file_path ?? params?.path;
|
|
7855
|
+
}
|
|
7856
|
+
const toolExecuteBefore = async (input, output) => {
|
|
7857
|
+
if (input.tool.toLowerCase() !== "batch")
|
|
7858
|
+
return;
|
|
7859
|
+
const args = output.args;
|
|
7860
|
+
if (!args?.tool_calls)
|
|
7861
|
+
return;
|
|
7862
|
+
const filePaths = [];
|
|
7863
|
+
for (const call of args.tool_calls) {
|
|
7864
|
+
if (TRACKED_TOOLS.includes(call.tool.toLowerCase())) {
|
|
7865
|
+
const filePath = extractFilePathFromToolCall(call);
|
|
7866
|
+
if (filePath) {
|
|
7867
|
+
filePaths.push(filePath);
|
|
7868
|
+
}
|
|
7869
|
+
}
|
|
7870
|
+
}
|
|
7871
|
+
if (filePaths.length > 0) {
|
|
7872
|
+
pendingBatchFiles.set(input.callID, filePaths);
|
|
7873
|
+
}
|
|
7874
|
+
};
|
|
7875
|
+
const toolExecuteAfter = async (input, output) => {
|
|
7876
|
+
const toolName = input.tool.toLowerCase();
|
|
7877
|
+
if (TRACKED_TOOLS.includes(toolName)) {
|
|
7878
|
+
processFilePathForInjection(output.title, input.sessionID, output);
|
|
7879
|
+
return;
|
|
7880
|
+
}
|
|
7881
|
+
if (toolName === "batch") {
|
|
7882
|
+
const filePaths = pendingBatchFiles.get(input.callID);
|
|
7883
|
+
if (filePaths) {
|
|
7884
|
+
for (const filePath of filePaths) {
|
|
7885
|
+
processFilePathForInjection(filePath, input.sessionID, output);
|
|
7886
|
+
}
|
|
7887
|
+
pendingBatchFiles.delete(input.callID);
|
|
7888
|
+
}
|
|
7889
|
+
}
|
|
7801
7890
|
};
|
|
7802
7891
|
const eventHandler = async ({ event }) => {
|
|
7803
7892
|
const props = event.properties;
|
|
@@ -7817,6 +7906,7 @@ ${rule.content}`;
|
|
|
7817
7906
|
}
|
|
7818
7907
|
};
|
|
7819
7908
|
return {
|
|
7909
|
+
"tool.execute.before": toolExecuteBefore,
|
|
7820
7910
|
"tool.execute.after": toolExecuteAfter,
|
|
7821
7911
|
event: eventHandler
|
|
7822
7912
|
};
|
|
@@ -27826,6 +27916,9 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
27826
27916
|
await claudeCodeHooks["tool.execute.before"](input, output);
|
|
27827
27917
|
await nonInteractiveEnv?.["tool.execute.before"](input, output);
|
|
27828
27918
|
await commentChecker?.["tool.execute.before"](input, output);
|
|
27919
|
+
await directoryAgentsInjector?.["tool.execute.before"]?.(input, output);
|
|
27920
|
+
await directoryReadmeInjector?.["tool.execute.before"]?.(input, output);
|
|
27921
|
+
await rulesInjector?.["tool.execute.before"]?.(input, output);
|
|
27829
27922
|
if (input.tool === "task") {
|
|
27830
27923
|
const args = output.args;
|
|
27831
27924
|
const subagentType = args.subagent_type;
|