dskcode 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -19,6 +19,7 @@
19
19
  - **权限控制** — 三级审批策略(Allow / Ask / Deny),安全可控
20
20
  - **TOML 配置** — 多层级配置(全局 + 项目 + 环境变量 + CLI flag)
21
21
  - **中文优先** — 界面提示、帮助信息、文档均为中文
22
+ - **内置小游戏** — `dskcode game` 启动游戏列表,打砖块等内置游戏供休闲娱乐
22
23
 
23
24
  ## 快速开始
24
25
 
@@ -48,6 +49,7 @@ npx dskcode chat
48
49
  | `dskcode run <prompt>` | 执行一次性任务(如"修改所有 TODO") |
49
50
  | `dskcode setup` | 运行配置向导,设置 API Key 等 |
50
51
  | `dskcode init` | 在当前项目生成 AGENTS.md 项目记忆文件 |
52
+ | `dskcode game <name>` | 启动内置小游戏,不指定名称则显示交互式游戏列表 |
51
53
  | `dskcode completion` | 生成 shell 自动补全配置 |
52
54
 
53
55
  ### 全局选项
@@ -104,9 +106,8 @@ src/
104
106
  ## 开发
105
107
 
106
108
  ```bash
107
- # 克隆仓库
108
- git clone https://github.com/esengine/DeepSeek-Reasonix.git
109
- cd ts-version
109
+ # 克隆仓库(clone 后直接安装即可)
110
+ git clone https://github.com/Awu12277/deepseek-agent-cli.git
110
111
 
111
112
  # 安装依赖
112
113
  npm install
package/dist/index.js CHANGED
@@ -214,9 +214,870 @@ function ChatSession({ providerCount, toolCount, verbose }) {
214
214
  ] });
215
215
  }
216
216
 
217
+ // src/ui/GamePicker.tsx
218
+ import { Box as Box4, Text as Text5, useInput } from "ink";
219
+ import { useState as useState3, useCallback as useCallback2 } from "react";
220
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
221
+ function GamePicker({ games, onSelect, onExit }) {
222
+ const [selectedIndex, setSelectedIndex] = useState3(0);
223
+ useInput(
224
+ useCallback2(
225
+ (input, key) => {
226
+ if (games.length === 0) return;
227
+ if (key.upArrow || input === "k") {
228
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : games.length - 1);
229
+ } else if (key.downArrow || input === "j") {
230
+ setSelectedIndex((prev) => prev < games.length - 1 ? prev + 1 : 0);
231
+ } else if (key.return) {
232
+ const game = games[selectedIndex];
233
+ if (game) onSelect(game);
234
+ } else if (key.escape || input === "q") {
235
+ onExit();
236
+ }
237
+ },
238
+ [games, selectedIndex, onSelect, onExit]
239
+ )
240
+ );
241
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
242
+ /* @__PURE__ */ jsx4(Box4, { marginBottom: 1, children: /* @__PURE__ */ jsx4(Text5, { bold: true, color: "#00ffff", children: "\u{1F3AE} \u6E38\u620F\u5217\u8868" }) }),
243
+ /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: games.map((game, index) => {
244
+ const isSelected = index === selectedIndex;
245
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
246
+ /* @__PURE__ */ jsx4(Box4, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx4(Text5, { bold: true, color: "#00ff41", children: "\u25B8 " }) : /* @__PURE__ */ jsx4(Text5, { children: " " }) }),
247
+ /* @__PURE__ */ jsx4(Box4, { width: 20, flexShrink: 0, children: /* @__PURE__ */ jsx4(Text5, { bold: true, color: isSelected ? "#00ff41" : "#ffffff", children: game.name }) }),
248
+ /* @__PURE__ */ jsx4(Box4, { children: /* @__PURE__ */ jsx4(Text5, { color: "#888888", children: game.description }) })
249
+ ] }, game.id);
250
+ }) }),
251
+ /* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx4(Text5, { dimColor: true, children: " \u2191/\u2193 \u9009\u62E9 Enter \u542F\u52A8 q \u8FD4\u56DE" }) })
252
+ ] });
253
+ }
254
+
255
+ // src/game/index.ts
256
+ var registry = /* @__PURE__ */ new Map();
257
+ function registerGame(game) {
258
+ registry.set(game.id, game);
259
+ }
260
+ function getGame(id) {
261
+ return registry.get(id);
262
+ }
263
+ function listGames() {
264
+ return Array.from(registry.values());
265
+ }
266
+
267
+ // src/game/brick-breaker/index.tsx
268
+ import { Box as Box5, Text as Text6, useInput as useInput2, render as render2 } from "ink";
269
+ import { useState as useState4, useEffect as useEffect3, useRef, useCallback as useCallback3 } from "react";
270
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
271
+ var GAME_WIDTH = 40;
272
+ var GAME_HEIGHT = 18;
273
+ var PADDLE_WIDTH = 9;
274
+ var BRICK_COLORS = [166, 214, 76, 69];
275
+ var LEVELS = [
276
+ { rows: 4, cols: 8, bw: 3, desc: "\u7ECF\u5178 4\xD78", pattern: () => true },
277
+ { rows: 3, cols: 8, bw: 3, desc: "\u8F7B\u677E 3 \u5C42", pattern: () => true },
278
+ { rows: 6, cols: 8, bw: 3, desc: "\u539A\u5899 6 \u5C42", pattern: () => true },
279
+ { rows: 4, cols: 8, bw: 3, desc: "\u68CB\u76D8\u683C", pattern: (c, r) => (c + r) % 2 === 0 },
280
+ { rows: 4, cols: 8, bw: 3, desc: "\u91D1\u5B57\u5854", pattern: (c, r, _, tc) => c >= r && c < tc - r },
281
+ { rows: 4, cols: 8, bw: 3, desc: "\u4EA4\u9519\u6392\u5217", pattern: (c, r) => r % 2 === 0 || c >= 1 && c <= 6 },
282
+ { rows: 4, cols: 8, bw: 3, desc: "\u4E2D\u7A7A\u8FB9\u6846", pattern: (c, r, tr, tc) => r === 0 || r === tr - 1 || c === 0 || c === tc - 1 },
283
+ { rows: 4, cols: 10, bw: 2, desc: "\u5BC6\u96C6 10 \u5217", pattern: () => true },
284
+ { rows: 7, cols: 8, bw: 3, desc: "\u9AD8\u5899 7 \u5C42", pattern: () => true },
285
+ { rows: 8, cols: 8, bw: 3, desc: "\u6EE1\u5C4F 8 \u5C42", pattern: () => true }
286
+ ];
287
+ function getLevel(level) {
288
+ return LEVELS[(level - 1) % LEVELS.length];
289
+ }
290
+ function createBricks(level) {
291
+ const def = getLevel(level);
292
+ const bricks = [];
293
+ const gap = 2;
294
+ const totalW = def.cols * def.bw + (def.cols - 1) * gap;
295
+ const startX = Math.floor((GAME_WIDTH - totalW) / 2);
296
+ const step = def.bw + gap;
297
+ for (let row = 0; row < def.rows; row++) {
298
+ for (let col = 0; col < def.cols; col++) {
299
+ if (def.pattern(col, row, def.rows, def.cols)) {
300
+ bricks.push({
301
+ x: startX + col * step,
302
+ y: 2 + row * 2,
303
+ w: def.bw,
304
+ alive: true
305
+ });
306
+ }
307
+ }
308
+ }
309
+ return bricks;
310
+ }
311
+ function createInitialState(level) {
312
+ const def = getLevel(level);
313
+ const totalW = def.cols * def.bw + (def.cols - 1) * 2;
314
+ const startX = Math.floor((GAME_WIDTH - totalW) / 2);
315
+ return {
316
+ level,
317
+ bricks: createBricks(level),
318
+ paddleX: Math.floor(GAME_WIDTH / 2) - Math.floor(PADDLE_WIDTH / 2),
319
+ ball: { x: GAME_WIDTH / 2, y: GAME_HEIGHT - 3 },
320
+ ballDir: { x: 1, y: -1 },
321
+ score: 0,
322
+ lives: 3,
323
+ gameOver: false,
324
+ win: false,
325
+ paused: false
326
+ };
327
+ }
328
+ function update(state) {
329
+ if (state.paused || state.gameOver || state.win) return;
330
+ state.ball.x += state.ballDir.x;
331
+ state.ball.y += state.ballDir.y;
332
+ if (state.ball.x <= 0) {
333
+ state.ball.x = 0;
334
+ state.ballDir.x = 1;
335
+ }
336
+ if (state.ball.x >= GAME_WIDTH - 1) {
337
+ state.ball.x = GAME_WIDTH - 1;
338
+ state.ballDir.x = -1;
339
+ }
340
+ if (state.ball.y <= 0) {
341
+ state.ball.y = 0;
342
+ state.ballDir.y = 1;
343
+ }
344
+ if (state.ball.y === GAME_HEIGHT - 1 && state.ball.x >= state.paddleX && state.ball.x <= state.paddleX + PADDLE_WIDTH) {
345
+ state.ballDir.y = -1;
346
+ const hitPos = (state.ball.x - state.paddleX) / PADDLE_WIDTH;
347
+ state.ballDir.x = hitPos < 0.5 ? -1 : 1;
348
+ }
349
+ if (state.ball.y > GAME_HEIGHT) {
350
+ state.lives--;
351
+ if (state.lives <= 0) {
352
+ state.gameOver = true;
353
+ } else {
354
+ state.ball = { x: GAME_WIDTH / 2, y: GAME_HEIGHT - 3 };
355
+ state.ballDir = { x: 1, y: -1 };
356
+ state.paddleX = Math.floor(GAME_WIDTH / 2) - Math.floor(PADDLE_WIDTH / 2);
357
+ }
358
+ }
359
+ const hitBrick = state.bricks.find((b) => {
360
+ if (!b.alive) return false;
361
+ return state.ball.x >= b.x && state.ball.x < b.x + b.w && state.ball.y >= b.y && state.ball.y < b.y + 1;
362
+ });
363
+ if (hitBrick) {
364
+ hitBrick.alive = false;
365
+ state.score += 10;
366
+ state.ballDir.y = -state.ballDir.y;
367
+ }
368
+ if (state.bricks.every((b) => !b.alive)) state.win = true;
369
+ }
370
+ function buildBoard(state) {
371
+ const lines = [];
372
+ function brickColorIndex(x, y) {
373
+ const row = Math.floor((y - 2) / 2);
374
+ if (row >= 0) {
375
+ const b = state.bricks.find((br) => br.y === y && br.alive && x >= br.x && x < br.x + br.w);
376
+ if (b) return row % BRICK_COLORS.length;
377
+ }
378
+ return void 0;
379
+ }
380
+ for (let y = 0; y < GAME_HEIGHT; y++) {
381
+ let line = "";
382
+ for (let x = 0; x < GAME_WIDTH; x++) {
383
+ const isBall = state.ball.x === x && state.ball.y === y;
384
+ const isPaddle = y === GAME_HEIGHT - 1 && x >= state.paddleX && x < state.paddleX + PADDLE_WIDTH;
385
+ const brickRow = brickColorIndex(x, y);
386
+ if (isBall) {
387
+ line += "\x1B[97m\u25CF\x1B[0m";
388
+ } else if (isPaddle) {
389
+ line += "\x1B[94m\u2584\x1B[0m";
390
+ } else if (brickRow !== void 0) {
391
+ line += `\x1B[38;5;${BRICK_COLORS[brickRow]}m\u2580\x1B[0m`;
392
+ } else {
393
+ line += " ";
394
+ }
395
+ }
396
+ lines.push(line);
397
+ }
398
+ return lines.map((l) => `\u2502${l}\u2502`).join("\n");
399
+ }
400
+ function BrickBreakerGame({ onExit: _onExit }) {
401
+ const [initialLevel, setInitialLevel] = useState4(1);
402
+ const [selectingLevel, setSelectingLevel] = useState4(true);
403
+ const stateRef = useRef(createInitialState(initialLevel));
404
+ const [tick, setTick] = useState4(0);
405
+ const onExitRef = useRef(_onExit);
406
+ onExitRef.current = _onExit;
407
+ useEffect3(() => {
408
+ if (selectingLevel) return;
409
+ const interval = setInterval(() => {
410
+ update(stateRef.current);
411
+ setTick((t) => t + 1);
412
+ }, 80);
413
+ return () => clearInterval(interval);
414
+ }, [selectingLevel]);
415
+ const restart = useCallback3((level) => {
416
+ const lv = level ?? stateRef.current.level;
417
+ stateRef.current = createInitialState(lv);
418
+ setInitialLevel(lv);
419
+ setSelectingLevel(false);
420
+ setTick(0);
421
+ }, []);
422
+ const startLevelSelect = useCallback3(() => {
423
+ setSelectingLevel(true);
424
+ }, []);
425
+ useInput2(
426
+ useCallback3((input, key) => {
427
+ const s2 = stateRef.current;
428
+ if (selectingLevel) {
429
+ if (input >= "1" && input <= "9") {
430
+ restart(Number(input));
431
+ } else if (input === "0") {
432
+ restart(10);
433
+ } else if (key.escape || input === "q") {
434
+ onExitRef.current();
435
+ }
436
+ return;
437
+ }
438
+ if (key.leftArrow) {
439
+ s2.paddleX = Math.max(0, s2.paddleX - 1);
440
+ setTick((t) => t + 1);
441
+ } else if (key.rightArrow) {
442
+ s2.paddleX = Math.min(GAME_WIDTH - PADDLE_WIDTH, s2.paddleX + 1);
443
+ setTick((t) => t + 1);
444
+ } else if (input === "p" || input === " ") {
445
+ s2.paused = !s2.paused;
446
+ } else if (input === "r") {
447
+ if (s2.gameOver || s2.win) restart();
448
+ } else if (input === "l") {
449
+ if (s2.gameOver || s2.win) startLevelSelect();
450
+ } else if (input === "q" || key.escape) {
451
+ onExitRef.current();
452
+ }
453
+ }, [selectingLevel, restart, startLevelSelect])
454
+ );
455
+ const s = stateRef.current;
456
+ const aliveCount = s.bricks.filter((b) => b.alive).length;
457
+ const board = buildBoard(s);
458
+ const def = getLevel(s.level);
459
+ void tick;
460
+ return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
461
+ /* @__PURE__ */ jsxs5(Box5, { flexDirection: "row", children: [
462
+ /* @__PURE__ */ jsx5(Box5, { width: 20, children: /* @__PURE__ */ jsxs5(Text6, { children: [
463
+ "\u5173\u5361 ",
464
+ s.level,
465
+ ": ",
466
+ /* @__PURE__ */ jsx5(Text6, { color: "cyan", children: def.desc })
467
+ ] }) }),
468
+ /* @__PURE__ */ jsx5(Box5, { width: 12, children: /* @__PURE__ */ jsxs5(Text6, { children: [
469
+ "\u5206\u6570: ",
470
+ /* @__PURE__ */ jsx5(Text6, { color: "yellow", children: String(s.score).padStart(3, "0") })
471
+ ] }) }),
472
+ /* @__PURE__ */ jsx5(Box5, { width: 12, children: /* @__PURE__ */ jsxs5(Text6, { children: [
473
+ "\u751F\u547D: ",
474
+ /* @__PURE__ */ jsx5(Text6, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) })
475
+ ] }) }),
476
+ /* @__PURE__ */ jsx5(Box5, { width: 10, children: /* @__PURE__ */ jsxs5(Text6, { children: [
477
+ "\u7816\u5757: ",
478
+ /* @__PURE__ */ jsx5(Text6, { color: "cyan", children: aliveCount })
479
+ ] }) }),
480
+ /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsxs5(Text6, { color: s.paused ? "gray" : "green", children: [
481
+ "[",
482
+ s.paused ? "\u6682\u505C" : "\u8FD0\u884C\u4E2D",
483
+ "]"
484
+ ] }) })
485
+ ] }),
486
+ /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
487
+ /* @__PURE__ */ jsxs5(Text6, { children: [
488
+ "\u250C",
489
+ "\u2500".repeat(GAME_WIDTH),
490
+ "\u2510"
491
+ ] }),
492
+ /* @__PURE__ */ jsx5(Text6, { children: selectingLevel ? " \x1B[90m\u9009\u62E9\u5173\u5361\u540E\u5F00\u59CB...\x1B[0m" : board }),
493
+ /* @__PURE__ */ jsxs5(Text6, { children: [
494
+ "\u2514",
495
+ "\u2500".repeat(GAME_WIDTH),
496
+ "\u2518"
497
+ ] })
498
+ ] }),
499
+ selectingLevel && /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, flexDirection: "column", children: [
500
+ /* @__PURE__ */ jsx5(Text6, { bold: true, color: "yellow", children: "\u9009\u62E9\u5173\u5361" }),
501
+ /* @__PURE__ */ jsx5(Box5, { flexDirection: "row", flexWrap: "wrap", children: LEVELS.map((lv, i) => /* @__PURE__ */ jsx5(Box5, { width: 22, children: /* @__PURE__ */ jsxs5(Text6, { children: [
502
+ /* @__PURE__ */ jsx5(Text6, { color: initialLevel === i + 1 ? "green" : "white", children: i + 1 === 10 ? "0" : String(i + 1) }),
503
+ ". ",
504
+ lv.desc,
505
+ " (",
506
+ lv.rows,
507
+ "\xD7",
508
+ lv.cols,
509
+ ")"
510
+ ] }) }, i)) }),
511
+ /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text6, { dimColor: true, children: "\u6309\u6570\u5B57\u9009\u5173 q \u9000\u51FA" }) })
512
+ ] }),
513
+ !selectingLevel && (s.gameOver || s.win) && /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, children: [
514
+ /* @__PURE__ */ jsx5(Text6, { bold: true, color: s.gameOver ? "red" : "green", children: s.gameOver ? "\u6E38\u620F\u7ED3\u675F\uFF01" : "\u606D\u559C\u901A\u5173\uFF01" }),
515
+ /* @__PURE__ */ jsxs5(Text6, { children: [
516
+ " \u5206\u6570: ",
517
+ /* @__PURE__ */ jsx5(Text6, { color: "yellow", children: s.score })
518
+ ] })
519
+ ] }),
520
+ !selectingLevel && /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: s.gameOver || s.win ? /* @__PURE__ */ jsx5(Text6, { dimColor: true, children: "\u2190 \u2192 \u79FB\u52A8 r \u91CD\u5F00 l \u9009\u5173 q \u9000\u51FA" }) : /* @__PURE__ */ jsx5(Text6, { dimColor: true, children: "\u2190 \u2192 \u79FB\u52A8 p \u6682\u505C q \u9000\u51FA" }) })
521
+ ] });
522
+ }
523
+ var brick_breaker_default = {
524
+ id: "brick-breaker",
525
+ name: "Brick Breaker",
526
+ description: "\u7ECF\u5178\u6253\u7816\u5757\u6E38\u620F\uFF0C10 \u4E2A\u5173\u5361\u53EF\u9009\uFF01",
527
+ play: async () => {
528
+ await new Promise((resolve) => {
529
+ const { unmount } = render2(
530
+ /* @__PURE__ */ jsx5(BrickBreakerGame, { onExit: () => {
531
+ unmount();
532
+ resolve();
533
+ } })
534
+ );
535
+ });
536
+ }
537
+ };
538
+
539
+ // src/game/coder-check/index.tsx
540
+ import { Box as Box6, Text as Text7, useInput as useInput3, render as render3 } from "ink";
541
+ import { useState as useState5, useEffect as useEffect4, useRef as useRef2, useCallback as useCallback4 } from "react";
542
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
543
+ var GAME_W = 66;
544
+ var GAME_H = 20;
545
+ var SCORE_H = 6;
546
+ var MAX_WORDS = 10;
547
+ var CYBER_PALETTE2 = ["#00ffff", "#ff00ff", "#00ff41", "#ff1493", "#8b00ff"];
548
+ var DIGIT_ART = {
549
+ "0": [" \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588", "\u2588\u2588 \u2588\u2588", "\u2588\u2588 \u2588\u2588", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
550
+ "1": [" \u2588\u2588 ", " \u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
551
+ "2": [" \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
552
+ "3": [" \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
553
+ "4": ["\u2588\u2588 \u2588\u2588", "\u2588\u2588 \u2588\u2588", " \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 "],
554
+ "5": [" \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
555
+ "6": [" \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 \u2588\u2588", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
556
+ "7": [" \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 "],
557
+ "8": [" \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588", " \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588", " \u2588\u2588\u2588\u2588\u2588\u2588 "],
558
+ "9": [" \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588", " \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588\u2588 "]
559
+ };
560
+ function buildScoreLines(scoreStr) {
561
+ const lines = ["", "", "", "", ""];
562
+ for (const ch of scoreStr) {
563
+ const art = DIGIT_ART[ch] ?? DIGIT_ART["0"];
564
+ for (let r = 0; r < 5; r++) {
565
+ lines[r] += " " + (art[r] ?? "");
566
+ }
567
+ }
568
+ const pad = 6;
569
+ return lines.map((l) => " ".repeat(pad) + l);
570
+ }
571
+ function hexToRgb(hex) {
572
+ const r = parseInt(hex.slice(1, 3), 16);
573
+ const g = parseInt(hex.slice(3, 5), 16);
574
+ const b = parseInt(hex.slice(5, 7), 16);
575
+ return `${r};${g};${b}`;
576
+ }
577
+ var WORDS_BANK = [
578
+ // ── 框架 & 库 ──
579
+ "react",
580
+ "vue",
581
+ "next",
582
+ "node",
583
+ "axios",
584
+ "express",
585
+ "lodash",
586
+ "jquery",
587
+ "webpack",
588
+ "vite",
589
+ "babel",
590
+ "eslint",
591
+ "prettier",
592
+ "tailwind",
593
+ "bootstrap",
594
+ "sass",
595
+ "less",
596
+ "postcss",
597
+ "redux",
598
+ "pinia",
599
+ "vuex",
600
+ "router",
601
+ "nestjs",
602
+ "socket",
603
+ "graphql",
604
+ "rest",
605
+ "grpc",
606
+ "prisma",
607
+ "typeorm",
608
+ // ── 前端 ──
609
+ "html",
610
+ "css",
611
+ "jsx",
612
+ "tsx",
613
+ "dom",
614
+ "spa",
615
+ "ssr",
616
+ "csr",
617
+ "pwa",
618
+ "component",
619
+ "prop",
620
+ "hook",
621
+ "composable",
622
+ "directive",
623
+ "filter",
624
+ "mixin",
625
+ "template",
626
+ "render",
627
+ "virtual",
628
+ "diff",
629
+ "patch",
630
+ "hydration",
631
+ "responsive",
632
+ "flexbox",
633
+ "grid",
634
+ "animation",
635
+ "transition",
636
+ // ── 后端 ──
637
+ "api",
638
+ "route",
639
+ "middleware",
640
+ "controller",
641
+ "service",
642
+ "module",
643
+ "dto",
644
+ "entity",
645
+ "schema",
646
+ "migration",
647
+ "seeder",
648
+ "factory",
649
+ "auth",
650
+ "jwt",
651
+ "oauth",
652
+ "session",
653
+ "cookie",
654
+ "token",
655
+ "cors",
656
+ "cache",
657
+ "redis",
658
+ "mq",
659
+ "rabbit",
660
+ "kafka",
661
+ "nats",
662
+ // ── 数据库 ──
663
+ "sql",
664
+ "mysql",
665
+ "pg",
666
+ "sqlite",
667
+ "mongo",
668
+ "redis",
669
+ "orm",
670
+ "table",
671
+ "index",
672
+ "query",
673
+ "join",
674
+ "union",
675
+ "group",
676
+ "order",
677
+ "where",
678
+ "having",
679
+ "limit",
680
+ "offset",
681
+ "insert",
682
+ "update",
683
+ "delete",
684
+ // ── DevOps ──
685
+ "docker",
686
+ "nginx",
687
+ "linux",
688
+ "bash",
689
+ "shell",
690
+ "yaml",
691
+ "toml",
692
+ "ci",
693
+ "cd",
694
+ "deploy",
695
+ "rollback",
696
+ "release",
697
+ "build",
698
+ "test",
699
+ "lint",
700
+ "format",
701
+ "stage",
702
+ "commit",
703
+ "branch",
704
+ "merge",
705
+ "rebase",
706
+ // ── 数据结构 & 算法 ──
707
+ "array",
708
+ "stack",
709
+ "queue",
710
+ "tree",
711
+ "graph",
712
+ "list",
713
+ "map",
714
+ "set",
715
+ "sort",
716
+ "search",
717
+ "filter",
718
+ "reduce",
719
+ "map",
720
+ "async",
721
+ "await",
722
+ "promise",
723
+ "callback",
724
+ "closure",
725
+ "proxy",
726
+ "reflect",
727
+ "decorator",
728
+ // ── 常用操作 ──
729
+ "create",
730
+ "read",
731
+ "update",
732
+ "delete",
733
+ "crud",
734
+ "parse",
735
+ "stringify",
736
+ "encode",
737
+ "decode",
738
+ "transform",
739
+ "validate",
740
+ "format",
741
+ "parse",
742
+ "upload",
743
+ "download",
744
+ "export",
745
+ "import",
746
+ "backup",
747
+ "restore",
748
+ // ── 类型 & 变量 ──
749
+ "string",
750
+ "number",
751
+ "boolean",
752
+ "object",
753
+ "array",
754
+ "tuple",
755
+ "enum",
756
+ "interface",
757
+ "type",
758
+ "class",
759
+ "function",
760
+ "method",
761
+ "property",
762
+ "public",
763
+ "private",
764
+ "static",
765
+ "readonly",
766
+ "optional",
767
+ "abstract",
768
+ "const",
769
+ "let",
770
+ "var",
771
+ "void",
772
+ "null",
773
+ "undef",
774
+ "never",
775
+ "any",
776
+ // ── 补充 ──
777
+ "config",
778
+ "logger",
779
+ "monitor",
780
+ "metric",
781
+ "alert",
782
+ "webhook",
783
+ "endpoint",
784
+ "payload",
785
+ "header",
786
+ "status",
787
+ "timeout",
788
+ "retry",
789
+ "fallback",
790
+ "circuit",
791
+ "breaker",
792
+ "throttle",
793
+ "debounce",
794
+ "scroll",
795
+ "resize",
796
+ "click",
797
+ "hover",
798
+ "focus",
799
+ "blur"
800
+ ];
801
+ function randomWord(used) {
802
+ let w;
803
+ do {
804
+ w = WORDS_BANK[Math.floor(Math.random() * WORDS_BANK.length)];
805
+ } while (used.has(w));
806
+ return w;
807
+ }
808
+ function createInitialState2() {
809
+ return {
810
+ words: [],
811
+ score: 0,
812
+ lives: 3,
813
+ speed: 0.3,
814
+ spawnTimer: 0,
815
+ gameOver: false,
816
+ paused: false,
817
+ typed: "",
818
+ target: null,
819
+ combo: 0,
820
+ message: "",
821
+ messageTimer: 0,
822
+ usedWords: /* @__PURE__ */ new Set()
823
+ };
824
+ }
825
+ function pickTarget(s) {
826
+ let best = null;
827
+ for (const w of s.words) {
828
+ if (!best || w.col < best.col) best = w;
829
+ }
830
+ return best?.text ?? null;
831
+ }
832
+ function update2(s) {
833
+ if (s.paused || s.gameOver) return;
834
+ s.spawnTimer++;
835
+ if (s.spawnTimer >= Math.max(20, 50 - Math.floor(s.speed * 15))) {
836
+ s.spawnTimer = 0;
837
+ if (s.words.length < MAX_WORDS) {
838
+ const used = new Set(s.usedWords);
839
+ for (const w of s.words) used.add(w.text);
840
+ const text = randomWord(used);
841
+ const usedRows = new Set(s.words.map((w) => w.row));
842
+ let row = -1;
843
+ for (let r = SCORE_H; r < GAME_H; r++) {
844
+ if (!usedRows.has(r)) {
845
+ row = r;
846
+ break;
847
+ }
848
+ }
849
+ if (row >= 0) {
850
+ s.words.push({ text, row, col: GAME_W - 1 });
851
+ s.usedWords.add(text);
852
+ }
853
+ }
854
+ }
855
+ for (const w of s.words) {
856
+ w.col -= s.speed;
857
+ }
858
+ const before = s.words.length;
859
+ s.words = s.words.filter((w) => w.col > -w.text.length);
860
+ const removed = before - s.words.length;
861
+ if (removed > 0) {
862
+ s.lives -= removed;
863
+ s.typed = "";
864
+ s.target = pickTarget(s);
865
+ if (s.lives <= 0) {
866
+ s.gameOver = true;
867
+ s.words = [];
868
+ }
869
+ }
870
+ s.target = pickTarget(s);
871
+ if (s.messageTimer > 0) {
872
+ s.messageTimer--;
873
+ if (s.messageTimer <= 0) s.message = "";
874
+ }
875
+ }
876
+ function buildGameView(s, scoreLines, scoreColor, message) {
877
+ const rows = [];
878
+ for (let y = 0; y < GAME_H; y++) {
879
+ let line = "";
880
+ if (y < SCORE_H) {
881
+ if (y < 5) {
882
+ const raw = (scoreLines[y] ?? "").padEnd(GAME_W);
883
+ line = `\x1B[38;2;${hexToRgb(scoreColor)}m${raw}\x1B[0m`;
884
+ } else if (y === 5) {
885
+ if (s.combo >= 3) {
886
+ const comboText = `${s.combo}\u8FDE\u51FB!`;
887
+ const pad = Math.floor((GAME_W - comboText.length) / 2);
888
+ const comboColor = CYBER_PALETTE2[s.combo % CYBER_PALETTE2.length];
889
+ const raw = " ".repeat(pad) + comboText + " ".repeat(GAME_W - pad - comboText.length);
890
+ line = `\x1B[38;2;${hexToRgb(comboColor)}m${raw}\x1B[0m`;
891
+ } else if (s.paused) {
892
+ const pauseText = "\u6682\u505C";
893
+ const pad = Math.floor((GAME_W - pauseText.length) / 2);
894
+ line = " ".repeat(pad) + pauseText;
895
+ line = line.padEnd(GAME_W);
896
+ }
897
+ }
898
+ line = line.padEnd(GAME_W);
899
+ } else {
900
+ if (y === SCORE_H && message) {
901
+ const pad = Math.floor((GAME_W - message.length) / 2);
902
+ const raw = " ".repeat(pad) + message + " ".repeat(GAME_W - pad - message.length);
903
+ const msgColor = CYBER_PALETTE2[Math.floor(Math.random() * CYBER_PALETTE2.length)];
904
+ line = `\x1B[38;2;${hexToRgb(msgColor)}m${raw}\x1B[0m`;
905
+ } else {
906
+ for (let x = 0; x < GAME_W; x++) {
907
+ const word = s.words.find((w) => {
908
+ const charIdx = x - Math.floor(w.col);
909
+ return charIdx >= 0 && charIdx < w.text.length && w.row === y;
910
+ });
911
+ if (word) {
912
+ const charIdx = x - Math.floor(word.col);
913
+ const ch = word.text[charIdx];
914
+ const isTarget = word.text === s.target;
915
+ const typedIdx = s.target === word.text ? s.typed.length : 0;
916
+ const isTyped = isTarget && charIdx < typedIdx;
917
+ if (isTarget) {
918
+ line += isTyped ? `\x1B[92m${ch}\x1B[0m` : `\x1B[97m${ch}\x1B[0m`;
919
+ } else {
920
+ line += `\x1B[90m${ch}\x1B[0m`;
921
+ }
922
+ } else {
923
+ line += " ";
924
+ }
925
+ }
926
+ }
927
+ }
928
+ rows.push(line);
929
+ }
930
+ return rows;
931
+ }
932
+ function CoderCheck({ onExit: _onExit }) {
933
+ const stateRef = useRef2(createInitialState2());
934
+ const [tick, setTick] = useState5(0);
935
+ const [colorOffset, setColorOffset] = useState5(0);
936
+ const onExitRef = useRef2(_onExit);
937
+ onExitRef.current = _onExit;
938
+ useEffect4(() => {
939
+ const timer = setInterval(() => {
940
+ setColorOffset((prev) => (prev + 1) % CYBER_PALETTE2.length);
941
+ }, 400);
942
+ return () => clearInterval(timer);
943
+ }, []);
944
+ useEffect4(() => {
945
+ const interval = setInterval(() => {
946
+ update2(stateRef.current);
947
+ setTick((t) => t + 1);
948
+ }, 60);
949
+ return () => clearInterval(interval);
950
+ }, []);
951
+ useInput3(
952
+ useCallback4((input, key) => {
953
+ const s2 = stateRef.current;
954
+ if (s2.gameOver) {
955
+ if (input === "r") {
956
+ stateRef.current = createInitialState2();
957
+ setTick(0);
958
+ } else if (input === "q" || key.escape) {
959
+ onExitRef.current();
960
+ }
961
+ return;
962
+ }
963
+ if (input === "p" && key.ctrl || input === " ") {
964
+ s2.paused = !s2.paused;
965
+ return;
966
+ }
967
+ if (input === "q" && key.ctrl || key.escape) {
968
+ onExitRef.current();
969
+ return;
970
+ }
971
+ if (s2.paused) return;
972
+ if (input.length === 1 && input >= "a" && input <= "z") {
973
+ if (!s2.target) {
974
+ s2.target = pickTarget(s2);
975
+ }
976
+ if (s2.target) {
977
+ const nextChar = s2.target[s2.typed.length];
978
+ if (nextChar === input) {
979
+ s2.typed += input;
980
+ if (s2.typed === s2.target) {
981
+ s2.words = s2.words.filter((w) => w.text !== s2.target);
982
+ s2.combo++;
983
+ const prevScore = s2.score;
984
+ const basePts = s2.target.length;
985
+ const comboBonus = s2.combo >= 3 ? s2.score : 0;
986
+ s2.score += basePts + comboBonus;
987
+ s2.speed = s2.speed + 0.02;
988
+ const prevMilestone = Math.floor(prevScore / 500);
989
+ const newMilestone = Math.floor(s2.score / 500);
990
+ if (newMilestone > prevMilestone) {
991
+ s2.speed += 0.15;
992
+ }
993
+ if (s2.score >= 1e5 && prevScore < 1e5) {
994
+ s2.message = "\u606D\u559C\u901A\u5173! \u96BE\u5EA6\u6700\u5927\u5316!";
995
+ s2.messageTimer = 100;
996
+ }
997
+ s2.typed = "";
998
+ s2.target = pickTarget(s2);
999
+ }
1000
+ } else {
1001
+ s2.combo = 0;
1002
+ }
1003
+ }
1004
+ }
1005
+ }, [])
1006
+ );
1007
+ const s = stateRef.current;
1008
+ const scoreColor = CYBER_PALETTE2[colorOffset];
1009
+ const scoreStr = String(s.score).padStart(5, "0");
1010
+ const scoreLines = buildScoreLines(scoreStr);
1011
+ const view = buildGameView(s, scoreLines, scoreColor, s.message);
1012
+ void tick;
1013
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, children: [
1014
+ /* @__PURE__ */ jsx6(Box6, { flexDirection: "row", children: /* @__PURE__ */ jsxs6(Text7, { children: [
1015
+ "\u751F\u547D ",
1016
+ /* @__PURE__ */ jsx6(Text7, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) }),
1017
+ " ",
1018
+ "\u901F\u5EA6 ",
1019
+ /* @__PURE__ */ jsxs6(Text7, { color: "cyan", children: [
1020
+ "Lv.",
1021
+ Math.floor(s.speed * 10)
1022
+ ] })
1023
+ ] }) }),
1024
+ !s.gameOver && s.target && /* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
1025
+ "\u6253\u5B57: ",
1026
+ /* @__PURE__ */ jsx6(Text7, { color: "green", children: s.typed }),
1027
+ /* @__PURE__ */ jsx6(Text7, { color: "white", children: s.target.slice(s.typed.length) })
1028
+ ] }) }),
1029
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginTop: 1, children: [
1030
+ /* @__PURE__ */ jsxs6(Text7, { children: [
1031
+ "\u250C",
1032
+ "\u2500".repeat(GAME_W),
1033
+ "\u2510"
1034
+ ] }),
1035
+ view.map((row, i) => /* @__PURE__ */ jsx6(Text7, { children: `\u2502${row}\u2502` }, i)),
1036
+ /* @__PURE__ */ jsxs6(Text7, { children: [
1037
+ "\u2514",
1038
+ "\u2500".repeat(GAME_W),
1039
+ "\u2518"
1040
+ ] })
1041
+ ] }),
1042
+ s.gameOver && /* @__PURE__ */ jsxs6(Box6, { marginTop: 1, children: [
1043
+ /* @__PURE__ */ jsx6(Text7, { bold: true, color: "red", children: "\u6E38\u620F\u7ED3\u675F\uFF01" }),
1044
+ /* @__PURE__ */ jsxs6(Text7, { children: [
1045
+ " \u5F97\u5206: ",
1046
+ /* @__PURE__ */ jsx6(Text7, { color: "yellow", children: s.score }),
1047
+ " r \u91CD\u5F00 q \u9000\u51FA"
1048
+ ] })
1049
+ ] }),
1050
+ /* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text7, { dimColor: true, children: "\u6253\u5B57\u6D88\u9664\u5355\u8BCD \u7A7A\u683C/Ctrl+P\u6682\u505C Ctrl+Q\u9000\u51FA" }) })
1051
+ ] });
1052
+ }
1053
+ var coder_check_default = {
1054
+ id: "coder-check",
1055
+ name: "Coder Check",
1056
+ description: "\u6781\u901F\u6253\u5B57\u6E38\u620F\uFF0C\u8F93\u5165\u5355\u8BCD\u6D88\u9664\u5B83\u4EEC\uFF01",
1057
+ play: async () => {
1058
+ await new Promise((resolve) => {
1059
+ const { unmount } = render3(
1060
+ /* @__PURE__ */ jsx6(CoderCheck, { onExit: () => {
1061
+ unmount();
1062
+ resolve();
1063
+ } })
1064
+ );
1065
+ });
1066
+ }
1067
+ };
1068
+
1069
+ // src/game/registry.ts
1070
+ function initGames() {
1071
+ registerGame(brick_breaker_default);
1072
+ registerGame(coder_check_default);
1073
+ return listGames();
1074
+ }
1075
+
217
1076
  // src/cli/index.tsx
218
- import { jsx as jsx4 } from "react/jsx-runtime";
219
- var SUBCOMMANDS = ["chat", "run", "setup", "init", "completion"];
1077
+ import { render as render4 } from "ink";
1078
+ import chalk2 from "chalk";
1079
+ import { jsx as jsx7 } from "react/jsx-runtime";
1080
+ var SUBCOMMANDS = ["chat", "run", "setup", "init", "completion", "game"];
220
1081
  function createCli() {
221
1082
  const program2 = new Command();
222
1083
  program2.exitOverride();
@@ -233,7 +1094,7 @@ function createCli() {
233
1094
  }
234
1095
  const ctx = this.dskcodeCtx;
235
1096
  const app = renderApp(
236
- /* @__PURE__ */ jsx4(
1097
+ /* @__PURE__ */ jsx7(
237
1098
  ChatSession,
238
1099
  {
239
1100
  providerCount: ctx?.config.providers.length ?? 1,
@@ -279,12 +1140,56 @@ _dskcode_completion() {
279
1140
  "setup:\u8FD0\u884C\u914D\u7F6E\u5411\u5BFC"
280
1141
  "init:\u751F\u6210\u9879\u76EE\u8BB0\u5FC6\u6587\u4EF6"
281
1142
  "completion:\u8F93\u51FA shell \u81EA\u52A8\u8865\u5168\u8BF4\u660E"
1143
+ "game:\u5185\u7F6E\u5C0F\u6E38\u620F"
282
1144
  )
283
1145
  _describe 'dskcode commands' commands
284
1146
  }
285
1147
  compdef _dskcode_completion dskcode`);
286
1148
  }
287
1149
  });
1150
+ initGames();
1151
+ program2.command("game").description("\u542F\u52A8\u5185\u7F6E\u5C0F\u6E38\u620F").argument("[name]", "\u6E38\u620F\u540D\u79F0\uFF0C\u4E0D\u6307\u5B9A\u5219\u663E\u793A\u4EA4\u4E92\u5F0F\u6E38\u620F\u5217\u8868").action(async function(name) {
1152
+ if (name) {
1153
+ const game = getGame(name);
1154
+ if (!game) {
1155
+ console.error(`\u672A\u627E\u5230\u6E38\u620F "${name}"\u3002\u4F7F\u7528 dskcode game \u67E5\u770B\u53EF\u7528\u6E38\u620F\u5217\u8868\u3002`);
1156
+ process.exit(1);
1157
+ }
1158
+ console.log(`\u6B63\u5728\u542F\u52A8: ${game.name} \u2014 ${game.description}
1159
+ `);
1160
+ await game.play();
1161
+ } else {
1162
+ const games = listGames();
1163
+ if (games.length === 0) {
1164
+ console.log("\u6682\u65E0\u53EF\u7528\u6E38\u620F\u3002");
1165
+ return;
1166
+ }
1167
+ const selectedGame = await new Promise((resolve) => {
1168
+ const { unmount } = render4(
1169
+ /* @__PURE__ */ jsx7(
1170
+ GamePicker,
1171
+ {
1172
+ games,
1173
+ onSelect: (game) => {
1174
+ unmount();
1175
+ resolve(game);
1176
+ },
1177
+ onExit: () => {
1178
+ unmount();
1179
+ resolve(null);
1180
+ }
1181
+ }
1182
+ )
1183
+ );
1184
+ });
1185
+ if (selectedGame) {
1186
+ console.log(`
1187
+ \u542F\u52A8\u6E38\u620F: ${chalk2.green(selectedGame.name)}
1188
+ `);
1189
+ await selectedGame.play();
1190
+ }
1191
+ }
1192
+ });
288
1193
  return program2;
289
1194
  }
290
1195
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/index.tsx","../src/cli/middleware.ts","../src/cli/help.ts","../src/ui/RenderScope.tsx","../src/ui/Spinner.tsx","../src/ui/StatusMessage.tsx","../src/ui/DskcodeSplash.tsx","../src/ui/ChatSession.tsx","../src/cli/exit-codes.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\r\nimport { loadConfigMiddleware } from \"./middleware.js\";\r\nimport { customHelp } from \"./help.js\";\r\nimport { renderApp, ChatSession } from \"../ui/index.js\";\r\n\r\nconst SUBCOMMANDS = [\"chat\", \"run\", \"setup\", \"init\", \"completion\"];\r\n\r\nexport function createCli(): Command {\r\n const program = new Command();\r\n program.exitOverride();\r\n\r\n program\r\n .name(\"dskcode\")\r\n .description(\"基于 DeepSeek 的 AI 编程助手终端工具\")\r\n .version(\"0.0.0\", \"-V, --version\", \"显示版本号\")\r\n .option(\"--verbose\", \"开启详细日志输出\")\r\n .option(\"--config <path>\", \"指定配置文件路径\");\r\n\r\n program.helpInformation = () => customHelp(program);\r\n\r\n program.hook(\"preAction\", async (thisCommand) => {\r\n const ctx = await loadConfigMiddleware.call(thisCommand);\r\n (thisCommand as unknown as Record<string, unknown>).dskcodeCtx = ctx;\r\n });\r\n\r\n // chat — 交互式对话\r\n program\r\n .command(\"chat\")\r\n .description(\"启动交互式对话会话\")\r\n .action(async function () {\r\n if (!process.stdin.isTTY) {\r\n console.error(\"dskcode chat 需要交互式终端。如需执行一次性任务,请使用 dskcode run。\");\r\n process.exit(1);\r\n }\r\n\r\n const ctx = (this as unknown as Record<string, unknown>).dskcodeCtx as\r\n | { verbose: boolean; config: { providers: unknown[]; tools: unknown[] } }\r\n | undefined;\r\n\r\n const app = renderApp(\r\n <ChatSession\r\n providerCount={ctx?.config.providers.length ?? 1}\r\n toolCount={ctx?.config.tools.length ?? 0}\r\n verbose={ctx?.verbose ?? false}\r\n />,\r\n );\r\n\r\n await app.waitUntilExit;\r\n });\r\n\r\n // run\r\n program\r\n .command(\"run\")\r\n .description(\"执行一次性任务\")\r\n .argument(\"[prompt...]\", \"任务描述\")\r\n .option(\"--model <name>\", \"指定使用的模型\")\r\n .action(async function (_prompt: string[]) {\r\n console.log(\"dskcode run — 待实现(第07章)\");\r\n });\r\n\r\n // setup\r\n program\r\n .command(\"setup\")\r\n .description(\"运行配置向导\")\r\n .option(\"--export\", \"以 JSON 格式导出配置\")\r\n .option(\"--test\", \"测试 API Key 连通性\")\r\n .action(async function () {\r\n console.log(\"dskcode setup — 待实现(第14章)\");\r\n });\r\n\r\n // init\r\n program\r\n .command(\"init\")\r\n .description(\"在当前项目下生成项目记忆文件(AGENTS.md)\")\r\n .action(async function () {\r\n console.log(\"dskcode init — 待实现(第11章)\");\r\n });\r\n\r\n // completion\r\n program\r\n .command(\"completion\")\r\n .description(\"输出 shell 自动补全配置说明(bash/zsh)\")\r\n .argument(\"[shell]\", \"shell 类型\", /^(bash|zsh)$/i)\r\n .action(async function (shell?: string) {\r\n if (!shell) {\r\n console.log(\"请指定 shell 类型:dskcode completion bash 或 dskcode completion zsh\");\r\n return;\r\n }\r\n if (shell === \"bash\") {\r\n console.log(`# dskcode bash 自动补全\r\n_dskcode_completion() {\r\n local cur=\\${COMP_WORDS[COMP_CWORD]}\r\n if [[ \\${COMP_CWORD} -eq 1 ]]; then\r\n COMPREPLY=( $(compgen -W \"${SUBCOMMANDS.join(\" \")}\" -- \"\\${cur}\") )\r\n return 0\r\n fi\r\n COMPREPLY=( $(compgen -W \"--verbose --config --model\" -- \"\\${cur}\") )\r\n}\r\ncomplete -F _dskcode_completion dskcode`);\r\n } else {\r\n console.log(`# dskcode zsh 自动补全\r\n_dskcode_completion() {\r\n local -a commands\r\n commands=(\r\n \"chat:启动交互式对话会话\"\r\n \"run:执行一次性任务\"\r\n \"setup:运行配置向导\"\r\n \"init:生成项目记忆文件\"\r\n \"completion:输出 shell 自动补全说明\"\r\n )\r\n _describe 'dskcode commands' commands\r\n}\r\ncompdef _dskcode_completion dskcode`);\r\n }\r\n });\r\n\r\n return program;\r\n}\r\n","import type { Command } from \"commander\";\r\nimport type { Config } from \"../config/index.js\";\r\nimport { loadConfig } from \"../config/index.js\";\r\n\r\n/**\r\n * dskcode 运行时上下文。\r\n * 通过 commander 的 preAction hook 注入到每个命令中。\r\n */\r\nexport interface DskcodeContext {\r\n config: Config;\r\n verbose: boolean;\r\n}\r\n\r\n/**\r\n * 在 preAction hook 中加载配置并构造上下文。\r\n */\r\nexport async function loadConfigMiddleware(this: Command): Promise<DskcodeContext> {\r\n const opts = this.optsWithGlobals() as { verbose?: boolean; config?: string };\r\n const verbose = opts.verbose ?? false;\r\n\r\n let config: Config;\r\n try {\r\n config = await loadConfig(opts.config);\r\n } catch {\r\n const { defaultConfig } = await import(\"../config/index.js\");\r\n config = defaultConfig;\r\n }\r\n\r\n return { config, verbose };\r\n}\r\n","import type { Command } from \"commander\";\r\nimport chalk from \"chalk\";\r\n\r\nexport function customHelp(program: Command): string {\r\n const lines: string[] = [];\r\n\r\n lines.push(\"\");\r\n lines.push(chalk.bold(\"用法:\"));\r\n lines.push(` ${chalk.cyan(\"dskcode\")} ${chalk.dim(\"[global-options]\")} ${chalk.green(\"<command>\")} ${chalk.dim(\"[options]\")}`);\r\n lines.push(\"\");\r\n\r\n const globalOpts = program.options.filter(\r\n (o) => o.long !== \"--help\" && o.long !== \"--version\" && o.long !== \"--config\",\r\n );\r\n if (globalOpts.length > 0) {\r\n lines.push(chalk.bold(\"全局选项:\"));\r\n for (const opt of globalOpts) {\r\n const flags = [opt.short, opt.long].filter(Boolean).join(\", \");\r\n lines.push(` ${chalk.cyan(flags.padEnd(24))} ${opt.description ?? \"\"}`);\r\n }\r\n lines.push(\"\");\r\n }\r\n\r\n lines.push(chalk.bold(\"内置选项:\"));\r\n for (const flag of [\"-h, --help\", \"-V, --version\"]) {\r\n const opt = program.options.find(\r\n (o) => o.long === (flag.includes(\"help\") ? \"--help\" : \"--version\"),\r\n );\r\n if (opt) {\r\n lines.push(` ${chalk.cyan(flag.padEnd(24))} ${opt.description ?? \"\"}`);\r\n }\r\n }\r\n lines.push(\"\");\r\n\r\n const cmds = program.commands.filter((c) => !c.name().startsWith(\"help\"));\r\n if (cmds.length > 0) {\r\n lines.push(chalk.bold(\"命令:\"));\r\n for (const cmd of cmds) {\r\n lines.push(` ${chalk.green(cmd.name().padEnd(24))} ${cmd.description()}`);\r\n }\r\n lines.push(\"\");\r\n }\r\n\r\n lines.push(chalk.bold(\"示例:\"));\r\n lines.push(` ${chalk.dim(\"# 启动交互式对话\")}`);\r\n lines.push(\" dskcode chat\");\r\n lines.push(` ${chalk.dim(\"# 让 AI 执行一个任务\")}`);\r\n lines.push(\" dskcode run 修改所有 TODO 注释\");\r\n lines.push(` ${chalk.dim(\"# 运行配置向导\")}`);\r\n lines.push(\" dskcode setup\");\r\n lines.push(` ${chalk.dim(\"# 生成 shell 自动补全\")}`);\r\n lines.push(\" dskcode completion\");\r\n lines.push(\"\");\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n","import { render } from \"ink\";\r\nimport type { ReactNode } from \"react\";\r\n\r\nexport interface RenderScopeHandle {\r\n waitUntilExit: Promise<unknown>;\r\n unmount: () => void;\r\n clear: () => void;\r\n}\r\n\r\nexport function renderApp(node: ReactNode): RenderScopeHandle {\r\n const { waitUntilExit, clear, unmount } = render(node);\r\n return { waitUntilExit: waitUntilExit(), clear, unmount };\r\n}\r\n\r\nexport async function unmountApp(handle: RenderScopeHandle): Promise<void> {\r\n handle.unmount();\r\n await new Promise((resolve) => setTimeout(resolve, 50));\r\n}\r\n","import { Text } from \"ink\";\r\nimport InkSpinner from \"ink-spinner\";\r\n\r\ninterface SpinnerProps {\r\n type?: \"dots\" | \"line\" | \"bouncingBar\" | \"aesthetic\";\r\n label?: string;\r\n}\r\n\r\nexport function Spinner({ type = \"dots\", label }: SpinnerProps) {\r\n return (\r\n <Text>\r\n <Text color=\"cyan\">\r\n <InkSpinner type={type} />\r\n </Text>\r\n {label ? <Text> {label}</Text> : null}\r\n </Text>\r\n );\r\n}\r\n","import { Box, Text } from \"ink\";\r\n\r\ntype MessageType = \"info\" | \"success\" | \"warning\" | \"error\";\r\n\r\ninterface StatusMessageProps {\r\n type?: MessageType;\r\n label: string;\r\n detail?: string;\r\n}\r\n\r\nconst STYLES: Record<MessageType, { color: string; icon: string }> = {\r\n info: { color: \"cyan\", icon: \"ℹ\" },\r\n success: { color: \"green\", icon: \"✔\" },\r\n warning: { color: \"yellow\", icon: \"⚠\" },\r\n error: { color: \"red\", icon: \"✖\" },\r\n};\r\n\r\nexport function StatusMessage({ type = \"info\", label, detail }: StatusMessageProps) {\r\n const { color, icon } = STYLES[type];\r\n return (\r\n <Box>\r\n <Text color={color}>\r\n {icon} {label}\r\n </Text>\r\n {detail ? <Text dimColor>: {detail}</Text> : null}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text } from \"ink\";\r\nimport { useEffect, useState } from \"react\";\r\n\r\nconst CYBER_PALETTE = [\"#00ffff\", \"#ff00ff\", \"#00ff41\", \"#ff1493\", \"#8b00ff\"];\r\n\r\nconst LOGO_LINES = [\r\n \" ██████╗ ███████╗██╗ ██╗\",\r\n \" ██╔══██╗██╔════╝██║ ██╔╝\",\r\n \" ██║ ██║███████╗█████╔╝ \",\r\n \" ██║ ██║╚════██║██╔═██╗ \",\r\n \" ██████╔╝███████║██║ ██╗\",\r\n \" ╚═════╝ ╚══════╝╚═╝ ╚═╝\",\r\n];\r\n\r\nexport function DskcodeSplash() {\r\n const [offset, setOffset] = useState(0);\r\n\r\n useEffect(() => {\r\n const timer = setInterval(() => {\r\n setOffset((prev) => (prev + 1) % CYBER_PALETTE.length);\r\n }, 500);\r\n return () => clearInterval(timer);\r\n }, []);\r\n\r\n return (\r\n <Box flexDirection=\"column\" paddingLeft={1}>\r\n {LOGO_LINES.map((line, i) => {\r\n const colorIndex = (i + offset) % CYBER_PALETTE.length;\r\n return (\r\n <Box key={i}>\r\n <Text bold color={CYBER_PALETTE[colorIndex]}>\r\n {line}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text } from \"ink\";\r\nimport TextInput from \"ink-text-input\";\r\nimport { useEffect, useState, useCallback } from \"react\";\r\n\r\nconst CYBER_PALETTE = [\"#00ffff\", \"#ff00ff\", \"#00ff41\", \"#ff1493\", \"#8b00ff\"];\r\n\r\nconst LOGO_LINES = [\r\n \" ██████╗ ███████╗██╗ ██╗\",\r\n \" ██╔══██╗██╔════╝██║ ██╔╝\",\r\n \" ██║ ██║███████╗█████╔╝ \",\r\n \" ██║ ██║╚════██║██╔═██╗ \",\r\n \" ██████╔╝███████║██║ ██╗\",\r\n \" ╚═════╝ ╚══════╝╚═╝ ╚═╝\",\r\n];\r\n\r\nconst COMMANDS: Record<string, { desc: string; handler: () => string }> = {\r\n \"/exit\": { desc: \"退出对话\", handler: () => \"\" },\r\n \"/quit\": { desc: \"退出对话\", handler: () => \"\" },\r\n \"/help\": {\r\n desc: \"显示帮助信息\",\r\n handler: () =>\r\n [\r\n \"可用命令:\",\r\n \" /exit, /quit 退出对话\",\r\n \" /help 显示此帮助\",\r\n \" /clear 清空对话历史\",\r\n \" /version 显示版本信息\",\r\n ].join(\"\\n\"),\r\n },\r\n \"/clear\": { desc: \"清空对话历史\", handler: () => \"\" },\r\n \"/version\": { desc: \"显示版本信息\", handler: () => \"dskcode v0.0.0\" },\r\n};\r\n\r\ninterface ChatMessage {\r\n role: \"user\" | \"assistant\";\r\n content: string;\r\n}\r\n\r\ninterface ChatSessionProps {\r\n providerCount: number;\r\n toolCount: number;\r\n verbose: boolean;\r\n}\r\n\r\nexport function ChatSession({ providerCount, toolCount, verbose }: ChatSessionProps) {\r\n const [offset, setOffset] = useState(0);\r\n const [messages, setMessages] = useState<ChatMessage[]>([]);\r\n const [input, setInput] = useState(\"\");\r\n\r\n useEffect(() => {\r\n const timer = setInterval(() => {\r\n setOffset((prev) => (prev + 1) % CYBER_PALETTE.length);\r\n }, 500);\r\n return () => clearInterval(timer);\r\n }, []);\r\n\r\n const handleSubmit = useCallback((value: string) => {\r\n const trimmed = value.trim();\r\n if (!trimmed) return;\r\n\r\n if (trimmed.startsWith(\"/\")) {\r\n const cmd = COMMANDS[trimmed.toLowerCase()];\r\n if (cmd) {\r\n if (trimmed.toLowerCase() === \"/exit\" || trimmed.toLowerCase() === \"/quit\") {\r\n process.exit(0);\r\n return;\r\n }\r\n if (trimmed.toLowerCase() === \"/clear\") {\r\n setMessages([]);\r\n setInput(\"\");\r\n return;\r\n }\r\n const result = cmd.handler();\r\n if (result) {\r\n setMessages((prev) => [\r\n ...prev,\r\n { role: \"user\", content: trimmed },\r\n { role: \"assistant\", content: result },\r\n ]);\r\n }\r\n setInput(\"\");\r\n return;\r\n }\r\n setMessages((prev) => [\r\n ...prev,\r\n { role: \"user\", content: trimmed },\r\n { role: \"assistant\", content: `未知命令:${trimmed}。输入 /help 查看。` },\r\n ]);\r\n setInput(\"\");\r\n return;\r\n }\r\n\r\n setMessages((prev) => [\r\n ...prev,\r\n { role: \"user\", content: trimmed },\r\n { role: \"assistant\", content: \"dskcode AI — 待实现(第07章)。当前为 CLI 框架演示模式。\" },\r\n ]);\r\n setInput(\"\");\r\n }, []);\r\n\r\n return (\r\n <Box flexDirection=\"column\" paddingLeft={1} paddingRight={1}>\r\n {/* Logo + 状态栏 — 左右布局 */}\r\n <Box flexDirection=\"row\" marginBottom={1}>\r\n {/* Logo */}\r\n <Box flexDirection=\"column\" marginRight={4}>\r\n {LOGO_LINES.map((line, i) => {\r\n const colorIndex = (i + offset) % CYBER_PALETTE.length;\r\n return (\r\n <Box key={i}>\r\n <Text bold color={CYBER_PALETTE[colorIndex]}>\r\n {line}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n\r\n {/* 状态信息 */}\r\n <Box flexDirection=\"column\" justifyContent=\"center\">\r\n <Text color=\"#00ff41\">{\" ✔ \"}已加载 {providerCount} 个 Provider</Text>\r\n <Text color=\"#00ffff\">{\" ℹ \"}已就绪 {toolCount} 个工具</Text>\r\n {verbose ? <Text color=\"#ff1493\">{\" ⚡ Verbose\"}</Text> : null}\r\n </Box>\r\n </Box>\r\n\r\n {/* Messages */}\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {messages.map((msg, i) => (\r\n <Box key={i} marginTop={1}>\r\n <Box width={8} flexShrink={0}>\r\n <Text bold color={msg.role === \"user\" ? \"#00ff41\" : \"#ff00ff\"}>\r\n {msg.role === \"user\" ? \" 👤\" : \" 🤖\"}\r\n </Text>\r\n </Box>\r\n <Box flexGrow={1}>\r\n <Text wrap=\"wrap\">{msg.content}</Text>\r\n </Box>\r\n </Box>\r\n ))}\r\n </Box>\r\n\r\n {/* Input */}\r\n <Box marginTop={1}>\r\n <Box width={8} flexShrink={0}>\r\n <Text bold color=\"#00ff41\">\r\n {\" ⚡\"}\r\n </Text>\r\n </Box>\r\n <Box flexGrow={1}>\r\n <TextInput\r\n value={input}\r\n onChange={setInput}\r\n onSubmit={handleSubmit}\r\n placeholder=\"输入你的问题...\"\r\n />\r\n </Box>\r\n </Box>\r\n\r\n <Box marginTop={1}>\r\n <Text color=\"#00ffff\" dimColor>\r\n {\" \" + \"─\".repeat(36)}\r\n </Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","/** dskcode 退出码规范 */\r\nexport const ExitCode = {\r\n /** 正常执行完成 */\r\n SUCCESS: 0,\r\n /** 通用错误 */\r\n GENERAL_ERROR: 1,\r\n /** 配置错误 */\r\n CONFIG_ERROR: 2,\r\n /** 用户通过 Ctrl+C 中断 */\r\n SIGINT: 130,\r\n} as const;\r\n","#!/usr/bin/env node\r\n\r\nimport { createCli } from \"./cli/index.js\";\r\nimport { ExitCode } from \"./cli/exit-codes.js\";\r\n\r\nprocess.on(\"SIGINT\", () => {\r\n process.exit(ExitCode.SIGINT);\r\n});\r\n\r\nconst program = createCli();\r\n\r\ntry {\r\n await program.parseAsync(process.argv);\r\n} catch (err: unknown) {\r\n const error = err as { exitCode?: number; code?: string };\r\n\r\n if (error.code === \"commander.helpDisplayed\" || error.code === \"commander.version\") {\r\n process.exit(error.exitCode ?? ExitCode.SUCCESS);\r\n }\r\n\r\n if (typeof error.exitCode === \"number\") {\r\n process.exit(error.exitCode);\r\n }\r\n\r\n console.error(String(err));\r\n process.exit(ExitCode.GENERAL_ERROR);\r\n}\r\n"],"mappings":"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","names":["program","Text","jsxs","Box","Text","jsx","Box","Text","useEffect","useState","jsx","jsxs","jsx","program"]}
1
+ {"version":3,"sources":["../src/cli/index.tsx","../src/cli/middleware.ts","../src/cli/help.ts","../src/ui/RenderScope.tsx","../src/ui/Spinner.tsx","../src/ui/StatusMessage.tsx","../src/ui/DskcodeSplash.tsx","../src/ui/ChatSession.tsx","../src/ui/GamePicker.tsx","../src/game/index.ts","../src/game/brick-breaker/index.tsx","../src/game/coder-check/index.tsx","../src/game/registry.ts","../src/cli/exit-codes.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\r\nimport { loadConfigMiddleware } from \"./middleware.js\";\r\nimport { customHelp } from \"./help.js\";\r\nimport { renderApp, ChatSession } from \"../ui/index.js\";\r\nimport { initGames } from \"../game/registry.js\";\r\nimport { listGames, getGame } from \"../game/index.js\";\r\nimport type { Game } from \"../game/index.js\";\r\nimport { GamePicker } from \"../ui/GamePicker.js\";\r\nimport { render } from \"ink\";\r\nimport chalk from \"chalk\";\r\n\r\nconst SUBCOMMANDS = [\"chat\", \"run\", \"setup\", \"init\", \"completion\", \"game\"];\r\n\r\nexport function createCli(): Command {\r\n const program = new Command();\r\n program.exitOverride();\r\n\r\n program\r\n .name(\"dskcode\")\r\n .description(\"基于 DeepSeek 的 AI 编程助手终端工具\")\r\n .version(\"0.0.0\", \"-V, --version\", \"显示版本号\")\r\n .option(\"--verbose\", \"开启详细日志输出\")\r\n .option(\"--config <path>\", \"指定配置文件路径\");\r\n\r\n program.helpInformation = () => customHelp(program);\r\n\r\n program.hook(\"preAction\", async (thisCommand) => {\r\n const ctx = await loadConfigMiddleware.call(thisCommand);\r\n (thisCommand as unknown as Record<string, unknown>).dskcodeCtx = ctx;\r\n });\r\n\r\n // chat — 交互式对话\r\n program\r\n .command(\"chat\")\r\n .description(\"启动交互式对话会话\")\r\n .action(async function () {\r\n if (!process.stdin.isTTY) {\r\n console.error(\"dskcode chat 需要交互式终端。如需执行一次性任务,请使用 dskcode run。\");\r\n process.exit(1);\r\n }\r\n\r\n const ctx = (this as unknown as Record<string, unknown>).dskcodeCtx as\r\n | { verbose: boolean; config: { providers: unknown[]; tools: unknown[] } }\r\n | undefined;\r\n\r\n const app = renderApp(\r\n <ChatSession\r\n providerCount={ctx?.config.providers.length ?? 1}\r\n toolCount={ctx?.config.tools.length ?? 0}\r\n verbose={ctx?.verbose ?? false}\r\n />,\r\n );\r\n\r\n await app.waitUntilExit;\r\n });\r\n\r\n // run\r\n program\r\n .command(\"run\")\r\n .description(\"执行一次性任务\")\r\n .argument(\"[prompt...]\", \"任务描述\")\r\n .option(\"--model <name>\", \"指定使用的模型\")\r\n .action(async function (_prompt: string[]) {\r\n console.log(\"dskcode run — 待实现(第07章)\");\r\n });\r\n\r\n // setup\r\n program\r\n .command(\"setup\")\r\n .description(\"运行配置向导\")\r\n .option(\"--export\", \"以 JSON 格式导出配置\")\r\n .option(\"--test\", \"测试 API Key 连通性\")\r\n .action(async function () {\r\n console.log(\"dskcode setup — 待实现(第14章)\");\r\n });\r\n\r\n // init\r\n program\r\n .command(\"init\")\r\n .description(\"在当前项目下生成项目记忆文件(AGENTS.md)\")\r\n .action(async function () {\r\n console.log(\"dskcode init — 待实现(第11章)\");\r\n });\r\n\r\n // completion\r\n program\r\n .command(\"completion\")\r\n .description(\"输出 shell 自动补全配置说明(bash/zsh)\")\r\n .argument(\"[shell]\", \"shell 类型\", /^(bash|zsh)$/i)\r\n .action(async function (shell?: string) {\r\n if (!shell) {\r\n console.log(\"请指定 shell 类型:dskcode completion bash 或 dskcode completion zsh\");\r\n return;\r\n }\r\n if (shell === \"bash\") {\r\n console.log(`# dskcode bash 自动补全\r\n_dskcode_completion() {\r\n local cur=\\${COMP_WORDS[COMP_CWORD]}\r\n if [[ \\${COMP_CWORD} -eq 1 ]]; then\r\n COMPREPLY=( $(compgen -W \"${SUBCOMMANDS.join(\" \")}\" -- \"\\${cur}\") )\r\n return 0\r\n fi\r\n COMPREPLY=( $(compgen -W \"--verbose --config --model\" -- \"\\${cur}\") )\r\n}\r\ncomplete -F _dskcode_completion dskcode`);\r\n } else {\r\n console.log(`# dskcode zsh 自动补全\r\n_dskcode_completion() {\r\n local -a commands\r\n commands=(\r\n \"chat:启动交互式对话会话\"\r\n \"run:执行一次性任务\"\r\n \"setup:运行配置向导\"\r\n \"init:生成项目记忆文件\"\r\n \"completion:输出 shell 自动补全说明\"\r\n \"game:内置小游戏\"\r\n )\r\n _describe 'dskcode commands' commands\r\n}\r\ncompdef _dskcode_completion dskcode`);\r\n }\r\n });\r\n\r\n // game — 游戏模式\r\n initGames();\r\n\r\n program\r\n .command(\"game\")\r\n .description(\"启动内置小游戏\")\r\n .argument(\"[name]\", \"游戏名称,不指定则显示交互式游戏列表\")\r\n .action(async function (name?: string) {\r\n if (name) {\r\n const game = getGame(name);\r\n if (!game) {\r\n console.error(`未找到游戏 \"${name}\"。使用 dskcode game 查看可用游戏列表。`);\r\n process.exit(1);\r\n }\r\n console.log(`正在启动: ${game.name} — ${game.description}\\n`);\r\n await game.play();\r\n } else {\r\n const games = listGames();\r\n if (games.length === 0) {\r\n console.log(\"暂无可用游戏。\");\r\n return;\r\n }\r\n\r\n const selectedGame = await new Promise<Game | null>((resolve) => {\r\n const { unmount } = render(\r\n <GamePicker\r\n games={games}\r\n onSelect={(game) => {\r\n unmount();\r\n resolve(game);\r\n }}\r\n onExit={() => {\r\n unmount();\r\n resolve(null);\r\n }}\r\n />,\r\n );\r\n });\r\n\r\n if (selectedGame) {\r\n console.log(`\\n 启动游戏: ${chalk.green(selectedGame.name)}\\n`);\r\n await selectedGame.play();\r\n }\r\n }\r\n });\r\n\r\n return program;\r\n}\r\n","import type { Command } from \"commander\";\r\nimport type { Config } from \"../config/index.js\";\r\nimport { loadConfig } from \"../config/index.js\";\r\n\r\n/**\r\n * dskcode 运行时上下文。\r\n * 通过 commander 的 preAction hook 注入到每个命令中。\r\n */\r\nexport interface DskcodeContext {\r\n config: Config;\r\n verbose: boolean;\r\n}\r\n\r\n/**\r\n * 在 preAction hook 中加载配置并构造上下文。\r\n */\r\nexport async function loadConfigMiddleware(this: Command): Promise<DskcodeContext> {\r\n const opts = this.optsWithGlobals() as { verbose?: boolean; config?: string };\r\n const verbose = opts.verbose ?? false;\r\n\r\n let config: Config;\r\n try {\r\n config = await loadConfig(opts.config);\r\n } catch {\r\n const { defaultConfig } = await import(\"../config/index.js\");\r\n config = defaultConfig;\r\n }\r\n\r\n return { config, verbose };\r\n}\r\n","import type { Command } from \"commander\";\r\nimport chalk from \"chalk\";\r\n\r\nexport function customHelp(program: Command): string {\r\n const lines: string[] = [];\r\n\r\n lines.push(\"\");\r\n lines.push(chalk.bold(\"用法:\"));\r\n lines.push(` ${chalk.cyan(\"dskcode\")} ${chalk.dim(\"[global-options]\")} ${chalk.green(\"<command>\")} ${chalk.dim(\"[options]\")}`);\r\n lines.push(\"\");\r\n\r\n const globalOpts = program.options.filter(\r\n (o) => o.long !== \"--help\" && o.long !== \"--version\" && o.long !== \"--config\",\r\n );\r\n if (globalOpts.length > 0) {\r\n lines.push(chalk.bold(\"全局选项:\"));\r\n for (const opt of globalOpts) {\r\n const flags = [opt.short, opt.long].filter(Boolean).join(\", \");\r\n lines.push(` ${chalk.cyan(flags.padEnd(24))} ${opt.description ?? \"\"}`);\r\n }\r\n lines.push(\"\");\r\n }\r\n\r\n lines.push(chalk.bold(\"内置选项:\"));\r\n for (const flag of [\"-h, --help\", \"-V, --version\"]) {\r\n const opt = program.options.find(\r\n (o) => o.long === (flag.includes(\"help\") ? \"--help\" : \"--version\"),\r\n );\r\n if (opt) {\r\n lines.push(` ${chalk.cyan(flag.padEnd(24))} ${opt.description ?? \"\"}`);\r\n }\r\n }\r\n lines.push(\"\");\r\n\r\n const cmds = program.commands.filter((c) => !c.name().startsWith(\"help\"));\r\n if (cmds.length > 0) {\r\n lines.push(chalk.bold(\"命令:\"));\r\n for (const cmd of cmds) {\r\n lines.push(` ${chalk.green(cmd.name().padEnd(24))} ${cmd.description()}`);\r\n }\r\n lines.push(\"\");\r\n }\r\n\r\n lines.push(chalk.bold(\"示例:\"));\r\n lines.push(` ${chalk.dim(\"# 启动交互式对话\")}`);\r\n lines.push(\" dskcode chat\");\r\n lines.push(` ${chalk.dim(\"# 让 AI 执行一个任务\")}`);\r\n lines.push(\" dskcode run 修改所有 TODO 注释\");\r\n lines.push(` ${chalk.dim(\"# 运行配置向导\")}`);\r\n lines.push(\" dskcode setup\");\r\n lines.push(` ${chalk.dim(\"# 生成 shell 自动补全\")}`);\r\n lines.push(\" dskcode completion\");\r\n lines.push(\"\");\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n","import { render } from \"ink\";\r\nimport type { ReactNode } from \"react\";\r\n\r\nexport interface RenderScopeHandle {\r\n waitUntilExit: Promise<unknown>;\r\n unmount: () => void;\r\n clear: () => void;\r\n}\r\n\r\nexport function renderApp(node: ReactNode): RenderScopeHandle {\r\n const { waitUntilExit, clear, unmount } = render(node);\r\n return { waitUntilExit: waitUntilExit(), clear, unmount };\r\n}\r\n\r\nexport async function unmountApp(handle: RenderScopeHandle): Promise<void> {\r\n handle.unmount();\r\n await new Promise((resolve) => setTimeout(resolve, 50));\r\n}\r\n","import { Text } from \"ink\";\r\nimport InkSpinner from \"ink-spinner\";\r\n\r\ninterface SpinnerProps {\r\n type?: \"dots\" | \"line\" | \"bouncingBar\" | \"aesthetic\";\r\n label?: string;\r\n}\r\n\r\nexport function Spinner({ type = \"dots\", label }: SpinnerProps) {\r\n return (\r\n <Text>\r\n <Text color=\"cyan\">\r\n <InkSpinner type={type} />\r\n </Text>\r\n {label ? <Text> {label}</Text> : null}\r\n </Text>\r\n );\r\n}\r\n","import { Box, Text } from \"ink\";\r\n\r\ntype MessageType = \"info\" | \"success\" | \"warning\" | \"error\";\r\n\r\ninterface StatusMessageProps {\r\n type?: MessageType;\r\n label: string;\r\n detail?: string;\r\n}\r\n\r\nconst STYLES: Record<MessageType, { color: string; icon: string }> = {\r\n info: { color: \"cyan\", icon: \"ℹ\" },\r\n success: { color: \"green\", icon: \"✔\" },\r\n warning: { color: \"yellow\", icon: \"⚠\" },\r\n error: { color: \"red\", icon: \"✖\" },\r\n};\r\n\r\nexport function StatusMessage({ type = \"info\", label, detail }: StatusMessageProps) {\r\n const { color, icon } = STYLES[type];\r\n return (\r\n <Box>\r\n <Text color={color}>\r\n {icon} {label}\r\n </Text>\r\n {detail ? <Text dimColor>: {detail}</Text> : null}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text } from \"ink\";\r\nimport { useEffect, useState } from \"react\";\r\n\r\nconst CYBER_PALETTE = [\"#00ffff\", \"#ff00ff\", \"#00ff41\", \"#ff1493\", \"#8b00ff\"];\r\n\r\nconst LOGO_LINES = [\r\n \" ██████╗ ███████╗██╗ ██╗\",\r\n \" ██╔══██╗██╔════╝██║ ██╔╝\",\r\n \" ██║ ██║███████╗█████╔╝ \",\r\n \" ██║ ██║╚════██║██╔═██╗ \",\r\n \" ██████╔╝███████║██║ ██╗\",\r\n \" ╚═════╝ ╚══════╝╚═╝ ╚═╝\",\r\n];\r\n\r\nexport function DskcodeSplash() {\r\n const [offset, setOffset] = useState(0);\r\n\r\n useEffect(() => {\r\n const timer = setInterval(() => {\r\n setOffset((prev) => (prev + 1) % CYBER_PALETTE.length);\r\n }, 500);\r\n return () => clearInterval(timer);\r\n }, []);\r\n\r\n return (\r\n <Box flexDirection=\"column\" paddingLeft={1}>\r\n {LOGO_LINES.map((line, i) => {\r\n const colorIndex = (i + offset) % CYBER_PALETTE.length;\r\n return (\r\n <Box key={i}>\r\n <Text bold color={CYBER_PALETTE[colorIndex]}>\r\n {line}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text } from \"ink\";\r\nimport TextInput from \"ink-text-input\";\r\nimport { useEffect, useState, useCallback } from \"react\";\r\n\r\nconst CYBER_PALETTE = [\"#00ffff\", \"#ff00ff\", \"#00ff41\", \"#ff1493\", \"#8b00ff\"];\r\n\r\nconst LOGO_LINES = [\r\n \" ██████╗ ███████╗██╗ ██╗\",\r\n \" ██╔══██╗██╔════╝██║ ██╔╝\",\r\n \" ██║ ██║███████╗█████╔╝ \",\r\n \" ██║ ██║╚════██║██╔═██╗ \",\r\n \" ██████╔╝███████║██║ ██╗\",\r\n \" ╚═════╝ ╚══════╝╚═╝ ╚═╝\",\r\n];\r\n\r\nconst COMMANDS: Record<string, { desc: string; handler: () => string }> = {\r\n \"/exit\": { desc: \"退出对话\", handler: () => \"\" },\r\n \"/quit\": { desc: \"退出对话\", handler: () => \"\" },\r\n \"/help\": {\r\n desc: \"显示帮助信息\",\r\n handler: () =>\r\n [\r\n \"可用命令:\",\r\n \" /exit, /quit 退出对话\",\r\n \" /help 显示此帮助\",\r\n \" /clear 清空对话历史\",\r\n \" /version 显示版本信息\",\r\n ].join(\"\\n\"),\r\n },\r\n \"/clear\": { desc: \"清空对话历史\", handler: () => \"\" },\r\n \"/version\": { desc: \"显示版本信息\", handler: () => \"dskcode v0.0.0\" },\r\n};\r\n\r\ninterface ChatMessage {\r\n role: \"user\" | \"assistant\";\r\n content: string;\r\n}\r\n\r\ninterface ChatSessionProps {\r\n providerCount: number;\r\n toolCount: number;\r\n verbose: boolean;\r\n}\r\n\r\nexport function ChatSession({ providerCount, toolCount, verbose }: ChatSessionProps) {\r\n const [offset, setOffset] = useState(0);\r\n const [messages, setMessages] = useState<ChatMessage[]>([]);\r\n const [input, setInput] = useState(\"\");\r\n\r\n useEffect(() => {\r\n const timer = setInterval(() => {\r\n setOffset((prev) => (prev + 1) % CYBER_PALETTE.length);\r\n }, 500);\r\n return () => clearInterval(timer);\r\n }, []);\r\n\r\n const handleSubmit = useCallback((value: string) => {\r\n const trimmed = value.trim();\r\n if (!trimmed) return;\r\n\r\n if (trimmed.startsWith(\"/\")) {\r\n const cmd = COMMANDS[trimmed.toLowerCase()];\r\n if (cmd) {\r\n if (trimmed.toLowerCase() === \"/exit\" || trimmed.toLowerCase() === \"/quit\") {\r\n process.exit(0);\r\n return;\r\n }\r\n if (trimmed.toLowerCase() === \"/clear\") {\r\n setMessages([]);\r\n setInput(\"\");\r\n return;\r\n }\r\n const result = cmd.handler();\r\n if (result) {\r\n setMessages((prev) => [\r\n ...prev,\r\n { role: \"user\", content: trimmed },\r\n { role: \"assistant\", content: result },\r\n ]);\r\n }\r\n setInput(\"\");\r\n return;\r\n }\r\n setMessages((prev) => [\r\n ...prev,\r\n { role: \"user\", content: trimmed },\r\n { role: \"assistant\", content: `未知命令:${trimmed}。输入 /help 查看。` },\r\n ]);\r\n setInput(\"\");\r\n return;\r\n }\r\n\r\n setMessages((prev) => [\r\n ...prev,\r\n { role: \"user\", content: trimmed },\r\n { role: \"assistant\", content: \"dskcode AI — 待实现(第07章)。当前为 CLI 框架演示模式。\" },\r\n ]);\r\n setInput(\"\");\r\n }, []);\r\n\r\n return (\r\n <Box flexDirection=\"column\" paddingLeft={1} paddingRight={1}>\r\n {/* Logo + 状态栏 — 左右布局 */}\r\n <Box flexDirection=\"row\" marginBottom={1}>\r\n {/* Logo */}\r\n <Box flexDirection=\"column\" marginRight={4}>\r\n {LOGO_LINES.map((line, i) => {\r\n const colorIndex = (i + offset) % CYBER_PALETTE.length;\r\n return (\r\n <Box key={i}>\r\n <Text bold color={CYBER_PALETTE[colorIndex]}>\r\n {line}\r\n </Text>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n\r\n {/* 状态信息 */}\r\n <Box flexDirection=\"column\" justifyContent=\"center\">\r\n <Text color=\"#00ff41\">{\" ✔ \"}已加载 {providerCount} 个 Provider</Text>\r\n <Text color=\"#00ffff\">{\" ℹ \"}已就绪 {toolCount} 个工具</Text>\r\n {verbose ? <Text color=\"#ff1493\">{\" ⚡ Verbose\"}</Text> : null}\r\n </Box>\r\n </Box>\r\n\r\n {/* Messages */}\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {messages.map((msg, i) => (\r\n <Box key={i} marginTop={1}>\r\n <Box width={8} flexShrink={0}>\r\n <Text bold color={msg.role === \"user\" ? \"#00ff41\" : \"#ff00ff\"}>\r\n {msg.role === \"user\" ? \" 👤\" : \" 🤖\"}\r\n </Text>\r\n </Box>\r\n <Box flexGrow={1}>\r\n <Text wrap=\"wrap\">{msg.content}</Text>\r\n </Box>\r\n </Box>\r\n ))}\r\n </Box>\r\n\r\n {/* Input */}\r\n <Box marginTop={1}>\r\n <Box width={8} flexShrink={0}>\r\n <Text bold color=\"#00ff41\">\r\n {\" ⚡\"}\r\n </Text>\r\n </Box>\r\n <Box flexGrow={1}>\r\n <TextInput\r\n value={input}\r\n onChange={setInput}\r\n onSubmit={handleSubmit}\r\n placeholder=\"输入你的问题...\"\r\n />\r\n </Box>\r\n </Box>\r\n\r\n <Box marginTop={1}>\r\n <Text color=\"#00ffff\" dimColor>\r\n {\" \" + \"─\".repeat(36)}\r\n </Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import { Box, Text, useInput } from \"ink\";\r\nimport { useState, useCallback } from \"react\";\r\nimport type { Game } from \"../game/index.js\";\r\n\r\ninterface GamePickerProps {\r\n games: Game[];\r\n onSelect: (game: Game) => void;\r\n onExit: () => void;\r\n}\r\n\r\nexport function GamePicker({ games, onSelect, onExit }: GamePickerProps) {\r\n const [selectedIndex, setSelectedIndex] = useState(0);\r\n\r\n useInput(\r\n useCallback(\r\n (input, key) => {\r\n if (games.length === 0) return;\r\n if (key.upArrow || input === \"k\") {\r\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : games.length - 1));\r\n } else if (key.downArrow || input === \"j\") {\r\n setSelectedIndex((prev) => (prev < games.length - 1 ? prev + 1 : 0));\r\n } else if (key.return) {\r\n const game = games[selectedIndex];\r\n if (game) onSelect(game);\r\n } else if (key.escape || input === \"q\") {\r\n onExit();\r\n }\r\n },\r\n [games, selectedIndex, onSelect, onExit],\r\n ),\r\n );\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n <Box marginBottom={1}>\r\n <Text bold color=\"#00ffff\">\r\n 🎮 游戏列表\r\n </Text>\r\n </Box>\r\n\r\n <Box flexDirection=\"column\">\r\n {games.map((game, index) => {\r\n const isSelected = index === selectedIndex;\r\n return (\r\n <Box key={game.id} flexDirection=\"row\">\r\n <Box width={3} flexShrink={0}>\r\n {isSelected ? (\r\n <Text bold color=\"#00ff41\">\r\n {\"▸ \"}\r\n </Text>\r\n ) : (\r\n <Text>{\" \"}</Text>\r\n )}\r\n </Box>\r\n <Box width={20} flexShrink={0}>\r\n <Text bold color={isSelected ? \"#00ff41\" : \"#ffffff\"}>\r\n {game.name}\r\n </Text>\r\n </Box>\r\n <Box>\r\n <Text color=\"#888888\">{game.description}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n\r\n <Box marginTop={1}>\r\n <Text dimColor>\r\n {\" ↑/↓ 选择 Enter 启动 q 返回\"}\r\n </Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","export interface Game {\r\n /** 游戏唯一标识 */\r\n id: string;\r\n /** 游戏名称 */\r\n name: string;\r\n /** 简短描述 */\r\n description: string;\r\n /** 启动游戏 */\r\n play: () => Promise<void>;\r\n}\r\n\r\nconst registry = new Map<string, Game>();\r\n\r\nexport function registerGame(game: Game): void {\r\n registry.set(game.id, game);\r\n}\r\n\r\nexport function getGame(id: string): Game | undefined {\r\n return registry.get(id);\r\n}\r\n\r\nexport function listGames(): Game[] {\r\n return Array.from(registry.values());\r\n}\r\n","import { Box, Text, useInput, render } from \"ink\";\r\nimport { useState, useEffect, useRef, useCallback } from \"react\";\r\n\r\nconst GAME_WIDTH = 40;\r\nconst GAME_HEIGHT = 18;\r\nconst PADDLE_WIDTH = 9;\r\nconst BRICK_COLORS = [166, 214, 76, 69];\r\n\r\ninterface Vec2 {\r\n x: number;\r\n y: number;\r\n}\r\n\r\ninterface Brick {\r\n x: number;\r\n y: number;\r\n w: number;\r\n alive: boolean;\r\n}\r\n\r\n// ─── 10 个关卡定义 ──────────────────────────────────────────────\r\n\r\ninterface LevelDef {\r\n rows: number;\r\n cols: number;\r\n bw: number; // 砖块宽度(格数)\r\n desc: string;\r\n // 返回 true 表示该位置有砖块\r\n pattern: (col: number, row: number, rows: number, cols: number) => boolean;\r\n}\r\n\r\nconst LEVELS: LevelDef[] = [\r\n { rows: 4, cols: 8, bw: 3, desc: \"经典 4×8\", pattern: () => true },\r\n { rows: 3, cols: 8, bw: 3, desc: \"轻松 3 层\", pattern: () => true },\r\n { rows: 6, cols: 8, bw: 3, desc: \"厚墙 6 层\", pattern: () => true },\r\n { rows: 4, cols: 8, bw: 3, desc: \"棋盘格\", pattern: (c, r) => (c + r) % 2 === 0 },\r\n { rows: 4, cols: 8, bw: 3, desc: \"金字塔\", pattern: (c, r, _, tc) => c >= r && c < tc - r },\r\n { rows: 4, cols: 8, bw: 3, desc: \"交错排列\", pattern: (c, r) => r % 2 === 0 || (c >= 1 && c <= 6) },\r\n { rows: 4, cols: 8, bw: 3, desc: \"中空边框\", pattern: (c, r, tr, tc) => r === 0 || r === tr - 1 || c === 0 || c === tc - 1 },\r\n { rows: 4, cols: 10, bw: 2, desc: \"密集 10 列\", pattern: () => true },\r\n { rows: 7, cols: 8, bw: 3, desc: \"高墙 7 层\", pattern: () => true },\r\n { rows: 8, cols: 8, bw: 3, desc: \"满屏 8 层\", pattern: () => true },\r\n];\r\n\r\nfunction getLevel(level: number): LevelDef {\r\n return LEVELS[(level - 1) % LEVELS.length] as LevelDef;\r\n}\r\n\r\nfunction createBricks(level: number): Brick[] {\r\n const def = getLevel(level);\r\n const bricks: Brick[] = [];\r\n const gap = 2;\r\n const totalW = def.cols * def.bw + (def.cols - 1) * gap;\r\n const startX = Math.floor((GAME_WIDTH - totalW) / 2);\r\n const step = def.bw + gap;\r\n\r\n for (let row = 0; row < def.rows; row++) {\r\n for (let col = 0; col < def.cols; col++) {\r\n if (def.pattern(col, row, def.rows, def.cols)) {\r\n bricks.push({\r\n x: startX + col * step,\r\n y: 2 + row * 2,\r\n w: def.bw,\r\n alive: true,\r\n });\r\n }\r\n }\r\n }\r\n return bricks;\r\n}\r\n\r\n// ─── 游戏状态 ──────────────────────────────────────────────────\r\n\r\ninterface GameState {\r\n level: number;\r\n bricks: Brick[];\r\n paddleX: number;\r\n ball: Vec2;\r\n ballDir: Vec2;\r\n score: number;\r\n lives: number;\r\n gameOver: boolean;\r\n win: boolean;\r\n paused: boolean;\r\n}\r\n\r\nfunction createInitialState(level: number): GameState {\r\n const def = getLevel(level);\r\n const totalW = def.cols * def.bw + (def.cols - 1) * 2;\r\n const startX = Math.floor((GAME_WIDTH - totalW) / 2);\r\n return {\r\n level,\r\n bricks: createBricks(level),\r\n paddleX: Math.floor(GAME_WIDTH / 2) - Math.floor(PADDLE_WIDTH / 2),\r\n ball: { x: GAME_WIDTH / 2, y: GAME_HEIGHT - 3 },\r\n ballDir: { x: 1, y: -1 },\r\n score: 0,\r\n lives: 3,\r\n gameOver: false,\r\n win: false,\r\n paused: false,\r\n };\r\n}\r\n\r\n// ─── 物理更新 ──────────────────────────────────────────────────\r\n\r\nfunction update(state: GameState): void {\r\n if (state.paused || state.gameOver || state.win) return;\r\n\r\n state.ball.x += state.ballDir.x;\r\n state.ball.y += state.ballDir.y;\r\n\r\n if (state.ball.x <= 0) { state.ball.x = 0; state.ballDir.x = 1; }\r\n if (state.ball.x >= GAME_WIDTH - 1) { state.ball.x = GAME_WIDTH - 1; state.ballDir.x = -1; }\r\n if (state.ball.y <= 0) { state.ball.y = 0; state.ballDir.y = 1; }\r\n\r\n // 挡板碰撞\r\n if (\r\n state.ball.y === GAME_HEIGHT - 1 &&\r\n state.ball.x >= state.paddleX &&\r\n state.ball.x <= state.paddleX + PADDLE_WIDTH\r\n ) {\r\n state.ballDir.y = -1;\r\n const hitPos = (state.ball.x - state.paddleX) / PADDLE_WIDTH;\r\n state.ballDir.x = hitPos < 0.5 ? -1 : 1;\r\n }\r\n\r\n // 出界\r\n if (state.ball.y > GAME_HEIGHT) {\r\n state.lives--;\r\n if (state.lives <= 0) {\r\n state.gameOver = true;\r\n } else {\r\n state.ball = { x: GAME_WIDTH / 2, y: GAME_HEIGHT - 3 };\r\n state.ballDir = { x: 1, y: -1 };\r\n state.paddleX = Math.floor(GAME_WIDTH / 2) - Math.floor(PADDLE_WIDTH / 2);\r\n }\r\n }\r\n\r\n // 砖块碰撞\r\n const hitBrick = state.bricks.find((b) => {\r\n if (!b.alive) return false;\r\n return state.ball.x >= b.x && state.ball.x < b.x + b.w && state.ball.y >= b.y && state.ball.y < b.y + 1;\r\n });\r\n\r\n if (hitBrick) {\r\n hitBrick.alive = false;\r\n state.score += 10;\r\n state.ballDir.y = -state.ballDir.y;\r\n }\r\n\r\n if (state.bricks.every((b) => !b.alive)) state.win = true;\r\n}\r\n\r\n// ─── 画面渲染(含 ANSI 颜色) ─────────────────────────────────\r\n\r\nfunction buildBoard(state: GameState): string {\r\n const lines: string[] = [];\r\n\r\n function brickColorIndex(x: number, y: number): number | undefined {\r\n const row = Math.floor((y - 2) / 2);\r\n if (row >= 0) {\r\n const b = state.bricks.find((br) => br.y === y && br.alive && x >= br.x && x < br.x + br.w);\r\n if (b) return row % BRICK_COLORS.length;\r\n }\r\n return undefined;\r\n }\r\n\r\n for (let y = 0; y < GAME_HEIGHT; y++) {\r\n let line = \"\";\r\n for (let x = 0; x < GAME_WIDTH; x++) {\r\n const isBall = state.ball.x === x && state.ball.y === y;\r\n const isPaddle = y === GAME_HEIGHT - 1 && x >= state.paddleX && x < state.paddleX + PADDLE_WIDTH;\r\n const brickRow = brickColorIndex(x, y);\r\n\r\n if (isBall) {\r\n line += \"\\x1b[97m●\\x1b[0m\";\r\n } else if (isPaddle) {\r\n line += \"\\x1b[94m▄\\x1b[0m\";\r\n } else if (brickRow !== undefined) {\r\n line += `\\x1b[38;5;${BRICK_COLORS[brickRow] as number}m▀\\x1b[0m`;\r\n } else {\r\n line += \" \";\r\n }\r\n }\r\n lines.push(line);\r\n }\r\n\r\n return lines.map((l) => `│${l}│`).join(\"\\n\");\r\n}\r\n\r\n// ─── Ink 组件 ──────────────────────────────────────────────────\r\n\r\ninterface BrickBreakerGameProps {\r\n onExit: () => void;\r\n}\r\n\r\nfunction BrickBreakerGame({ onExit: _onExit }: BrickBreakerGameProps) {\r\n const [initialLevel, setInitialLevel] = useState(1);\r\n const [selectingLevel, setSelectingLevel] = useState(true);\r\n const stateRef = useRef<GameState>(createInitialState(initialLevel));\r\n const [tick, setTick] = useState(0);\r\n const onExitRef = useRef(_onExit);\r\n onExitRef.current = _onExit;\r\n\r\n useEffect(() => {\r\n if (selectingLevel) return;\r\n const interval = setInterval(() => {\r\n update(stateRef.current);\r\n setTick((t) => t + 1);\r\n }, 80);\r\n return () => clearInterval(interval);\r\n }, [selectingLevel]);\r\n\r\n // 重新开始(保留当前关卡)\r\n const restart = useCallback((level?: number) => {\r\n const lv = level ?? stateRef.current.level;\r\n stateRef.current = createInitialState(lv);\r\n setInitialLevel(lv);\r\n setSelectingLevel(false);\r\n setTick(0);\r\n }, []);\r\n\r\n // 选关\r\n const startLevelSelect = useCallback(() => {\r\n setSelectingLevel(true);\r\n }, []);\r\n\r\n useInput(\r\n useCallback((input, key) => {\r\n const s = stateRef.current;\r\n\r\n // 选关模式\r\n if (selectingLevel) {\r\n if (input >= \"1\" && input <= \"9\") {\r\n restart(Number(input));\r\n } else if (input === \"0\") {\r\n restart(10);\r\n } else if (key.escape || input === \"q\") {\r\n onExitRef.current();\r\n }\r\n return;\r\n }\r\n\r\n if (key.leftArrow) {\r\n s.paddleX = Math.max(0, s.paddleX - 1);\r\n setTick((t) => t + 1);\r\n } else if (key.rightArrow) {\r\n s.paddleX = Math.min(GAME_WIDTH - PADDLE_WIDTH, s.paddleX + 1);\r\n setTick((t) => t + 1);\r\n } else if (input === \"p\" || input === \" \") {\r\n s.paused = !s.paused;\r\n } else if (input === \"r\") {\r\n if (s.gameOver || s.win) restart();\r\n } else if (input === \"l\") {\r\n if (s.gameOver || s.win) startLevelSelect();\r\n } else if (input === \"q\" || key.escape) {\r\n onExitRef.current();\r\n }\r\n }, [selectingLevel, restart, startLevelSelect]),\r\n );\r\n\r\n const s = stateRef.current;\r\n const aliveCount = s.bricks.filter((b) => b.alive).length;\r\n const board = buildBoard(s);\r\n const def = getLevel(s.level);\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n void tick;\r\n\r\n return (\r\n <Box flexDirection=\"column\">\r\n {/* 状态栏 */}\r\n <Box flexDirection=\"row\">\r\n <Box width={20}>\r\n <Text>\r\n 关卡 {s.level}: <Text color=\"cyan\">{def.desc}</Text>\r\n </Text>\r\n </Box>\r\n <Box width={12}>\r\n <Text>\r\n 分数: <Text color=\"yellow\">{String(s.score).padStart(3, \"0\")}</Text>\r\n </Text>\r\n </Box>\r\n <Box width={12}>\r\n <Text>\r\n 生命: <Text color=\"red\">{\"♥\".repeat(Math.max(0, s.lives))}</Text>\r\n </Text>\r\n </Box>\r\n <Box width={10}>\r\n <Text>\r\n 砖块: <Text color=\"cyan\">{aliveCount}</Text>\r\n </Text>\r\n </Box>\r\n <Box>\r\n <Text color={s.paused ? \"gray\" : \"green\"}>\r\n [{s.paused ? \"暂停\" : \"运行中\"}]\r\n </Text>\r\n </Box>\r\n </Box>\r\n\r\n {/* 游戏画面 */}\r\n <Box flexDirection=\"column\">\r\n <Text>┌{\"─\".repeat(GAME_WIDTH)}┐</Text>\r\n <Text>{selectingLevel ? \" \\x1b[90m选择关卡后开始...\\x1b[0m\" : board}</Text>\r\n <Text>└{\"─\".repeat(GAME_WIDTH)}┘</Text>\r\n </Box>\r\n\r\n {/* 选关界面 */}\r\n {selectingLevel && (\r\n <Box marginTop={1} flexDirection=\"column\">\r\n <Text bold color=\"yellow\">选择关卡</Text>\r\n <Box flexDirection=\"row\" flexWrap=\"wrap\">\r\n {LEVELS.map((lv, i) => (\r\n <Box key={i} width={22}>\r\n <Text>\r\n <Text color={initialLevel === i + 1 ? \"green\" : \"white\"}>\r\n {i + 1 === 10 ? \"0\" : String(i + 1)}\r\n </Text>\r\n . {lv.desc} ({lv.rows}×{lv.cols})\r\n </Text>\r\n </Box>\r\n ))}\r\n </Box>\r\n <Box marginTop={1}>\r\n <Text dimColor>按数字选关 q 退出</Text>\r\n </Box>\r\n </Box>\r\n )}\r\n\r\n {/* 结束/通关信息 */}\r\n {!selectingLevel && (s.gameOver || s.win) && (\r\n <Box marginTop={1}>\r\n <Text bold color={s.gameOver ? \"red\" : \"green\"}>\r\n {s.gameOver ? \"游戏结束!\" : \"恭喜通关!\"}\r\n </Text>\r\n <Text>\r\n {\" 分数: \"}<Text color=\"yellow\">{s.score}</Text>\r\n </Text>\r\n </Box>\r\n )}\r\n\r\n {/* 操作提示 */}\r\n {!selectingLevel && (\r\n <Box marginTop={1}>\r\n {s.gameOver || s.win ? (\r\n <Text dimColor>\r\n {\"← → 移动 r 重开 l 选关 q 退出\"}\r\n </Text>\r\n ) : (\r\n <Text dimColor>\r\n {\"← → 移动 p 暂停 q 退出\"}\r\n </Text>\r\n )}\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n}\r\n\r\n// ─── 导出 ──────────────────────────────────────────────────────\r\n\r\nexport default {\r\n id: \"brick-breaker\",\r\n name: \"Brick Breaker\",\r\n description: \"经典打砖块游戏,10 个关卡可选!\",\r\n play: async () => {\r\n await new Promise<void>((resolve) => {\r\n const { unmount } = render(\r\n <BrickBreakerGame onExit={() => { unmount(); resolve(); }} />,\r\n );\r\n });\r\n },\r\n};\r\n","import { Box, Text, useInput, render } from \"ink\";\r\nimport { useState, useEffect, useRef, useCallback } from \"react\";\r\n\r\nconst GAME_W = 66;\r\nconst GAME_H = 20; // 6 行分数 + 14 行掉落单词\r\nconst SCORE_H = 6;\r\nconst WORD_H = 14;\r\nconst MAX_WORDS = 10;\r\nconst CYBER_PALETTE = [\"#00ffff\", \"#ff00ff\", \"#00ff41\", \"#ff1493\", \"#8b00ff\"];\r\n\r\n// 3×5 像素大号数字(每个像素 = ██,每数字 6 列)\r\nconst DIGIT_ART: Record<string, string[]> = {\r\n \"0\": [\" ██████ \", \"██ ██\", \"██ ██\", \"██ ██\", \" ██████ \"],\r\n \"1\": [\" ██ \", \" ████ \", \" ██ \", \" ██ \", \" ██████ \"],\r\n \"2\": [\" ██████ \", \" ██ \", \" ██████ \", \" ██ \", \" ██████ \"],\r\n \"3\": [\" ██████ \", \" ██ \", \" ██████ \", \" ██ \", \" ██████ \"],\r\n \"4\": [\"██ ██\", \"██ ██\", \" ██████ \", \" ██ \", \" ██ \"],\r\n \"5\": [\" ██████ \", \" ██ \", \" ██████ \", \" ██ \", \" ██████ \"],\r\n \"6\": [\" ██████ \", \" ██ \", \" ██████ \", \" ██ ██\", \" ██████ \"],\r\n \"7\": [\" ██████ \", \" ██ \", \" ██ \", \" ██ \", \" ██ \"],\r\n \"8\": [\" ██████ \", \"██ ██\", \" ██████ \", \"██ ██\", \" ██████ \"],\r\n \"9\": [\" ██████ \", \"██ ██\", \" ██████ \", \" ██ \", \" ██████ \"],\r\n};\r\n\r\nfunction buildScoreLines(scoreStr: string): string[] {\r\n const lines = [\"\", \"\", \"\", \"\", \"\"];\r\n for (const ch of scoreStr) {\r\n const art = DIGIT_ART[ch] ?? DIGIT_ART[\"0\"]!;\r\n for (let r = 0; r < 5; r++) {\r\n lines[r] += \" \" + (art[r] ?? \"\");\r\n }\r\n }\r\n // 左右各留 6 格间距\r\n const pad = 6;\r\n return lines.map((l) => \" \".repeat(pad) + l);\r\n}\r\n\r\nfunction hexToRgb(hex: string): string {\r\n const r = parseInt(hex.slice(1, 3), 16);\r\n const g = parseInt(hex.slice(3, 5), 16);\r\n const b = parseInt(hex.slice(5, 7), 16);\r\n return `${r};${g};${b}`;\r\n}\r\n\r\n// ─── 200 个常见单词 ────────────────────────────────────────────\r\n\r\nconst WORDS_BANK = [\r\n // ── 框架 & 库 ──\r\n \"react\", \"vue\", \"next\", \"node\", \"axios\", \"express\", \"lodash\", \"jquery\",\r\n \"webpack\", \"vite\", \"babel\", \"eslint\", \"prettier\", \"tailwind\", \"bootstrap\",\r\n \"sass\", \"less\", \"postcss\", \"redux\", \"pinia\", \"vuex\", \"router\",\r\n \"nestjs\", \"socket\", \"graphql\", \"rest\", \"grpc\", \"prisma\", \"typeorm\",\r\n\r\n // ── 前端 ──\r\n \"html\", \"css\", \"jsx\", \"tsx\", \"dom\", \"spa\", \"ssr\", \"csr\", \"pwa\",\r\n \"component\", \"prop\", \"hook\", \"composable\", \"directive\", \"filter\", \"mixin\",\r\n \"template\", \"render\", \"virtual\", \"diff\", \"patch\", \"hydration\",\r\n \"responsive\", \"flexbox\", \"grid\", \"animation\", \"transition\",\r\n\r\n // ── 后端 ──\r\n \"api\", \"route\", \"middleware\", \"controller\", \"service\", \"module\",\r\n \"dto\", \"entity\", \"schema\", \"migration\", \"seeder\", \"factory\",\r\n \"auth\", \"jwt\", \"oauth\", \"session\", \"cookie\", \"token\", \"cors\",\r\n \"cache\", \"redis\", \"mq\", \"rabbit\", \"kafka\", \"nats\",\r\n\r\n // ── 数据库 ──\r\n \"sql\", \"mysql\", \"pg\", \"sqlite\", \"mongo\", \"redis\", \"orm\",\r\n \"table\", \"index\", \"query\", \"join\", \"union\", \"group\", \"order\",\r\n \"where\", \"having\", \"limit\", \"offset\", \"insert\", \"update\", \"delete\",\r\n\r\n // ── DevOps ──\r\n \"docker\", \"nginx\", \"linux\", \"bash\", \"shell\", \"yaml\", \"toml\",\r\n \"ci\", \"cd\", \"deploy\", \"rollback\", \"release\", \"build\", \"test\",\r\n \"lint\", \"format\", \"stage\", \"commit\", \"branch\", \"merge\", \"rebase\",\r\n\r\n // ── 数据结构 & 算法 ──\r\n \"array\", \"stack\", \"queue\", \"tree\", \"graph\", \"list\", \"map\", \"set\",\r\n \"sort\", \"search\", \"filter\", \"reduce\", \"map\", \"async\", \"await\",\r\n \"promise\", \"callback\", \"closure\", \"proxy\", \"reflect\", \"decorator\",\r\n\r\n // ── 常用操作 ──\r\n \"create\", \"read\", \"update\", \"delete\", \"crud\", \"parse\", \"stringify\",\r\n \"encode\", \"decode\", \"transform\", \"validate\", \"format\", \"parse\",\r\n \"upload\", \"download\", \"export\", \"import\", \"backup\", \"restore\",\r\n\r\n // ── 类型 & 变量 ──\r\n \"string\", \"number\", \"boolean\", \"object\", \"array\", \"tuple\", \"enum\",\r\n \"interface\", \"type\", \"class\", \"function\", \"method\", \"property\",\r\n \"public\", \"private\", \"static\", \"readonly\", \"optional\", \"abstract\",\r\n \"const\", \"let\", \"var\", \"void\", \"null\", \"undef\", \"never\", \"any\",\r\n\r\n // ── 补充 ──\r\n \"config\", \"logger\", \"monitor\", \"metric\", \"alert\", \"webhook\",\r\n \"endpoint\", \"payload\", \"header\", \"status\", \"timeout\", \"retry\",\r\n \"fallback\", \"circuit\", \"breaker\", \"throttle\", \"debounce\",\r\n \"scroll\", \"resize\", \"click\", \"hover\", \"focus\", \"blur\",\r\n];\r\n\r\nfunction randomWord(used: Set<string>): string {\r\n let w: string;\r\n do { w = WORDS_BANK[Math.floor(Math.random() * WORDS_BANK.length)] as string; }\r\n while (used.has(w));\r\n return w;\r\n}\r\n\r\n// ─── 游戏状态 ──────────────────────────────────────────────────\r\n\r\ninterface DropWord {\r\n text: string;\r\n row: number;\r\n col: number;\r\n}\r\n\r\ninterface GameState {\r\n words: DropWord[];\r\n score: number;\r\n lives: number;\r\n speed: number;\r\n spawnTimer: number;\r\n gameOver: boolean;\r\n paused: boolean;\r\n typed: string;\r\n target: string | null;\r\n combo: number;\r\n message: string;\r\n messageTimer: number;\r\n usedWords: Set<string>;\r\n}\r\n\r\nfunction createInitialState(): GameState {\r\n return {\r\n words: [],\r\n score: 0,\r\n lives: 3,\r\n speed: 0.3,\r\n spawnTimer: 0,\r\n gameOver: false,\r\n paused: false,\r\n typed: \"\",\r\n target: null,\r\n combo: 0,\r\n message: \"\",\r\n messageTimer: 0,\r\n usedWords: new Set(),\r\n };\r\n}\r\n\r\nfunction pickTarget(s: GameState): string | null {\r\n // 选取最靠左的存活单词作为目标\r\n let best: DropWord | null = null;\r\n for (const w of s.words) {\r\n if (!best || w.col < best.col) best = w;\r\n }\r\n return best?.text ?? null;\r\n}\r\n\r\n// ─── 物理更新 ──────────────────────────────────────────────────\r\n\r\nfunction update(s: GameState): void {\r\n if (s.paused || s.gameOver) return;\r\n\r\n // 生成新单词\r\n s.spawnTimer++;\r\n if (s.spawnTimer >= Math.max(20, 50 - Math.floor(s.speed * 15))) {\r\n s.spawnTimer = 0;\r\n if (s.words.length < MAX_WORDS) {\r\n const used = new Set(s.usedWords);\r\n for (const w of s.words) used.add(w.text);\r\n const text = randomWord(used);\r\n // 找空白行\r\n const usedRows = new Set(s.words.map((w) => w.row));\r\n let row = -1;\r\n for (let r = SCORE_H; r < GAME_H; r++) {\r\n if (!usedRows.has(r)) { row = r; break; }\r\n }\r\n if (row >= 0) {\r\n s.words.push({ text, row, col: GAME_W - 1 });\r\n s.usedWords.add(text);\r\n }\r\n }\r\n }\r\n\r\n // 移动单词\r\n for (const w of s.words) {\r\n w.col -= s.speed;\r\n }\r\n\r\n // 移除超出左边的 + 更新目标\r\n const before = s.words.length;\r\n s.words = s.words.filter((w) => w.col > -w.text.length);\r\n const removed = before - s.words.length;\r\n\r\n // 单词漏掉了 → 扣命\r\n if (removed > 0) {\r\n s.lives -= removed;\r\n s.typed = \"\";\r\n s.target = pickTarget(s);\r\n if (s.lives <= 0) {\r\n s.gameOver = true;\r\n s.words = [];\r\n }\r\n }\r\n\r\n // 更新目标\r\n s.target = pickTarget(s);\r\n\r\n // 消息计时\r\n if (s.messageTimer > 0) {\r\n s.messageTimer--;\r\n if (s.messageTimer <= 0) s.message = \"\";\r\n }\r\n}\r\n\r\n// ─── 画面渲染 ──────────────────────────────────────────────────\r\n\r\nfunction buildGameView(s: GameState, scoreLines: string[], scoreColor: string, message: string): string[] {\r\n const rows: string[] = [];\r\n\r\n for (let y = 0; y < GAME_H; y++) {\r\n let line = \"\";\r\n\r\n // 分数区域(前 6 行)\r\n if (y < SCORE_H) {\r\n if (y < 5) {\r\n // 数字行 — 先补足宽度再套赛博朋克色\r\n const raw = (scoreLines[y] ?? \"\").padEnd(GAME_W);\r\n line = `\\x1b[38;2;${hexToRgb(scoreColor)}m${raw}\\x1b[0m`;\r\n } else if (y === 5) {\r\n // 第 6 行:连击 / 暂停\r\n if (s.combo >= 3) {\r\n const comboText = `${s.combo}连击!`;\r\n const pad = Math.floor((GAME_W - comboText.length) / 2);\r\n const comboColor = CYBER_PALETTE[s.combo % CYBER_PALETTE.length] as string;\r\n const raw = \" \".repeat(pad) + comboText + \" \".repeat(GAME_W - pad - comboText.length);\r\n line = `\\x1b[38;2;${hexToRgb(comboColor)}m${raw}\\x1b[0m`;\r\n } else if (s.paused) {\r\n const pauseText = \"暂停\";\r\n const pad = Math.floor((GAME_W - pauseText.length) / 2);\r\n line = \" \".repeat(pad) + pauseText;\r\n line = line.padEnd(GAME_W);\r\n }\r\n }\r\n // 补全到 GAME_W 宽度\r\n line = line.padEnd(GAME_W);\r\n } else {\r\n // 单词区域\r\n // 第 1 行显示消息(如果有)\r\n if (y === SCORE_H && message) {\r\n const pad = Math.floor((GAME_W - message.length) / 2);\r\n const raw = \" \".repeat(pad) + message + \" \".repeat(GAME_W - pad - message.length);\r\n const msgColor = CYBER_PALETTE[Math.floor(Math.random() * CYBER_PALETTE.length)] as string;\r\n line = `\\x1b[38;2;${hexToRgb(msgColor)}m${raw}\\x1b[0m`;\r\n } else {\r\n for (let x = 0; x < GAME_W; x++) {\r\n const word = s.words.find((w) => {\r\n const charIdx = x - Math.floor(w.col);\r\n return charIdx >= 0 && charIdx < w.text.length && w.row === y;\r\n });\r\n if (word) {\r\n const charIdx = x - Math.floor(word.col);\r\n const ch = word.text[charIdx] as string;\r\n const isTarget = word.text === s.target;\r\n const typedIdx = s.target === word.text ? s.typed.length : 0;\r\n const isTyped = isTarget && charIdx < typedIdx;\r\n if (isTarget) {\r\n line += isTyped ? `\\x1b[92m${ch}\\x1b[0m` : `\\x1b[97m${ch}\\x1b[0m`;\r\n } else {\r\n line += `\\x1b[90m${ch}\\x1b[0m`;\r\n }\r\n } else {\r\n line += \" \";\r\n }\r\n }\r\n }\r\n }\r\n\r\n rows.push(line);\r\n }\r\n return rows;\r\n}\r\n\r\n// ─── Ink 组件 ──────────────────────────────────────────────────\r\n\r\ninterface CoderCheckProps {\r\n onExit: () => void;\r\n}\r\n\r\nfunction CoderCheck({ onExit: _onExit }: CoderCheckProps) {\r\n const stateRef = useRef<GameState>(createInitialState());\r\n const [tick, setTick] = useState(0);\r\n const [colorOffset, setColorOffset] = useState(0);\r\n const onExitRef = useRef(_onExit);\r\n onExitRef.current = _onExit;\r\n\r\n // 赛博朋克颜色动画\r\n useEffect(() => {\r\n const timer = setInterval(() => {\r\n setColorOffset((prev) => (prev + 1) % CYBER_PALETTE.length);\r\n }, 400);\r\n return () => clearInterval(timer);\r\n }, []);\r\n\r\n // 游戏循环\r\n useEffect(() => {\r\n const interval = setInterval(() => {\r\n update(stateRef.current);\r\n setTick((t) => t + 1);\r\n }, 60);\r\n return () => clearInterval(interval);\r\n }, []);\r\n\r\n useInput(\r\n useCallback((input, key) => {\r\n const s = stateRef.current;\r\n if (s.gameOver) {\r\n if (input === \"r\") {\r\n stateRef.current = createInitialState();\r\n setTick(0);\r\n } else if (input === \"q\" || key.escape) {\r\n onExitRef.current();\r\n }\r\n return;\r\n }\r\n\r\n if ((input === \"p\" && key.ctrl) || input === \" \") {\r\n s.paused = !s.paused;\r\n return;\r\n }\r\n if ((input === \"q\" && key.ctrl) || key.escape) {\r\n onExitRef.current();\r\n return;\r\n }\r\n\r\n if (s.paused) return;\r\n\r\n // 打字输入\r\n if (input.length === 1 && input >= \"a\" && input <= \"z\") {\r\n // 选取目标\r\n if (!s.target) {\r\n s.target = pickTarget(s);\r\n }\r\n if (s.target) {\r\n const nextChar = s.target[s.typed.length];\r\n if (nextChar === input) {\r\n s.typed += input;\r\n // 检查是否完成\r\n if (s.typed === s.target) {\r\n // 移除该单词\r\n s.words = s.words.filter((w) => w.text !== s.target);\r\n s.combo++;\r\n // 连击 >= 3 时以当前分数翻倍奖励\r\n const prevScore = s.score;\r\n const basePts = s.target.length;\r\n const comboBonus = s.combo >= 3 ? s.score : 0;\r\n s.score += basePts + comboBonus;\r\n s.speed = s.speed + 0.02;\r\n\r\n // 每 500 分提速\r\n const prevMilestone = Math.floor(prevScore / 500);\r\n const newMilestone = Math.floor(s.score / 500);\r\n if (newMilestone > prevMilestone) {\r\n s.speed += 0.15;\r\n }\r\n\r\n // 超过 99999 分提示通关\r\n if (s.score >= 100000 && prevScore < 100000) {\r\n s.message = \"恭喜通关! 难度最大化!\";\r\n s.messageTimer = 100;\r\n }\r\n s.typed = \"\";\r\n s.target = pickTarget(s);\r\n }\r\n } else {\r\n // 打错字符,连击中断\r\n s.combo = 0;\r\n }\r\n }\r\n }\r\n }, []),\r\n );\r\n\r\n const s = stateRef.current;\r\n const scoreColor = CYBER_PALETTE[colorOffset] as string;\r\n const scoreStr = String(s.score).padStart(5, \"0\");\r\n const scoreLines = buildScoreLines(scoreStr);\r\n const view = buildGameView(s, scoreLines, scoreColor, s.message);\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n void tick;\r\n\r\n return (\r\n <Box flexDirection=\"column\" paddingX={1}>\r\n {/* 顶栏:生命 + 速度 */}\r\n <Box flexDirection=\"row\">\r\n <Text>\r\n 生命 <Text color=\"red\">{\"♥\".repeat(Math.max(0, s.lives))}</Text>\r\n {\" \"}速度 <Text color=\"cyan\">Lv.{Math.floor(s.speed * 10)}</Text>\r\n </Text>\r\n </Box>\r\n\r\n {/* 目标单词提示 */}\r\n {!s.gameOver && s.target && (\r\n <Box marginTop={1}>\r\n <Text>\r\n 打字: <Text color=\"green\">{s.typed}</Text>\r\n <Text color=\"white\">{s.target.slice(s.typed.length)}</Text>\r\n </Text>\r\n </Box>\r\n )}\r\n\r\n {/* 游戏画面(含分数) */}\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n <Text>┌{\"─\".repeat(GAME_W)}┐</Text>\r\n {view.map((row, i) => (\r\n <Text key={i}>{`│${row}│`}</Text>\r\n ))}\r\n <Text>└{\"─\".repeat(GAME_W)}┘</Text>\r\n </Box>\r\n\r\n {/* 游戏结束 */}\r\n {s.gameOver && (\r\n <Box marginTop={1}>\r\n <Text bold color=\"red\">\r\n 游戏结束!\r\n </Text>\r\n <Text>\r\n {\" 得分: \"}<Text color=\"yellow\">{s.score}</Text>\r\n {\" r 重开 q 退出\"}\r\n </Text>\r\n </Box>\r\n )}\r\n\r\n {/* 操作提示 */}\r\n <Box marginTop={1}>\r\n <Text dimColor>\r\n {\"打字消除单词 空格/Ctrl+P暂停 Ctrl+Q退出\"}\r\n </Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n\r\n// ─── 导出 ──────────────────────────────────────────────────────\r\n\r\nexport default {\r\n id: \"coder-check\",\r\n name: \"Coder Check\",\r\n description: \"极速打字游戏,输入单词消除它们!\",\r\n play: async () => {\r\n await new Promise<void>((resolve) => {\r\n const { unmount } = render(\r\n <CoderCheck onExit={() => { unmount(); resolve(); }} />,\r\n );\r\n });\r\n },\r\n};\r\n","import { registerGame, listGames } from \"./index.js\";\r\nimport type { Game } from \"./index.js\";\r\nimport brickBreaker from \"./brick-breaker/index.js\";\r\nimport coderCheck from \"./coder-check/index.js\";\r\n\r\n/** 在此注册所有游戏 */\r\nexport function initGames(): Game[] {\r\n registerGame(brickBreaker);\r\n registerGame(coderCheck);\r\n return listGames();\r\n}\r\n","/** dskcode 退出码规范 */\r\nexport const ExitCode = {\r\n /** 正常执行完成 */\r\n SUCCESS: 0,\r\n /** 通用错误 */\r\n GENERAL_ERROR: 1,\r\n /** 配置错误 */\r\n CONFIG_ERROR: 2,\r\n /** 用户通过 Ctrl+C 中断 */\r\n SIGINT: 130,\r\n} as const;\r\n","#!/usr/bin/env node\r\n\r\nimport { createCli } from \"./cli/index.js\";\r\nimport { ExitCode } from \"./cli/exit-codes.js\";\r\n\r\nprocess.on(\"SIGINT\", () => {\r\n process.exit(ExitCode.SIGINT);\r\n});\r\n\r\nconst program = createCli();\r\n\r\ntry {\r\n await program.parseAsync(process.argv);\r\n} catch (err: unknown) {\r\n const error = err as { exitCode?: number; code?: string };\r\n\r\n if (error.code === \"commander.helpDisplayed\" || error.code === \"commander.version\") {\r\n process.exit(error.exitCode ?? ExitCode.SUCCESS);\r\n }\r\n\r\n if (typeof error.exitCode === \"number\") {\r\n process.exit(error.exitCode);\r\n }\r\n\r\n console.error(String(err));\r\n process.exit(ExitCode.GENERAL_ERROR);\r\n}\r\n"],"mappings":"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","names":["program","Text","jsxs","Box","Text","jsx","Box","Text","useEffect","useState","jsx","jsxs","Box","Text","useState","useCallback","jsx","jsxs","Box","Text","useInput","render","useState","useEffect","useCallback","jsx","jsxs","s","Box","Text","useInput","render","useState","useEffect","useRef","useCallback","jsx","jsxs","CYBER_PALETTE","createInitialState","update","useRef","useState","useEffect","useInput","useCallback","s","jsxs","Box","jsx","Text","render","render","chalk","jsx","program"]}
package/package.json CHANGED
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "name": "dskcode",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/Awu12277/deepseek-agent-cli/tree/main"
7
+ },
4
8
  "description": "A DeepSeek-native AI coding agent for your terminal",
5
9
  "type": "module",
6
10
  "bin": {