@openharmonyinsight/opencode-oh 0.1.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.
- package/AGENTS.md +98 -0
- package/README.md +80 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +7 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config/index.d.ts +13 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +95 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/config/types.d.ts +29 -0
- package/dist/src/config/types.d.ts.map +1 -0
- package/dist/src/config/types.js +2 -0
- package/dist/src/config/types.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +24 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/provider/templates.d.ts +5 -0
- package/dist/src/provider/templates.d.ts.map +1 -0
- package/dist/src/provider/templates.js +74 -0
- package/dist/src/provider/templates.js.map +1 -0
- package/dist/src/tui/index.d.ts +12 -0
- package/dist/src/tui/index.d.ts.map +1 -0
- package/dist/src/tui/index.js +136 -0
- package/dist/src/tui/index.js.map +1 -0
- package/dist/src/validation/index.d.ts +6 -0
- package/dist/src/validation/index.d.ts.map +1 -0
- package/dist/src/validation/index.js +24 -0
- package/dist/src/validation/index.js.map +1 -0
- package/dist/tests/config.test.d.ts +2 -0
- package/dist/tests/config.test.d.ts.map +1 -0
- package/dist/tests/config.test.js +104 -0
- package/dist/tests/config.test.js.map +1 -0
- package/dist/tests/validation.test.d.ts +2 -0
- package/dist/tests/validation.test.d.ts.map +1 -0
- package/dist/tests/validation.test.js +37 -0
- package/dist/tests/validation.test.js.map +1 -0
- package/docs/plans/2026-02-12-opencode-oh-design.md +90 -0
- package/package.json +38 -0
- package/src/cli.ts +8 -0
- package/src/config/index.ts +106 -0
- package/src/config/types.ts +29 -0
- package/src/index.ts +26 -0
- package/src/provider/templates.ts +76 -0
- package/src/tui/index.ts +159 -0
- package/src/validation/index.ts +30 -0
- package/tests/config.test.ts +117 -0
- package/tests/validation.test.ts +44 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +19 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# AGENTS.md - Agent Guidelines for opencode-oh
|
|
2
|
+
|
|
3
|
+
Guidelines for agentic coding assistants working on this project.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run build # Build TypeScript to dist/
|
|
9
|
+
npm test # Run all tests (vitest with globals)
|
|
10
|
+
npm run test:coverage # Run tests with coverage
|
|
11
|
+
npm run lint # ESLint on src directory
|
|
12
|
+
npm run dev # Run in dev mode (tsx)
|
|
13
|
+
|
|
14
|
+
# Run single tests
|
|
15
|
+
npx vitest tests/config.test.ts # Specific test file
|
|
16
|
+
npx vitest -t "should validate" # Pattern matching
|
|
17
|
+
npx vitest --watch # Watch mode
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Code Style
|
|
21
|
+
|
|
22
|
+
### TypeScript & Imports
|
|
23
|
+
- **Target**: ES2022, **Modules**: ESNext, **Strict**: enabled
|
|
24
|
+
- Use `.js` extensions in all imports (ES modules with `"type": "module"`)
|
|
25
|
+
- Named imports: `import { describe, expect } from 'vitest'`
|
|
26
|
+
- Type imports: `import type { ProviderConfig } from './config/types.js'`
|
|
27
|
+
|
|
28
|
+
### Naming Conventions
|
|
29
|
+
- Classes/Interfaces/Types: PascalCase (`ConfigManager`, `ProviderConfig`, `ValidationResult`)
|
|
30
|
+
- Functions/Methods: camelCase (`validateApiKey`, `getConfigPath`)
|
|
31
|
+
- Constants: UPPER_SNAKE_CASE (`CONFIG_DIR`, `DEFAULT_SCHEMA`)
|
|
32
|
+
|
|
33
|
+
### Error Handling
|
|
34
|
+
```typescript
|
|
35
|
+
// Throw descriptive errors with context
|
|
36
|
+
throw new Error(`Failed to read: ${error instanceof Error ? error.message : String(error)}`);
|
|
37
|
+
|
|
38
|
+
// Async functions return Result objects
|
|
39
|
+
export interface ValidationResult { valid: boolean; error?: string; }
|
|
40
|
+
|
|
41
|
+
// Try-catch for I/O operations
|
|
42
|
+
try {
|
|
43
|
+
const content = fs.readFileSync(path, 'utf-8');
|
|
44
|
+
return JSON.parse(content);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw new Error(`Failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Testing Patterns
|
|
51
|
+
```typescript
|
|
52
|
+
describe('functionName', () => {
|
|
53
|
+
beforeEach(() => {
|
|
54
|
+
vi.restoreAllMocks();
|
|
55
|
+
const mockFetch = vi.fn().mockResolvedValue({ ok: true });
|
|
56
|
+
global.fetch = mockFetch;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
// Clean up temp files with fs.rmSync
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should do something', () => expect(result).toBe(expected));
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Formatting
|
|
68
|
+
- 2-space indentation, single quotes (double for import/export)
|
|
69
|
+
- Optional semicolons, `JSON.stringify(config, null, 2)` for JSON
|
|
70
|
+
|
|
71
|
+
### File Organization
|
|
72
|
+
```
|
|
73
|
+
src/module/
|
|
74
|
+
index.ts # Barrel exports
|
|
75
|
+
types.ts # Type definitions
|
|
76
|
+
tests/module.test.ts
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Configuration
|
|
80
|
+
- Config path: `~/.config/opencode/opencode.json`
|
|
81
|
+
- Backup: `opencode.json.<timestamp>.bak` (always create before modifying)
|
|
82
|
+
|
|
83
|
+
### Provider Templates
|
|
84
|
+
```typescript
|
|
85
|
+
export const PROVIDER_TEMPLATES: Record<string, ProviderTemplate> = {
|
|
86
|
+
providerId: {
|
|
87
|
+
id, displayName, npm, baseURL,
|
|
88
|
+
supportsApiKeyValidation,
|
|
89
|
+
validateApiKey: async (apiKey: string, model?: string) => Promise<boolean>
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Important Notes
|
|
95
|
+
- Check null/undefined before accessing nested properties
|
|
96
|
+
- Provider IDs with hyphens use quotes: `'volcengine-codingplan'`
|
|
97
|
+
- Create temp test dirs and clean up in afterEach
|
|
98
|
+
- Bilingual support (en/zh) via message objects
|
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# opencode-oh
|
|
2
|
+
|
|
3
|
+
OpenHarmony OpenCode Helper Tool - Configure opencode with third-party model providers through an interactive TUI.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Interactive TUI interface for easy configuration
|
|
8
|
+
- Support for multiple providers (Volcengine, OpenAI, DeepSeek, etc.)
|
|
9
|
+
- API key validation before applying configuration
|
|
10
|
+
- Automatic backup of existing configuration
|
|
11
|
+
- Bilingual support (Chinese/English)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g opencode-oh
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Run the tool:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
opencode-oh
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Follow the interactive prompts to:
|
|
28
|
+
|
|
29
|
+
1. Select a provider
|
|
30
|
+
2. Enter your API key
|
|
31
|
+
3. Enter the model name
|
|
32
|
+
4. Validate your API key
|
|
33
|
+
5. Apply the configuration
|
|
34
|
+
|
|
35
|
+
## Supported Providers
|
|
36
|
+
|
|
37
|
+
- **Volcengine** (火山引擎) - OpenAI-compatible API
|
|
38
|
+
- **OpenAI** - Official OpenAI API
|
|
39
|
+
- **DeepSeek** - OpenAI-compatible API
|
|
40
|
+
|
|
41
|
+
## Configuration
|
|
42
|
+
|
|
43
|
+
The tool modifies `~/.config/opencode/opencode.json`. Before making any changes, it automatically creates a timestamped backup file.
|
|
44
|
+
|
|
45
|
+
## Development
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Install dependencies
|
|
49
|
+
npm install
|
|
50
|
+
|
|
51
|
+
# Build the project
|
|
52
|
+
npm run build
|
|
53
|
+
|
|
54
|
+
# Run tests
|
|
55
|
+
npm test
|
|
56
|
+
|
|
57
|
+
# Run in development mode
|
|
58
|
+
npm run dev
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Project Structure
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
src/
|
|
65
|
+
cli.ts # CLI entry point
|
|
66
|
+
index.ts # Main module
|
|
67
|
+
config/ # Configuration management
|
|
68
|
+
index.ts
|
|
69
|
+
types.ts
|
|
70
|
+
provider/ # Provider templates
|
|
71
|
+
templates.ts
|
|
72
|
+
tui/ # TUI interface
|
|
73
|
+
index.ts
|
|
74
|
+
validation/ # API key validation
|
|
75
|
+
index.ts
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IAClB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OpenCodeConfig, ProviderInput } from './types.js';
|
|
2
|
+
export declare class ConfigManager {
|
|
3
|
+
private configPath;
|
|
4
|
+
constructor();
|
|
5
|
+
getConfigPath(): string;
|
|
6
|
+
readConfig(): OpenCodeConfig | null;
|
|
7
|
+
writeConfig(config: OpenCodeConfig): void;
|
|
8
|
+
backupConfig(): string | null;
|
|
9
|
+
restoreBackup(backupPath: string): void;
|
|
10
|
+
addProvider(input: ProviderInput): void;
|
|
11
|
+
getDefaultConfig(): OpenCodeConfig;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhF,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAS;;IAM3B,aAAa,IAAI,MAAM;IAIvB,UAAU,IAAI,cAAc,GAAG,IAAI;IAYnC,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAYzC,YAAY,IAAI,MAAM,GAAG,IAAI;IAgB7B,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAQvC,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IA8BvC,gBAAgB,IAAI,cAAc;CAMnC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import { getProviderTemplate } from '../provider/templates.js';
|
|
5
|
+
const CONFIG_DIR = path.join(os.homedir(), '.config', 'opencode');
|
|
6
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'opencode.json');
|
|
7
|
+
const DEFAULT_SCHEMA = 'https://opencode.ai/config.json';
|
|
8
|
+
export class ConfigManager {
|
|
9
|
+
configPath;
|
|
10
|
+
constructor() {
|
|
11
|
+
this.configPath = CONFIG_FILE;
|
|
12
|
+
}
|
|
13
|
+
getConfigPath() {
|
|
14
|
+
return this.configPath;
|
|
15
|
+
}
|
|
16
|
+
readConfig() {
|
|
17
|
+
try {
|
|
18
|
+
if (!fs.existsSync(this.configPath)) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const content = fs.readFileSync(this.configPath, 'utf-8');
|
|
22
|
+
return JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw new Error(`Failed to read config: ${error instanceof Error ? error.message : String(error)}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
writeConfig(config) {
|
|
29
|
+
try {
|
|
30
|
+
const configDir = path.dirname(this.configPath);
|
|
31
|
+
if (!fs.existsSync(configDir)) {
|
|
32
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw new Error(`Failed to write config: ${error instanceof Error ? error.message : String(error)}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
backupConfig() {
|
|
41
|
+
try {
|
|
42
|
+
if (!fs.existsSync(this.configPath)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const backupPath = `${this.configPath}.bak`;
|
|
46
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
47
|
+
const timestampedBackupPath = `${this.configPath}.${timestamp}.bak`;
|
|
48
|
+
fs.copyFileSync(this.configPath, timestampedBackupPath);
|
|
49
|
+
return timestampedBackupPath;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
throw new Error(`Failed to backup config: ${error instanceof Error ? error.message : String(error)}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
restoreBackup(backupPath) {
|
|
56
|
+
try {
|
|
57
|
+
fs.copyFileSync(backupPath, this.configPath);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new Error(`Failed to restore backup: ${error instanceof Error ? error.message : String(error)}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
addProvider(input) {
|
|
64
|
+
const config = this.readConfig() || this.getDefaultConfig();
|
|
65
|
+
if (!config.provider || typeof config.provider !== 'object') {
|
|
66
|
+
config.provider = {};
|
|
67
|
+
}
|
|
68
|
+
const template = getProviderTemplate(input.providerId);
|
|
69
|
+
if (!template) {
|
|
70
|
+
throw new Error(`Unknown provider: ${input.providerId}`);
|
|
71
|
+
}
|
|
72
|
+
const providerConfig = {
|
|
73
|
+
npm: template.npm,
|
|
74
|
+
name: template.id,
|
|
75
|
+
options: {
|
|
76
|
+
baseURL: template.baseURL,
|
|
77
|
+
apiKey: input.apiKey
|
|
78
|
+
},
|
|
79
|
+
models: {
|
|
80
|
+
[input.modelName]: {
|
|
81
|
+
name: input.modelName
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
config.provider[input.providerId] = providerConfig;
|
|
86
|
+
this.writeConfig(config);
|
|
87
|
+
}
|
|
88
|
+
getDefaultConfig() {
|
|
89
|
+
return {
|
|
90
|
+
$schema: DEFAULT_SCHEMA,
|
|
91
|
+
provider: {}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ProviderConfig {
|
|
2
|
+
npm: string;
|
|
3
|
+
name: string;
|
|
4
|
+
options: {
|
|
5
|
+
baseURL: string;
|
|
6
|
+
apiKey: string;
|
|
7
|
+
};
|
|
8
|
+
models: Record<string, {
|
|
9
|
+
name: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export interface OpenCodeConfig {
|
|
13
|
+
$schema: string;
|
|
14
|
+
provider: Record<string, ProviderConfig>;
|
|
15
|
+
}
|
|
16
|
+
export interface ProviderTemplate {
|
|
17
|
+
id: string;
|
|
18
|
+
displayName: string;
|
|
19
|
+
npm: string;
|
|
20
|
+
baseURL: string;
|
|
21
|
+
supportsApiKeyValidation: boolean;
|
|
22
|
+
validateApiKey?: (apiKey: string, model: string) => Promise<boolean>;
|
|
23
|
+
}
|
|
24
|
+
export interface ProviderInput {
|
|
25
|
+
providerId: string;
|
|
26
|
+
apiKey: string;
|
|
27
|
+
modelName: string;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB,EAAE,OAAO,CAAC;IAClC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBzC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ConfigManager } from './config/index.js';
|
|
2
|
+
import { TUIManager } from './tui/index.js';
|
|
3
|
+
export async function run() {
|
|
4
|
+
const configManager = new ConfigManager();
|
|
5
|
+
const tuiManager = new TUIManager();
|
|
6
|
+
try {
|
|
7
|
+
const input = await tuiManager.run();
|
|
8
|
+
if (!input) {
|
|
9
|
+
console.log('Cancelled');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const backupPath = configManager.backupConfig();
|
|
13
|
+
if (backupPath) {
|
|
14
|
+
tuiManager.showBackup(backupPath);
|
|
15
|
+
}
|
|
16
|
+
configManager.addProvider(input);
|
|
17
|
+
tuiManager.showMessage('configUpdated');
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
tuiManager.showError(error instanceof Error ? error.message : String(error));
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,GAAG;IACvB,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,aAAa,CAAC,YAAY,EAAE,CAAC;QAChD,IAAI,UAAU,EAAE,CAAC;YACf,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;QAED,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACjC,UAAU,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,UAAU,CAAC,SAAS,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ProviderTemplate } from '../config/types.js';
|
|
2
|
+
export declare const PROVIDER_TEMPLATES: Record<string, ProviderTemplate>;
|
|
3
|
+
export declare function getProviderTemplate(id: string): ProviderTemplate | undefined;
|
|
4
|
+
export declare function getAllProviderTemplates(): ProviderTemplate[];
|
|
5
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/provider/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAiE/D,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE5E;AAED,wBAAgB,uBAAuB,IAAI,gBAAgB,EAAE,CAE5D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export const PROVIDER_TEMPLATES = {
|
|
2
|
+
volcengine: {
|
|
3
|
+
id: 'volcengine',
|
|
4
|
+
displayName: '火山引擎',
|
|
5
|
+
npm: '@ai-sdk/openai-compatible',
|
|
6
|
+
baseURL: 'https://ark.cn-beijing.volces.com/api/v3',
|
|
7
|
+
supportsApiKeyValidation: true,
|
|
8
|
+
validateApiKey: async (apiKey, model) => {
|
|
9
|
+
try {
|
|
10
|
+
const response = await fetch('https://ark.cn-beijing.volces.com/api/v3/models', {
|
|
11
|
+
method: 'GET',
|
|
12
|
+
headers: {
|
|
13
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
14
|
+
'Content-Type': 'application/json'
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return response.ok;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
'volcengine-codingplan': {
|
|
25
|
+
id: 'volcengine-codingplan',
|
|
26
|
+
displayName: '火山引擎CodingPlan',
|
|
27
|
+
npm: '@ai-sdk/openai-compatible',
|
|
28
|
+
baseURL: 'https://ark.cn-beijing.volces.com/api/coding/v3',
|
|
29
|
+
supportsApiKeyValidation: true,
|
|
30
|
+
validateApiKey: async (apiKey, model) => {
|
|
31
|
+
try {
|
|
32
|
+
const response = await fetch('https://ark.cn-beijing.volces.com/api/coding/v3/models', {
|
|
33
|
+
method: 'GET',
|
|
34
|
+
headers: {
|
|
35
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
36
|
+
'Content-Type': 'application/json'
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return response.ok;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
'ZhiPu-CodingPlan': {
|
|
47
|
+
id: 'ZhiPu-CodingPlan',
|
|
48
|
+
displayName: '智谱CodingPlan',
|
|
49
|
+
npm: '@ai-sdk/openai-compatible',
|
|
50
|
+
baseURL: 'https://open.bigmodel.cn/api/paas/v4',
|
|
51
|
+
supportsApiKeyValidation: true,
|
|
52
|
+
validateApiKey: async (apiKey) => {
|
|
53
|
+
try {
|
|
54
|
+
const response = await fetch('https://open.bigmodel.cn/api/paas/v4/models', {
|
|
55
|
+
method: 'GET',
|
|
56
|
+
headers: {
|
|
57
|
+
'Authorization': `Bearer ${apiKey}`
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return response.ok;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
export function getProviderTemplate(id) {
|
|
69
|
+
return PROVIDER_TEMPLATES[id];
|
|
70
|
+
}
|
|
71
|
+
export function getAllProviderTemplates() {
|
|
72
|
+
return Object.values(PROVIDER_TEMPLATES);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/provider/templates.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAqC;IAClE,UAAU,EAAE;QACV,EAAE,EAAE,YAAY;QAChB,WAAW,EAAE,MAAM;QACnB,GAAG,EAAE,2BAA2B;QAChC,OAAO,EAAE,0CAA0C;QACnD,wBAAwB,EAAE,IAAI;QAC9B,cAAc,EAAE,KAAK,EAAE,MAAc,EAAE,KAAa,EAAE,EAAE;YACtD,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,iDAAiD,EAAE;oBAC9E,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE;wBACP,eAAe,EAAE,UAAU,MAAM,EAAE;wBACnC,cAAc,EAAE,kBAAkB;qBACnC;iBACF,CAAC,CAAC;gBACH,OAAO,QAAQ,CAAC,EAAE,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;KACF;IAED,uBAAuB,EAAE;QACvB,EAAE,EAAE,uBAAuB;QAC3B,WAAW,EAAE,gBAAgB;QAC7B,GAAG,EAAE,2BAA2B;QAChC,OAAO,EAAE,iDAAiD;QAC1D,wBAAwB,EAAE,IAAI;QAC9B,cAAc,EAAE,KAAK,EAAE,MAAc,EAAE,KAAa,EAAE,EAAE;YACtD,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,wDAAwD,EAAE;oBACrF,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE;wBACP,eAAe,EAAE,UAAU,MAAM,EAAE;wBACnC,cAAc,EAAE,kBAAkB;qBACnC;iBACF,CAAC,CAAC;gBACH,OAAO,QAAQ,CAAC,EAAE,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;KACF;IAED,kBAAkB,EAAE;QAClB,EAAE,EAAE,kBAAkB;QACtB,WAAW,EAAE,cAAc;QAC3B,GAAG,EAAE,2BAA2B;QAChC,OAAO,EAAE,sCAAsC;QAC/C,wBAAwB,EAAE,IAAI;QAC9B,cAAc,EAAE,KAAK,EAAE,MAAc,EAAE,EAAE;YACvC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,6CAA6C,EAAE;oBAC1E,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE;wBACP,eAAe,EAAE,UAAU,MAAM,EAAE;qBACpC;iBACF,CAAC,CAAC;gBACH,OAAO,QAAQ,CAAC,EAAE,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;KACF;CACF,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,EAAU;IAC5C,OAAO,kBAAkB,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ProviderInput } from '../config/types.js';
|
|
2
|
+
export declare class TUIManager {
|
|
3
|
+
private language;
|
|
4
|
+
private messages;
|
|
5
|
+
constructor();
|
|
6
|
+
run(): Promise<ProviderInput | null>;
|
|
7
|
+
private validateWithRetry;
|
|
8
|
+
showMessage(key: string): void;
|
|
9
|
+
showError(message: string): void;
|
|
10
|
+
showBackup(path: string): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tui/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA0CxD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAAyB;;IAQnC,GAAG,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;YAiD5B,iBAAiB;IA6C/B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI9B,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIhC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAG/B"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import { getAllProviderTemplates } from '../provider/templates.js';
|
|
3
|
+
import { validateApiKey } from '../validation/index.js';
|
|
4
|
+
const MESSAGES = {
|
|
5
|
+
en: {
|
|
6
|
+
welcome: 'Welcome to opencode-oh - OpenCode Helper Tool',
|
|
7
|
+
selectProvider: 'Select a provider to configure:',
|
|
8
|
+
providerBaseURL: 'Provider Base URL:',
|
|
9
|
+
enterApiKey: 'Enter API key:',
|
|
10
|
+
enterModelName: 'Enter model name:',
|
|
11
|
+
validating: 'Validating API key...',
|
|
12
|
+
validationSuccess: 'API key validated successfully',
|
|
13
|
+
validationFailed: 'API key validation failed',
|
|
14
|
+
retry: 'Would you like to retry?',
|
|
15
|
+
skipValidation: 'Skip validation and proceed?',
|
|
16
|
+
configUpdated: 'Configuration updated successfully',
|
|
17
|
+
backupCreated: 'Backup created at:',
|
|
18
|
+
errorOccurred: 'An error occurred:',
|
|
19
|
+
noProviders: 'No providers available'
|
|
20
|
+
},
|
|
21
|
+
zh: {
|
|
22
|
+
welcome: '欢迎使用 opencode-oh - OpenCode 辅助工具',
|
|
23
|
+
selectProvider: '选择要配置的提供商:',
|
|
24
|
+
providerBaseURL: '提供商 Base URL:',
|
|
25
|
+
enterApiKey: '输入 API key:',
|
|
26
|
+
enterModelName: '输入模型名称:',
|
|
27
|
+
validating: '正在验证 API key...',
|
|
28
|
+
validationSuccess: 'API key 验证成功',
|
|
29
|
+
validationFailed: 'API key 验证失败',
|
|
30
|
+
retry: '是否重试?',
|
|
31
|
+
skipValidation: '跳过验证并继续?',
|
|
32
|
+
configUpdated: '配置更新成功',
|
|
33
|
+
backupCreated: '备份已创建于:',
|
|
34
|
+
errorOccurred: '发生错误:',
|
|
35
|
+
noProviders: '没有可用的提供商'
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
export class TUIManager {
|
|
39
|
+
language;
|
|
40
|
+
messages;
|
|
41
|
+
constructor() {
|
|
42
|
+
const locale = process.env.LANG || 'en_US';
|
|
43
|
+
this.language = locale.startsWith('zh') ? 'zh' : 'en';
|
|
44
|
+
this.messages = MESSAGES[this.language];
|
|
45
|
+
}
|
|
46
|
+
async run() {
|
|
47
|
+
console.log(`\n${this.messages.welcome}\n`);
|
|
48
|
+
const providers = getAllProviderTemplates();
|
|
49
|
+
if (providers.length === 0) {
|
|
50
|
+
console.error(this.messages.noProviders);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const { providerId } = await inquirer.prompt([
|
|
54
|
+
{
|
|
55
|
+
type: 'list',
|
|
56
|
+
name: 'providerId',
|
|
57
|
+
message: this.messages.selectProvider,
|
|
58
|
+
choices: providers.map(p => ({
|
|
59
|
+
name: p.displayName,
|
|
60
|
+
value: p.id
|
|
61
|
+
}))
|
|
62
|
+
}
|
|
63
|
+
]);
|
|
64
|
+
const selectedProvider = providers.find(p => p.id === providerId);
|
|
65
|
+
if (selectedProvider) {
|
|
66
|
+
console.log(`\n${this.messages.providerBaseURL} ${selectedProvider.baseURL}\n`);
|
|
67
|
+
}
|
|
68
|
+
const { apiKey } = await inquirer.prompt([
|
|
69
|
+
{
|
|
70
|
+
type: 'password',
|
|
71
|
+
name: 'apiKey',
|
|
72
|
+
message: this.messages.enterApiKey,
|
|
73
|
+
validate: (input) => input.length > 0 || 'API key is required'
|
|
74
|
+
}
|
|
75
|
+
]);
|
|
76
|
+
const { modelName } = await inquirer.prompt([
|
|
77
|
+
{
|
|
78
|
+
type: 'input',
|
|
79
|
+
name: 'modelName',
|
|
80
|
+
message: this.messages.enterModelName,
|
|
81
|
+
validate: (input) => input.length > 0 || 'Model name is required'
|
|
82
|
+
}
|
|
83
|
+
]);
|
|
84
|
+
const input = { providerId, apiKey, modelName };
|
|
85
|
+
return await this.validateWithRetry(input);
|
|
86
|
+
}
|
|
87
|
+
async validateWithRetry(input) {
|
|
88
|
+
console.log(`\n${this.messages.validating}`);
|
|
89
|
+
const result = await validateApiKey(input.providerId, input.apiKey, input.modelName);
|
|
90
|
+
if (result.valid) {
|
|
91
|
+
console.log(`✓ ${this.messages.validationSuccess}\n`);
|
|
92
|
+
return input;
|
|
93
|
+
}
|
|
94
|
+
console.log(`✗ ${this.messages.validationFailed}`);
|
|
95
|
+
if (result.error) {
|
|
96
|
+
console.log(` ${result.error}`);
|
|
97
|
+
}
|
|
98
|
+
const { action } = await inquirer.prompt([
|
|
99
|
+
{
|
|
100
|
+
type: 'list',
|
|
101
|
+
name: 'action',
|
|
102
|
+
message: this.messages.retry,
|
|
103
|
+
choices: [
|
|
104
|
+
{ name: 'Retry', value: 'retry' },
|
|
105
|
+
{ name: 'Skip', value: 'skip' },
|
|
106
|
+
{ name: 'Cancel', value: 'cancel' }
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
]);
|
|
110
|
+
if (action === 'retry') {
|
|
111
|
+
const { apiKey } = await inquirer.prompt([
|
|
112
|
+
{
|
|
113
|
+
type: 'password',
|
|
114
|
+
name: 'apiKey',
|
|
115
|
+
message: this.messages.enterApiKey
|
|
116
|
+
}
|
|
117
|
+
]);
|
|
118
|
+
input.apiKey = apiKey;
|
|
119
|
+
return this.validateWithRetry(input);
|
|
120
|
+
}
|
|
121
|
+
else if (action === 'skip') {
|
|
122
|
+
return input;
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
showMessage(key) {
|
|
127
|
+
console.log(this.messages[key]);
|
|
128
|
+
}
|
|
129
|
+
showError(message) {
|
|
130
|
+
console.error(`${this.messages.errorOccurred} ${message}`);
|
|
131
|
+
}
|
|
132
|
+
showBackup(path) {
|
|
133
|
+
console.log(`${this.messages.backupCreated} ${path}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tui/index.ts"],"names":[],"mappings":"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"}
|