xling 0.0.2 → 0.3.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 (122) hide show
  1. package/README.md +276 -1
  2. package/dist/base-BWvHbkly.js +69 -0
  3. package/dist/base-BWvHbkly.js.map +1 -0
  4. package/dist/base-BXJVsMwL.d.ts +45 -0
  5. package/dist/base-BXJVsMwL.d.ts.map +1 -0
  6. package/dist/base-DdIJJBHV.js +34 -0
  7. package/dist/base-DdIJJBHV.js.map +1 -0
  8. package/dist/base-EQ6uvBQs.d.ts +43 -0
  9. package/dist/base-EQ6uvBQs.d.ts.map +1 -0
  10. package/dist/claude-BsdlWM7z.js +31 -0
  11. package/dist/claude-BsdlWM7z.js.map +1 -0
  12. package/dist/claude-D7KdpYHQ.js +209 -0
  13. package/dist/claude-D7KdpYHQ.js.map +1 -0
  14. package/dist/claudeDefault-pd-Kyu6o.js +19 -0
  15. package/dist/claudeDefault-pd-Kyu6o.js.map +1 -0
  16. package/dist/codex-Crifr9cw.js +32 -0
  17. package/dist/codex-Crifr9cw.js.map +1 -0
  18. package/dist/codex-UJ2PYHA6.js +85 -0
  19. package/dist/codex-UJ2PYHA6.js.map +1 -0
  20. package/dist/commands/settings/get.d.ts +24 -0
  21. package/dist/commands/settings/get.d.ts.map +1 -0
  22. package/dist/commands/settings/get.js +118 -0
  23. package/dist/commands/settings/get.js.map +1 -0
  24. package/dist/commands/settings/inspect.d.ts +19 -0
  25. package/dist/commands/settings/inspect.d.ts.map +1 -0
  26. package/dist/commands/settings/inspect.js +88 -0
  27. package/dist/commands/settings/inspect.js.map +1 -0
  28. package/dist/commands/settings/list.d.ts +25 -0
  29. package/dist/commands/settings/list.d.ts.map +1 -0
  30. package/dist/commands/settings/list.js +147 -0
  31. package/dist/commands/settings/list.js.map +1 -0
  32. package/dist/commands/settings/set.d.ts +22 -0
  33. package/dist/commands/settings/set.d.ts.map +1 -0
  34. package/dist/commands/settings/set.js +83 -0
  35. package/dist/commands/settings/set.js.map +1 -0
  36. package/dist/commands/settings/switch.d.ts +27 -0
  37. package/dist/commands/settings/switch.d.ts.map +1 -0
  38. package/dist/commands/settings/switch.js +164 -0
  39. package/dist/commands/settings/switch.js.map +1 -0
  40. package/dist/commands/x/index.d.ts +25 -0
  41. package/dist/commands/x/index.d.ts.map +1 -0
  42. package/dist/commands/x/index.js +130 -0
  43. package/dist/commands/x/index.js.map +1 -0
  44. package/dist/dispatcher-BUU7wUgm.js +94 -0
  45. package/dist/dispatcher-BUU7wUgm.js.map +1 -0
  46. package/dist/dispatcher-Co94YvDc.js +76 -0
  47. package/dist/dispatcher-Co94YvDc.js.map +1 -0
  48. package/dist/domain/interfaces.d.ts +3 -0
  49. package/dist/domain/interfaces.js +1 -0
  50. package/dist/domain/types.d.ts +2 -0
  51. package/dist/domain/types.js +1 -0
  52. package/dist/domain/validators.d.ts +82 -0
  53. package/dist/domain/validators.d.ts.map +1 -0
  54. package/dist/domain/validators.js +58 -0
  55. package/dist/domain/validators.js.map +1 -0
  56. package/dist/editor-D4qoje1V.js +32 -0
  57. package/dist/editor-D4qoje1V.js.map +1 -0
  58. package/dist/errors-CAZ5k5YT.js +89 -0
  59. package/dist/errors-CAZ5k5YT.js.map +1 -0
  60. package/dist/format-Cqecj3RS.js +229 -0
  61. package/dist/format-Cqecj3RS.js.map +1 -0
  62. package/dist/fsStore-BPnFUGta.js +122 -0
  63. package/dist/fsStore-BPnFUGta.js.map +1 -0
  64. package/dist/gemini-Qo5146d_.js +52 -0
  65. package/dist/gemini-Qo5146d_.js.map +1 -0
  66. package/dist/interfaces-DRNAGN0l.d.ts +75 -0
  67. package/dist/interfaces-DRNAGN0l.d.ts.map +1 -0
  68. package/dist/run.d.ts +1 -0
  69. package/dist/run.js +15 -0
  70. package/dist/run.js.map +1 -0
  71. package/dist/runner-BE7zZq1g.js +89 -0
  72. package/dist/runner-BE7zZq1g.js.map +1 -0
  73. package/dist/services/launch/adapters/base.d.ts +4 -0
  74. package/dist/services/launch/adapters/base.js +4 -0
  75. package/dist/services/launch/adapters/claude.d.ts +25 -0
  76. package/dist/services/launch/adapters/claude.d.ts.map +1 -0
  77. package/dist/services/launch/adapters/claude.js +5 -0
  78. package/dist/services/launch/adapters/codex.d.ts +26 -0
  79. package/dist/services/launch/adapters/codex.d.ts.map +1 -0
  80. package/dist/services/launch/adapters/codex.js +5 -0
  81. package/dist/services/launch/dispatcher.d.ts +44 -0
  82. package/dist/services/launch/dispatcher.d.ts.map +1 -0
  83. package/dist/services/launch/dispatcher.js +8 -0
  84. package/dist/services/settings/adapters/base.d.ts +4 -0
  85. package/dist/services/settings/adapters/base.js +5 -0
  86. package/dist/services/settings/adapters/claude.d.ts +43 -0
  87. package/dist/services/settings/adapters/claude.d.ts.map +1 -0
  88. package/dist/services/settings/adapters/claude.js +9 -0
  89. package/dist/services/settings/adapters/codex.d.ts +45 -0
  90. package/dist/services/settings/adapters/codex.d.ts.map +1 -0
  91. package/dist/services/settings/adapters/codex.js +6 -0
  92. package/dist/services/settings/adapters/gemini.d.ts +32 -0
  93. package/dist/services/settings/adapters/gemini.d.ts.map +1 -0
  94. package/dist/services/settings/adapters/gemini.js +6 -0
  95. package/dist/services/settings/dispatcher.d.ts +36 -0
  96. package/dist/services/settings/dispatcher.d.ts.map +1 -0
  97. package/dist/services/settings/dispatcher.js +12 -0
  98. package/dist/services/settings/fsStore.d.ts +46 -0
  99. package/dist/services/settings/fsStore.d.ts.map +1 -0
  100. package/dist/services/settings/fsStore.js +4 -0
  101. package/dist/services/settings/templates/claudeDefault.d.ts +20 -0
  102. package/dist/services/settings/templates/claudeDefault.d.ts.map +1 -0
  103. package/dist/services/settings/templates/claudeDefault.js +3 -0
  104. package/dist/types--0tjriPy.d.ts +104 -0
  105. package/dist/types--0tjriPy.d.ts.map +1 -0
  106. package/dist/utils/editor.d.ts +6 -0
  107. package/dist/utils/editor.d.ts.map +1 -0
  108. package/dist/utils/editor.js +4 -0
  109. package/dist/utils/errors.d.ts +61 -0
  110. package/dist/utils/errors.d.ts.map +1 -0
  111. package/dist/utils/errors.js +3 -0
  112. package/dist/utils/format.d.ts +20 -0
  113. package/dist/utils/format.d.ts.map +1 -0
  114. package/dist/utils/format.js +3 -0
  115. package/dist/utils/logger.d.ts +32 -0
  116. package/dist/utils/logger.d.ts.map +1 -0
  117. package/dist/utils/logger.js +46 -0
  118. package/dist/utils/logger.js.map +1 -0
  119. package/dist/utils/runner.d.ts +36 -0
  120. package/dist/utils/runner.d.ts.map +1 -0
  121. package/dist/utils/runner.js +3 -0
  122. package/package.json +66 -6
package/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ # xling
2
+
3
+ Unified CLI for managing AI tool settings across Claude Code, Codex, and Gemini CLI.
4
+
1
5
  ## What's in a Name? The Story of `xling`
2
6
 
3
7
  The name `xling` was carefully chosen to represent the project's philosophy, blending modern tech symbolism with a rich, dual-meaning core.
@@ -16,4 +20,275 @@ At the heart of the name is `ling`, a concept with two harmonious faces rooted i
16
20
  1. **令 (lìng)**: This means "command" or "order." It represents the tool's heritage as a command-line interface—unwavering, precise, and powerful.
17
21
  2. **灵 (líng)**: This translates to "intelligence," "spirit," or "agility." It embodies the AI engine that gives `xling` its smarts, allowing it to understand natural language, anticipate intent, and perform complex tasks with a touch of magic.
18
22
 
19
- Together, `xling` is more than just a tool; it's an intelligent partner that amplifies your ability to command your digital world.
23
+ Together, `xling` is more than just a tool; it's an intelligent partner that amplifies your ability to command your digital world.
24
+
25
+ ## Features
26
+
27
+ - **Unified Interface**: Manage settings for multiple AI CLI tools with a single command
28
+ - **Quick Launcher**: Just type `xling x` to start Claude Code instantly with yolo mode
29
+ - **Multiple Scopes**: Support for user, project, local, and system-level configurations
30
+ - **Profile Switching**: Switch between different configuration profiles (Codex)
31
+ - **Dry Run Mode**: Preview changes before applying them
32
+ - **JSON Output**: Machine-readable output for scripting
33
+ - **Type Safe**: Built with TypeScript for reliability
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ # Install dependencies
39
+ bun install
40
+
41
+ # Build the project
42
+ bun run build
43
+
44
+ # Link globally (optional)
45
+ npm link
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ ### Quick Start - The `x` Command
51
+
52
+ The fastest way to start your AI tools! Just type `xling x` to launch Claude Code with yolo mode.
53
+
54
+ **Claude Code is launched by default** - the ultimate convenience!
55
+
56
+ ```bash
57
+ # 🚀 Fastest way - Start Claude Code instantly
58
+ xling x
59
+
60
+ # Continue last conversation/session
61
+ xling x -c
62
+
63
+ # Resume from conversation/session list
64
+ xling x -r
65
+
66
+ # Pass arguments to Claude
67
+ xling x -- chat "Hello, how are you?"
68
+
69
+ # Start without yolo mode
70
+ xling x --no-yolo
71
+
72
+ # Start Codex instead
73
+ xling x --tool codex
74
+ # or use the short flag
75
+ xling x -t codex
76
+
77
+ # Continue last Codex session
78
+ xling x -t codex -c
79
+
80
+ # Start Codex in a specific directory
81
+ xling x -t codex -C /path/to/project
82
+ ```
83
+
84
+ **Resume Options:**
85
+ - `-c` or `--continue`: Continue the last conversation/session
86
+ - Claude Code: `claude -c`
87
+ - Codex: `codex resume --last`
88
+ - `-r` or `--resume`: Show a list to choose from
89
+ - Claude Code: `claude -r`
90
+ - Codex: `codex resume`
91
+
92
+ **Yolo mode flags:**
93
+ - Claude Code: `--dangerously-skip-permissions`
94
+ - Codex: `--dangerously-bypass-approvals-and-sandbox`
95
+
96
+ ### List Settings
97
+
98
+ ```bash
99
+ # List all settings for Claude Code (user scope)
100
+ xling settings:list --tool claude --scope user
101
+
102
+ # List Codex settings in table format
103
+ xling settings:list --tool codex --table
104
+ ```
105
+
106
+ > Claude-specific: `settings:list --tool claude` now enumerates every
107
+ > `settings*.json` file (for example `settings.hxi.json`) in the selected scope
108
+ > so you can quickly discover switchable variants.
109
+ >
110
+ > Codex-specific: `settings:list --tool codex` surfaces only the `model_providers`
111
+ > block from `~/.codex/config.toml`, helping you audit provider names, base URLs,
112
+ > and env key bindings at a glance.
113
+
114
+ `settings:list` 默认输出 YAML 风格的简洁概览;如需表格/JSON,请加 `--table` 或
115
+ `--json`。其余命令仍以 JSON 为默认输出,可通过 `--no-json` 获取文本格式。
116
+
117
+ ### Get Settings File
118
+
119
+ ```bash
120
+ # Show Claude user settings (plain text default)
121
+ xling settings:get --tool claude --scope user
122
+
123
+ # Inspect a Claude variant (settings.hxi.json)
124
+ xling settings:get hxi --tool claude --scope user
125
+
126
+ # Show Codex config (plain text)
127
+ xling settings:get --tool codex
128
+ ```
129
+
130
+ ### Edit Settings (Claude)
131
+
132
+ ```bash
133
+ # Create/edit settings.hxi.json in VS Code (default)
134
+ xling settings:set --tool claude --scope user --name hxi
135
+
136
+ # Open default settings in Cursor
137
+ xling settings:set --tool claude --scope project --name default --ide cursor --no-json
138
+ ```
139
+
140
+ `settings:set` 现专注于整文件编辑:传 `--name`(默认 `default`)即可创建/打开
141
+ `settings.<name>.json`,并使用 `--ide` 指定编辑器(默认 VS Code 的 `code`)。
142
+
143
+ > Note: 所有 `settings:*` 命令仅依赖 `--tool`、`--scope`、`--name` 等 flag;不再提供
144
+ > `developerShortcuts.runCommand` 这类键级参数。
145
+
146
+ ### Switch Profiles or Claude Variants
147
+
148
+ ```bash
149
+ # Switch to a different profile
150
+ xling settings:switch oss --tool codex
151
+
152
+ # Activate settings.hxi.json for Claude user scope
153
+ xling settings:switch hxi --tool claude --scope user
154
+
155
+ # Apply without prompt (Claude)
156
+ xling settings:switch hxi --tool claude --scope user --force
157
+
158
+ # Force and keep a .bak backup
159
+ xling settings:switch hxi --tool claude --scope user --force --backup
160
+ ```
161
+
162
+ Claude switches现在默认进行交互式 diff 预览:命令会先打印彩色统一 diff,
163
+ 然后提示 `overwrite / backup / cancel`。若要非交互执行,使用 `--force`,并可
164
+ 通过 `--backup` 强制保留 `.bak`。Codex 保持原行为,直接切换 profile。
165
+
166
+ ### Inspect Configuration
167
+
168
+ ```bash
169
+ # View configuration file information
170
+ xling settings:inspect --tool claude --scope user
171
+ ```
172
+
173
+ ## Supported Tools
174
+
175
+ ### Claude Code
176
+
177
+ - **Scopes**: user, project, local
178
+ - **Config Files**:
179
+ - User: `~/.claude/settings.json`
180
+ - Project: `.claude/settings.json`
181
+ - Local: `.claude/settings.local.json`
182
+
183
+ ### Codex
184
+
185
+ - **Scopes**: user
186
+ - **Config Files**:
187
+ - User: `~/.codex/config.toml`
188
+ - **Features**: Profile switching
189
+
190
+ ### Gemini CLI
191
+
192
+ - **Scopes**: user, project, system
193
+ - **Config Files**:
194
+ - User: `~/.gemini/settings.json`
195
+ - Project: `.gemini/settings.json`
196
+ - System: Platform-dependent
197
+
198
+ ## Architecture
199
+
200
+ The project follows SOLID principles:
201
+
202
+ - **Single Responsibility**: Each adapter handles one tool
203
+ - **Open/Closed**: Easy to add new tools without modifying existing code
204
+ - **Liskov Substitution**: All adapters implement the same interface
205
+ - **Interface Segregation**: Clean, focused interfaces
206
+ - **Dependency Inversion**: Commands depend on abstractions, not implementations
207
+
208
+ ### Directory Structure
209
+
210
+ ```
211
+ xling/
212
+ ├── bin/
213
+ │ └── run.js # CLI entry point
214
+ ├── src/
215
+ │ ├── commands/ # oclif commands
216
+ │ │ └── settings/
217
+ │ ├── domain/ # Types and interfaces
218
+ │ ├── services/ # Business logic
219
+ │ │ └── settings/
220
+ │ │ ├── adapters/ # Tool adapters
221
+ │ │ ├── fsStore.ts # File system operations
222
+ │ │ └── dispatcher.ts
223
+ │ └── utils/ # Utilities
224
+ └── test/ # Tests and fixtures
225
+ ```
226
+
227
+ ## Development
228
+
229
+ ```bash
230
+ # Install dependencies
231
+ bun install
232
+
233
+ # Build (using tsdown)
234
+ bun run build
235
+
236
+ # Watch mode (tsdown --watch)
237
+ bun run dev
238
+
239
+ # Code quality
240
+ bun run lint # Lint with oxlint
241
+ bun run lint:fix # Auto-fix lint issues
242
+ bun run format # Format with oxfmt
243
+ bun run format:check # Check formatting
244
+ bun run typecheck # Type check with tsc
245
+
246
+ # Run tests
247
+ bun test
248
+ bun test:watch
249
+ bun test:coverage
250
+ ```
251
+
252
+ ### Toolchain
253
+
254
+ **Build System**
255
+
256
+ This project uses [tsdown](https://tsdown.vercel.app/) for fast TypeScript compilation and bundling:
257
+
258
+ - **Fast builds**: Powered by rolldown (Rust-based bundler)
259
+ - **ESM output**: Generates `.js` files for modern Node.js
260
+ - **Type definitions**: Automatically generates `.d.ts` files
261
+ - **Source maps**: Includes source maps for debugging
262
+ - **Tree shaking**: Optimized bundle size
263
+
264
+ **Code Quality**
265
+
266
+ - **Linting**: [oxlint](https://oxc.rs/) - Rust-based linter, 50-100x faster than ESLint
267
+ - **Formatting**: [oxfmt](https://oxc.rs/) - Fast formatter compatible with Prettier config
268
+ - **Type Checking**: TypeScript compiler for strict type safety
269
+
270
+ ## Testing
271
+
272
+ ```bash
273
+ # Run all tests
274
+ bun test
275
+
276
+ # Run with coverage
277
+ bun test:coverage
278
+ ```
279
+
280
+ ## Contributing
281
+
282
+ 1. Fork the repository
283
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
284
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
285
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
286
+ 5. Open a Pull Request
287
+
288
+ ## License
289
+
290
+ Apache-2.0
291
+
292
+ ## Author
293
+
294
+ Kingsword <kingsword09@gmail.com>
@@ -0,0 +1,69 @@
1
+ import { a as InvalidScopeError } from "./errors-CAZ5k5YT.js";
2
+ import { a as readJSON, c as writeJSON, i as getFileInfo, r as fileExists } from "./fsStore-BPnFUGta.js";
3
+
4
+ //#region src/services/settings/adapters/base.ts
5
+ /**
6
+ * 抽象基类
7
+ */
8
+ var BaseAdapter = class {
9
+ /**
10
+ * 列出所有配置
11
+ */
12
+ async list(scope) {
13
+ if (!this.validateScope(scope)) throw new InvalidScopeError(scope);
14
+ const path = this.resolvePath(scope);
15
+ return {
16
+ type: "entries",
17
+ entries: this.readConfig(path),
18
+ filePath: path
19
+ };
20
+ }
21
+ /**
22
+ * 默认 switchProfile 会抛出,子类可覆盖
23
+ */
24
+ async switchProfile(_scope, _profile, _options) {
25
+ throw new Error(`Tool ${this.toolId} does not support profile switching`);
26
+ }
27
+ /**
28
+ * 检查配置文件
29
+ */
30
+ async inspect(scope) {
31
+ if (!this.validateScope(scope)) throw new InvalidScopeError(scope);
32
+ const path = this.resolvePath(scope);
33
+ if (!fileExists(path)) return {
34
+ path,
35
+ exists: false
36
+ };
37
+ const fileInfo = getFileInfo(path);
38
+ const config = this.readConfig(path);
39
+ return {
40
+ path,
41
+ exists: true,
42
+ content: JSON.stringify(config, null, 2),
43
+ size: fileInfo?.size,
44
+ lastModified: fileInfo?.lastModified
45
+ };
46
+ }
47
+ /**
48
+ * 默认 edit 会抛出,子类可覆盖
49
+ */
50
+ async edit(scope, _options) {
51
+ throw new Error(`Tool ${this.toolId} does not support edit for ${scope}`);
52
+ }
53
+ /**
54
+ * 读取配置文件(子类可覆盖)
55
+ */
56
+ readConfig(path) {
57
+ return readJSON(path);
58
+ }
59
+ /**
60
+ * 写入配置文件(子类可覆盖)
61
+ */
62
+ writeConfig(path, data, backup = true) {
63
+ writeJSON(path, data, backup);
64
+ }
65
+ };
66
+
67
+ //#endregion
68
+ export { BaseAdapter as t };
69
+ //# sourceMappingURL=base-BWvHbkly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-BWvHbkly.js","names":["fsStore.fileExists","fsStore.getFileInfo","fsStore.readJSON"],"sources":["../src/services/settings/adapters/base.ts"],"sourcesContent":["/**\n * 适配器抽象基类\n * 实现通用逻辑,减少重复代码(DRY 原则)\n */\n\nimport type { SettingsAdapter } from \"@/domain/interfaces.ts\";\nimport type {\n ToolId,\n Scope,\n InspectResult,\n SettingsListData,\n SettingsResult,\n EditOptions,\n SwitchOptions,\n} from \"@/domain/types.ts\";\nimport { InvalidScopeError } from \"@/utils/errors.ts\";\nimport * as fsStore from \"@/services/settings/fsStore.ts\";\n\n/**\n * 抽象基类\n */\nexport abstract class BaseAdapter implements SettingsAdapter {\n abstract readonly toolId: ToolId;\n\n /**\n * 子类必须实现的方法\n */\n abstract resolvePath(scope: Scope): string;\n abstract validateScope(scope: Scope): boolean;\n\n /**\n * 列出所有配置\n */\n async list(scope: Scope): Promise<SettingsListData> {\n if (!this.validateScope(scope)) {\n throw new InvalidScopeError(scope);\n }\n\n const path = this.resolvePath(scope);\n const config = this.readConfig(path);\n\n return {\n type: \"entries\",\n entries: config,\n filePath: path,\n };\n }\n\n /**\n * 默认 switchProfile 会抛出,子类可覆盖\n */\n async switchProfile(\n _scope: Scope,\n _profile: string,\n _options?: SwitchOptions,\n ): Promise<SettingsResult> {\n throw new Error(`Tool ${this.toolId} does not support profile switching`);\n }\n\n /**\n * 检查配置文件\n */\n async inspect(scope: Scope): Promise<InspectResult> {\n if (!this.validateScope(scope)) {\n throw new InvalidScopeError(scope);\n }\n\n const path = this.resolvePath(scope);\n const exists = fsStore.fileExists(path);\n\n if (!exists) {\n return {\n path,\n exists: false,\n };\n }\n\n const fileInfo = fsStore.getFileInfo(path);\n const config = this.readConfig(path);\n\n return {\n path,\n exists: true,\n content: JSON.stringify(config, null, 2),\n size: fileInfo?.size,\n lastModified: fileInfo?.lastModified,\n };\n }\n\n /**\n * 默认 edit 会抛出,子类可覆盖\n */\n async edit(scope: Scope, _options: EditOptions): Promise<SettingsResult> {\n throw new Error(`Tool ${this.toolId} does not support edit for ${scope}`);\n }\n\n /**\n * 读取配置文件(子类可覆盖)\n */\n protected readConfig(path: string): Record<string, unknown> {\n return fsStore.readJSON(path);\n }\n\n /**\n * 写入配置文件(子类可覆盖)\n */\n protected writeConfig(\n path: string,\n data: Record<string, unknown>,\n backup = true,\n ): void {\n fsStore.writeJSON(path, data, backup);\n }\n}\n"],"mappings":";;;;;;;AAqBA,IAAsB,cAAtB,MAA6D;;;;CAY3D,MAAM,KAAK,OAAyC;AAClD,MAAI,CAAC,KAAK,cAAc,MAAM,CAC5B,OAAM,IAAI,kBAAkB,MAAM;EAGpC,MAAM,OAAO,KAAK,YAAY,MAAM;AAGpC,SAAO;GACL,MAAM;GACN,SAJa,KAAK,WAAW,KAAK;GAKlC,UAAU;GACX;;;;;CAMH,MAAM,cACJ,QACA,UACA,UACyB;AACzB,QAAM,IAAI,MAAM,QAAQ,KAAK,OAAO,qCAAqC;;;;;CAM3E,MAAM,QAAQ,OAAsC;AAClD,MAAI,CAAC,KAAK,cAAc,MAAM,CAC5B,OAAM,IAAI,kBAAkB,MAAM;EAGpC,MAAM,OAAO,KAAK,YAAY,MAAM;AAGpC,MAAI,CAFWA,WAAmB,KAAK,CAGrC,QAAO;GACL;GACA,QAAQ;GACT;EAGH,MAAM,WAAWC,YAAoB,KAAK;EAC1C,MAAM,SAAS,KAAK,WAAW,KAAK;AAEpC,SAAO;GACL;GACA,QAAQ;GACR,SAAS,KAAK,UAAU,QAAQ,MAAM,EAAE;GACxC,MAAM,UAAU;GAChB,cAAc,UAAU;GACzB;;;;;CAMH,MAAM,KAAK,OAAc,UAAgD;AACvE,QAAM,IAAI,MAAM,QAAQ,KAAK,OAAO,6BAA6B,QAAQ;;;;;CAM3E,AAAU,WAAW,MAAuC;AAC1D,SAAOC,SAAiB,KAAK;;;;;CAM/B,AAAU,YACR,MACA,MACA,SAAS,MACH;AACN,YAAkB,MAAM,MAAM,OAAO"}
@@ -0,0 +1,45 @@
1
+ import { m as ToolId, r as LaunchCommandSpec } from "./types--0tjriPy.js";
2
+ import { t as LaunchAdapter } from "./interfaces-DRNAGN0l.js";
3
+
4
+ //#region src/services/launch/adapters/base.d.ts
5
+
6
+ /**
7
+ * 抽象基类
8
+ * 体现 SOLID 原则:
9
+ * - SRP: 只负责命令规范构建
10
+ * - Template Method: 定义算法骨架,子类实现具体步骤
11
+ * - DRY: 复用 validateAvailability 和 getVersion 实现
12
+ */
13
+ declare abstract class BaseLaunchAdapter implements LaunchAdapter {
14
+ /**
15
+ * 工具标识符(子类必须实现)
16
+ */
17
+ abstract readonly toolId: ToolId;
18
+ /**
19
+ * 可执行文件名称(子类必须实现)
20
+ */
21
+ abstract readonly executable: string;
22
+ /**
23
+ * 构建启动命令配置(子类必须实现)
24
+ * @param payload Launch 请求参数
25
+ * @returns 命令规范
26
+ */
27
+ abstract buildCommandSpec(payload: {
28
+ yolo?: boolean;
29
+ resume?: boolean;
30
+ continue?: boolean;
31
+ }): LaunchCommandSpec;
32
+ /**
33
+ * 默认实现:检查可执行文件是否存在
34
+ * 子类可以覆盖此方法以提供自定义验证逻辑
35
+ */
36
+ validateAvailability(): Promise<boolean>;
37
+ /**
38
+ * 默认版本检查实现
39
+ * 子类可以覆盖此方法以使用不同的版本参数
40
+ */
41
+ getVersion(): Promise<string>;
42
+ }
43
+ //#endregion
44
+ export { BaseLaunchAdapter as t };
45
+ //# sourceMappingURL=base-BXJVsMwL.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-BXJVsMwL.d.ts","names":[],"sources":["../src/services/launch/adapters/base.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;uBAgBsB,iBAAA,YAA6B;;;;4BAIvB;;;;;;;;;;;;;;MAgBtB;;;;;0BAM0B;;;;;gBAQV"}
@@ -0,0 +1,34 @@
1
+ import { n as getExecutableVersion, t as checkExecutable } from "./runner-BE7zZq1g.js";
2
+
3
+ //#region src/services/launch/adapters/base.ts
4
+ /**
5
+ * 抽象基类
6
+ * 体现 SOLID 原则:
7
+ * - SRP: 只负责命令规范构建
8
+ * - Template Method: 定义算法骨架,子类实现具体步骤
9
+ * - DRY: 复用 validateAvailability 和 getVersion 实现
10
+ */
11
+ var BaseLaunchAdapter = class {
12
+ /**
13
+ * 默认实现:检查可执行文件是否存在
14
+ * 子类可以覆盖此方法以提供自定义验证逻辑
15
+ */
16
+ async validateAvailability() {
17
+ return checkExecutable(this.executable);
18
+ }
19
+ /**
20
+ * 默认版本检查实现
21
+ * 子类可以覆盖此方法以使用不同的版本参数
22
+ */
23
+ async getVersion() {
24
+ try {
25
+ return await getExecutableVersion(this.executable);
26
+ } catch {
27
+ return "unknown";
28
+ }
29
+ }
30
+ };
31
+
32
+ //#endregion
33
+ export { BaseLaunchAdapter as t };
34
+ //# sourceMappingURL=base-DdIJJBHV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-DdIJJBHV.js","names":[],"sources":["../src/services/launch/adapters/base.ts"],"sourcesContent":["/**\n * Launch 适配器抽象基类\n * 实现通用逻辑,减少重复代码(DRY 原则)\n */\n\nimport type { LaunchAdapter } from \"@/domain/interfaces.ts\";\nimport type { ToolId, LaunchCommandSpec } from \"@/domain/types.ts\";\nimport { checkExecutable, getExecutableVersion } from \"@/utils/runner.ts\";\n\n/**\n * 抽象基类\n * 体现 SOLID 原则:\n * - SRP: 只负责命令规范构建\n * - Template Method: 定义算法骨架,子类实现具体步骤\n * - DRY: 复用 validateAvailability 和 getVersion 实现\n */\nexport abstract class BaseLaunchAdapter implements LaunchAdapter {\n /**\n * 工具标识符(子类必须实现)\n */\n abstract readonly toolId: ToolId;\n\n /**\n * 可执行文件名称(子类必须实现)\n */\n abstract readonly executable: string;\n\n /**\n * 构建启动命令配置(子类必须实现)\n * @param payload Launch 请求参数\n * @returns 命令规范\n */\n abstract buildCommandSpec(payload: {\n yolo?: boolean;\n resume?: boolean;\n continue?: boolean;\n }): LaunchCommandSpec;\n\n /**\n * 默认实现:检查可执行文件是否存在\n * 子类可以覆盖此方法以提供自定义验证逻辑\n */\n async validateAvailability(): Promise<boolean> {\n return checkExecutable(this.executable);\n }\n\n /**\n * 默认版本检查实现\n * 子类可以覆盖此方法以使用不同的版本参数\n */\n async getVersion(): Promise<string> {\n try {\n return await getExecutableVersion(this.executable);\n } catch {\n return \"unknown\";\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAgBA,IAAsB,oBAAtB,MAAiE;;;;;CA0B/D,MAAM,uBAAyC;AAC7C,SAAO,gBAAgB,KAAK,WAAW;;;;;;CAOzC,MAAM,aAA8B;AAClC,MAAI;AACF,UAAO,MAAM,qBAAqB,KAAK,WAAW;UAC5C;AACN,UAAO"}
@@ -0,0 +1,43 @@
1
+ import { f as SettingsResult, m as ToolId, n as InspectResult, p as SwitchOptions, s as Scope, t as EditOptions, u as SettingsListData } from "./types--0tjriPy.js";
2
+ import { n as SettingsAdapter } from "./interfaces-DRNAGN0l.js";
3
+
4
+ //#region src/services/settings/adapters/base.d.ts
5
+
6
+ /**
7
+ * 抽象基类
8
+ */
9
+ declare abstract class BaseAdapter implements SettingsAdapter {
10
+ abstract readonly toolId: ToolId;
11
+ /**
12
+ * 子类必须实现的方法
13
+ */
14
+ abstract resolvePath(scope: Scope): string;
15
+ abstract validateScope(scope: Scope): boolean;
16
+ /**
17
+ * 列出所有配置
18
+ */
19
+ list(scope: Scope): Promise<SettingsListData>;
20
+ /**
21
+ * 默认 switchProfile 会抛出,子类可覆盖
22
+ */
23
+ switchProfile(_scope: Scope, _profile: string, _options?: SwitchOptions): Promise<SettingsResult>;
24
+ /**
25
+ * 检查配置文件
26
+ */
27
+ inspect(scope: Scope): Promise<InspectResult>;
28
+ /**
29
+ * 默认 edit 会抛出,子类可覆盖
30
+ */
31
+ edit(scope: Scope, _options: EditOptions): Promise<SettingsResult>;
32
+ /**
33
+ * 读取配置文件(子类可覆盖)
34
+ */
35
+ protected readConfig(path: string): Record<string, unknown>;
36
+ /**
37
+ * 写入配置文件(子类可覆盖)
38
+ */
39
+ protected writeConfig(path: string, data: Record<string, unknown>, backup?: boolean): void;
40
+ }
41
+ //#endregion
42
+ export { BaseAdapter as t };
43
+ //# sourceMappingURL=base-EQ6uvBQs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-EQ6uvBQs.d.ts","names":[],"sources":["../src/services/settings/adapters/base.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAiCoC,uBAZd,WAAA,YAAuB,eAYT,CAAA;EAAR,kBAAA,MAAA,EAXA,MAWA;EAmBhB;;;EAGP,SAAA,WAAA,CAAA,KAAA,EA5ByB,KA4BzB,CAAA,EAAA,MAAA;EAOkB,SAAA,aAAA,CAAA,KAAA,EAlCS,KAkCT,CAAA,EAAA,OAAA;EAAgB;;;EA8BF,IAAA,CAAA,KAAA,EA3DjB,KA2DiB,CAAA,EA3DT,OA2DS,CA3DD,gBA2DC,CAAA;EAAsB;;;EAgBjD,aAAA,CAAA,MAAA,EAxDE,KAwDF,EAAA,QAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAtDK,aAsDL,CAAA,EArDL,OAqDK,CArDG,cAqDH,CAAA;EAvFmC;;;iBAyCtB,QAAQ,QAAQ;;;;cA8BnB,iBAAiB,cAAc,QAAQ;;;;sCAOrB;;;;4CAS5B"}
@@ -0,0 +1,31 @@
1
+ import { t as BaseLaunchAdapter } from "./base-DdIJJBHV.js";
2
+
3
+ //#region src/services/launch/adapters/claude.ts
4
+ /**
5
+ * Claude Code Launch 适配器
6
+ */
7
+ /**
8
+ * Claude Code 启动适配器
9
+ *
10
+ * Yolo 模式: --dangerously-skip-permissions
11
+ * Resume 模式: -r (显示对话列表选择)
12
+ * Continue 模式: -c (继续最后一个对话)
13
+ */
14
+ var ClaudeLaunchAdapter = class extends BaseLaunchAdapter {
15
+ toolId = "claude";
16
+ executable = "claude";
17
+ buildCommandSpec(payload) {
18
+ const baseArgs = [];
19
+ if (payload.continue) baseArgs.push("-c");
20
+ else if (payload.resume) baseArgs.push("-r");
21
+ return {
22
+ executable: this.executable,
23
+ baseArgs,
24
+ yoloArgs: payload.yolo ? ["--dangerously-skip-permissions"] : void 0
25
+ };
26
+ }
27
+ };
28
+
29
+ //#endregion
30
+ export { ClaudeLaunchAdapter as t };
31
+ //# sourceMappingURL=claude-BsdlWM7z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-BsdlWM7z.js","names":["baseArgs: string[]"],"sources":["../src/services/launch/adapters/claude.ts"],"sourcesContent":["/**\n * Claude Code Launch 适配器\n */\n\nimport { BaseLaunchAdapter } from \"./base.ts\";\nimport type { LaunchCommandSpec } from \"@/domain/types.ts\";\n\n/**\n * Claude Code 启动适配器\n *\n * Yolo 模式: --dangerously-skip-permissions\n * Resume 模式: -r (显示对话列表选择)\n * Continue 模式: -c (继续最后一个对话)\n */\nexport class ClaudeLaunchAdapter extends BaseLaunchAdapter {\n readonly toolId = \"claude\" as const;\n readonly executable = \"claude\";\n\n buildCommandSpec(payload: {\n yolo?: boolean;\n resume?: boolean;\n continue?: boolean;\n }): LaunchCommandSpec {\n const baseArgs: string[] = [];\n\n // Resume 和 Continue 是互斥的\n if (payload.continue) {\n baseArgs.push(\"-c\");\n } else if (payload.resume) {\n baseArgs.push(\"-r\");\n }\n\n return {\n executable: this.executable,\n baseArgs,\n yoloArgs: payload.yolo ? [\"--dangerously-skip-permissions\"] : undefined,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAa,sBAAb,cAAyC,kBAAkB;CACzD,AAAS,SAAS;CAClB,AAAS,aAAa;CAEtB,iBAAiB,SAIK;EACpB,MAAMA,WAAqB,EAAE;AAG7B,MAAI,QAAQ,SACV,UAAS,KAAK,KAAK;WACV,QAAQ,OACjB,UAAS,KAAK,KAAK;AAGrB,SAAO;GACL,YAAY,KAAK;GACjB;GACA,UAAU,QAAQ,OAAO,CAAC,iCAAiC,GAAG;GAC/D"}