oh-my-opencode 3.1.4 → 3.1.5
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/agents/metis.d.ts +1 -1
- package/dist/agents/prometheus-prompt.d.ts +1 -1
- package/dist/cli/index.js +24 -22
- package/dist/features/opencode-skill-loader/types.d.ts +1 -1
- package/dist/index.js +521 -234
- package/dist/shared/agent-variant.d.ts +4 -0
- package/dist/shared/ollama-ndjson-parser.d.ts +108 -0
- package/dist/shared/opencode-version.d.ts +8 -0
- package/dist/shared/system-directive.d.ts +14 -0
- package/dist/shared/system-directive.test.d.ts +1 -0
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -236,6 +236,9 @@ function createSystemDirective(type) {
|
|
|
236
236
|
function isSystemDirective(text) {
|
|
237
237
|
return text.trimStart().startsWith(SYSTEM_DIRECTIVE_PREFIX);
|
|
238
238
|
}
|
|
239
|
+
function removeSystemReminders(text) {
|
|
240
|
+
return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/gi, "").trim();
|
|
241
|
+
}
|
|
239
242
|
var SYSTEM_DIRECTIVE_PREFIX = "[SYSTEM DIRECTIVE: OH-MY-OPENCODE", SystemDirectiveTypes;
|
|
240
243
|
var init_system_directive = __esm(() => {
|
|
241
244
|
SystemDirectiveTypes = {
|
|
@@ -4550,9 +4553,56 @@ var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai
|
|
|
4550
4553
|
var init_opencode_config_dir = () => {};
|
|
4551
4554
|
|
|
4552
4555
|
// src/shared/opencode-version.ts
|
|
4553
|
-
|
|
4556
|
+
import { execSync } from "child_process";
|
|
4557
|
+
function parseVersion(version) {
|
|
4558
|
+
const cleaned = version.replace(/^v/, "").split("-")[0];
|
|
4559
|
+
return cleaned.split(".").map((n) => parseInt(n, 10) || 0);
|
|
4560
|
+
}
|
|
4561
|
+
function compareVersions(a, b) {
|
|
4562
|
+
const partsA = parseVersion(a);
|
|
4563
|
+
const partsB = parseVersion(b);
|
|
4564
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
4565
|
+
for (let i2 = 0;i2 < maxLen; i2++) {
|
|
4566
|
+
const numA = partsA[i2] ?? 0;
|
|
4567
|
+
const numB = partsB[i2] ?? 0;
|
|
4568
|
+
if (numA < numB)
|
|
4569
|
+
return -1;
|
|
4570
|
+
if (numA > numB)
|
|
4571
|
+
return 1;
|
|
4572
|
+
}
|
|
4573
|
+
return 0;
|
|
4574
|
+
}
|
|
4575
|
+
function isVersionGte(a, b) {
|
|
4576
|
+
return compareVersions(a, b) >= 0;
|
|
4577
|
+
}
|
|
4578
|
+
function getOpenCodeVersion() {
|
|
4579
|
+
if (cachedVersion !== NOT_CACHED) {
|
|
4580
|
+
return cachedVersion;
|
|
4581
|
+
}
|
|
4582
|
+
try {
|
|
4583
|
+
const result = execSync("opencode --version", {
|
|
4584
|
+
encoding: "utf-8",
|
|
4585
|
+
timeout: 5000,
|
|
4586
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
4587
|
+
}).trim();
|
|
4588
|
+
const versionMatch = result.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
|
|
4589
|
+
cachedVersion = versionMatch?.[1] ?? null;
|
|
4590
|
+
return cachedVersion;
|
|
4591
|
+
} catch {
|
|
4592
|
+
cachedVersion = null;
|
|
4593
|
+
return null;
|
|
4594
|
+
}
|
|
4595
|
+
}
|
|
4596
|
+
function isOpenCodeVersionAtLeast(version) {
|
|
4597
|
+
const current = getOpenCodeVersion();
|
|
4598
|
+
if (!current)
|
|
4599
|
+
return true;
|
|
4600
|
+
return isVersionGte(current, version);
|
|
4601
|
+
}
|
|
4602
|
+
var OPENCODE_NATIVE_AGENTS_INJECTION_VERSION = "1.1.37", NOT_CACHED, cachedVersion;
|
|
4554
4603
|
var init_opencode_version = __esm(() => {
|
|
4555
4604
|
NOT_CACHED = Symbol("NOT_CACHED");
|
|
4605
|
+
cachedVersion = NOT_CACHED;
|
|
4556
4606
|
});
|
|
4557
4607
|
|
|
4558
4608
|
// src/shared/permission-compat.ts
|
|
@@ -4783,6 +4833,131 @@ function equalsIgnoreCase(a, b) {
|
|
|
4783
4833
|
return a.toLowerCase() === b.toLowerCase();
|
|
4784
4834
|
}
|
|
4785
4835
|
|
|
4836
|
+
// src/shared/model-requirements.ts
|
|
4837
|
+
var AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS;
|
|
4838
|
+
var init_model_requirements = __esm(() => {
|
|
4839
|
+
AGENT_MODEL_REQUIREMENTS = {
|
|
4840
|
+
sisyphus: {
|
|
4841
|
+
fallbackChain: [
|
|
4842
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4843
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
4844
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
4845
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4846
|
+
]
|
|
4847
|
+
},
|
|
4848
|
+
oracle: {
|
|
4849
|
+
fallbackChain: [
|
|
4850
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4851
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4852
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4853
|
+
]
|
|
4854
|
+
},
|
|
4855
|
+
librarian: {
|
|
4856
|
+
fallbackChain: [
|
|
4857
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
4858
|
+
{ providers: ["opencode"], model: "big-pickle" },
|
|
4859
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" }
|
|
4860
|
+
]
|
|
4861
|
+
},
|
|
4862
|
+
explore: {
|
|
4863
|
+
fallbackChain: [
|
|
4864
|
+
{ providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
|
|
4865
|
+
{ providers: ["github-copilot"], model: "gpt-5-mini" },
|
|
4866
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
4867
|
+
]
|
|
4868
|
+
},
|
|
4869
|
+
"multimodal-looker": {
|
|
4870
|
+
fallbackChain: [
|
|
4871
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
4872
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
4873
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.6v" },
|
|
4874
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
4875
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
4876
|
+
]
|
|
4877
|
+
},
|
|
4878
|
+
prometheus: {
|
|
4879
|
+
fallbackChain: [
|
|
4880
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4881
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4882
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4883
|
+
]
|
|
4884
|
+
},
|
|
4885
|
+
metis: {
|
|
4886
|
+
fallbackChain: [
|
|
4887
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4888
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4889
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
4890
|
+
]
|
|
4891
|
+
},
|
|
4892
|
+
momus: {
|
|
4893
|
+
fallbackChain: [
|
|
4894
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "medium" },
|
|
4895
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5" },
|
|
4896
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
4897
|
+
]
|
|
4898
|
+
},
|
|
4899
|
+
atlas: {
|
|
4900
|
+
fallbackChain: [
|
|
4901
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
4902
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
4903
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4904
|
+
]
|
|
4905
|
+
}
|
|
4906
|
+
};
|
|
4907
|
+
CATEGORY_MODEL_REQUIREMENTS = {
|
|
4908
|
+
"visual-engineering": {
|
|
4909
|
+
fallbackChain: [
|
|
4910
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" },
|
|
4911
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4912
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" }
|
|
4913
|
+
]
|
|
4914
|
+
},
|
|
4915
|
+
ultrabrain: {
|
|
4916
|
+
fallbackChain: [
|
|
4917
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "xhigh" },
|
|
4918
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4919
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4920
|
+
]
|
|
4921
|
+
},
|
|
4922
|
+
artistry: {
|
|
4923
|
+
fallbackChain: [
|
|
4924
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" },
|
|
4925
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4926
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
4927
|
+
]
|
|
4928
|
+
},
|
|
4929
|
+
quick: {
|
|
4930
|
+
fallbackChain: [
|
|
4931
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
4932
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
4933
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
4934
|
+
]
|
|
4935
|
+
},
|
|
4936
|
+
"unspecified-low": {
|
|
4937
|
+
fallbackChain: [
|
|
4938
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
4939
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
4940
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" }
|
|
4941
|
+
]
|
|
4942
|
+
},
|
|
4943
|
+
"unspecified-high": {
|
|
4944
|
+
fallbackChain: [
|
|
4945
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4946
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4947
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4948
|
+
]
|
|
4949
|
+
},
|
|
4950
|
+
writing: {
|
|
4951
|
+
fallbackChain: [
|
|
4952
|
+
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
4953
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
4954
|
+
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
4955
|
+
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
4956
|
+
]
|
|
4957
|
+
}
|
|
4958
|
+
};
|
|
4959
|
+
});
|
|
4960
|
+
|
|
4786
4961
|
// src/shared/agent-variant.ts
|
|
4787
4962
|
function resolveAgentVariant(config, agentName) {
|
|
4788
4963
|
if (!agentName) {
|
|
@@ -4802,13 +4977,39 @@ function resolveAgentVariant(config, agentName) {
|
|
|
4802
4977
|
}
|
|
4803
4978
|
return config.categories?.[categoryName]?.variant;
|
|
4804
4979
|
}
|
|
4980
|
+
function resolveVariantForModel(config, agentName, currentModel) {
|
|
4981
|
+
const agentRequirement = AGENT_MODEL_REQUIREMENTS[agentName];
|
|
4982
|
+
if (agentRequirement) {
|
|
4983
|
+
return findVariantInChain(agentRequirement.fallbackChain, currentModel.providerID);
|
|
4984
|
+
}
|
|
4985
|
+
const agentOverrides = config.agents;
|
|
4986
|
+
const agentOverride = agentOverrides ? findCaseInsensitive(agentOverrides, agentName) : undefined;
|
|
4987
|
+
const categoryName = agentOverride?.category;
|
|
4988
|
+
if (categoryName) {
|
|
4989
|
+
const categoryRequirement = CATEGORY_MODEL_REQUIREMENTS[categoryName];
|
|
4990
|
+
if (categoryRequirement) {
|
|
4991
|
+
return findVariantInChain(categoryRequirement.fallbackChain, currentModel.providerID);
|
|
4992
|
+
}
|
|
4993
|
+
}
|
|
4994
|
+
return;
|
|
4995
|
+
}
|
|
4996
|
+
function findVariantInChain(fallbackChain, providerID) {
|
|
4997
|
+
for (const entry of fallbackChain) {
|
|
4998
|
+
if (entry.providers.includes(providerID)) {
|
|
4999
|
+
return entry.variant;
|
|
5000
|
+
}
|
|
5001
|
+
}
|
|
5002
|
+
return;
|
|
5003
|
+
}
|
|
4805
5004
|
function applyAgentVariant(config, agentName, message) {
|
|
4806
5005
|
const variant = resolveAgentVariant(config, agentName);
|
|
4807
5006
|
if (variant !== undefined && message.variant === undefined) {
|
|
4808
5007
|
message.variant = variant;
|
|
4809
5008
|
}
|
|
4810
5009
|
}
|
|
4811
|
-
var init_agent_variant = () => {
|
|
5010
|
+
var init_agent_variant = __esm(() => {
|
|
5011
|
+
init_model_requirements();
|
|
5012
|
+
});
|
|
4812
5013
|
|
|
4813
5014
|
// src/shared/session-cursor.ts
|
|
4814
5015
|
function buildMessageKey(message, index) {
|
|
@@ -4942,131 +5143,6 @@ var init_agent_tool_restrictions = __esm(() => {
|
|
|
4942
5143
|
};
|
|
4943
5144
|
});
|
|
4944
5145
|
|
|
4945
|
-
// src/shared/model-requirements.ts
|
|
4946
|
-
var AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS;
|
|
4947
|
-
var init_model_requirements = __esm(() => {
|
|
4948
|
-
AGENT_MODEL_REQUIREMENTS = {
|
|
4949
|
-
sisyphus: {
|
|
4950
|
-
fallbackChain: [
|
|
4951
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4952
|
-
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
4953
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
4954
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4955
|
-
]
|
|
4956
|
-
},
|
|
4957
|
-
oracle: {
|
|
4958
|
-
fallbackChain: [
|
|
4959
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4960
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4961
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4962
|
-
]
|
|
4963
|
-
},
|
|
4964
|
-
librarian: {
|
|
4965
|
-
fallbackChain: [
|
|
4966
|
-
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
4967
|
-
{ providers: ["opencode"], model: "big-pickle" },
|
|
4968
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" }
|
|
4969
|
-
]
|
|
4970
|
-
},
|
|
4971
|
-
explore: {
|
|
4972
|
-
fallbackChain: [
|
|
4973
|
-
{ providers: ["anthropic", "opencode"], model: "claude-haiku-4-5" },
|
|
4974
|
-
{ providers: ["github-copilot"], model: "gpt-5-mini" },
|
|
4975
|
-
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
4976
|
-
]
|
|
4977
|
-
},
|
|
4978
|
-
"multimodal-looker": {
|
|
4979
|
-
fallbackChain: [
|
|
4980
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
4981
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
4982
|
-
{ providers: ["zai-coding-plan"], model: "glm-4.6v" },
|
|
4983
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
4984
|
-
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
4985
|
-
]
|
|
4986
|
-
},
|
|
4987
|
-
prometheus: {
|
|
4988
|
-
fallbackChain: [
|
|
4989
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4990
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4991
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
4992
|
-
]
|
|
4993
|
-
},
|
|
4994
|
-
metis: {
|
|
4995
|
-
fallbackChain: [
|
|
4996
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
4997
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
4998
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
4999
|
-
]
|
|
5000
|
-
},
|
|
5001
|
-
momus: {
|
|
5002
|
-
fallbackChain: [
|
|
5003
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "medium" },
|
|
5004
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5" },
|
|
5005
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
5006
|
-
]
|
|
5007
|
-
},
|
|
5008
|
-
atlas: {
|
|
5009
|
-
fallbackChain: [
|
|
5010
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
5011
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" },
|
|
5012
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
5013
|
-
]
|
|
5014
|
-
}
|
|
5015
|
-
};
|
|
5016
|
-
CATEGORY_MODEL_REQUIREMENTS = {
|
|
5017
|
-
"visual-engineering": {
|
|
5018
|
-
fallbackChain: [
|
|
5019
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" },
|
|
5020
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5021
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" }
|
|
5022
|
-
]
|
|
5023
|
-
},
|
|
5024
|
-
ultrabrain: {
|
|
5025
|
-
fallbackChain: [
|
|
5026
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "xhigh" },
|
|
5027
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5028
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
5029
|
-
]
|
|
5030
|
-
},
|
|
5031
|
-
artistry: {
|
|
5032
|
-
fallbackChain: [
|
|
5033
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" },
|
|
5034
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5035
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
5036
|
-
]
|
|
5037
|
-
},
|
|
5038
|
-
quick: {
|
|
5039
|
-
fallbackChain: [
|
|
5040
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
5041
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
5042
|
-
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
5043
|
-
]
|
|
5044
|
-
},
|
|
5045
|
-
"unspecified-low": {
|
|
5046
|
-
fallbackChain: [
|
|
5047
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
5048
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" },
|
|
5049
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" }
|
|
5050
|
-
]
|
|
5051
|
-
},
|
|
5052
|
-
"unspecified-high": {
|
|
5053
|
-
fallbackChain: [
|
|
5054
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" },
|
|
5055
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" },
|
|
5056
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }
|
|
5057
|
-
]
|
|
5058
|
-
},
|
|
5059
|
-
writing: {
|
|
5060
|
-
fallbackChain: [
|
|
5061
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
5062
|
-
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-5" },
|
|
5063
|
-
{ providers: ["zai-coding-plan"], model: "glm-4.7" },
|
|
5064
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }
|
|
5065
|
-
]
|
|
5066
|
-
}
|
|
5067
|
-
};
|
|
5068
|
-
});
|
|
5069
|
-
|
|
5070
5146
|
// src/shared/connected-providers-cache.ts
|
|
5071
5147
|
import { existsSync as existsSync9, readFileSync as readFileSync6, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
5072
5148
|
import { join as join12 } from "path";
|
|
@@ -7531,9 +7607,9 @@ v${latestVersion} available. Restart OpenCode to apply.` : `OpenCode is now on S
|
|
|
7531
7607
|
return;
|
|
7532
7608
|
hasChecked = true;
|
|
7533
7609
|
setTimeout(async () => {
|
|
7534
|
-
const
|
|
7610
|
+
const cachedVersion2 = getCachedVersion();
|
|
7535
7611
|
const localDevVersion = getLocalDevVersion(ctx.directory);
|
|
7536
|
-
const displayVersion = localDevVersion ??
|
|
7612
|
+
const displayVersion = localDevVersion ?? cachedVersion2;
|
|
7537
7613
|
await showConfigErrorsIfAny(ctx);
|
|
7538
7614
|
await showModelCacheWarningIfNeeded(ctx);
|
|
7539
7615
|
await updateAndShowConnectedProvidersCacheStatus(ctx);
|
|
@@ -7560,8 +7636,8 @@ async function runBackgroundUpdateCheck(ctx, autoUpdate, getToastMessage) {
|
|
|
7560
7636
|
log("[auto-update-checker] Plugin not found in config");
|
|
7561
7637
|
return;
|
|
7562
7638
|
}
|
|
7563
|
-
const
|
|
7564
|
-
const currentVersion =
|
|
7639
|
+
const cachedVersion2 = getCachedVersion();
|
|
7640
|
+
const currentVersion = cachedVersion2 ?? pluginInfo.pinnedVersion;
|
|
7565
7641
|
if (!currentVersion) {
|
|
7566
7642
|
log("[auto-update-checker] No version found (cached or pinned)");
|
|
7567
7643
|
return;
|
|
@@ -18505,7 +18581,7 @@ async function executePreToolUseHooks(ctx, config, extendedConfig) {
|
|
|
18505
18581
|
}
|
|
18506
18582
|
if (result.stdout) {
|
|
18507
18583
|
try {
|
|
18508
|
-
const output = JSON.parse(result.stdout);
|
|
18584
|
+
const output = JSON.parse(result.stdout || "{}");
|
|
18509
18585
|
let decision;
|
|
18510
18586
|
let reason;
|
|
18511
18587
|
let modifiedInput;
|
|
@@ -18741,7 +18817,7 @@ ${result.stderr.trim()}`);
|
|
|
18741
18817
|
}
|
|
18742
18818
|
if (result.exitCode === 0 && result.stdout) {
|
|
18743
18819
|
try {
|
|
18744
|
-
const output = JSON.parse(result.stdout);
|
|
18820
|
+
const output = JSON.parse(result.stdout || "{}");
|
|
18745
18821
|
if (output.decision === "block") {
|
|
18746
18822
|
return {
|
|
18747
18823
|
block: true,
|
|
@@ -18934,7 +19010,7 @@ async function executeStopHooks(ctx, config, extendedConfig) {
|
|
|
18934
19010
|
}
|
|
18935
19011
|
if (result.stdout) {
|
|
18936
19012
|
try {
|
|
18937
|
-
const output = JSON.parse(result.stdout);
|
|
19013
|
+
const output = JSON.parse(result.stdout || "{}");
|
|
18938
19014
|
if (output.stop_hook_active !== undefined) {
|
|
18939
19015
|
stopHookActiveState.set(ctx.sessionId, output.stop_hook_active);
|
|
18940
19016
|
}
|
|
@@ -18991,7 +19067,7 @@ async function executePreCompactHooks(ctx, config, extendedConfig) {
|
|
|
18991
19067
|
}
|
|
18992
19068
|
if (result.stdout) {
|
|
18993
19069
|
try {
|
|
18994
|
-
const output = JSON.parse(result.stdout);
|
|
19070
|
+
const output = JSON.parse(result.stdout || "{}");
|
|
18995
19071
|
if (output.hookSpecificOutput?.additionalContext) {
|
|
18996
19072
|
collectedContext.push(...output.hookSpecificOutput.additionalContext);
|
|
18997
19073
|
} else if (output.context) {
|
|
@@ -19194,6 +19270,9 @@ ${result.inputLines ?? ""}`,
|
|
|
19194
19270
|
}
|
|
19195
19271
|
},
|
|
19196
19272
|
"tool.execute.after": async (input, output) => {
|
|
19273
|
+
if (!output) {
|
|
19274
|
+
return;
|
|
19275
|
+
}
|
|
19197
19276
|
const claudeConfig = await loadClaudeHooksConfig();
|
|
19198
19277
|
const extendedConfig = await loadPluginExtendedConfig();
|
|
19199
19278
|
const cachedInput = getToolInput(input.sessionID, input.tool, input.callID) || {};
|
|
@@ -20064,7 +20143,81 @@ You ARE the planner. Your job: create bulletproof work plans.
|
|
|
20064
20143
|
- External library APIs and constraints
|
|
20065
20144
|
- Similar implementations in OSS (via librarian)
|
|
20066
20145
|
|
|
20067
|
-
**NEVER plan blind. Context first, plan second
|
|
20146
|
+
**NEVER plan blind. Context first, plan second.**
|
|
20147
|
+
|
|
20148
|
+
---
|
|
20149
|
+
|
|
20150
|
+
## MANDATORY OUTPUT: PARALLEL TASK GRAPH + TODO LIST
|
|
20151
|
+
|
|
20152
|
+
**YOUR PRIMARY OUTPUT IS A PARALLEL EXECUTION TASK GRAPH.**
|
|
20153
|
+
|
|
20154
|
+
When you finalize a plan, you MUST structure it for maximum parallel execution:
|
|
20155
|
+
|
|
20156
|
+
### 1. Parallel Execution Waves (REQUIRED)
|
|
20157
|
+
|
|
20158
|
+
Analyze task dependencies and group independent tasks into parallel waves:
|
|
20159
|
+
|
|
20160
|
+
\`\`\`
|
|
20161
|
+
Wave 1 (Start Immediately - No Dependencies):
|
|
20162
|
+
\u251C\u2500\u2500 Task 1: [description] \u2192 category: X, skills: [a, b]
|
|
20163
|
+
\u2514\u2500\u2500 Task 4: [description] \u2192 category: Y, skills: [c]
|
|
20164
|
+
|
|
20165
|
+
Wave 2 (After Wave 1 Completes):
|
|
20166
|
+
\u251C\u2500\u2500 Task 2: [depends: 1] \u2192 category: X, skills: [a]
|
|
20167
|
+
\u251C\u2500\u2500 Task 3: [depends: 1] \u2192 category: Z, skills: [d]
|
|
20168
|
+
\u2514\u2500\u2500 Task 5: [depends: 4] \u2192 category: Y, skills: [c]
|
|
20169
|
+
|
|
20170
|
+
Wave 3 (After Wave 2 Completes):
|
|
20171
|
+
\u2514\u2500\u2500 Task 6: [depends: 2, 3] \u2192 category: X, skills: [a, b]
|
|
20172
|
+
|
|
20173
|
+
Critical Path: Task 1 \u2192 Task 2 \u2192 Task 6
|
|
20174
|
+
Estimated Parallel Speedup: ~40% faster than sequential
|
|
20175
|
+
\`\`\`
|
|
20176
|
+
|
|
20177
|
+
### 2. Dependency Matrix (REQUIRED)
|
|
20178
|
+
|
|
20179
|
+
| Task | Depends On | Blocks | Can Parallelize With |
|
|
20180
|
+
|------|------------|--------|---------------------|
|
|
20181
|
+
| 1 | None | 2, 3 | 4 |
|
|
20182
|
+
| 2 | 1 | 6 | 3, 5 |
|
|
20183
|
+
| 3 | 1 | 6 | 2, 5 |
|
|
20184
|
+
| 4 | None | 5 | 1 |
|
|
20185
|
+
| 5 | 4 | None | 2, 3 |
|
|
20186
|
+
| 6 | 2, 3 | None | None (final) |
|
|
20187
|
+
|
|
20188
|
+
### 3. TODO List Structure (REQUIRED)
|
|
20189
|
+
|
|
20190
|
+
Each TODO item MUST include:
|
|
20191
|
+
|
|
20192
|
+
\`\`\`markdown
|
|
20193
|
+
- [ ] N. [Task Title]
|
|
20194
|
+
|
|
20195
|
+
**What to do**: [Clear steps]
|
|
20196
|
+
|
|
20197
|
+
**Dependencies**: [Task numbers this depends on] | None
|
|
20198
|
+
**Blocks**: [Task numbers that depend on this]
|
|
20199
|
+
**Parallel Group**: Wave N (with Tasks X, Y)
|
|
20200
|
+
|
|
20201
|
+
**Recommended Agent Profile**:
|
|
20202
|
+
- **Category**: \`[visual-engineering | ultrabrain | artistry | quick | unspecified-low | unspecified-high | writing]\`
|
|
20203
|
+
- **Skills**: [\`skill-1\`, \`skill-2\`]
|
|
20204
|
+
|
|
20205
|
+
**Acceptance Criteria**: [Verifiable conditions]
|
|
20206
|
+
\`\`\`
|
|
20207
|
+
|
|
20208
|
+
### 4. Agent Dispatch Summary (REQUIRED)
|
|
20209
|
+
|
|
20210
|
+
| Wave | Tasks | Dispatch Command |
|
|
20211
|
+
|------|-------|------------------|
|
|
20212
|
+
| 1 | 1, 4 | \`delegate_task(category="...", load_skills=[...], run_in_background=true)\` \xD7 2 |
|
|
20213
|
+
| 2 | 2, 3, 5 | \`delegate_task(...)\` \xD7 3 after Wave 1 completes |
|
|
20214
|
+
| 3 | 6 | \`delegate_task(...)\` final integration |
|
|
20215
|
+
|
|
20216
|
+
**WHY PARALLEL TASK GRAPH IS MANDATORY:**
|
|
20217
|
+
- Orchestrator (Sisyphus) executes tasks in parallel waves
|
|
20218
|
+
- Independent tasks run simultaneously via background agents
|
|
20219
|
+
- Proper dependency tracking prevents race conditions
|
|
20220
|
+
- Category + skills ensure optimal model routing per task`;
|
|
20068
20221
|
function isPlannerAgent(agentName) {
|
|
20069
20222
|
if (!agentName)
|
|
20070
20223
|
return false;
|
|
@@ -20169,52 +20322,52 @@ delegate_task(agent="oracle", prompt="Review my approach: [describe plan]")
|
|
|
20169
20322
|
YOU MUST LEVERAGE ALL AVAILABLE AGENTS / **CATEGORY + SKILLS** TO THEIR FULLEST POTENTIAL.
|
|
20170
20323
|
TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
|
|
20171
20324
|
|
|
20172
|
-
## MANDATORY:
|
|
20325
|
+
## MANDATORY: PLAN AGENT INVOCATION (NON-NEGOTIABLE)
|
|
20173
20326
|
|
|
20174
|
-
**YOU MUST ALWAYS INVOKE
|
|
20327
|
+
**YOU MUST ALWAYS INVOKE THE PLAN AGENT FOR ANY NON-TRIVIAL TASK.**
|
|
20175
20328
|
|
|
20176
20329
|
| Condition | Action |
|
|
20177
20330
|
|-----------|--------|
|
|
20178
|
-
| Task has 2+ steps | MUST call
|
|
20179
|
-
| Task scope unclear | MUST call
|
|
20180
|
-
| Implementation required | MUST call
|
|
20181
|
-
| Architecture decision needed | MUST call
|
|
20331
|
+
| Task has 2+ steps | MUST call plan agent |
|
|
20332
|
+
| Task scope unclear | MUST call plan agent |
|
|
20333
|
+
| Implementation required | MUST call plan agent |
|
|
20334
|
+
| Architecture decision needed | MUST call plan agent |
|
|
20182
20335
|
|
|
20183
20336
|
\`\`\`
|
|
20184
|
-
delegate_task(subagent_type="
|
|
20337
|
+
delegate_task(subagent_type="plan", prompt="<gathered context + user request>")
|
|
20185
20338
|
\`\`\`
|
|
20186
20339
|
|
|
20187
|
-
**WHY
|
|
20188
|
-
-
|
|
20189
|
-
-
|
|
20190
|
-
-
|
|
20340
|
+
**WHY PLAN AGENT IS MANDATORY:**
|
|
20341
|
+
- Plan agent analyzes dependencies and parallel execution opportunities
|
|
20342
|
+
- Plan agent outputs a **parallel task graph** with waves and dependencies
|
|
20343
|
+
- Plan agent provides structured TODO list with category + skills per task
|
|
20191
20344
|
- YOU are an orchestrator, NOT an implementer
|
|
20192
20345
|
|
|
20193
|
-
### SESSION CONTINUITY WITH
|
|
20346
|
+
### SESSION CONTINUITY WITH PLAN AGENT (CRITICAL)
|
|
20194
20347
|
|
|
20195
|
-
**
|
|
20348
|
+
**Plan agent returns a session_id. USE IT for follow-up interactions.**
|
|
20196
20349
|
|
|
20197
20350
|
| Scenario | Action |
|
|
20198
20351
|
|----------|--------|
|
|
20199
|
-
|
|
|
20352
|
+
| Plan agent asks clarifying questions | \`delegate_task(session_id="{returned_session_id}", prompt="<your answer>")\` |
|
|
20200
20353
|
| Need to refine the plan | \`delegate_task(session_id="{returned_session_id}", prompt="Please adjust: <feedback>")\` |
|
|
20201
20354
|
| Plan needs more detail | \`delegate_task(session_id="{returned_session_id}", prompt="Add more detail to Task N")\` |
|
|
20202
20355
|
|
|
20203
20356
|
**WHY SESSION_ID IS CRITICAL:**
|
|
20204
|
-
-
|
|
20357
|
+
- Plan agent retains FULL conversation context
|
|
20205
20358
|
- No repeated exploration or context gathering
|
|
20206
20359
|
- Saves 70%+ tokens on follow-ups
|
|
20207
20360
|
- Maintains interview continuity until plan is finalized
|
|
20208
20361
|
|
|
20209
20362
|
\`\`\`
|
|
20210
20363
|
// WRONG: Starting fresh loses all context
|
|
20211
|
-
delegate_task(subagent_type="
|
|
20364
|
+
delegate_task(subagent_type="plan", prompt="Here's more info...")
|
|
20212
20365
|
|
|
20213
20366
|
// CORRECT: Resume preserves everything
|
|
20214
20367
|
delegate_task(session_id="ses_abc123", prompt="Here's my answer to your question: ...")
|
|
20215
20368
|
\`\`\`
|
|
20216
20369
|
|
|
20217
|
-
**FAILURE TO CALL
|
|
20370
|
+
**FAILURE TO CALL PLAN AGENT = INCOMPLETE WORK.**
|
|
20218
20371
|
|
|
20219
20372
|
---
|
|
20220
20373
|
|
|
@@ -20226,7 +20379,7 @@ delegate_task(session_id="ses_abc123", prompt="Here's my answer to your question
|
|
|
20226
20379
|
|-----------|--------|-----|
|
|
20227
20380
|
| Codebase exploration | delegate_task(subagent_type="explore", run_in_background=true) | Parallel, context-efficient |
|
|
20228
20381
|
| Documentation lookup | delegate_task(subagent_type="librarian", run_in_background=true) | Specialized knowledge |
|
|
20229
|
-
| Planning | delegate_task(subagent_type="plan") |
|
|
20382
|
+
| Planning | delegate_task(subagent_type="plan") | Parallel task graph + structured TODO list |
|
|
20230
20383
|
| Architecture/Debugging | delegate_task(subagent_type="oracle") | High-IQ reasoning |
|
|
20231
20384
|
| Implementation | delegate_task(category="...", load_skills=[...]) | Domain-optimized models |
|
|
20232
20385
|
|
|
@@ -20286,20 +20439,20 @@ delegate_task(..., run_in_background=true) // task_id_3
|
|
|
20286
20439
|
delegate_task(subagent_type="librarian", run_in_background=true, prompt="...")
|
|
20287
20440
|
\`\`\`
|
|
20288
20441
|
|
|
20289
|
-
2. **INVOKE
|
|
20442
|
+
2. **INVOKE PLAN AGENT** (MANDATORY for non-trivial tasks):
|
|
20290
20443
|
\`\`\`
|
|
20291
|
-
result = delegate_task(subagent_type="
|
|
20444
|
+
result = delegate_task(subagent_type="plan", prompt="<context + request>")
|
|
20292
20445
|
// STORE the session_id for follow-ups!
|
|
20293
|
-
|
|
20446
|
+
plan_session_id = result.session_id
|
|
20294
20447
|
\`\`\`
|
|
20295
20448
|
|
|
20296
|
-
3. **ITERATE WITH
|
|
20449
|
+
3. **ITERATE WITH PLAN AGENT** (if clarification needed):
|
|
20297
20450
|
\`\`\`
|
|
20298
20451
|
// Use session_id to continue the conversation
|
|
20299
|
-
delegate_task(session_id=
|
|
20452
|
+
delegate_task(session_id=plan_session_id, prompt="<answer to plan agent's question>")
|
|
20300
20453
|
\`\`\`
|
|
20301
20454
|
|
|
20302
|
-
4. **EXECUTE VIA DELEGATION** (category + skills from
|
|
20455
|
+
4. **EXECUTE VIA DELEGATION** (category + skills from plan agent's output):
|
|
20303
20456
|
\`\`\`
|
|
20304
20457
|
delegate_task(category="...", load_skills=[...], prompt="<task from plan>")
|
|
20305
20458
|
\`\`\`
|
|
@@ -20378,9 +20531,9 @@ Write these criteria explicitly. Share with user if scope is non-trivial.
|
|
|
20378
20531
|
THE USER ASKED FOR X. DELIVER EXACTLY X. NOT A SUBSET. NOT A DEMO. NOT A STARTING POINT.
|
|
20379
20532
|
|
|
20380
20533
|
1. EXPLORES + LIBRARIANS (background)
|
|
20381
|
-
2. GATHER -> delegate_task(subagent_type="
|
|
20382
|
-
3. ITERATE WITH
|
|
20383
|
-
4. WORK BY DELEGATING TO CATEGORY + SKILLS AGENTS (following
|
|
20534
|
+
2. GATHER -> delegate_task(subagent_type="plan", prompt="<context + request>")
|
|
20535
|
+
3. ITERATE WITH PLAN AGENT (session_id resume) UNTIL PLAN IS FINALIZED
|
|
20536
|
+
4. WORK BY DELEGATING TO CATEGORY + SKILLS AGENTS (following plan agent's parallel task graph)
|
|
20384
20537
|
|
|
20385
20538
|
NOW.
|
|
20386
20539
|
|
|
@@ -20453,7 +20606,8 @@ function createKeywordDetectorHook(ctx, collector) {
|
|
|
20453
20606
|
return;
|
|
20454
20607
|
}
|
|
20455
20608
|
const currentAgent = getSessionAgent(input.sessionID) ?? input.agent;
|
|
20456
|
-
|
|
20609
|
+
const cleanText = removeSystemReminders(promptText);
|
|
20610
|
+
let detectedKeywords = detectKeywordsWithType(removeCodeBlocks2(cleanText), currentAgent);
|
|
20457
20611
|
if (isPlannerAgent(currentAgent)) {
|
|
20458
20612
|
detectedKeywords = detectedKeywords.filter((k) => k.type !== "ultrawork");
|
|
20459
20613
|
}
|
|
@@ -21577,6 +21731,9 @@ async function loadMcpJsonFromDir(skillDir) {
|
|
|
21577
21731
|
function parseAllowedTools(allowedTools) {
|
|
21578
21732
|
if (!allowedTools)
|
|
21579
21733
|
return;
|
|
21734
|
+
if (Array.isArray(allowedTools)) {
|
|
21735
|
+
return allowedTools.map((t) => t.trim()).filter(Boolean);
|
|
21736
|
+
}
|
|
21580
21737
|
return allowedTools.split(/\s+/).filter(Boolean);
|
|
21581
21738
|
}
|
|
21582
21739
|
async function loadSkillFromPath(skillPath, resolvedPath, defaultName, scope) {
|
|
@@ -21744,6 +21901,14 @@ init_deep_merge();
|
|
|
21744
21901
|
import { readFileSync as readFileSync21, existsSync as existsSync31 } from "fs";
|
|
21745
21902
|
import { dirname as dirname7, resolve as resolve6, isAbsolute as isAbsolute2 } from "path";
|
|
21746
21903
|
import { homedir as homedir10 } from "os";
|
|
21904
|
+
function parseAllowedToolsFromMetadata(allowedTools) {
|
|
21905
|
+
if (!allowedTools)
|
|
21906
|
+
return;
|
|
21907
|
+
if (Array.isArray(allowedTools)) {
|
|
21908
|
+
return allowedTools.map((t) => t.trim()).filter(Boolean);
|
|
21909
|
+
}
|
|
21910
|
+
return allowedTools.split(/\s+/).filter(Boolean);
|
|
21911
|
+
}
|
|
21747
21912
|
var SCOPE_PRIORITY = {
|
|
21748
21913
|
builtin: 1,
|
|
21749
21914
|
config: 2,
|
|
@@ -21835,7 +22000,7 @@ $ARGUMENTS
|
|
|
21835
22000
|
subtask: entry.subtask ?? fileMetadata.subtask,
|
|
21836
22001
|
argumentHint: entry["argument-hint"] || fileMetadata["argument-hint"]
|
|
21837
22002
|
};
|
|
21838
|
-
const allowedTools = entry["allowed-tools"] || (fileMetadata["allowed-tools"] ? fileMetadata["allowed-tools"]
|
|
22003
|
+
const allowedTools = entry["allowed-tools"] || (fileMetadata["allowed-tools"] ? parseAllowedToolsFromMetadata(fileMetadata["allowed-tools"]) : undefined);
|
|
21839
22004
|
return {
|
|
21840
22005
|
name,
|
|
21841
22006
|
path: entry.from ? resolveFilePath2(entry.from, configDir) : undefined,
|
|
@@ -24617,7 +24782,7 @@ ${contextInfo}`;
|
|
|
24617
24782
|
};
|
|
24618
24783
|
}
|
|
24619
24784
|
// src/hooks/atlas/index.ts
|
|
24620
|
-
import { execSync } from "child_process";
|
|
24785
|
+
import { execSync as execSync2 } from "child_process";
|
|
24621
24786
|
init_hook_message_injector();
|
|
24622
24787
|
init_logger();
|
|
24623
24788
|
init_system_directive();
|
|
@@ -24856,7 +25021,7 @@ function extractSessionIdFromOutput(output) {
|
|
|
24856
25021
|
}
|
|
24857
25022
|
function getGitDiffStats(directory) {
|
|
24858
25023
|
try {
|
|
24859
|
-
const output =
|
|
25024
|
+
const output = execSync2("git diff --numstat HEAD", {
|
|
24860
25025
|
cwd: directory,
|
|
24861
25026
|
encoding: "utf-8",
|
|
24862
25027
|
timeout: 5000,
|
|
@@ -24864,7 +25029,7 @@ function getGitDiffStats(directory) {
|
|
|
24864
25029
|
}).trim();
|
|
24865
25030
|
if (!output)
|
|
24866
25031
|
return [];
|
|
24867
|
-
const statusOutput =
|
|
25032
|
+
const statusOutput = execSync2("git status --porcelain", {
|
|
24868
25033
|
cwd: directory,
|
|
24869
25034
|
encoding: "utf-8",
|
|
24870
25035
|
timeout: 5000,
|
|
@@ -25161,6 +25326,9 @@ function createAtlasHook(ctx, options) {
|
|
|
25161
25326
|
}
|
|
25162
25327
|
},
|
|
25163
25328
|
"tool.execute.after": async (input, output) => {
|
|
25329
|
+
if (!output) {
|
|
25330
|
+
return;
|
|
25331
|
+
}
|
|
25164
25332
|
if (!isCallerOrchestrator(input.sessionID)) {
|
|
25165
25333
|
return;
|
|
25166
25334
|
}
|
|
@@ -43589,7 +43757,10 @@ async function executeSync(args, toolContext, ctx) {
|
|
|
43589
43757
|
const createResult = await ctx.client.session.create({
|
|
43590
43758
|
body: {
|
|
43591
43759
|
parentID: toolContext.sessionID,
|
|
43592
|
-
title: `${args.description} (@${args.subagent_type} subagent)
|
|
43760
|
+
title: `${args.description} (@${args.subagent_type} subagent)`,
|
|
43761
|
+
permission: [
|
|
43762
|
+
{ permission: "question", action: "deny", pattern: "*" }
|
|
43763
|
+
]
|
|
43593
43764
|
},
|
|
43594
43765
|
query: {
|
|
43595
43766
|
directory: parentDirectory
|
|
@@ -43597,6 +43768,17 @@ async function executeSync(args, toolContext, ctx) {
|
|
|
43597
43768
|
});
|
|
43598
43769
|
if (createResult.error) {
|
|
43599
43770
|
log(`[call_omo_agent] Session create error:`, createResult.error);
|
|
43771
|
+
const errorStr = String(createResult.error);
|
|
43772
|
+
if (errorStr.toLowerCase().includes("unauthorized")) {
|
|
43773
|
+
return `Error: Failed to create session (Unauthorized). This may be due to:
|
|
43774
|
+
1. OAuth token restrictions (e.g., Claude Code credentials are restricted to Claude Code only)
|
|
43775
|
+
2. Provider authentication issues
|
|
43776
|
+
3. Session permission inheritance problems
|
|
43777
|
+
|
|
43778
|
+
Try using a different provider or API key authentication.
|
|
43779
|
+
|
|
43780
|
+
Original error: ${createResult.error}`;
|
|
43781
|
+
}
|
|
43600
43782
|
return `Error: Failed to create session: ${createResult.error}`;
|
|
43601
43783
|
}
|
|
43602
43784
|
sessionID = createResult.data.id;
|
|
@@ -43837,7 +44019,10 @@ If the requested information is not found, clearly state what is missing.`;
|
|
|
43837
44019
|
const createResult = await ctx.client.session.create({
|
|
43838
44020
|
body: {
|
|
43839
44021
|
parentID: toolContext.sessionID,
|
|
43840
|
-
title: `look_at: ${args.goal.substring(0, 50)}
|
|
44022
|
+
title: `look_at: ${args.goal.substring(0, 50)}`,
|
|
44023
|
+
permission: [
|
|
44024
|
+
{ permission: "question", action: "deny", pattern: "*" }
|
|
44025
|
+
]
|
|
43841
44026
|
},
|
|
43842
44027
|
query: {
|
|
43843
44028
|
directory: parentDirectory
|
|
@@ -43845,6 +44030,17 @@ If the requested information is not found, clearly state what is missing.`;
|
|
|
43845
44030
|
});
|
|
43846
44031
|
if (createResult.error) {
|
|
43847
44032
|
log(`[look_at] Session create error:`, createResult.error);
|
|
44033
|
+
const errorStr = String(createResult.error);
|
|
44034
|
+
if (errorStr.toLowerCase().includes("unauthorized")) {
|
|
44035
|
+
return `Error: Failed to create session (Unauthorized). This may be due to:
|
|
44036
|
+
1. OAuth token restrictions (e.g., Claude Code credentials are restricted to Claude Code only)
|
|
44037
|
+
2. Provider authentication issues
|
|
44038
|
+
3. Session permission inheritance problems
|
|
44039
|
+
|
|
44040
|
+
Try using a different provider or API key authentication.
|
|
44041
|
+
|
|
44042
|
+
Original error: ${createResult.error}`;
|
|
44043
|
+
}
|
|
43848
44044
|
return `Error: Failed to create session: ${createResult.error}`;
|
|
43849
44045
|
}
|
|
43850
44046
|
const sessionID = createResult.data.id;
|
|
@@ -44681,6 +44877,11 @@ To continue this session: session_id="${sessionID}"`;
|
|
|
44681
44877
|
return `Cannot use subagent_type="${SISYPHUS_JUNIOR_AGENT}" directly. Use category parameter instead (e.g., ${categoryExamples}).
|
|
44682
44878
|
|
|
44683
44879
|
Sisyphus-Junior is spawned automatically when you specify a category. Pick the appropriate category for your task domain.`;
|
|
44880
|
+
}
|
|
44881
|
+
if (isPlanAgent(agentName) && isPlanAgent(parentAgent)) {
|
|
44882
|
+
return `You are prometheus. You cannot delegate to prometheus via delegate_task.
|
|
44883
|
+
|
|
44884
|
+
Create the work plan directly - that's your job as the planning agent.`;
|
|
44684
44885
|
}
|
|
44685
44886
|
agentToUse = agentName;
|
|
44686
44887
|
try {
|
|
@@ -44809,6 +45010,7 @@ To continue this session: session_id="${task.sessionID}"`;
|
|
|
44809
45010
|
}
|
|
44810
45011
|
});
|
|
44811
45012
|
try {
|
|
45013
|
+
const allowDelegateTask = isPlanAgent(agentToUse);
|
|
44812
45014
|
await client2.session.prompt({
|
|
44813
45015
|
path: { id: sessionID },
|
|
44814
45016
|
body: {
|
|
@@ -44816,7 +45018,7 @@ To continue this session: session_id="${task.sessionID}"`;
|
|
|
44816
45018
|
system: systemContent,
|
|
44817
45019
|
tools: {
|
|
44818
45020
|
task: false,
|
|
44819
|
-
delegate_task:
|
|
45021
|
+
delegate_task: allowDelegateTask,
|
|
44820
45022
|
call_omo_agent: true,
|
|
44821
45023
|
question: false
|
|
44822
45024
|
},
|
|
@@ -52919,6 +53121,8 @@ call_omo_agent(subagent_type="librarian", prompt="Find OSS implementations of Z.
|
|
|
52919
53121
|
- [Risk 2]: [Mitigation]
|
|
52920
53122
|
|
|
52921
53123
|
## Directives for Prometheus
|
|
53124
|
+
|
|
53125
|
+
### Core Directives
|
|
52922
53126
|
- MUST: [Required action]
|
|
52923
53127
|
- MUST: [Required action]
|
|
52924
53128
|
- MUST NOT: [Forbidden action]
|
|
@@ -52926,6 +53130,29 @@ call_omo_agent(subagent_type="librarian", prompt="Find OSS implementations of Z.
|
|
|
52926
53130
|
- PATTERN: Follow \`[file:lines]\`
|
|
52927
53131
|
- TOOL: Use \`[specific tool]\` for [purpose]
|
|
52928
53132
|
|
|
53133
|
+
### QA/Acceptance Criteria Directives (MANDATORY)
|
|
53134
|
+
> **ZERO USER INTERVENTION PRINCIPLE**: All acceptance criteria MUST be executable by agents.
|
|
53135
|
+
|
|
53136
|
+
- MUST: Write acceptance criteria as executable commands (curl, bun test, playwright actions)
|
|
53137
|
+
- MUST: Include exact expected outputs, not vague descriptions
|
|
53138
|
+
- MUST: Specify verification tool for each deliverable type (playwright for UI, curl for API, etc.)
|
|
53139
|
+
- MUST NOT: Create criteria requiring "user manually tests..."
|
|
53140
|
+
- MUST NOT: Create criteria requiring "user visually confirms..."
|
|
53141
|
+
- MUST NOT: Create criteria requiring "user clicks/interacts..."
|
|
53142
|
+
- MUST NOT: Use placeholders without concrete examples (bad: "[endpoint]", good: "/api/users")
|
|
53143
|
+
|
|
53144
|
+
Example of GOOD acceptance criteria:
|
|
53145
|
+
\`\`\`
|
|
53146
|
+
curl -s http://localhost:3000/api/health | jq '.status'
|
|
53147
|
+
# Assert: Output is "ok"
|
|
53148
|
+
\`\`\`
|
|
53149
|
+
|
|
53150
|
+
Example of BAD acceptance criteria (FORBIDDEN):
|
|
53151
|
+
\`\`\`
|
|
53152
|
+
User opens browser and checks if the page loads correctly.
|
|
53153
|
+
User confirms the button works as expected.
|
|
53154
|
+
\`\`\`
|
|
53155
|
+
|
|
52929
53156
|
## Recommended Approach
|
|
52930
53157
|
[1-2 sentence summary of how to proceed]
|
|
52931
53158
|
\`\`\`
|
|
@@ -52952,12 +53179,16 @@ call_omo_agent(subagent_type="librarian", prompt="Find OSS implementations of Z.
|
|
|
52952
53179
|
- Ask generic questions ("What's the scope?")
|
|
52953
53180
|
- Proceed without addressing ambiguity
|
|
52954
53181
|
- Make assumptions about user's codebase
|
|
53182
|
+
- Suggest acceptance criteria requiring user intervention ("user manually tests", "user confirms", "user clicks")
|
|
53183
|
+
- Leave QA/acceptance criteria vague or placeholder-heavy
|
|
52955
53184
|
|
|
52956
53185
|
**ALWAYS**:
|
|
52957
53186
|
- Classify intent FIRST
|
|
52958
53187
|
- Be specific ("Should this change UserService only, or also AuthService?")
|
|
52959
53188
|
- Explore before asking (for Build/Research intents)
|
|
52960
53189
|
- Provide actionable directives for Prometheus
|
|
53190
|
+
- Include QA automation directives in every output
|
|
53191
|
+
- Ensure acceptance criteria are agent-executable (commands, not human actions)
|
|
52961
53192
|
`;
|
|
52962
53193
|
var metisRestrictions = createAgentToolRestrictions([
|
|
52963
53194
|
"write",
|
|
@@ -55714,27 +55945,37 @@ Each TODO follows RED-GREEN-REFACTOR:
|
|
|
55714
55945
|
- Example: Create \`src/__tests__/example.test.ts\`
|
|
55715
55946
|
- Verify: \`bun test\` \u2192 1 test passes
|
|
55716
55947
|
|
|
55717
|
-
### If
|
|
55948
|
+
### If Automated Verification Only (NO User Intervention)
|
|
55718
55949
|
|
|
55719
|
-
**CRITICAL
|
|
55950
|
+
> **CRITICAL PRINCIPLE: ZERO USER INTERVENTION**
|
|
55951
|
+
>
|
|
55952
|
+
> **NEVER** create acceptance criteria that require:
|
|
55953
|
+
> - "User manually tests..." / "\uC0AC\uC6A9\uC790\uAC00 \uC9C1\uC811 \uD14C\uC2A4\uD2B8..."
|
|
55954
|
+
> - "User visually confirms..." / "\uC0AC\uC6A9\uC790\uAC00 \uB208\uC73C\uB85C \uD655\uC778..."
|
|
55955
|
+
> - "User interacts with..." / "\uC0AC\uC6A9\uC790\uAC00 \uC9C1\uC811 \uC870\uC791..."
|
|
55956
|
+
> - "Ask user to verify..." / "\uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD655\uC778 \uC694\uCCAD..."
|
|
55957
|
+
> - ANY step that requires a human to perform an action
|
|
55958
|
+
>
|
|
55959
|
+
> **ALL verification MUST be automated and executable by the agent.**
|
|
55960
|
+
> If a verification cannot be automated, find an automated alternative or explicitly note it as a known limitation.
|
|
55720
55961
|
|
|
55721
|
-
Each TODO includes
|
|
55962
|
+
Each TODO includes EXECUTABLE verification procedures that agents can run directly:
|
|
55722
55963
|
|
|
55723
55964
|
**By Deliverable Type:**
|
|
55724
55965
|
|
|
55725
|
-
| Type | Verification Tool | Procedure |
|
|
55726
|
-
|
|
55727
|
-
| **Frontend/UI** | Playwright browser |
|
|
55728
|
-
| **TUI/CLI** | interactive_bash (tmux) |
|
|
55729
|
-
| **API/Backend** | curl / httpie |
|
|
55730
|
-
| **Library/Module** | Node/Python REPL |
|
|
55731
|
-
| **Config/Infra** | Shell commands |
|
|
55966
|
+
| Type | Verification Tool | Automated Procedure |
|
|
55967
|
+
|------|------------------|---------------------|
|
|
55968
|
+
| **Frontend/UI** | Playwright browser via playwright skill | Agent navigates, clicks, screenshots, asserts DOM state |
|
|
55969
|
+
| **TUI/CLI** | interactive_bash (tmux) | Agent runs command, captures output, validates expected strings |
|
|
55970
|
+
| **API/Backend** | curl / httpie via Bash | Agent sends request, parses response, validates JSON fields |
|
|
55971
|
+
| **Library/Module** | Node/Python REPL via Bash | Agent imports, calls function, compares output |
|
|
55972
|
+
| **Config/Infra** | Shell commands via Bash | Agent applies config, runs state check, validates output |
|
|
55732
55973
|
|
|
55733
|
-
**Evidence
|
|
55734
|
-
-
|
|
55735
|
-
- Screenshots for visual
|
|
55736
|
-
-
|
|
55737
|
-
-
|
|
55974
|
+
**Evidence Requirements (Agent-Executable):**
|
|
55975
|
+
- Command output captured and compared against expected patterns
|
|
55976
|
+
- Screenshots saved to .sisyphus/evidence/ for visual verification
|
|
55977
|
+
- JSON response fields validated with specific assertions
|
|
55978
|
+
- Exit codes checked (0 = success)
|
|
55738
55979
|
|
|
55739
55980
|
---
|
|
55740
55981
|
|
|
@@ -55844,53 +56085,76 @@ Parallel Speedup: ~40% faster than sequential
|
|
|
55844
56085
|
|
|
55845
56086
|
**Acceptance Criteria**:
|
|
55846
56087
|
|
|
55847
|
-
> CRITICAL:
|
|
55848
|
-
>
|
|
56088
|
+
> **CRITICAL: AGENT-EXECUTABLE VERIFICATION ONLY**
|
|
56089
|
+
>
|
|
56090
|
+
> - Acceptance = EXECUTION by the agent, not "user checks if it works"
|
|
56091
|
+
> - Every criterion MUST be verifiable by running a command or using a tool
|
|
56092
|
+
> - NO steps like "user opens browser", "user clicks", "user confirms"
|
|
56093
|
+
> - If you write "[placeholder]" - REPLACE IT with actual values based on task context
|
|
55849
56094
|
|
|
55850
56095
|
**If TDD (tests enabled):**
|
|
55851
|
-
- [ ] Test file created:
|
|
55852
|
-
- [ ] Test covers:
|
|
55853
|
-
- [ ]
|
|
55854
|
-
|
|
55855
|
-
**
|
|
55856
|
-
|
|
55857
|
-
|
|
55858
|
-
|
|
55859
|
-
|
|
55860
|
-
|
|
55861
|
-
|
|
55862
|
-
|
|
55863
|
-
|
|
55864
|
-
|
|
55865
|
-
|
|
55866
|
-
|
|
55867
|
-
|
|
55868
|
-
|
|
55869
|
-
|
|
55870
|
-
|
|
55871
|
-
|
|
55872
|
-
|
|
55873
|
-
|
|
55874
|
-
|
|
55875
|
-
|
|
55876
|
-
|
|
55877
|
-
|
|
55878
|
-
|
|
55879
|
-
|
|
55880
|
-
|
|
55881
|
-
|
|
55882
|
-
|
|
55883
|
-
|
|
55884
|
-
|
|
55885
|
-
|
|
55886
|
-
|
|
55887
|
-
|
|
55888
|
-
|
|
55889
|
-
|
|
55890
|
-
**
|
|
55891
|
-
|
|
55892
|
-
|
|
55893
|
-
-
|
|
56096
|
+
- [ ] Test file created: src/auth/login.test.ts
|
|
56097
|
+
- [ ] Test covers: successful login returns JWT token
|
|
56098
|
+
- [ ] bun test src/auth/login.test.ts \u2192 PASS (3 tests, 0 failures)
|
|
56099
|
+
|
|
56100
|
+
**Automated Verification (ALWAYS include, choose by deliverable type):**
|
|
56101
|
+
|
|
56102
|
+
**For Frontend/UI changes** (using playwright skill):
|
|
56103
|
+
\\\`\\\`\\\`
|
|
56104
|
+
# Agent executes via playwright browser automation:
|
|
56105
|
+
1. Navigate to: http://localhost:3000/login
|
|
56106
|
+
2. Fill: input[name="email"] with "test@example.com"
|
|
56107
|
+
3. Fill: input[name="password"] with "password123"
|
|
56108
|
+
4. Click: button[type="submit"]
|
|
56109
|
+
5. Wait for: selector ".dashboard-welcome" to be visible
|
|
56110
|
+
6. Assert: text "Welcome back" appears on page
|
|
56111
|
+
7. Screenshot: .sisyphus/evidence/task-1-login-success.png
|
|
56112
|
+
\\\`\\\`\\\`
|
|
56113
|
+
|
|
56114
|
+
**For TUI/CLI changes** (using interactive_bash):
|
|
56115
|
+
\\\`\\\`\\\`
|
|
56116
|
+
# Agent executes via tmux session:
|
|
56117
|
+
1. Command: ./my-cli --config test.yaml
|
|
56118
|
+
2. Wait for: "Configuration loaded" in output
|
|
56119
|
+
3. Send keys: "q" to quit
|
|
56120
|
+
4. Assert: Exit code 0
|
|
56121
|
+
5. Assert: Output contains "Goodbye"
|
|
56122
|
+
\\\`\\\`\\\`
|
|
56123
|
+
|
|
56124
|
+
**For API/Backend changes** (using Bash curl):
|
|
56125
|
+
\\\`\\\`\\\`bash
|
|
56126
|
+
# Agent runs:
|
|
56127
|
+
curl -s -X POST http://localhost:8080/api/users \\
|
|
56128
|
+
-H "Content-Type: application/json" \\
|
|
56129
|
+
-d '{"email":"new@test.com","name":"Test User"}' \\
|
|
56130
|
+
| jq '.id'
|
|
56131
|
+
# Assert: Returns non-empty UUID
|
|
56132
|
+
# Assert: HTTP status 201
|
|
56133
|
+
\\\`\\\`\\\`
|
|
56134
|
+
|
|
56135
|
+
**For Library/Module changes** (using Bash node/bun):
|
|
56136
|
+
\\\`\\\`\\\`bash
|
|
56137
|
+
# Agent runs:
|
|
56138
|
+
bun -e "import { validateEmail } from './src/utils/validate'; console.log(validateEmail('test@example.com'))"
|
|
56139
|
+
# Assert: Output is "true"
|
|
56140
|
+
|
|
56141
|
+
bun -e "import { validateEmail } from './src/utils/validate'; console.log(validateEmail('invalid'))"
|
|
56142
|
+
# Assert: Output is "false"
|
|
56143
|
+
\\\`\\\`\\\`
|
|
56144
|
+
|
|
56145
|
+
**For Config/Infra changes** (using Bash):
|
|
56146
|
+
\\\`\\\`\\\`bash
|
|
56147
|
+
# Agent runs:
|
|
56148
|
+
docker compose up -d
|
|
56149
|
+
# Wait 5s for containers
|
|
56150
|
+
docker compose ps --format json | jq '.[].State'
|
|
56151
|
+
# Assert: All states are "running"
|
|
56152
|
+
\\\`\\\`\\\`
|
|
56153
|
+
|
|
56154
|
+
**Evidence to Capture:**
|
|
56155
|
+
- [ ] Terminal output from verification commands (actual output, not expected)
|
|
56156
|
+
- [ ] Screenshot files in .sisyphus/evidence/ for UI changes
|
|
56157
|
+
- [ ] JSON response bodies for API changes
|
|
55894
56158
|
|
|
55895
56159
|
**Commit**: YES | NO (groups with N)
|
|
55896
56160
|
- Message: \`type(scope): desc\`
|
|
@@ -56292,7 +56556,20 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
56292
56556
|
const toolOutputTruncator = isHookEnabled("tool-output-truncator") ? createToolOutputTruncatorHook(ctx, {
|
|
56293
56557
|
experimental: pluginConfig.experimental
|
|
56294
56558
|
}) : null;
|
|
56295
|
-
|
|
56559
|
+
let directoryAgentsInjector = null;
|
|
56560
|
+
if (isHookEnabled("directory-agents-injector")) {
|
|
56561
|
+
const currentVersion = getOpenCodeVersion();
|
|
56562
|
+
const hasNativeSupport = currentVersion !== null && isOpenCodeVersionAtLeast(OPENCODE_NATIVE_AGENTS_INJECTION_VERSION);
|
|
56563
|
+
if (hasNativeSupport) {
|
|
56564
|
+
console.warn(`[oh-my-opencode] directory-agents-injector hook auto-disabled: ` + `OpenCode ${currentVersion} has native AGENTS.md support (>= ${OPENCODE_NATIVE_AGENTS_INJECTION_VERSION})`);
|
|
56565
|
+
log("directory-agents-injector auto-disabled due to native OpenCode support", {
|
|
56566
|
+
currentVersion,
|
|
56567
|
+
nativeVersion: OPENCODE_NATIVE_AGENTS_INJECTION_VERSION
|
|
56568
|
+
});
|
|
56569
|
+
} else {
|
|
56570
|
+
directoryAgentsInjector = createDirectoryAgentsInjectorHook(ctx);
|
|
56571
|
+
}
|
|
56572
|
+
}
|
|
56296
56573
|
const directoryReadmeInjector = isHookEnabled("directory-readme-injector") ? createDirectoryReadmeInjectorHook(ctx) : null;
|
|
56297
56574
|
const emptyTaskResponseDetector = isHookEnabled("empty-task-response-detector") ? createEmptyTaskResponseDetectorHook(ctx) : null;
|
|
56298
56575
|
const thinkMode = isHookEnabled("think-mode") ? createThinkModeHook() : null;
|
|
@@ -56453,13 +56730,20 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
56453
56730
|
}
|
|
56454
56731
|
const message = output.message;
|
|
56455
56732
|
if (firstMessageVariantGate.shouldOverride(input.sessionID)) {
|
|
56456
|
-
const variant = resolveAgentVariant(pluginConfig, input.agent);
|
|
56733
|
+
const variant = input.model && input.agent ? resolveVariantForModel(pluginConfig, input.agent, input.model) : resolveAgentVariant(pluginConfig, input.agent);
|
|
56457
56734
|
if (variant !== undefined) {
|
|
56458
56735
|
message.variant = variant;
|
|
56459
56736
|
}
|
|
56460
56737
|
firstMessageVariantGate.markApplied(input.sessionID);
|
|
56461
56738
|
} else {
|
|
56462
|
-
|
|
56739
|
+
if (input.model && input.agent && message.variant === undefined) {
|
|
56740
|
+
const variant = resolveVariantForModel(pluginConfig, input.agent, input.model);
|
|
56741
|
+
if (variant !== undefined) {
|
|
56742
|
+
message.variant = variant;
|
|
56743
|
+
}
|
|
56744
|
+
} else {
|
|
56745
|
+
applyAgentVariant(pluginConfig, input.agent, message);
|
|
56746
|
+
}
|
|
56463
56747
|
}
|
|
56464
56748
|
await keywordDetector?.["chat.message"]?.(input, output);
|
|
56465
56749
|
await claudeCodeHooks["chat.message"]?.(input, output);
|
|
@@ -56636,6 +56920,9 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
56636
56920
|
}
|
|
56637
56921
|
},
|
|
56638
56922
|
"tool.execute.after": async (input, output) => {
|
|
56923
|
+
if (!output) {
|
|
56924
|
+
return;
|
|
56925
|
+
}
|
|
56639
56926
|
await claudeCodeHooks["tool.execute.after"](input, output);
|
|
56640
56927
|
await toolOutputTruncator?.["tool.execute.after"](input, output);
|
|
56641
56928
|
await contextWindowMonitor?.["tool.execute.after"](input, output);
|