okit-cli 0.0.1

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 (88) hide show
  1. package/README.md +222 -0
  2. package/dist/commands/check.d.ts +13 -0
  3. package/dist/commands/check.d.ts.map +1 -0
  4. package/dist/commands/check.js +259 -0
  5. package/dist/commands/check.js.map +1 -0
  6. package/dist/commands/claude.d.ts +10 -0
  7. package/dist/commands/claude.d.ts.map +1 -0
  8. package/dist/commands/claude.js +504 -0
  9. package/dist/commands/claude.js.map +1 -0
  10. package/dist/commands/menu.d.ts +3 -0
  11. package/dist/commands/menu.d.ts.map +1 -0
  12. package/dist/commands/menu.js +152 -0
  13. package/dist/commands/menu.js.map +1 -0
  14. package/dist/commands/repo.d.ts +3 -0
  15. package/dist/commands/repo.d.ts.map +1 -0
  16. package/dist/commands/repo.js +266 -0
  17. package/dist/commands/repo.js.map +1 -0
  18. package/dist/commands/uninstall.d.ts +2 -0
  19. package/dist/commands/uninstall.d.ts.map +1 -0
  20. package/dist/commands/uninstall.js +125 -0
  21. package/dist/commands/uninstall.js.map +1 -0
  22. package/dist/commands/upgrade.d.ts +6 -0
  23. package/dist/commands/upgrade.d.ts.map +1 -0
  24. package/dist/commands/upgrade.js +204 -0
  25. package/dist/commands/upgrade.js.map +1 -0
  26. package/dist/config/i18n.d.ts +141 -0
  27. package/dist/config/i18n.d.ts.map +1 -0
  28. package/dist/config/i18n.js +316 -0
  29. package/dist/config/i18n.js.map +1 -0
  30. package/dist/config/registry.d.ts +24 -0
  31. package/dist/config/registry.d.ts.map +1 -0
  32. package/dist/config/registry.js +388 -0
  33. package/dist/config/registry.js.map +1 -0
  34. package/dist/config/user.d.ts +32 -0
  35. package/dist/config/user.d.ts.map +1 -0
  36. package/dist/config/user.js +72 -0
  37. package/dist/config/user.js.map +1 -0
  38. package/dist/executor/deps/BrewDependencyProvider.d.ts +8 -0
  39. package/dist/executor/deps/BrewDependencyProvider.d.ts.map +1 -0
  40. package/dist/executor/deps/BrewDependencyProvider.js +52 -0
  41. package/dist/executor/deps/BrewDependencyProvider.js.map +1 -0
  42. package/dist/executor/deps/DependencyProvider.d.ts +11 -0
  43. package/dist/executor/deps/DependencyProvider.d.ts.map +1 -0
  44. package/dist/executor/deps/DependencyProvider.js +3 -0
  45. package/dist/executor/deps/DependencyProvider.js.map +1 -0
  46. package/dist/executor/deps/NpmDependencyProvider.d.ts +12 -0
  47. package/dist/executor/deps/NpmDependencyProvider.d.ts.map +1 -0
  48. package/dist/executor/deps/NpmDependencyProvider.js +78 -0
  49. package/dist/executor/deps/NpmDependencyProvider.js.map +1 -0
  50. package/dist/executor/deps/PipxDependencyProvider.d.ts +8 -0
  51. package/dist/executor/deps/PipxDependencyProvider.d.ts.map +1 -0
  52. package/dist/executor/deps/PipxDependencyProvider.js +32 -0
  53. package/dist/executor/deps/PipxDependencyProvider.js.map +1 -0
  54. package/dist/executor/deps/UvToolDependencyProvider.d.ts +8 -0
  55. package/dist/executor/deps/UvToolDependencyProvider.d.ts.map +1 -0
  56. package/dist/executor/deps/UvToolDependencyProvider.js +35 -0
  57. package/dist/executor/deps/UvToolDependencyProvider.js.map +1 -0
  58. package/dist/executor/plan/ExecutionPlanner.d.ts +13 -0
  59. package/dist/executor/plan/ExecutionPlanner.d.ts.map +1 -0
  60. package/dist/executor/plan/ExecutionPlanner.js +109 -0
  61. package/dist/executor/plan/ExecutionPlanner.js.map +1 -0
  62. package/dist/executor/plan/TopologicalSorter.d.ts +3 -0
  63. package/dist/executor/plan/TopologicalSorter.d.ts.map +1 -0
  64. package/dist/executor/plan/TopologicalSorter.js +49 -0
  65. package/dist/executor/plan/TopologicalSorter.js.map +1 -0
  66. package/dist/executor/plan/registryDeps.d.ts +3 -0
  67. package/dist/executor/plan/registryDeps.d.ts.map +1 -0
  68. package/dist/executor/plan/registryDeps.js +22 -0
  69. package/dist/executor/plan/registryDeps.js.map +1 -0
  70. package/dist/executor/runner.d.ts +13 -0
  71. package/dist/executor/runner.d.ts.map +1 -0
  72. package/dist/executor/runner.js +430 -0
  73. package/dist/executor/runner.js.map +1 -0
  74. package/dist/main.d.ts +3 -0
  75. package/dist/main.d.ts.map +1 -0
  76. package/dist/main.js +244 -0
  77. package/dist/main.js.map +1 -0
  78. package/dist/utils/sound.d.ts +10 -0
  79. package/dist/utils/sound.d.ts.map +1 -0
  80. package/dist/utils/sound.js +36 -0
  81. package/dist/utils/sound.js.map +1 -0
  82. package/dist/web/api/config.js +73 -0
  83. package/dist/web/api/stats.js +130 -0
  84. package/dist/web/public/app.js +284 -0
  85. package/dist/web/public/index.html +367 -0
  86. package/dist/web/public/styles.css +1004 -0
  87. package/dist/web/server.js +41 -0
  88. package/package.json +61 -0
package/dist/main.js ADDED
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const commander_1 = require("commander");
41
+ const kleur_1 = __importDefault(require("kleur"));
42
+ const prompts_1 = __importDefault(require("prompts"));
43
+ const package_json_1 = __importDefault(require("../package.json"));
44
+ const menu_1 = require("./commands/menu");
45
+ const upgrade_1 = require("./commands/upgrade");
46
+ const uninstall_1 = require("./commands/uninstall");
47
+ const repo_1 = require("./commands/repo");
48
+ const check_1 = require("./commands/check");
49
+ const registry_1 = require("./config/registry");
50
+ const i18n_1 = require("./config/i18n");
51
+ const user_1 = require("./config/user");
52
+ const program = new commander_1.Command();
53
+ // 显示 Banner
54
+ function showBanner() {
55
+ const banner = `
56
+ ██████╗ ██╗ ██╗ ██╗ ████████╗
57
+ ██╔═══██╗ ██║ ██╔╝ ██║ ╚══██╔══╝
58
+ ██║ ██║ █████╔╝ ██║ ██║
59
+ ██║ ██║ ██╔═██╗ ██║ ██║
60
+ ╚██████╔╝ ██║ ██╗ ██║ ██║
61
+ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
62
+ `;
63
+ console.log(kleur_1.default.cyan(banner));
64
+ console.log(kleur_1.default.gray(" OKIT v1 - macOS 开发工具管理器\n"));
65
+ }
66
+ program
67
+ .name("okit")
68
+ .description("OKIT v1 - 精简版工具执行器")
69
+ .version(package_json_1.default.version);
70
+ function getUnknownSubcommand() {
71
+ const argv = process.argv.slice(2);
72
+ const firstArg = argv.find((arg) => !arg.startsWith("-"));
73
+ if (!firstArg)
74
+ return null;
75
+ const known = new Set(program.commands.map((cmd) => cmd.name()));
76
+ return known.has(firstArg) ? null : firstArg;
77
+ }
78
+ // 语言选择(首次运行时显示)
79
+ async function selectLanguageIfNeeded() {
80
+ // 先尝试加载已保存的语言配置
81
+ const savedLang = await (0, i18n_1.loadLanguageConfig)();
82
+ if (savedLang) {
83
+ // 已有配置,直接使用
84
+ (0, i18n_1.setLanguage)(savedLang);
85
+ return;
86
+ }
87
+ // 首次运行,显示语言选择
88
+ const response = await (0, prompts_1.default)({
89
+ type: "select",
90
+ name: "lang",
91
+ message: "选择语言 / Select language",
92
+ choices: [
93
+ { title: "中文", value: "zh" },
94
+ { title: "English", value: "en" },
95
+ ],
96
+ });
97
+ if (response.lang) {
98
+ (0, i18n_1.setLanguage)(response.lang);
99
+ }
100
+ }
101
+ // 配置 prompts 使用中文提示
102
+ function configurePrompts(lang) {
103
+ if (lang === "zh") {
104
+ // 设置 prompts 的默认提示文本
105
+ prompts_1.default.prompts = {
106
+ ...prompts_1.default.prompts,
107
+ autocomplete: {
108
+ instructions: "上下箭头选择,回车确认,输入过滤",
109
+ },
110
+ autocompleteMultiselect: {
111
+ instructions: "↑/↓: 高亮选项,←/→/空格: 选择/取消,Ctrl+A: 全选/取消全选,回车: 确认,Ctrl+C: 取消",
112
+ },
113
+ multiselect: {
114
+ instructions: "↑/↓: 高亮选项,空格: 选择/取消,Ctrl+A: 全选/取消全选,回车: 确认",
115
+ },
116
+ select: {
117
+ instructions: "↑/↓: 选择,回车: 确认",
118
+ },
119
+ };
120
+ }
121
+ }
122
+ // 默认:交互菜单
123
+ program.action(async () => {
124
+ const unknown = getUnknownSubcommand();
125
+ if (unknown) {
126
+ console.log(kleur_1.default.red(`✗ Unknown command: ${unknown}`));
127
+ program.outputHelp();
128
+ process.exit(1);
129
+ }
130
+ checkPlatform();
131
+ showBanner();
132
+ await selectLanguageIfNeeded();
133
+ configurePrompts((0, i18n_1.getLanguage)());
134
+ await showMainHelpHintOnce();
135
+ await (0, menu_1.showMainMenu)();
136
+ });
137
+ // upgrade 子命令
138
+ program
139
+ .command("upgrade")
140
+ .description("升级 OKIT(默认)或工具")
141
+ .option("--tools", "升级所有工具")
142
+ .option("--menu", "打开升级菜单")
143
+ .action(async (options) => {
144
+ checkPlatform();
145
+ await selectLanguageIfNeeded();
146
+ if (options.menu) {
147
+ await (0, upgrade_1.showUpgradeMenu)();
148
+ return;
149
+ }
150
+ if (options.tools) {
151
+ await (0, upgrade_1.upgradeTools)();
152
+ return;
153
+ }
154
+ await (0, upgrade_1.upgradeSelf)();
155
+ });
156
+ // uninstall 子命令
157
+ program
158
+ .command("uninstall")
159
+ .description("卸载 OKIT")
160
+ .action(async () => {
161
+ checkPlatform();
162
+ await selectLanguageIfNeeded();
163
+ await (0, uninstall_1.uninstallOkit)();
164
+ });
165
+ // claude 子命令
166
+ program
167
+ .command("claude")
168
+ .description("Claude Code 交互菜单")
169
+ .action(async () => {
170
+ checkPlatform();
171
+ await selectLanguageIfNeeded();
172
+ await (0, menu_1.showClaudeMenu)();
173
+ });
174
+ // repo 子命令
175
+ const repo = program
176
+ .command("repo")
177
+ .description("Repo 设置与创建")
178
+ .action(async () => {
179
+ checkPlatform();
180
+ await selectLanguageIfNeeded();
181
+ await (0, repo_1.showRepoMenu)();
182
+ });
183
+ repo
184
+ .command("create")
185
+ .description("创建远程仓库并绑定")
186
+ .action(async () => {
187
+ checkPlatform();
188
+ await selectLanguageIfNeeded();
189
+ await (0, repo_1.createRepositoryFlow)();
190
+ });
191
+ // check 子命令 - 环境健康检查
192
+ program
193
+ .command("check")
194
+ .description("环境健康检查(工具版本、升级、授权状态)")
195
+ .option("--json", "输出 JSON 格式(适合 Agent 消费)")
196
+ .action(async (options) => {
197
+ checkPlatform();
198
+ await selectLanguageIfNeeded();
199
+ await (0, check_1.runCheck)({ json: options.json });
200
+ });
201
+ // reset 子命令 - 不需要选择语言
202
+ program
203
+ .command("reset")
204
+ .description("重置配置为默认")
205
+ .action(async () => {
206
+ checkPlatform();
207
+ // reset 使用默认中文
208
+ (0, i18n_1.setLanguage)("zh");
209
+ await (0, registry_1.resetRegistry)();
210
+ });
211
+ // web 子命令 - 启动 Web UI
212
+ program
213
+ .command("web")
214
+ .description("启动 Claude Code Web UI")
215
+ .option("-p, --port <number>", "端口号", "3000")
216
+ .option("-o, --open", "自动打开浏览器", false)
217
+ .action(async (options) => {
218
+ checkPlatform();
219
+ const port = parseInt(options.port, 10) || 3000;
220
+ // 动态导入 web server
221
+ // @ts-ignore
222
+ const { startServer } = await Promise.resolve().then(() => __importStar(require("./web/server.js")));
223
+ if (options.open) {
224
+ const { exec } = await Promise.resolve().then(() => __importStar(require("child_process")));
225
+ exec(`open http://localhost:${port}`);
226
+ }
227
+ // @ts-ignore
228
+ startServer(port);
229
+ });
230
+ function checkPlatform() {
231
+ if (process.platform !== "darwin") {
232
+ console.log(kleur_1.default.red("✗ 当前仅支持 macOS 平台"));
233
+ process.exit(1);
234
+ }
235
+ }
236
+ async function showMainHelpHintOnce() {
237
+ const config = await (0, user_1.loadUserConfig)();
238
+ if (config.hints?.mainHelpShown)
239
+ return;
240
+ console.log(kleur_1.default.gray((0, i18n_1.t)("mainHelpHint")));
241
+ await (0, user_1.updateUserConfig)({ hints: { mainHelpShown: true } });
242
+ }
243
+ program.parse();
244
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yCAAoC;AACpC,kDAA0B;AAC1B,sDAA8B;AAC9B,mEAAkC;AAClC,0CAA+D;AAC/D,gDAAgF;AAChF,oDAAqD;AACrD,0CAAqE;AACrE,4CAA4C;AAC5C,gDAAkD;AAClD,wCAAwG;AACxG,wCAAiE;AAEjE,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,YAAY;AACZ,SAAS,UAAU;IACjB,MAAM,MAAM,GAAG;;;;;;;GAOd,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,oBAAoB,CAAC;KACjC,OAAO,CAAC,sBAAG,CAAC,OAAO,CAAC,CAAC;AAExB,SAAS,oBAAoB;IAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACjE,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/C,CAAC;AAED,gBAAgB;AAChB,KAAK,UAAU,sBAAsB;IACnC,gBAAgB;IAChB,MAAM,SAAS,GAAG,MAAM,IAAA,yBAAkB,GAAE,CAAC;IAE7C,IAAI,SAAS,EAAE,CAAC;QACd,YAAY;QACZ,IAAA,kBAAW,EAAC,SAAS,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IAED,cAAc;IACd,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAO,EAAC;QAC7B,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,wBAAwB;QACjC,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;YAC5B,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;SAClC;KACF,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClB,IAAA,kBAAW,EAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,oBAAoB;AACpB,SAAS,gBAAgB,CAAC,IAAc;IACtC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,qBAAqB;QACpB,iBAAe,CAAC,OAAO,GAAG;YACzB,GAAI,iBAAe,CAAC,OAAO;YAC3B,YAAY,EAAE;gBACZ,YAAY,EAAE,kBAAkB;aACjC;YACD,uBAAuB,EAAE;gBACvB,YAAY,EAAE,2DAA2D;aAC1E;YACD,WAAW,EAAE;gBACX,YAAY,EAAE,4CAA4C;aAC3D;YACD,MAAM,EAAE;gBACN,YAAY,EAAE,gBAAgB;aAC/B;SACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,UAAU;AACV,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;IACxB,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,sBAAsB,OAAO,EAAE,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,aAAa,EAAE,CAAC;IAChB,UAAU,EAAE,CAAC;IACb,MAAM,sBAAsB,EAAE,CAAC;IAC/B,gBAAgB,CAAC,IAAA,kBAAW,GAAE,CAAC,CAAC;IAChC,MAAM,oBAAoB,EAAE,CAAC;IAC7B,MAAM,IAAA,mBAAY,GAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,cAAc;AACd,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,gBAAgB,CAAC;KAC7B,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC;KAC3B,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC;KAC1B,MAAM,CAAC,KAAK,EAAE,OAA4C,EAAE,EAAE;IAC7D,aAAa,EAAE,CAAC;IAChB,MAAM,sBAAsB,EAAE,CAAC;IAC/B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,IAAA,yBAAe,GAAE,CAAC;QACxB,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,IAAA,sBAAY,GAAE,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,IAAA,qBAAW,GAAE,CAAC;AACtB,CAAC,CAAC,CAAC;AAEL,gBAAgB;AAChB,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,SAAS,CAAC;KACtB,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,aAAa,EAAE,CAAC;IAChB,MAAM,sBAAsB,EAAE,CAAC;IAC/B,MAAM,IAAA,yBAAa,GAAE,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,aAAa;AACb,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,kBAAkB,CAAC;KAC/B,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,aAAa,EAAE,CAAC;IAChB,MAAM,sBAAsB,EAAE,CAAC;IAC/B,MAAM,IAAA,qBAAc,GAAE,CAAC;AACzB,CAAC,CAAC,CAAC;AAEL,WAAW;AACX,MAAM,IAAI,GAAG,OAAO;KACjB,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,YAAY,CAAC;KACzB,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,aAAa,EAAE,CAAC;IAChB,MAAM,sBAAsB,EAAE,CAAC;IAC/B,MAAM,IAAA,mBAAY,GAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,IAAI;KACD,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,WAAW,CAAC;KACxB,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,aAAa,EAAE,CAAC;IAChB,MAAM,sBAAsB,EAAE,CAAC;IAC/B,MAAM,IAAA,2BAAoB,GAAE,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEL,qBAAqB;AACrB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,QAAQ,EAAE,yBAAyB,CAAC;KAC3C,MAAM,CAAC,KAAK,EAAE,OAA2B,EAAE,EAAE;IAC5C,aAAa,EAAE,CAAC;IAChB,MAAM,sBAAsB,EAAE,CAAC;IAC/B,MAAM,IAAA,gBAAQ,EAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEL,sBAAsB;AACtB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,SAAS,CAAC;KACtB,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,aAAa,EAAE,CAAC;IAChB,eAAe;IACf,IAAA,kBAAW,EAAC,IAAI,CAAC,CAAC;IAClB,MAAM,IAAA,wBAAa,GAAE,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,sBAAsB;AACtB,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,qBAAqB,EAAE,KAAK,EAAE,MAAM,CAAC;KAC5C,MAAM,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC;KACtC,MAAM,CAAC,KAAK,EAAE,OAAwC,EAAE,EAAE;IACzD,aAAa,EAAE,CAAC;IAChB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;IAEhD,kBAAkB;IAClB,aAAa;IACb,MAAM,EAAE,WAAW,EAAE,GAAG,wDAAa,iBAAiB,GAAC,CAAC;IAExD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,EAAE,IAAI,EAAE,GAAG,wDAAa,eAAe,GAAC,CAAC;QAC/C,IAAI,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,aAAa;IACb,WAAW,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC;AAEL,SAAS,aAAa;IACpB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,oBAAoB;IACjC,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAc,GAAE,CAAC;IACtC,IAAI,MAAM,CAAC,KAAK,EAAE,aAAa;QAAE,OAAO;IACxC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,IAAA,QAAC,EAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,IAAA,uBAAgB,EAAC,EAAE,KAAK,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 播放提示音
3
+ * 使用 macOS 系统提示音或蜂鸣声
4
+ */
5
+ export declare function playSound(type?: "success" | "error" | "warning" | "input"): void;
6
+ /**
7
+ * 蜂鸣声(最简单的方式,跨平台)
8
+ */
9
+ export declare function beep(): void;
10
+ //# sourceMappingURL=sound.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sound.d.ts","sourceRoot":"","sources":["../../src/utils/sound.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAmB,QAmBpF;AAED;;GAEG;AACH,wBAAgB,IAAI,SAEnB"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.playSound = playSound;
4
+ exports.beep = beep;
5
+ const child_process_1 = require("child_process");
6
+ /**
7
+ * 播放提示音
8
+ * 使用 macOS 系统提示音或蜂鸣声
9
+ */
10
+ function playSound(type = "success") {
11
+ try {
12
+ // 使用 macOS 的 afplay 播放系统提示音
13
+ const soundFiles = {
14
+ success: "/System/Library/Sounds/Glass.aiff",
15
+ error: "/System/Library/Sounds/Basso.aiff",
16
+ warning: "/System/Library/Sounds/Ping.aiff",
17
+ input: "/System/Library/Sounds/Tink.aiff",
18
+ };
19
+ const soundFile = soundFiles[type];
20
+ if (soundFile) {
21
+ // 后台播放,不阻塞程序
22
+ (0, child_process_1.execSync)(`afplay "${soundFile}" &`, { stdio: "ignore" });
23
+ }
24
+ }
25
+ catch {
26
+ // 如果 afplay 失败,使用蜂鸣声作为备选
27
+ process.stdout.write("\x07");
28
+ }
29
+ }
30
+ /**
31
+ * 蜂鸣声(最简单的方式,跨平台)
32
+ */
33
+ function beep() {
34
+ process.stdout.write("\x07");
35
+ }
36
+ //# sourceMappingURL=sound.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sound.js","sourceRoot":"","sources":["../../src/utils/sound.ts"],"names":[],"mappings":";;AAMA,8BAmBC;AAKD,oBAEC;AAhCD,iDAAyC;AAEzC;;;GAGG;AACH,SAAgB,SAAS,CAAC,OAAkD,SAAS;IACnF,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,UAAU,GAA2B;YACzC,OAAO,EAAE,mCAAmC;YAC5C,KAAK,EAAE,mCAAmC;YAC1C,OAAO,EAAE,kCAAkC;YAC3C,KAAK,EAAE,kCAAkC;SAC1C,CAAC;QAEF,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,SAAS,EAAE,CAAC;YACd,aAAa;YACb,IAAA,wBAAQ,EAAC,WAAW,SAAS,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,IAAI;IAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,73 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ const CLAUDE_DIR = path.join(os.homedir(), '.claude');
6
+ const SETTINGS_FILE = path.join(CLAUDE_DIR, 'settings.json');
7
+ const CLAUDE_JSON_FILE = path.join(os.homedir(), '.claude.json');
8
+
9
+ async function readSettings() {
10
+ try {
11
+ const content = await fs.readFile(SETTINGS_FILE, 'utf-8');
12
+ return JSON.parse(content);
13
+ } catch {
14
+ return {};
15
+ }
16
+ }
17
+
18
+ async function writeSettings(settings) {
19
+ await fs.writeFile(SETTINGS_FILE, JSON.stringify(settings, null, 2), 'utf-8');
20
+ }
21
+
22
+ async function readClaudeJson() {
23
+ try {
24
+ const content = await fs.readFile(CLAUDE_JSON_FILE, 'utf-8');
25
+ return JSON.parse(content);
26
+ } catch {
27
+ return {};
28
+ }
29
+ }
30
+
31
+ async function getConfig(req, res) {
32
+ try {
33
+ const [settings, claudeJson] = await Promise.all([
34
+ readSettings(),
35
+ readClaudeJson(),
36
+ ]);
37
+
38
+ res.json({
39
+ settings,
40
+ mcpServers: claudeJson.mcpServers || {},
41
+ });
42
+ } catch (error) {
43
+ console.error('Error fetching config:', error);
44
+ res.status(500).json({ error: 'Failed to fetch config' });
45
+ }
46
+ }
47
+
48
+ async function updateConfig(req, res) {
49
+ try {
50
+ const updates = req.body;
51
+
52
+ // Read current settings
53
+ const settings = await readSettings();
54
+
55
+ // Apply updates
56
+ const updatedSettings = { ...settings, ...updates };
57
+
58
+ // Write back
59
+ await writeSettings(updatedSettings);
60
+
61
+ // Return updated config
62
+ const claudeJson = await readClaudeJson();
63
+ res.json({
64
+ settings: updatedSettings,
65
+ mcpServers: claudeJson.mcpServers || {},
66
+ });
67
+ } catch (error) {
68
+ console.error('Error updating config:', error);
69
+ res.status(500).json({ error: 'Failed to update config' });
70
+ }
71
+ }
72
+
73
+ module.exports = { getConfig, updateConfig };
@@ -0,0 +1,130 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ const CLAUDE_DIR = path.join(os.homedir(), '.claude');
6
+ const STATS_CACHE_FILE = path.join(CLAUDE_DIR, 'stats-cache.json');
7
+ const PROJECTS_DIR = path.join(CLAUDE_DIR, 'projects');
8
+
9
+ // Estimate cost based on model (rough estimation)
10
+ function estimateCost(tokens, model) {
11
+ // Default to Sonnet pricing if unknown
12
+ const inputPrice = 3e-6; // $3 per million
13
+ const outputPrice = 15e-6; // $15 per million
14
+
15
+ // Assume 50/50 split for estimation
16
+ return (tokens / 2) * inputPrice + (tokens / 2) * outputPrice;
17
+ }
18
+
19
+ async function parseStatsCache() {
20
+ try {
21
+ const content = await fs.readFile(STATS_CACHE_FILE, 'utf-8');
22
+ return JSON.parse(content);
23
+ } catch {
24
+ return {};
25
+ }
26
+ }
27
+
28
+ async function getProjectSessions() {
29
+ const sessions = [];
30
+
31
+ try {
32
+ const projects = await fs.readdir(PROJECTS_DIR);
33
+
34
+ for (const projectDir of projects) {
35
+ const projectPath = path.join(PROJECTS_DIR, projectDir);
36
+ const stat = await fs.stat(projectPath);
37
+
38
+ if (!stat.isDirectory()) continue;
39
+
40
+ // Decode project name
41
+ const projectName = projectDir.replace(/-/g, '/').replace(/ /g, '/');
42
+
43
+ const sessionFiles = await fs.readdir(projectPath);
44
+
45
+ for (const sessionFile of sessionFiles) {
46
+ if (!sessionFile.endsWith('.jsonl')) continue;
47
+ if (sessionFile.startsWith('agent-')) continue; // Skip sub-agent sessions
48
+
49
+ const sessionPath = path.join(projectPath, sessionFile);
50
+ const sessionStat = await fs.stat(sessionPath);
51
+
52
+ let sessionTokens = 0;
53
+ let sessionModel = undefined;
54
+
55
+ try {
56
+ const content = await fs.readFile(sessionPath, 'utf-8');
57
+ const lines = content.split('\n').filter(Boolean);
58
+
59
+ for (const line of lines) {
60
+ try {
61
+ const entry = JSON.parse(line);
62
+ if (entry.message?.usage) {
63
+ sessionTokens +=
64
+ (entry.message.usage.input_tokens || 0) +
65
+ (entry.message.usage.output_tokens || 0);
66
+ }
67
+ if (entry.message?.model && !sessionModel) {
68
+ sessionModel = entry.message.model;
69
+ }
70
+ } catch {
71
+ // Skip invalid lines
72
+ }
73
+ }
74
+ } catch {
75
+ // Skip files that can't be read
76
+ }
77
+
78
+ sessions.push({
79
+ sessionId: sessionFile.replace('.jsonl', ''),
80
+ project: projectName,
81
+ timestamp: sessionStat.mtimeMs,
82
+ tokens: sessionTokens,
83
+ model: sessionModel,
84
+ });
85
+ }
86
+ }
87
+ } catch {
88
+ // Return empty if projects dir doesn't exist
89
+ }
90
+
91
+ // Sort by timestamp descending
92
+ return sessions.sort((a, b) => b.timestamp - a.timestamp);
93
+ }
94
+
95
+ async function getStats(req, res) {
96
+ try {
97
+ const [cache, sessions] = await Promise.all([
98
+ parseStatsCache(),
99
+ getProjectSessions(),
100
+ ]);
101
+
102
+ const totalTokens = sessions.reduce((sum, s) => sum + s.tokens, 0);
103
+ const totalCost = estimateCost(totalTokens);
104
+ const sessionCount = sessions.length;
105
+
106
+ // Extract metrics from cache if available
107
+ const activeTime = cache.active_time_total || 0;
108
+ const linesOfCode = cache.lines_of_code_count || 0;
109
+ const commitCount = cache.commit_count || 0;
110
+ const prCount = cache.pull_request_count || 0;
111
+
112
+ const response = {
113
+ totalTokens,
114
+ totalCost,
115
+ sessionCount,
116
+ activeTime,
117
+ linesOfCode,
118
+ commitCount,
119
+ prCount,
120
+ recentSessions: sessions.slice(0, 20), // Last 20 sessions
121
+ };
122
+
123
+ res.json(response);
124
+ } catch (error) {
125
+ console.error('Error fetching stats:', error);
126
+ res.status(500).json({ error: 'Failed to fetch stats' });
127
+ }
128
+ }
129
+
130
+ module.exports = { getStats };