nuwaxcode 1.1.27 → 1.1.29

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
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "1.1.27",
3
+ "version": "1.1.29",
4
4
  "name": "nuwaxcode",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -45,7 +45,76 @@
45
45
  "why-is-node-running": "3.2.2",
46
46
  "zod-to-json-schema": "3.24.5"
47
47
  },
48
-
48
+ "dependencies": {
49
+ "@actions/core": "1.11.1",
50
+ "@actions/github": "6.0.1",
51
+ "@agentclientprotocol/sdk": "0.5.1",
52
+ "@ai-sdk/amazon-bedrock": "3.0.73",
53
+ "@ai-sdk/anthropic": "2.0.57",
54
+ "@ai-sdk/azure": "2.0.91",
55
+ "@ai-sdk/cerebras": "1.0.34",
56
+ "@ai-sdk/cohere": "2.0.22",
57
+ "@ai-sdk/deepinfra": "1.0.31",
58
+ "@ai-sdk/gateway": "2.0.25",
59
+ "@ai-sdk/google": "2.0.52",
60
+ "@ai-sdk/google-vertex": "3.0.97",
61
+ "@ai-sdk/groq": "2.0.34",
62
+ "@ai-sdk/mistral": "2.0.27",
63
+ "@ai-sdk/openai": "2.0.89",
64
+ "@ai-sdk/openai-compatible": "1.0.30",
65
+ "@ai-sdk/perplexity": "2.0.23",
66
+ "@ai-sdk/provider": "2.0.1",
67
+ "@ai-sdk/provider-utils": "3.0.20",
68
+ "@ai-sdk/togetherai": "1.0.31",
69
+ "@ai-sdk/vercel": "1.0.31",
70
+ "@ai-sdk/xai": "2.0.51",
71
+ "@clack/prompts": "1.0.0-alpha.1",
72
+ "@gitlab/gitlab-ai-provider": "3.1.2",
73
+ "@hono/standard-validator": "0.1.5",
74
+ "@hono/zod-validator": "catalog:",
75
+ "@modelcontextprotocol/sdk": "1.25.2",
76
+ "@octokit/graphql": "9.0.2",
77
+ "@octokit/rest": "catalog:",
78
+ "@openauthjs/openauth": "catalog:",
79
+ "@openrouter/ai-sdk-provider": "1.5.2",
80
+ "@opentui/core": "0.1.74",
81
+ "@opentui/solid": "0.1.74",
82
+ "@parcel/watcher": "2.5.1",
83
+ "@pierre/diffs": "catalog:",
84
+ "@solid-primitives/event-bus": "1.1.2",
85
+ "@solid-primitives/scheduled": "1.5.2",
86
+ "@standard-schema/spec": "1.0.0",
87
+ "@zip.js/zip.js": "2.7.62",
88
+ "ai": "catalog:",
89
+ "bonjour-service": "1.3.0",
90
+ "bun-pty": "0.4.4",
91
+ "chokidar": "4.0.3",
92
+ "clipboardy": "4.0.0",
93
+ "decimal.js": "10.5.0",
94
+ "diff": "catalog:",
95
+ "fuzzysort": "3.1.0",
96
+ "gray-matter": "4.0.3",
97
+ "hono": "catalog:",
98
+ "hono-openapi": "catalog:",
99
+ "ignore": "7.0.5",
100
+ "jsonc-parser": "3.3.1",
101
+ "minimatch": "10.0.3",
102
+ "open": "10.1.2",
103
+ "opentui-spinner": "0.0.6",
104
+ "partial-json": "0.1.7",
105
+ "remeda": "catalog:",
106
+ "solid-js": "catalog:",
107
+ "strip-ansi": "7.1.2",
108
+ "tree-sitter-bash": "0.25.0",
109
+ "turndown": "7.2.0",
110
+ "ulid": "catalog:",
111
+ "vscode-jsonrpc": "8.2.1",
112
+ "web-tree-sitter": "0.25.10",
113
+ "xdg-basedir": "5.1.0",
114
+ "yargs": "18.0.0",
115
+ "zod": "catalog:",
116
+ "zod-to-json-schema": "3.24.5"
117
+ },
49
118
  "optionalDependencies": {
50
119
  "nuwaxcode-darwin-arm64": "1.1.25",
51
120
  "nuwaxcode-darwin-x64": "1.1.25",
package/script/build.ts CHANGED
@@ -158,7 +158,7 @@ for (const item of targets) {
158
158
  JSON.stringify(
159
159
  {
160
160
  name,
161
- version: "1.1.27",
161
+ version: "1.1.26",
162
162
  os: [item.os],
163
163
  cpu: [item.arch],
164
164
  },
@@ -8,7 +8,7 @@ import { useTheme, tint } from "@tui/context/theme"
8
8
  // ~ = shadow top only (▀ with fg=shadow)
9
9
  const SHADOW_MARKER = /[_^~]/
10
10
 
11
- const LOGO_LEFT = [` `, `█▀▀█ █▀▀█ █▀▀█ █▀▀▄`, `█__█ █__█^^^__█`, `▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀~~▀`]
11
+ const LOGO_LEFT = [` `, `█▀▀▄ █ █ █ █ █▀▀█ ▀▄ ▄▀`, `█ █ █ █▄█▄█ █▄▄█ __ `, `▀ ▀ ▀▀▀▀ ▀ ▀ ▀ ▀ ▀`]
12
12
 
13
13
  const LOGO_RIGHT = [` ▄ `, `█▀▀▀ █▀▀█ █▀▀█ █▀▀█`, `█___ █__█ █__█ █^^^`, `▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀`]
14
14
 
package/src/cli/ui.ts CHANGED
@@ -4,10 +4,10 @@ import { NamedError } from "@opencode-ai/util/error"
4
4
 
5
5
  export namespace UI {
6
6
  const LOGO = [
7
- [`  `, ` ▄ `],
8
- [`█▀▀█ █▀▀█ █▀▀█ █▀▀▄ `, `█▀▀▀ █▀▀█ █▀▀█ █▀▀█`],
9
- [`█░░█ █░░█ █▀▀▀ █░░█ `, `█░░░ █░░█ █░░█ █▀▀▀`],
10
- [`▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀ ▀ `, `▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀`],
7
+ [`  `, ` ▄ `],
8
+ [`█▀▀▄ █ █ █ █ █▀▀█ ▀▄ ▄▀ `, `█▀▀▀ █▀▀█ █▀▀█ █▀▀█`],
9
+ [`█ █ █ █ █ █▄▄█ ░█░ `, `█░░░ █░░█ █░░█ █▀▀▀`],
10
+ [`▀ ▀ ▀▀▀▀ ▀ ▀ ▀ ▀▀ ▀ `, `▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀`],
11
11
  ]
12
12
 
13
13
  export const CancelledError = NamedError.create("UICancelledError", z.void())
@@ -0,0 +1,262 @@
1
+ import { describe, expect, test, beforeEach, mock } from "bun:test"
2
+ import type { AgentSideConnection } from "@agentclientprotocol/sdk"
3
+ import { z } from "zod"
4
+
5
+ // Mock the Log module
6
+ const logEntries: any[] = []
7
+ mock.module("../../src/util/log", () => {
8
+ return {
9
+ Log: {
10
+ create: () => ({
11
+ info: (msg: any, extra: any) => {
12
+ logEntries.push({ level: "INFO", msg, ...extra })
13
+ },
14
+ error: (msg: any, extra: any) => {
15
+ logEntries.push({ level: "ERROR", msg, ...extra })
16
+ },
17
+ debug: () => {},
18
+ warn: () => {},
19
+ time: () => ({ stop: () => {} })
20
+ }),
21
+ Level: z.enum(["DEBUG", "INFO", "WARN", "ERROR"])
22
+ }
23
+ }
24
+ })
25
+
26
+ // Dynamically import ACP after mocking
27
+ const { ACP } = await import("../../src/acp/agent")
28
+
29
+ describe("ACP System Prompt via _meta", () => {
30
+ let acp: import("../../src/acp/agent").ACP.Agent
31
+ let connection: AgentSideConnection
32
+
33
+ beforeEach(async () => {
34
+ // Clear logs
35
+ logEntries.length = 0
36
+
37
+ connection = {
38
+ async sessionUpdate() {},
39
+ async requestPermission() {
40
+ return { outcome: { outcome: "selected", optionId: "once" } } as any
41
+ }
42
+ } as any
43
+
44
+ const config = {
45
+ sdk: {
46
+ sessions: {
47
+ create: async () => ({ id: "test-session" })
48
+ },
49
+ events: {
50
+ subscribe: () => ({ async *[Symbol.asyncIterator]() {} })
51
+ }
52
+ } as any
53
+ }
54
+
55
+ acp = new ACP.Agent(connection, config)
56
+ })
57
+
58
+ test("should extract systemPrompt from _meta during session creation", async () => {
59
+ const customSystemPrompt = "你是 Nuwaxcode,一个强大的 AI 编程助手。请在回答前仔细思考..."
60
+
61
+ // Mock the session manager to capture the system prompt
62
+ let capturedSystemPrompt: string | { append: string } | undefined
63
+ acp["sessionManager"].create = async (cwd, mcpServers, model, systemPrompt) => {
64
+ capturedSystemPrompt = systemPrompt
65
+ return {
66
+ id: "test-session",
67
+ cwd,
68
+ mcpServers,
69
+ createdAt: new Date(),
70
+ model,
71
+ systemPrompt
72
+ }
73
+ }
74
+
75
+ // Mock loadSessionMode
76
+ acp["loadSessionMode"] = async () => ({
77
+ models: [{ providerID: "test", modelID: "test" }] as any,
78
+ modes: { availableModes: [], currentModeId: "default" },
79
+ sessionId: "test-session",
80
+ _meta: {}
81
+ })
82
+
83
+ const mockConfig = {
84
+ defaultModel: { providerID: "test", modelID: "test" },
85
+ sdk: acp["config"].sdk
86
+ }
87
+ acp["config"] = mockConfig as any
88
+
89
+ const params = {
90
+ cwd: "/test/directory",
91
+ mcpServers: [],
92
+ _meta: {
93
+ systemPrompt: customSystemPrompt
94
+ }
95
+ }
96
+
97
+ await acp.newSession(params as any)
98
+
99
+ expect(capturedSystemPrompt).toBe(customSystemPrompt)
100
+ })
101
+
102
+ test("should handle append-style system prompt", async () => {
103
+ const appendPrompt = { append: "请始终用中文回答问题。" }
104
+
105
+ let capturedSystemPrompt: string | { append: string } | undefined
106
+ acp["sessionManager"].create = async (cwd, mcpServers, model, systemPrompt) => {
107
+ capturedSystemPrompt = systemPrompt
108
+ return {
109
+ id: "test-session",
110
+ cwd,
111
+ mcpServers,
112
+ createdAt: new Date(),
113
+ model,
114
+ systemPrompt
115
+ }
116
+ }
117
+
118
+ acp["loadSessionMode"] = async () => ({
119
+ models: [{ providerID: "test", modelID: "test" }] as any,
120
+ modes: { availableModes: [], currentModeId: "default" },
121
+ sessionId: "test-session",
122
+ _meta: {}
123
+ })
124
+
125
+ const mockConfig = {
126
+ defaultModel: { providerID: "test", modelID: "test" },
127
+ sdk: acp["config"].sdk
128
+ }
129
+ acp["config"] = mockConfig as any
130
+
131
+ const params = {
132
+ cwd: "/test/directory",
133
+ mcpServers: [],
134
+ _meta: {
135
+ systemPrompt: appendPrompt
136
+ }
137
+ }
138
+
139
+ await acp.newSession(params as any)
140
+
141
+ expect(capturedSystemPrompt).toEqual(appendPrompt)
142
+ })
143
+
144
+ test("should work without _meta systemPrompt", async () => {
145
+ let capturedSystemPrompt: string | { append: string } | undefined
146
+ acp["sessionManager"].create = async (cwd, mcpServers, model, systemPrompt) => {
147
+ capturedSystemPrompt = systemPrompt
148
+ return {
149
+ id: "test-session",
150
+ cwd,
151
+ mcpServers,
152
+ createdAt: new Date(),
153
+ model,
154
+ systemPrompt
155
+ }
156
+ }
157
+
158
+ acp["loadSessionMode"] = async () => ({
159
+ models: [{ providerID: "test", modelID: "test" }] as any,
160
+ modes: { availableModes: [], currentModeId: "default" },
161
+ sessionId: "test-session",
162
+ _meta: {}
163
+ })
164
+
165
+ const mockConfig = {
166
+ defaultModel: { providerID: "test", modelID: "test" },
167
+ sdk: acp["config"].sdk
168
+ }
169
+ acp["config"] = mockConfig as any
170
+
171
+ const params = {
172
+ cwd: "/test/directory",
173
+ mcpServers: []
174
+ // No _meta
175
+ }
176
+
177
+ await acp.newSession(params as any)
178
+
179
+ expect(capturedSystemPrompt).toBeUndefined()
180
+ })
181
+
182
+ test("should work with empty _meta", async () => {
183
+ let capturedSystemPrompt: string | { append: string } | undefined
184
+ acp["sessionManager"].create = async (cwd, mcpServers, model, systemPrompt) => {
185
+ capturedSystemPrompt = systemPrompt
186
+ return {
187
+ id: "test-session",
188
+ cwd,
189
+ mcpServers,
190
+ createdAt: new Date(),
191
+ model,
192
+ systemPrompt
193
+ }
194
+ }
195
+
196
+ acp["loadSessionMode"] = async () => ({
197
+ models: [{ providerID: "test", modelID: "test" }] as any,
198
+ modes: { availableModes: [], currentModeId: "default" },
199
+ sessionId: "test-session",
200
+ _meta: {}
201
+ })
202
+
203
+ const mockConfig = {
204
+ defaultModel: { providerID: "test", modelID: "test" },
205
+ sdk: acp["config"].sdk
206
+ }
207
+ acp["config"] = mockConfig as any
208
+
209
+ const params = {
210
+ cwd: "/test/directory",
211
+ mcpServers: [],
212
+ _meta: {}
213
+ }
214
+
215
+ await acp.newSession(params as any)
216
+
217
+ expect(capturedSystemPrompt).toBeUndefined()
218
+ })
219
+
220
+ test("should log when systemPrompt is provided", async () => {
221
+ const customSystemPrompt = "Test system prompt"
222
+
223
+ acp["sessionManager"].create = async (cwd, mcpServers, model, systemPrompt) => {
224
+ return {
225
+ id: "test-session",
226
+ cwd,
227
+ mcpServers,
228
+ createdAt: new Date(),
229
+ model,
230
+ systemPrompt
231
+ }
232
+ }
233
+
234
+ acp["loadSessionMode"] = async () => ({
235
+ models: [{ providerID: "test", modelID: "test" }] as any,
236
+ modes: { availableModes: [], currentModeId: "default" },
237
+ sessionId: "test-session",
238
+ _meta: {}
239
+ })
240
+
241
+ const mockConfig = {
242
+ defaultModel: { providerID: "test", modelID: "test" },
243
+ sdk: acp["config"].sdk
244
+ }
245
+ acp["config"] = mockConfig as any
246
+
247
+ const params = {
248
+ cwd: "/test/directory",
249
+ mcpServers: [],
250
+ _meta: {
251
+ systemPrompt: customSystemPrompt
252
+ }
253
+ }
254
+
255
+ await acp.newSession(params as any)
256
+
257
+ const hasSystemPromptLog = logEntries.some(entry =>
258
+ entry.hasSystemPrompt === true && entry.level === "INFO"
259
+ )
260
+ expect(hasSystemPromptLog).toBe(true)
261
+ })
262
+ })