bingocode 1.1.122 → 1.1.124

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.
@@ -0,0 +1,13 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(node:*)",
5
+ "WebSearch",
6
+ "Bash(curl -s \"https://docs.anthropic.com/en/api/messages\" --max-time 30 -A \"Mozilla/5.0\")",
7
+ "Bash(curl -s \"https://docs.anthropic.com/en/api/messages-streaming\" --max-time 30 -A \"Mozilla/5.0\")",
8
+ "Bash(curl -sv \"https://docs.anthropic.com/en/api/messages\" --max-time 30)",
9
+ "Bash(curl -sv \"https://raw.githubusercontent.com/anthropics/anthropic-sdk-python/main/api.md\" --max-time 30)",
10
+ "Bash(curl -s \"https://raw.githubusercontent.com/anthropics/anthropic-sdk-python/refs/heads/main/README.md\" --max-time 30)"
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: leanchy
3
+ description: Activate the Leanchy protocol: execution discipline, diagnostic rigor, decision hygiene, and architecture principles.
4
+ ---
5
+
6
+ # Leanchy Protocol
7
+
8
+ ## Execution
9
+ - Confirm the Definition of Done before starting. Lead with conclusions; append reasoning only if asked.
10
+ - No filler, no transition sentences, no restatement of what was just said.
11
+
12
+ ## Diagnosis
13
+ - No evidence → no change. The error site is not the fault site; trace to the control-flow root.
14
+ - Three failed fixes at the same logic point: stop, switch to forensic mode (add instrumentation, collect evidence).
15
+
16
+ ## Decisions
17
+ - When in doubt, explore the codebase or logs first. Don't ask what the code can answer.
18
+ - Always attach a recommendation with rationale when presenting options. No uncommitted lists.
19
+
20
+ ## Architecture
21
+ - Two duplications → abstract. Search the full codebase before modifying; reuse over reinvention.
22
+ - Module boundaries require explicit contracts. Semantic naming is the documentation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bingocode",
3
- "version": "1.1.122",
3
+ "version": "1.1.124",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "claude": "bin/claude-win.cjs",
@@ -14,7 +14,8 @@
14
14
  "bingocode": "bun run ./bin/bingocode-win.cjs",
15
15
  "docs:dev": "vitepress dev docs",
16
16
  "docs:build": "vitepress build docs",
17
- "docs:preview": "vitepress preview docs"
17
+ "docs:preview": "vitepress preview docs",
18
+ "postinstall": "node scripts/install-skills.cjs"
18
19
  },
19
20
  "files": [
20
21
  "bin/",
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * postinstall: copy bundled skills from .claude/skills/ → ~/.claude/skills/
4
+ *
5
+ * Rules:
6
+ * - Skips any skill directory that already exists (never overwrites user edits).
7
+ * - Silently exits in CI / headless environments where $HOME is unset.
8
+ * - CJS so it runs on any Node version without flags or transpilation.
9
+ */
10
+
11
+ 'use strict'
12
+
13
+ const fs = require('node:fs')
14
+ const path = require('node:path')
15
+ const os = require('node:os')
16
+
17
+ const home = os.homedir()
18
+ if (!home) process.exit(0)
19
+
20
+ const pkgRoot = path.resolve(__dirname, '..')
21
+ const srcSkillsDir = path.join(pkgRoot, '.claude', 'skills')
22
+ const dstSkillsDir = path.join(
23
+ process.env.CLAUDE_CONFIG_DIR || path.join(home, '.claude'),
24
+ 'skills',
25
+ )
26
+
27
+ if (!fs.existsSync(srcSkillsDir)) process.exit(0)
28
+
29
+ const skills = fs.readdirSync(srcSkillsDir, { withFileTypes: true })
30
+ .filter(e => e.isDirectory())
31
+ .map(e => e.name)
32
+
33
+ for (const skill of skills) {
34
+ const dst = path.join(dstSkillsDir, skill)
35
+ if (fs.existsSync(dst)) continue // respect existing user version
36
+
37
+ try {
38
+ fs.mkdirSync(dst, { recursive: true })
39
+ const src = path.join(srcSkillsDir, skill)
40
+ for (const file of fs.readdirSync(src)) {
41
+ fs.copyFileSync(path.join(src, file), path.join(dst, file))
42
+ }
43
+ console.log(`[bingocode] installed skill: ${skill}`)
44
+ } catch (err) {
45
+ // Non-fatal: log and continue
46
+ console.warn(`[bingocode] could not install skill ${skill}: ${err.message}`)
47
+ }
48
+ }
@@ -58,6 +58,12 @@ export function anthropicToOpenaiChat(body: AnthropicRequest): OpenAIChatRequest
58
58
  if (body.temperature !== undefined) result.temperature = body.temperature
59
59
  if (body.top_p !== undefined) result.top_p = body.top_p
60
60
 
61
+ // frequency_penalty: suppress repetition loops during multi-tool-call sequences.
62
+ // Anthropic API has no equivalent; inject for all OpenAI-compatible upstreams.
63
+ // Configurable via BINGO_FREQUENCY_PENALTY (default 0.1).
64
+ const fp = parseFloat(process.env.BINGO_FREQUENCY_PENALTY ?? '0.1')
65
+ if (!isNaN(fp) && fp !== 0) result.frequency_penalty = fp
66
+
61
67
  // stop_sequences → stop
62
68
  if (body.stop_sequences && body.stop_sequences.length > 0) {
63
69
  result.stop = body.stop_sequences
@@ -131,11 +137,14 @@ function convertUserMessage(blocks: AnthropicContentBlock[], output: OpenAIChatM
131
137
  contentParts.push({ type: 'image_url', image_url: { url } })
132
138
  } else if (block.type === 'tool_result') {
133
139
  // tool_result → separate tool message
134
- const resultContent = typeof block.content === 'string'
140
+ const rawContent = typeof block.content === 'string'
135
141
  ? block.content
136
142
  : Array.isArray(block.content)
137
143
  ? block.content.filter((b): b is Extract<AnthropicContentBlock, { type: 'text' }> => b.type === 'text').map((b) => b.text).join('\n')
138
144
  : ''
145
+ const resultContent = block.is_error
146
+ ? `<error>${rawContent}</error>`
147
+ : rawContent
139
148
  output.push({
140
149
  role: 'tool',
141
150
  tool_call_id: block.tool_use_id,
@@ -47,6 +47,12 @@ export function anthropicToOpenaiResponses(body: AnthropicRequest): OpenAIRespon
47
47
  if (body.temperature !== undefined) result.temperature = body.temperature
48
48
  if (body.top_p !== undefined) result.top_p = body.top_p
49
49
 
50
+ // frequency_penalty: suppress repetition loops during multi-tool-call sequences.
51
+ // Anthropic API has no equivalent; inject for all OpenAI-compatible upstreams.
52
+ // Configurable via BINGO_FREQUENCY_PENALTY (default 0.1).
53
+ const fp = parseFloat(process.env.BINGO_FREQUENCY_PENALTY ?? '0.1')
54
+ if (!isNaN(fp) && fp !== 0) result.frequency_penalty = fp
55
+
50
56
  // tools
51
57
  if (body.tools && body.tools.length > 0) {
52
58
  result.tools = body.tools
@@ -128,11 +134,14 @@ function convertMessageToInputItems(msg: AnthropicMessage, output: OpenAIRespons
128
134
  })
129
135
  } else if (block.type === 'tool_result') {
130
136
  // Lift to function_call_output item
131
- const resultContent = typeof block.content === 'string'
137
+ const rawContent = typeof block.content === 'string'
132
138
  ? block.content
133
139
  : Array.isArray(block.content)
134
140
  ? block.content.filter((b): b is Extract<AnthropicContentBlock, { type: 'text' }> => b.type === 'text').map((b) => b.text).join('\n')
135
141
  : ''
142
+ const resultContent = block.is_error
143
+ ? `<error>${rawContent}</error>`
144
+ : rawContent
136
145
  output.push({
137
146
  type: 'function_call_output',
138
147
  call_id: block.tool_use_id,
@@ -43,6 +43,7 @@ export type OpenAIChatRequest = {
43
43
  max_completion_tokens?: number
44
44
  temperature?: number
45
45
  top_p?: number
46
+ frequency_penalty?: number
46
47
  stop?: string | string[]
47
48
  stream?: boolean
48
49
  tools?: OpenAITool[]
@@ -113,6 +114,7 @@ export type OpenAIResponsesRequest = {
113
114
  max_output_tokens?: number
114
115
  temperature?: number
115
116
  top_p?: number
117
+ frequency_penalty?: number
116
118
  stream?: boolean
117
119
  tools?: OpenAITool[]
118
120
  tool_choice?: unknown
@@ -1,48 +0,0 @@
1
- ---
2
- name: claude-native-adapter
3
- description: 核心协议适配器,强制 LLM 模仿 Claude Code 的原生输出结构、工具调用逻辑和极致简练的沟通风格。
4
- user-invocable: true
5
- ---
6
-
7
- # Claude Native Protocol v7.0 (Core Adapter)
8
-
9
- 当你(LLM)作为 Claude Code 的引擎运行时,必须严格遵守以下协议。这不仅是风格问题,更是确保工具调用(Tool Use)成功的技术要求。
10
-
11
- ## 1. 响应结构 (The Structure)
12
-
13
- **严禁**任何开场白(如 "Sure", "I can help with that")或结尾总结。你的输出应直接进入分析或行动。
14
-
15
- **标准的输出流程:**
16
- 1. `<thought>`: 内部推理。分析用户意图,规划工具链调用。
17
- 2. `[Tool Calls]`: 发送工具调用命令。
18
- 3. `[Text Response]`: 仅在工具执行完毕、报错或需要询问用户时,输出极简的文字。
19
-
20
- ## 2. 工具调用规范 (Tool Execution)
21
-
22
- - **原子性**:除非任务是并行的,否则优先按逻辑顺序执行工具。
23
- - **参数精度**:
24
- - `Read`: 总是先 Read 再 Edit。
25
- - `Edit`: `old_string` 必须从最近的 `Read` 输出中**完全一致(包括空格、制表符、换行符)**地复制。不要自作聪明修复缩进。
26
- - `Bash`: 涉及路径时务必使用双引号。
27
-
28
- ## 3. 极简主义风格 (Terse Style)
29
-
30
- - **严禁废话**:不要解释你为什么要调用这个工具,除非步骤极其复杂且不直观。
31
- - **引用格式**:提及代码时,始终使用 `file_path:line_number` 格式。
32
- - **状态报告**:如果工具成功且结果直观,不要重复描述结果。
33
-
34
- ## 4. 容错逻辑 (Error Handling)
35
-
36
- - 如果 `Edit` 报错 `old_string` 未找到:
37
- 1. 立即重新 `Read` 该文件。
38
- 2. 对比最新的内容,检查是否有其他进程或之前的工具调用改变了代码。
39
- 3. 重新提取 `old_string`。
40
- - 不要尝试多次重复完全相同的失败命令。
41
-
42
- ## 5. 任务管理 (Task Management)
43
-
44
- - 对于多步骤任务,必须优先调用 `TaskCreate` 创建任务清单。
45
- - 每完成一个关键步骤,立即 `TaskUpdate` 标记 `completed`。这样可以帮助你自己(LLM)维持长程上下文。
46
-
47
- ---
48
- *此协议由 Claude Code 强制执行。一旦激活,你必须表现得像是一个直接嵌入在终端中的高效编译器,而非聊天机器人。*