micode 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -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="ask-tool-always">ALWAYS use the ask tool for questions - never plain text</principle>
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>
@@ -373,6 +367,12 @@ Your research is IMPLEMENTATION-LEVEL only:
373
367
  All research must serve the design - never second-guess design decisions.
374
368
  </research-scope>
375
369
 
370
+ <library-research description="For external library/framework APIs">
371
+ <tool name="context7">Use context7_resolve-library-id then context7_query-docs for API documentation.</tool>
372
+ <tool name="btca_ask">Use for understanding library internals when docs aren't enough.</tool>
373
+ <rule>Use these directly - no subagent needed for library research.</rule>
374
+ </library-research>
375
+
376
376
  <available-subagents>
377
377
  <subagent name="codebase-locator" spawn="parallel">
378
378
  Find exact file paths needed for implementation.
@@ -865,10 +865,6 @@ If you want exception to ANY rule, STOP and get explicit permission first.
865
865
  Breaking the letter or spirit of the rules is failure.
866
866
  </rule>
867
867
 
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
868
  <values>
873
869
  <value>Honesty. If you lie, you'll be replaced.</value>
874
870
  <value>Do it right, not fast. Never skip steps or take shortcuts.</value>
@@ -884,8 +880,6 @@ ALWAYS use the ask tool when you need user input. Never ask questions in plain t
884
880
  <rule>If uncomfortable pushing back, say "Strange things are afoot at the Circle K"</rule>
885
881
  <rule>STOP and ask for clarification rather than making assumptions</rule>
886
882
  <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
883
  </relationship>
890
884
 
891
885
  <proactiveness>
@@ -952,6 +946,15 @@ Just do it - including obvious follow-up actions.
952
946
  </parallelization>
953
947
  </agents>
954
948
 
949
+ <library-research description="For external library/framework questions">
950
+ <tool name="context7">Documentation lookup. Use context7_resolve-library-id then context7_query-docs.</tool>
951
+ <tool name="btca_ask">Source code search. Use for implementation details, internals, debugging.</tool>
952
+ <when-to-use>
953
+ <use tool="context7">API usage, examples, guides - "How do I use X?"</use>
954
+ <use tool="btca_ask">Implementation details - "How does X work internally?"</use>
955
+ </when-to-use>
956
+ </library-research>
957
+
955
958
  <tracking>
956
959
  <rule>Use TodoWrite to track what you're doing</rule>
957
960
  <rule>Never discard tasks without explicit approval</rule>
@@ -967,8 +970,7 @@ var primaryAgent = {
967
970
  budgetTokens: 32000
968
971
  },
969
972
  maxTokens: 64000,
970
- prompt: PROMPT,
971
- tools: { ask: true }
973
+ prompt: PROMPT
972
974
  };
973
975
  var PRIMARY_AGENT_NAME = process.env.OPENCODE_AGENT_NAME || "commander";
974
976
 
@@ -13838,6 +13840,69 @@ ${output}`;
13838
13840
  }
13839
13841
  });
13840
13842
 
13843
+ // src/tools/btca/index.ts
13844
+ var {spawn: spawn2, which: which2 } = globalThis.Bun;
13845
+ async function checkBtcaAvailable() {
13846
+ const btcaPath = which2("btca");
13847
+ if (btcaPath) {
13848
+ return { available: true };
13849
+ }
13850
+ return {
13851
+ available: false,
13852
+ message: `btca CLI not found. Library source code search will not work.
13853
+ ` + `Install from: https://github.com/anthropics/btca
13854
+ ` + " cargo install btca"
13855
+ };
13856
+ }
13857
+ var BTCA_TIMEOUT_MS = 120000;
13858
+ async function runBtca(args) {
13859
+ try {
13860
+ const proc = spawn2(["btca", ...args], {
13861
+ stdout: "pipe",
13862
+ stderr: "pipe"
13863
+ });
13864
+ const timeoutPromise = new Promise((_, reject) => {
13865
+ setTimeout(() => {
13866
+ proc.kill();
13867
+ reject(new Error("btca command timed out after 2 minutes"));
13868
+ }, BTCA_TIMEOUT_MS);
13869
+ });
13870
+ const [stdout, stderr, exitCode] = await Promise.race([
13871
+ Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text(), proc.exited]),
13872
+ timeoutPromise
13873
+ ]);
13874
+ if (exitCode !== 0) {
13875
+ const errorMsg = stderr.trim() || `Exit code ${exitCode}`;
13876
+ return { output: "", error: errorMsg };
13877
+ }
13878
+ return { output: stdout.trim() };
13879
+ } catch (e) {
13880
+ const err = e;
13881
+ if (err.message?.includes("ENOENT")) {
13882
+ return {
13883
+ output: "",
13884
+ error: `btca CLI not found. Install from: https://github.com/anthropics/btca
13885
+ ` + " cargo install btca"
13886
+ };
13887
+ }
13888
+ return { output: "", error: err.message };
13889
+ }
13890
+ }
13891
+ var btca_ask = tool({
13892
+ 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.",
13893
+ args: {
13894
+ tech: tool.schema.string().describe("Resource name configured in btca (e.g., 'react', 'express')"),
13895
+ question: tool.schema.string().describe("Question to ask about the library source code")
13896
+ },
13897
+ execute: async (args) => {
13898
+ const result = await runBtca(["ask", "-t", args.tech, "-q", args.question]);
13899
+ if (result.error) {
13900
+ return `Error: ${result.error}`;
13901
+ }
13902
+ return result.output || "No answer found";
13903
+ }
13904
+ });
13905
+
13841
13906
  // src/tools/look-at.ts
13842
13907
  import { readFileSync, statSync } from "fs";
13843
13908
  import { extname, basename } from "path";
@@ -14862,20 +14927,22 @@ function createTokenAwareTruncationHook(ctx) {
14862
14927
  };
14863
14928
  }
14864
14929
 
14865
- // src/hooks/context-window-monitor.ts
14866
- var WARNING_THRESHOLD = 0.7;
14867
- var CRITICAL_THRESHOLD = 0.85;
14868
- var DEFAULT_CONTEXT_LIMIT2 = 200000;
14930
+ // src/utils/model-limits.ts
14869
14931
  var MODEL_CONTEXT_LIMITS = {
14870
14932
  "claude-opus": 200000,
14871
14933
  "claude-sonnet": 200000,
14872
14934
  "claude-haiku": 200000,
14935
+ "claude-3": 200000,
14936
+ "claude-4": 200000,
14937
+ "gpt-4o": 128000,
14938
+ "gpt-4-turbo": 128000,
14873
14939
  "gpt-4": 128000,
14874
14940
  "gpt-5": 200000,
14875
14941
  o1: 200000,
14876
14942
  o3: 200000,
14877
14943
  gemini: 1e6
14878
14944
  };
14945
+ var DEFAULT_CONTEXT_LIMIT2 = 200000;
14879
14946
  function getContextLimit(modelID) {
14880
14947
  const modelLower = modelID.toLowerCase();
14881
14948
  for (const [pattern, limit] of Object.entries(MODEL_CONTEXT_LIMITS)) {
@@ -14885,6 +14952,10 @@ function getContextLimit(modelID) {
14885
14952
  }
14886
14953
  return DEFAULT_CONTEXT_LIMIT2;
14887
14954
  }
14955
+
14956
+ // src/hooks/context-window-monitor.ts
14957
+ var WARNING_THRESHOLD = 0.7;
14958
+ var CRITICAL_THRESHOLD = 0.85;
14888
14959
  var WARNING_COOLDOWN_MS = 120000;
14889
14960
  function createContextWindowMonitorHook(ctx) {
14890
14961
  const state = {
@@ -15163,33 +15234,9 @@ function createFileOpsTrackerHook(_ctx) {
15163
15234
  }
15164
15235
 
15165
15236
  // 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
15237
  var DEFAULT_THRESHOLD = 0.8;
15182
15238
  var MIN_TOKENS_FOR_CLEAR = 50000;
15183
15239
  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
15240
  function createAutoClearLedgerHook(ctx) {
15194
15241
  const state = {
15195
15242
  lastClearTime: new Map,
@@ -15224,7 +15271,7 @@ function createAutoClearLedgerHook(ctx) {
15224
15271
  if (totalUsed < MIN_TOKENS_FOR_CLEAR)
15225
15272
  return;
15226
15273
  const model = modelID || info?.modelID || "";
15227
- const contextLimit = getContextLimit2(model);
15274
+ const contextLimit = getContextLimit(model);
15228
15275
  const usageRatio = totalUsed / contextLimit;
15229
15276
  if (usageRatio < DEFAULT_THRESHOLD)
15230
15277
  return;
@@ -15923,6 +15970,10 @@ var OpenCodeConfigPlugin = async (ctx) => {
15923
15970
  if (!astGrepStatus.available) {
15924
15971
  console.warn(`[micode] ${astGrepStatus.message}`);
15925
15972
  }
15973
+ const btcaStatus = await checkBtcaAvailable();
15974
+ if (!btcaStatus.available) {
15975
+ console.warn(`[micode] ${btcaStatus.message}`);
15976
+ }
15926
15977
  const userConfig = await loadMicodeConfig();
15927
15978
  if (userConfig?.agents) {
15928
15979
  console.log(`[micode] Loaded model overrides for: ${Object.keys(userConfig.agents).join(", ")}`);
@@ -15944,6 +15995,7 @@ var OpenCodeConfigPlugin = async (ctx) => {
15944
15995
  tool: {
15945
15996
  ast_grep_search,
15946
15997
  ast_grep_replace,
15998
+ btca_ask,
15947
15999
  look_at,
15948
16000
  artifact_search,
15949
16001
  ...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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micode",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
4
4
  "description": "OpenCode plugin with Brainstorm-Research-Plan-Implement workflow",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",