arona-agent 1.0.0

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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +149 -0
  3. package/assets/blue-archive/arona/spine/arona_spr.atlas.txt +1168 -0
  4. package/assets/blue-archive/arona/spine/arona_spr.png +0 -0
  5. package/assets/blue-archive/arona/spine/arona_spr.skel +0 -0
  6. package/assets/blue-archive/arona/voice.mp3 +0 -0
  7. package/assets/blue-archive/hoshino/hoshino_spr.atlas.txt +174 -0
  8. package/assets/blue-archive/hoshino/hoshino_spr.json +15385 -0
  9. package/assets/blue-archive/hoshino/hoshino_spr.png +0 -0
  10. package/assets/blue-archive/hoshino/hoshino_spr.skel +0 -0
  11. package/assets/blue-archive/hoshino/robber/hoshino_robber_spr.atlas.txt +111 -0
  12. package/assets/blue-archive/hoshino/robber/hoshino_robber_spr.png +0 -0
  13. package/assets/blue-archive/hoshino/robber/hoshino_robber_spr.skel +0 -0
  14. package/assets/blue-archive/hoshino/swimsuit/hoshino_swimsuit_spr.atlas.txt +251 -0
  15. package/assets/blue-archive/hoshino/swimsuit/hoshino_swimsuit_spr.png +0 -0
  16. package/assets/blue-archive/hoshino/swimsuit/hoshino_swimsuit_spr.skel +0 -0
  17. package/assets/blue-archive/hoshino/voice.mp3 +0 -0
  18. package/assets/blue-archive/plana/spine/plana_spr.atlas.txt +1266 -0
  19. package/assets/blue-archive/plana/spine/plana_spr.png +0 -0
  20. package/assets/blue-archive/plana/spine/plana_spr.skel +0 -0
  21. package/assets/blue-archive/plana/voice.mp3 +0 -0
  22. package/assets/blue-archive/shiroko/ridingsuit/shiroko_ridingsuit_spr.atlas.txt +97 -0
  23. package/assets/blue-archive/shiroko/ridingsuit/shiroko_ridingsuit_spr.png +0 -0
  24. package/assets/blue-archive/shiroko/ridingsuit/shiroko_ridingsuit_spr.skel +0 -0
  25. package/assets/blue-archive/shiroko/robber/shiroko_robber_spr.atlas.txt +174 -0
  26. package/assets/blue-archive/shiroko/robber/shiroko_robber_spr.png +0 -0
  27. package/assets/blue-archive/shiroko/robber/shiroko_robber_spr.skel +0 -0
  28. package/assets/blue-archive/shiroko/shiroko_spr.atlas.txt +167 -0
  29. package/assets/blue-archive/shiroko/shiroko_spr.json +10702 -0
  30. package/assets/blue-archive/shiroko/shiroko_spr.png +0 -0
  31. package/assets/blue-archive/shiroko/shiroko_spr.skel +0 -0
  32. package/assets/blue-archive/shiroko/voice.mp3 +0 -0
  33. package/bin/arona.mjs +43 -0
  34. package/package.json +37 -0
  35. package/pet/agents.cjs +197 -0
  36. package/pet/main.cjs +462 -0
  37. package/pet/preload.cjs +21 -0
  38. package/pet/renderer/fx.html +30 -0
  39. package/pet/renderer/fx.js +41 -0
  40. package/pet/renderer/gallery.html +18 -0
  41. package/pet/renderer/gallery.js +31 -0
  42. package/pet/renderer/index.html +18 -0
  43. package/pet/renderer/renderer.js +382 -0
  44. package/pet/renderer/spine_layer.js +609 -0
  45. package/pet/renderer/spinetest.html +24 -0
  46. package/pet/renderer/spinetest.js +295 -0
  47. package/pet/renderer/style.css +63 -0
  48. package/pet/tools/gallery_capture.cjs +267 -0
  49. package/pet/tools/gen_sway.cjs +170 -0
  50. package/pet/tools/meshify_region.cjs +105 -0
  51. package/pet/tools/skel_inspect.cjs +112 -0
  52. package/pet/tools/skel_to_json.cjs +410 -0
  53. package/pet/tools/spine_node.cjs +69 -0
  54. package/pet/tools/visual_test.cjs +262 -0
  55. package/pet/vendor/spine/spine-canvas.js +8472 -0
  56. package/pet/vendor/spine/spine-webgl.js +10839 -0
  57. package/python/__pycache__/_i18n.cpython-313.pyc +0 -0
  58. package/python/__pycache__/_i18n.cpython-314.pyc +0 -0
  59. package/python/__pycache__/computer_use.cpython-314.pyc +0 -0
  60. package/python/__pycache__/hotkey.cpython-313.pyc +0 -0
  61. package/python/__pycache__/hotkey.cpython-314.pyc +0 -0
  62. package/python/__pycache__/stt.cpython-313.pyc +0 -0
  63. package/python/__pycache__/stt.cpython-314.pyc +0 -0
  64. package/python/__pycache__/tts.cpython-313.pyc +0 -0
  65. package/python/__pycache__/tts.cpython-314.pyc +0 -0
  66. package/python/__pycache__/tts_stream.cpython-313.pyc +0 -0
  67. package/python/__pycache__/tts_stream.cpython-314.pyc +0 -0
  68. package/python/__pycache__/voice_clone.cpython-314.pyc +0 -0
  69. package/python/_i18n.py +18 -0
  70. package/python/computer_use.py +190 -0
  71. package/python/hotkey.py +196 -0
  72. package/python/stt.py +240 -0
  73. package/python/tts_say.py +177 -0
  74. package/python/voice_clone.py +98 -0
  75. package/requirements.txt +6 -0
  76. package/src/agent.ts +791 -0
  77. package/src/agent_registry.ts +109 -0
  78. package/src/commands.ts +641 -0
  79. package/src/config.ts +245 -0
  80. package/src/in_memory_credentials.ts +61 -0
  81. package/src/index.ts +78 -0
  82. package/src/locale.ts +131 -0
  83. package/src/logo.ts +120 -0
  84. package/src/mcp.ts +192 -0
  85. package/src/memory.ts +303 -0
  86. package/src/pet.ts +346 -0
  87. package/src/renderer.ts +350 -0
  88. package/src/repl.ts +902 -0
  89. package/src/setup.ts +371 -0
  90. package/src/skills.ts +96 -0
  91. package/src/slash_menu.ts +371 -0
  92. package/src/slash_registry.ts +53 -0
  93. package/src/speaker_context.ts +41 -0
  94. package/src/text_split.ts +79 -0
  95. package/src/tools/computer_use.ts +142 -0
  96. package/src/tools/emotion_tool.ts +55 -0
  97. package/src/tools/keep_silent_tool.ts +26 -0
  98. package/src/tools/memory_tool.ts +24 -0
  99. package/src/tools/skill_tools.ts +100 -0
  100. package/src/tools/tavily_tools.ts +431 -0
  101. package/src/tools/voice_tools.ts +28 -0
  102. package/src/tts_stream.ts +260 -0
  103. package/src/tui_select.ts +146 -0
  104. package/src/undo.ts +451 -0
  105. package/src/utils/python.ts +211 -0
  106. package/src/utils/spawn.ts +56 -0
  107. package/src/voice.ts +83 -0
  108. package/src/voice_cli.ts +198 -0
  109. package/src/voices.ts +135 -0
package/bin/arona.mjs ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ // ARONA CLI entry point. Node 22's --experimental-strip-types refuses to load
3
+ // .ts files inside node_modules/, so we use `tsx` (shipped as a regular dep) as
4
+ // a child-process runner. `tsx` is a self-contained .ts loader that handles
5
+ // ESM, CJS, and node_modules code paths.
6
+ import { spawn } from 'node:child_process';
7
+ import { existsSync } from 'node:fs';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { dirname, join } from 'node:path';
10
+
11
+ const __dirname = dirname(fileURLToPath(import.meta.url));
12
+ const root = join(__dirname, '..');
13
+ const args = process.argv.slice(2);
14
+
15
+ const isSetup = args[0] === 'setup';
16
+ const isVoice = args[0] === 'voice';
17
+ const target = isSetup ? 'src/setup.ts' : isVoice ? 'src/voice_cli.ts' : 'src/index.ts';
18
+ const passArgs = (isSetup || isVoice) ? args.slice(1) : args;
19
+
20
+ // tsx ships a CLI binary alongside the package. We prefer the local install.
21
+ const tsxBin = process.platform === 'win32'
22
+ ? join(root, 'node_modules', '.bin', 'tsx.cmd')
23
+ : join(root, 'node_modules', '.bin', 'tsx');
24
+
25
+ if (!existsSync(tsxBin)) {
26
+ // 此文件无法 import TS,内联判定语言(仅环境变量)
27
+ const isEn = /^en/i.test(process.env.LANG ?? "");
28
+ console.error(
29
+ isEn
30
+ ? `Error: tsx not found at ${tsxBin}.\nRun \`npm install\` in ${root} (or run \`arona setup\` to install dependencies).`
31
+ : `错误:未找到 tsx(${tsxBin})。\n请在 ${root} 运行 \`npm install\`(或运行 \`arona setup\` 安装依赖)。`,
32
+ );
33
+ process.exit(1);
34
+ }
35
+
36
+ const child = spawn(tsxBin, [join(root, target), ...passArgs], {
37
+ stdio: 'inherit',
38
+ cwd: root,
39
+ // Windows: tsxBin 是 .cmd 批处理文件。Node >=20.12.2/18.20.2(CVE-2024-27980 修复,2024-04-10)
40
+ // 起,spawn .bat/.cmd 且不设 shell 会直接抛 EINVAL,导致 `arona setup` 在 Windows 上无法启动。
41
+ shell: process.platform === 'win32',
42
+ });
43
+ child.on('exit', (code) => process.exit(code ?? 0));
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "arona-agent",
3
+ "version": "1.0.0",
4
+ "description": "Terminal AI Agent with desktop pet Arona — eye-tracking pupils, voice cloning, Computer Use, TTS/STT, MCP.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "arona": "bin/arona.mjs"
9
+ },
10
+ "files": [
11
+ "src/",
12
+ "python/",
13
+ "pet/",
14
+ "assets/blue-archive/",
15
+ "bin/",
16
+ "requirements.txt"
17
+ ],
18
+ "scripts": {
19
+ "start": "tsx src/index.ts",
20
+ "dev": "tsx watch src/index.ts"
21
+ },
22
+ "dependencies": {
23
+ "@earendil-works/pi-ai": "^0.84.1",
24
+ "@earendil-works/pi-coding-agent": "^0.84.1",
25
+ "@modelcontextprotocol/sdk": "^1.30.0",
26
+ "@types/figlet": "^1.7.0",
27
+ "ba-click-fx": "^1.2.29",
28
+ "chalk": "^5.3.0",
29
+ "electron": "^43.3.0",
30
+ "figlet": "^1.11.4",
31
+ "tsx": "^4.20.0",
32
+ "typebox": "^1.3.0"
33
+ },
34
+ "engines": {
35
+ "node": ">=22.19.0"
36
+ }
37
+ }
package/pet/agents.cjs ADDED
@@ -0,0 +1,197 @@
1
+ // 桌宠角色配置(pet 侧单一事实源,替代旧 emotions.cjs)。
2
+ // 每个 Agent 独立定义:spine 资源路径、动画/骨名、情绪映射、闭眼/禁跟随预设集合。
3
+ // main.cjs 按 ARONA_AGENT 环境变量(默认 arona)选择;renderer 经 pet:get-agent-config 获取。
4
+ // 情绪键 = main.cjs 的情绪白名单(17 个,与 change_emotion 工具一致,勿改键);
5
+ // 值 = 数字预设动画名,renderer 构建 EMOTION_PRESET。
6
+ // 映射为用户对照目视图库逐项选定,以图库实际渲染效果为准。
7
+
8
+ const ARONA = {
9
+ id: "arona",
10
+ spineBase: "../../assets/blue-archive/arona/spine/",
11
+ skelFile: "arona_spr.skel",
12
+ atlasFile: "arona_spr.atlas.txt",
13
+ // 构图放大系数(fitCamera 用):Arona bounds 1:2.105 填满 320×674 窗口,保持 1.0
14
+ extraScale: 1,
15
+ anims: {
16
+ idle: "Idle_01", // 3.333s 全身循环。setup pose 是瘫开的折叠姿势,绝不能裸显
17
+ blink: "Eye_Close_01", // 闭眼(只 key 眼部 cover + 眉毛 translate,可安全叠加)
18
+ pat: "Pat_01_A", // 摸头静态 pose:闭眼 cover + 嘴(attachment 版)
19
+ patPose: "Pat_01_M", // 摸头静态 pose:眉毛 translate(M 版)
20
+ look: "Look_01_M", // 注视姿态(单帧 pose,含嘴部微动)
21
+ lookEnd: "LookEnd_01_M", // 回中
22
+ },
23
+ bones: {
24
+ head: "Head_Rot",
25
+ eyeL: "L_Eye_01",
26
+ eyeR: "R_Eye_01",
27
+ },
28
+ emotions: {
29
+ angry: "05",
30
+ assured: "22",
31
+ curious: "02",
32
+ delighted: "12",
33
+ desire: "21",
34
+ dizzy: "30",
35
+ doubt: "27",
36
+ dreaming: "23",
37
+ enjoy: "13",
38
+ excited: "12",
39
+ jealous: "07",
40
+ love: "11",
41
+ saying: "20",
42
+ scared: "04",
43
+ shame: "18",
44
+ smile: "99",
45
+ tired: "24",
46
+ },
47
+ // 闭眼预设:该预设 key 了 L/R_Eye_Cover → 情绪期间禁止眨眼
48
+ // (Eye_Close_01 播完末帧会把 cover 置 null,闭眼预设上眨眼会闪出"睁眼")
49
+ closedEyePresets: [
50
+ "03", "10", "11", "12", "13", "14", "18", "23", "24", "26", "27", "28", "29", "30", "32", "99",
51
+ ],
52
+ // 睁眼预设默认保留瞳孔跟随;以下预设禁跟随:jealous(07) 自带固定斜视(跟随会覆盖)、
53
+ // angry(05) 眼神固定不跟光标、doubt(27) 闭眼本就关闭(显式列出以便理解)
54
+ noGazePresets: ["05", "07", "27"],
55
+ };
56
+
57
+ const PLANA = {
58
+ id: "plana",
59
+ spineBase: "../../assets/blue-archive/plana/spine/",
60
+ skelFile: "plana_spr.skel",
61
+ atlasFile: "plana_spr.atlas.txt",
62
+ // 构图放大系数:Plana bounds 1154×2216(1:1.92,比例偏宽)→ 宽度先顶格,身高只占窗口 91%,
63
+ // 比 Arona(满窗 99.9%)矮 ~9%;1.10 使其身高 ≈ Arona(两侧各裁 ~16px,一般只裁到光环/发梢边缘)
64
+ extraScale: 1.1,
65
+ anims: {
66
+ idle: "Idle_01", // 6.667s 全身循环(与 Arona 的 3.333s 不同,勿改)
67
+ blink: "Eye_Close_01", // 0.333s 闭眼
68
+ pat: "Pat_01_A", // 摸头静态 pose:闭眼 cover + 嘴(attachment 版)
69
+ patPose: "Pat_01_M", // 摸头静态 pose:眉毛 translate(M 版)
70
+ look: "Look_01_M", // 注视姿态(单帧 pose)
71
+ lookEnd: "LookEnd_01_M", // 回中(0.433s)
72
+ },
73
+ bones: {
74
+ head: "Head_Rot",
75
+ eyeL: "L_Eye_01",
76
+ // ⚠️ Plana 右眼骨是 R_Eye_1(无前导零),Arona 是 R_Eye_01——勿"修正"
77
+ eyeR: "R_Eye_1",
78
+ },
79
+ emotions: {
80
+ // 用户 2026-08-15 对照重绑版图库(plana_emotions_rebind_*.html,无水印防错位版)重新指定;
81
+ // 共用预设:jealous/doubt=20;love/smile=17;delighted/excited=09(合并,与 Arona 12 同语义);
82
+ // dreaming/enjoy/scared/shame=14;desire/saying=18
83
+ angry: "05",
84
+ assured: "03",
85
+ curious: "07",
86
+ delighted: "09",
87
+ desire: "18",
88
+ dizzy: "13",
89
+ doubt: "20",
90
+ dreaming: "14",
91
+ enjoy: "14",
92
+ excited: "09",
93
+ jealous: "20",
94
+ love: "17",
95
+ saying: "18",
96
+ scared: "14",
97
+ shame: "14",
98
+ smile: "17",
99
+ tired: "06",
100
+ },
101
+ // 闭眼预设(客观普查:cover slot 非空,probe_cover 转储):闭眼预设期间禁止眨眼、关闭瞳孔跟随
102
+ closedEyePresets: ["04", "05", "06", "10", "11", "12", "13", "14", "16", "17", "99"],
103
+ // 禁跟随预设:05 闭眼冗余无害;07(curious)按 Arona 同源保留固定斜视,待用户目视确认跟随是否别扭
104
+ noGazePresets: ["05", "07"],
105
+ };
106
+
107
+ // ---- 精灵图切换式角色(Shiroko / Hoshino)----
108
+ // 与 Arona/Plana 的骨脸完全不同:仅 root / PC_Layer / halo 三骨,无 Head_Rot、无眼骨;
109
+ // 表情 = 数字预设整张 sprite 切换(Shiroko 切 00_default slot,Hoshino 切全 11 slot)。
110
+ // 仅 Idle_01(身体摆动)+ Eye_Close_01(眨眼),无 Look/Pat 动画。
111
+ // 闭眼/禁跟随集合为空:没有骨脸瞳孔跟随,自然不需要这些集合。
112
+
113
+ const SHIROKO = {
114
+ id: "shiroko",
115
+ // ⚠️ 资源直接放在 assets/blue-archive/shiroko/(无 spine/ 子目录,与 arona/plana 不同)
116
+ spineBase: "../../assets/blue-archive/shiroko/",
117
+ // .json = skel_to_json.cjs 导出 + gen_sway.cjs 注入衣摆微动(Idle_01 deform);
118
+ // 重新生成顺序:先 skel_to_json 再 gen_sway(只跑 skel_to_json 会覆盖掉形变)
119
+ skelFile: "shiroko_spr.json",
120
+ atlasFile: "shiroko_spr.atlas.txt",
121
+ // bounds 1133×2287(高 95.8%)→ 保持 1.0
122
+ extraScale: 1,
123
+ anims: {
124
+ idle: "Idle_01",
125
+ blink: "Eye_Close_01",
126
+ // 无 pat/look 动画:摸头走 emotion 预设 + PC_Layer 微倾斜
127
+ },
128
+ bones: {},
129
+ // 用户 2026-08-18 对照图库重绑:数字预设 00~17+99(19 个)
130
+ emotions: {
131
+ angry: "06",
132
+ assured: "05",
133
+ curious: "02",
134
+ delighted: "03",
135
+ desire: "09",
136
+ dizzy: "08",
137
+ doubt: "10",
138
+ dreaming: "03",
139
+ enjoy: "03",
140
+ excited: "03",
141
+ jealous: "02",
142
+ love: "04",
143
+ saying: "02",
144
+ scared: "07",
145
+ shame: "08",
146
+ smile: "03",
147
+ tired: "16",
148
+ },
149
+ closedEyePresets: [],
150
+ noGazePresets: [],
151
+ // 摸头:emotion 预设 + 仅旋转脸部/头发 Mesh(tiltSlots),避免 PC_Layer 整身晃动
152
+ pat: { type: "emotion", emotion: "enjoy", tiltSlots: ["00_default", "Hair_Cover", "eyeclose"] },
153
+ };
154
+
155
+ const HOSHINO = {
156
+ id: "hoshino",
157
+ spineBase: "../../assets/blue-archive/hoshino/",
158
+ // .json = skel_to_json 导出 + meshify_region 身体网格化(6×10) + gen_sway 衣摆形变;
159
+ // 重新生成顺序:skel_to_json → meshify_region → gen_sway(任何前一步都会覆盖后一步产物)
160
+ skelFile: "hoshino_spr.json",
161
+ atlasFile: "hoshino_spr.atlas.txt",
162
+ // bounds 1161×2074(高 84.8%)→ 1.1 使身高接近 Arona
163
+ extraScale: 1.1,
164
+ anims: {
165
+ idle: "Idle_01",
166
+ blink: "Eye_Close_01",
167
+ },
168
+ bones: {},
169
+ // 用户 2026-08-18 对照图库重绑:数字预设 00~17+99(19 个)
170
+ emotions: {
171
+ angry: "06",
172
+ assured: "01",
173
+ curious: "04",
174
+ delighted: "03",
175
+ desire: "17",
176
+ dizzy: "12",
177
+ doubt: "17",
178
+ dreaming: "11",
179
+ enjoy: "11",
180
+ excited: "03",
181
+ jealous: "07",
182
+ love: "12",
183
+ saying: "17",
184
+ scared: "12",
185
+ shame: "12",
186
+ smile: "14",
187
+ tired: "99",
188
+ },
189
+ closedEyePresets: [],
190
+ noGazePresets: [],
191
+ // 用户需求:星野不做摸头适配
192
+ pat: { type: "none" },
193
+ };
194
+
195
+ const AGENTS = { arona: ARONA, plana: PLANA, shiroko: SHIROKO, hoshino: HOSHINO };
196
+
197
+ module.exports = { AGENTS };