bingocode 1.0.4 → 1.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bingocode",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "claude": "bin/claude-win.cjs",
@@ -36,6 +36,7 @@
36
36
  "auto-bind": "^5.0.1",
37
37
  "axios": "^1.14.0",
38
38
  "bidi-js": "^1.0.3",
39
+ "bingocode": "^1.0.4",
39
40
  "chalk": "^5.6.2",
40
41
  "chokidar": "^5.0.0",
41
42
  "cli-boxes": "^4.0.1",
@@ -93,12 +94,7 @@
93
94
  "zod": "^4.3.6"
94
95
  },
95
96
  "devDependencies": {
96
- "@types/node": "^25.6.0",
97
- "mermaid": "^11.14.0",
98
- "vite-plugin-mock": "^3.0.2",
99
- "vitepress": "^1.6.3",
100
- "vitepress-plugin-mermaid": "^2.0.17",
101
- "vue": "^3.5.13"
97
+ "@types/node": "^25.6.0"
102
98
  },
103
99
  "description": "<p align=\"center\"> <img src=\"docs/images/logo-horizontal.jpg\" alt=\"Claude Code Haha\" width=\"480\"> </p>",
104
100
  "main": "index.js",
@@ -0,0 +1,11 @@
1
+ import type { Command } from '../../commands.js'
2
+
3
+ const releaseNotes: Command = {
4
+ description: 'View release notes',
5
+ name: 'release-notes',
6
+ type: 'local',
7
+ supportsNonInteractive: true,
8
+ load: () => import('./release-notes.js'),
9
+ }
10
+
11
+ export default releaseNotes
@@ -0,0 +1,50 @@
1
+ import type { LocalCommandResult } from '../../types/command.js'
2
+ import {
3
+ CHANGELOG_URL,
4
+ fetchAndStoreChangelog,
5
+ getAllReleaseNotes,
6
+ getStoredChangelog,
7
+ } from '../../utils/releaseNotes.js'
8
+
9
+ function formatReleaseNotes(notes: Array<[string, string[]]>): string {
10
+ return notes
11
+ .map(([version, notes]) => {
12
+ const header = `Version ${version}:`
13
+ const bulletPoints = notes.map(note => `· ${note}`).join('\n')
14
+ return `${header}\n${bulletPoints}`
15
+ })
16
+ .join('\n\n')
17
+ }
18
+
19
+ export async function call(): Promise<LocalCommandResult> {
20
+ // Try to fetch the latest changelog with a 500ms timeout
21
+ let freshNotes: Array<[string, string[]]> = []
22
+
23
+ try {
24
+ const timeoutPromise = new Promise<void>((_, reject) => {
25
+ setTimeout(rej => rej(new Error('Timeout')), 500, reject)
26
+ })
27
+
28
+ await Promise.race([fetchAndStoreChangelog(), timeoutPromise])
29
+ freshNotes = getAllReleaseNotes(await getStoredChangelog())
30
+ } catch {
31
+ // Either fetch failed or timed out - just use cached notes
32
+ }
33
+
34
+ // If we have fresh notes from the quick fetch, use those
35
+ if (freshNotes.length > 0) {
36
+ return { type: 'text', value: formatReleaseNotes(freshNotes) }
37
+ }
38
+
39
+ // Otherwise check cached notes
40
+ const cachedNotes = getAllReleaseNotes(await getStoredChangelog())
41
+ if (cachedNotes.length > 0) {
42
+ return { type: 'text', value: formatReleaseNotes(cachedNotes) }
43
+ }
44
+
45
+ // Nothing available, show link
46
+ return {
47
+ type: 'text',
48
+ value: `See the full changelog at: ${CHANGELOG_URL}`,
49
+ }
50
+ }
@@ -0,0 +1,123 @@
1
+ const args = process.argv.slice(2)
2
+
3
+ function getArg(name: string): string | undefined {
4
+ const index = args.indexOf(name)
5
+ return index >= 0 ? args[index + 1] : undefined
6
+ }
7
+
8
+ function emit(ws: WebSocket, payload: Record<string, unknown>) {
9
+ ws.send(JSON.stringify(payload) + '\n')
10
+ }
11
+
12
+ function extractUserText(message: any): string {
13
+ const content = message?.message?.content
14
+ if (!Array.isArray(content)) return ''
15
+ return content
16
+ .filter((block: any) => block?.type === 'text' && typeof block.text === 'string')
17
+ .map((block: any) => block.text)
18
+ .join(' ')
19
+ }
20
+
21
+ const sdkUrl = getArg('--sdk-url')
22
+ const sessionId = getArg('--session-id') || crypto.randomUUID()
23
+ const initMode = process.env.MOCK_SDK_INIT_MODE || 'on_open'
24
+ let initSent = false
25
+
26
+ if (!sdkUrl) {
27
+ console.error('Missing --sdk-url')
28
+ process.exit(1)
29
+ }
30
+
31
+ const ws = new WebSocket(sdkUrl)
32
+
33
+ function sendInit() {
34
+ if (initSent) return
35
+ initSent = true
36
+ emit(ws, {
37
+ type: 'system',
38
+ subtype: 'init',
39
+ model: 'mock-opus',
40
+ slash_commands: [{ name: 'help', description: 'Show help' }],
41
+ session_id: sessionId,
42
+ })
43
+ }
44
+
45
+ ws.addEventListener('open', () => {
46
+ if (initMode !== 'on_first_user') {
47
+ sendInit()
48
+ }
49
+ })
50
+
51
+ ws.addEventListener('message', (event) => {
52
+ const payload = typeof event.data === 'string' ? event.data : String(event.data)
53
+ const lines = payload.split('\n').map(line => line.trim()).filter(Boolean)
54
+
55
+ for (const line of lines) {
56
+ const parsed = JSON.parse(line)
57
+
58
+ if (parsed.type === 'user') {
59
+ sendInit()
60
+ const text = extractUserText(parsed)
61
+ emit(ws, {
62
+ type: 'stream_event',
63
+ event: { type: 'message_start' },
64
+ session_id: sessionId,
65
+ })
66
+ emit(ws, {
67
+ type: 'stream_event',
68
+ event: {
69
+ type: 'content_block_start',
70
+ index: 0,
71
+ content_block: { type: 'text', text: '' },
72
+ },
73
+ session_id: sessionId,
74
+ })
75
+ emit(ws, {
76
+ type: 'stream_event',
77
+ event: {
78
+ type: 'content_block_delta',
79
+ index: 0,
80
+ delta: { type: 'thinking_delta', thinking: 'Mock thinking...' },
81
+ },
82
+ session_id: sessionId,
83
+ })
84
+ emit(ws, {
85
+ type: 'stream_event',
86
+ event: {
87
+ type: 'content_block_delta',
88
+ index: 0,
89
+ delta: { type: 'text_delta', text: `Echo: ${text}` },
90
+ },
91
+ session_id: sessionId,
92
+ })
93
+ emit(ws, {
94
+ type: 'stream_event',
95
+ event: { type: 'content_block_stop', index: 0 },
96
+ session_id: sessionId,
97
+ })
98
+ emit(ws, {
99
+ type: 'result',
100
+ subtype: 'success',
101
+ is_error: false,
102
+ result: `Echo: ${text}`,
103
+ usage: { input_tokens: 3, output_tokens: 2 },
104
+ session_id: sessionId,
105
+ })
106
+ }
107
+
108
+ if (parsed.type === 'control_request' && parsed.request?.subtype === 'interrupt') {
109
+ emit(ws, {
110
+ type: 'result',
111
+ subtype: 'success',
112
+ is_error: false,
113
+ result: 'Interrupted',
114
+ usage: { input_tokens: 0, output_tokens: 0 },
115
+ session_id: sessionId,
116
+ })
117
+ }
118
+ }
119
+ })
120
+
121
+ ws.addEventListener('close', () => {
122
+ process.exit(0)
123
+ })