micode 0.4.1 → 0.5.0
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 +81 -44
- package/dist/tools/btca/index.d.ts +19 -0
- package/dist/utils/model-limits.d.ts +7 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,14 +16,12 @@ var brainstormerAgent = {
|
|
|
16
16
|
mode: "primary",
|
|
17
17
|
model: "anthropic/claude-opus-4-5",
|
|
18
18
|
temperature: 0.7,
|
|
19
|
-
tools: { ask: true },
|
|
20
19
|
prompt: `<purpose>
|
|
21
20
|
Turn ideas into fully formed designs through natural collaborative dialogue.
|
|
22
21
|
This is DESIGN ONLY. The planner agent handles detailed implementation plans.
|
|
23
22
|
</purpose>
|
|
24
23
|
|
|
25
24
|
<critical-rules>
|
|
26
|
-
<rule>ASK TOOL: Use the ask tool for EVERY question to the user. Never ask in plain text.</rule>
|
|
27
25
|
<rule>NO CODE: Never write code. Never provide code examples. Design only.</rule>
|
|
28
26
|
<rule>SUBAGENTS: Spawn multiple in parallel for codebase analysis.</rule>
|
|
29
27
|
<rule>TOOLS (grep, read, etc.): Do NOT use directly - use subagents instead.</rule>
|
|
@@ -54,8 +52,6 @@ This is DESIGN ONLY. The planner agent handles detailed implementation plans.
|
|
|
54
52
|
- codebase-analyzer: "Analyze existing [related feature]"
|
|
55
53
|
- pattern-finder: "Find patterns for [similar functionality]"
|
|
56
54
|
</spawn-example>
|
|
57
|
-
<rule>Use the ask tool for EVERY question - never plain text</rule>
|
|
58
|
-
<rule>Always provide MULTIPLE CHOICE options in the ask tool</rule>
|
|
59
55
|
<focus>purpose, constraints, success criteria</focus>
|
|
60
56
|
</phase>
|
|
61
57
|
|
|
@@ -91,9 +87,7 @@ This is DESIGN ONLY. The planner agent handles detailed implementation plans.
|
|
|
91
87
|
<principle name="design-only">NO CODE. Describe components, not implementations. Planner writes code.</principle>
|
|
92
88
|
<principle name="subagents-first">ALWAYS use subagents for code analysis, NEVER tools directly</principle>
|
|
93
89
|
<principle name="parallel-spawn">Spawn multiple subagents in a SINGLE message</principle>
|
|
94
|
-
<principle name="
|
|
95
|
-
<principle name="one-question">Ask ONE question at a time via ask tool. Wait for answer.</principle>
|
|
96
|
-
<principle name="multiple-choice">Present 3-5 options in ask tool questions</principle>
|
|
90
|
+
<principle name="one-question">Ask ONE question at a time. Wait for answer.</principle>
|
|
97
91
|
<principle name="yagni">Remove unnecessary features from ALL designs</principle>
|
|
98
92
|
<principle name="explore-alternatives">ALWAYS propose 2-3 approaches before settling</principle>
|
|
99
93
|
<principle name="incremental-validation">Present in sections, validate each before proceeding</principle>
|
|
@@ -865,10 +859,6 @@ If you want exception to ANY rule, STOP and get explicit permission first.
|
|
|
865
859
|
Breaking the letter or spirit of the rules is failure.
|
|
866
860
|
</rule>
|
|
867
861
|
|
|
868
|
-
<rule priority="critical">
|
|
869
|
-
ALWAYS use the ask tool when you need user input. Never ask questions in plain text.
|
|
870
|
-
</rule>
|
|
871
|
-
|
|
872
862
|
<values>
|
|
873
863
|
<value>Honesty. If you lie, you'll be replaced.</value>
|
|
874
864
|
<value>Do it right, not fast. Never skip steps or take shortcuts.</value>
|
|
@@ -884,8 +874,6 @@ ALWAYS use the ask tool when you need user input. Never ask questions in plain t
|
|
|
884
874
|
<rule>If uncomfortable pushing back, say "Strange things are afoot at the Circle K"</rule>
|
|
885
875
|
<rule>STOP and ask for clarification rather than making assumptions</rule>
|
|
886
876
|
<rule>STOP and ask for help when human input would be valuable</rule>
|
|
887
|
-
<rule>ALWAYS use the ask tool when asking questions - never plain text</rule>
|
|
888
|
-
<rule>Provide multiple-choice options in the ask tool whenever possible</rule>
|
|
889
877
|
</relationship>
|
|
890
878
|
|
|
891
879
|
<proactiveness>
|
|
@@ -967,8 +955,7 @@ var primaryAgent = {
|
|
|
967
955
|
budgetTokens: 32000
|
|
968
956
|
},
|
|
969
957
|
maxTokens: 64000,
|
|
970
|
-
prompt: PROMPT
|
|
971
|
-
tools: { ask: true }
|
|
958
|
+
prompt: PROMPT
|
|
972
959
|
};
|
|
973
960
|
var PRIMARY_AGENT_NAME = process.env.OPENCODE_AGENT_NAME || "commander";
|
|
974
961
|
|
|
@@ -13838,6 +13825,69 @@ ${output}`;
|
|
|
13838
13825
|
}
|
|
13839
13826
|
});
|
|
13840
13827
|
|
|
13828
|
+
// src/tools/btca/index.ts
|
|
13829
|
+
var {spawn: spawn2, which: which2 } = globalThis.Bun;
|
|
13830
|
+
async function checkBtcaAvailable() {
|
|
13831
|
+
const btcaPath = which2("btca");
|
|
13832
|
+
if (btcaPath) {
|
|
13833
|
+
return { available: true };
|
|
13834
|
+
}
|
|
13835
|
+
return {
|
|
13836
|
+
available: false,
|
|
13837
|
+
message: `btca CLI not found. Library source code search will not work.
|
|
13838
|
+
` + `Install from: https://github.com/anthropics/btca
|
|
13839
|
+
` + " cargo install btca"
|
|
13840
|
+
};
|
|
13841
|
+
}
|
|
13842
|
+
var BTCA_TIMEOUT_MS = 120000;
|
|
13843
|
+
async function runBtca(args) {
|
|
13844
|
+
try {
|
|
13845
|
+
const proc = spawn2(["btca", ...args], {
|
|
13846
|
+
stdout: "pipe",
|
|
13847
|
+
stderr: "pipe"
|
|
13848
|
+
});
|
|
13849
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
13850
|
+
setTimeout(() => {
|
|
13851
|
+
proc.kill();
|
|
13852
|
+
reject(new Error("btca command timed out after 2 minutes"));
|
|
13853
|
+
}, BTCA_TIMEOUT_MS);
|
|
13854
|
+
});
|
|
13855
|
+
const [stdout, stderr, exitCode] = await Promise.race([
|
|
13856
|
+
Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text(), proc.exited]),
|
|
13857
|
+
timeoutPromise
|
|
13858
|
+
]);
|
|
13859
|
+
if (exitCode !== 0) {
|
|
13860
|
+
const errorMsg = stderr.trim() || `Exit code ${exitCode}`;
|
|
13861
|
+
return { output: "", error: errorMsg };
|
|
13862
|
+
}
|
|
13863
|
+
return { output: stdout.trim() };
|
|
13864
|
+
} catch (e) {
|
|
13865
|
+
const err = e;
|
|
13866
|
+
if (err.message?.includes("ENOENT")) {
|
|
13867
|
+
return {
|
|
13868
|
+
output: "",
|
|
13869
|
+
error: `btca CLI not found. Install from: https://github.com/anthropics/btca
|
|
13870
|
+
` + " cargo install btca"
|
|
13871
|
+
};
|
|
13872
|
+
}
|
|
13873
|
+
return { output: "", error: err.message };
|
|
13874
|
+
}
|
|
13875
|
+
}
|
|
13876
|
+
var btca_ask = tool({
|
|
13877
|
+
description: "Ask questions about library/framework source code using btca. " + "Clones repos locally and searches source code to answer questions. " + "Use for understanding library internals, finding implementation details, or debugging.",
|
|
13878
|
+
args: {
|
|
13879
|
+
tech: tool.schema.string().describe("Resource name configured in btca (e.g., 'react', 'express')"),
|
|
13880
|
+
question: tool.schema.string().describe("Question to ask about the library source code")
|
|
13881
|
+
},
|
|
13882
|
+
execute: async (args) => {
|
|
13883
|
+
const result = await runBtca(["ask", "-t", args.tech, "-q", args.question]);
|
|
13884
|
+
if (result.error) {
|
|
13885
|
+
return `Error: ${result.error}`;
|
|
13886
|
+
}
|
|
13887
|
+
return result.output || "No answer found";
|
|
13888
|
+
}
|
|
13889
|
+
});
|
|
13890
|
+
|
|
13841
13891
|
// src/tools/look-at.ts
|
|
13842
13892
|
import { readFileSync, statSync } from "fs";
|
|
13843
13893
|
import { extname, basename } from "path";
|
|
@@ -14862,20 +14912,22 @@ function createTokenAwareTruncationHook(ctx) {
|
|
|
14862
14912
|
};
|
|
14863
14913
|
}
|
|
14864
14914
|
|
|
14865
|
-
// src/
|
|
14866
|
-
var WARNING_THRESHOLD = 0.7;
|
|
14867
|
-
var CRITICAL_THRESHOLD = 0.85;
|
|
14868
|
-
var DEFAULT_CONTEXT_LIMIT2 = 200000;
|
|
14915
|
+
// src/utils/model-limits.ts
|
|
14869
14916
|
var MODEL_CONTEXT_LIMITS = {
|
|
14870
14917
|
"claude-opus": 200000,
|
|
14871
14918
|
"claude-sonnet": 200000,
|
|
14872
14919
|
"claude-haiku": 200000,
|
|
14920
|
+
"claude-3": 200000,
|
|
14921
|
+
"claude-4": 200000,
|
|
14922
|
+
"gpt-4o": 128000,
|
|
14923
|
+
"gpt-4-turbo": 128000,
|
|
14873
14924
|
"gpt-4": 128000,
|
|
14874
14925
|
"gpt-5": 200000,
|
|
14875
14926
|
o1: 200000,
|
|
14876
14927
|
o3: 200000,
|
|
14877
14928
|
gemini: 1e6
|
|
14878
14929
|
};
|
|
14930
|
+
var DEFAULT_CONTEXT_LIMIT2 = 200000;
|
|
14879
14931
|
function getContextLimit(modelID) {
|
|
14880
14932
|
const modelLower = modelID.toLowerCase();
|
|
14881
14933
|
for (const [pattern, limit] of Object.entries(MODEL_CONTEXT_LIMITS)) {
|
|
@@ -14885,6 +14937,10 @@ function getContextLimit(modelID) {
|
|
|
14885
14937
|
}
|
|
14886
14938
|
return DEFAULT_CONTEXT_LIMIT2;
|
|
14887
14939
|
}
|
|
14940
|
+
|
|
14941
|
+
// src/hooks/context-window-monitor.ts
|
|
14942
|
+
var WARNING_THRESHOLD = 0.7;
|
|
14943
|
+
var CRITICAL_THRESHOLD = 0.85;
|
|
14888
14944
|
var WARNING_COOLDOWN_MS = 120000;
|
|
14889
14945
|
function createContextWindowMonitorHook(ctx) {
|
|
14890
14946
|
const state = {
|
|
@@ -15163,33 +15219,9 @@ function createFileOpsTrackerHook(_ctx) {
|
|
|
15163
15219
|
}
|
|
15164
15220
|
|
|
15165
15221
|
// src/hooks/auto-clear-ledger.ts
|
|
15166
|
-
var MODEL_CONTEXT_LIMITS2 = {
|
|
15167
|
-
"claude-opus": 200000,
|
|
15168
|
-
"claude-sonnet": 200000,
|
|
15169
|
-
"claude-haiku": 200000,
|
|
15170
|
-
"claude-3": 200000,
|
|
15171
|
-
"claude-4": 200000,
|
|
15172
|
-
"gpt-4o": 128000,
|
|
15173
|
-
"gpt-4-turbo": 128000,
|
|
15174
|
-
"gpt-4": 128000,
|
|
15175
|
-
"gpt-5": 200000,
|
|
15176
|
-
o1: 200000,
|
|
15177
|
-
o3: 200000,
|
|
15178
|
-
gemini: 1e6
|
|
15179
|
-
};
|
|
15180
|
-
var DEFAULT_CONTEXT_LIMIT3 = 200000;
|
|
15181
15222
|
var DEFAULT_THRESHOLD = 0.8;
|
|
15182
15223
|
var MIN_TOKENS_FOR_CLEAR = 50000;
|
|
15183
15224
|
var CLEAR_COOLDOWN_MS = 60000;
|
|
15184
|
-
function getContextLimit2(modelID) {
|
|
15185
|
-
const modelLower = modelID.toLowerCase();
|
|
15186
|
-
for (const [pattern, limit] of Object.entries(MODEL_CONTEXT_LIMITS2)) {
|
|
15187
|
-
if (modelLower.includes(pattern)) {
|
|
15188
|
-
return limit;
|
|
15189
|
-
}
|
|
15190
|
-
}
|
|
15191
|
-
return DEFAULT_CONTEXT_LIMIT3;
|
|
15192
|
-
}
|
|
15193
15225
|
function createAutoClearLedgerHook(ctx) {
|
|
15194
15226
|
const state = {
|
|
15195
15227
|
lastClearTime: new Map,
|
|
@@ -15224,7 +15256,7 @@ function createAutoClearLedgerHook(ctx) {
|
|
|
15224
15256
|
if (totalUsed < MIN_TOKENS_FOR_CLEAR)
|
|
15225
15257
|
return;
|
|
15226
15258
|
const model = modelID || info?.modelID || "";
|
|
15227
|
-
const contextLimit =
|
|
15259
|
+
const contextLimit = getContextLimit(model);
|
|
15228
15260
|
const usageRatio = totalUsed / contextLimit;
|
|
15229
15261
|
if (usageRatio < DEFAULT_THRESHOLD)
|
|
15230
15262
|
return;
|
|
@@ -15923,6 +15955,10 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
15923
15955
|
if (!astGrepStatus.available) {
|
|
15924
15956
|
console.warn(`[micode] ${astGrepStatus.message}`);
|
|
15925
15957
|
}
|
|
15958
|
+
const btcaStatus = await checkBtcaAvailable();
|
|
15959
|
+
if (!btcaStatus.available) {
|
|
15960
|
+
console.warn(`[micode] ${btcaStatus.message}`);
|
|
15961
|
+
}
|
|
15926
15962
|
const userConfig = await loadMicodeConfig();
|
|
15927
15963
|
if (userConfig?.agents) {
|
|
15928
15964
|
console.log(`[micode] Loaded model overrides for: ${Object.keys(userConfig.agents).join(", ")}`);
|
|
@@ -15944,6 +15980,7 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
15944
15980
|
tool: {
|
|
15945
15981
|
ast_grep_search,
|
|
15946
15982
|
ast_grep_replace,
|
|
15983
|
+
btca_ask,
|
|
15947
15984
|
look_at,
|
|
15948
15985
|
artifact_search,
|
|
15949
15986
|
...backgroundTaskTools
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if btca CLI is available on the system.
|
|
3
|
+
* Returns installation instructions if not found.
|
|
4
|
+
*/
|
|
5
|
+
export declare function checkBtcaAvailable(): Promise<{
|
|
6
|
+
available: boolean;
|
|
7
|
+
message?: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const btca_ask: {
|
|
10
|
+
description: string;
|
|
11
|
+
args: {
|
|
12
|
+
tech: import("zod").ZodString;
|
|
13
|
+
question: import("zod").ZodString;
|
|
14
|
+
};
|
|
15
|
+
execute(args: {
|
|
16
|
+
tech: string;
|
|
17
|
+
question: string;
|
|
18
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
19
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const MODEL_CONTEXT_LIMITS: Record<string, number>;
|
|
2
|
+
export declare const DEFAULT_CONTEXT_LIMIT = 200000;
|
|
3
|
+
/**
|
|
4
|
+
* Get the context window limit for a given model ID.
|
|
5
|
+
* Matches against known patterns and falls back to default.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getContextLimit(modelID: string): number;
|