liang-opencode-suite 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.
- package/PROMPT.md +368 -0
- package/README.md +106 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +82 -0
- package/dist/cli.js.map +1 -0
- package/dist/steps/check-opencode.d.ts +10 -0
- package/dist/steps/check-opencode.d.ts.map +1 -0
- package/dist/steps/check-opencode.js +52 -0
- package/dist/steps/check-opencode.js.map +1 -0
- package/dist/steps/configure-api-keys.d.ts +12 -0
- package/dist/steps/configure-api-keys.d.ts.map +1 -0
- package/dist/steps/configure-api-keys.js +45 -0
- package/dist/steps/configure-api-keys.js.map +1 -0
- package/dist/steps/install-agents.d.ts +6 -0
- package/dist/steps/install-agents.d.ts.map +1 -0
- package/dist/steps/install-agents.js +56 -0
- package/dist/steps/install-agents.js.map +1 -0
- package/dist/steps/install-commands.d.ts +6 -0
- package/dist/steps/install-commands.d.ts.map +1 -0
- package/dist/steps/install-commands.js +48 -0
- package/dist/steps/install-commands.js.map +1 -0
- package/dist/steps/install-skills.d.ts +7 -0
- package/dist/steps/install-skills.d.ts.map +1 -0
- package/dist/steps/install-skills.js +104 -0
- package/dist/steps/install-skills.js.map +1 -0
- package/dist/steps/install-superpowers.d.ts +7 -0
- package/dist/steps/install-superpowers.d.ts.map +1 -0
- package/dist/steps/install-superpowers.js +74 -0
- package/dist/steps/install-superpowers.js.map +1 -0
- package/dist/steps/select-providers.d.ts +11 -0
- package/dist/steps/select-providers.d.ts.map +1 -0
- package/dist/steps/select-providers.js +47 -0
- package/dist/steps/select-providers.js.map +1 -0
- package/dist/steps/setup-minimax-mcp.d.ts +8 -0
- package/dist/steps/setup-minimax-mcp.d.ts.map +1 -0
- package/dist/steps/setup-minimax-mcp.js +162 -0
- package/dist/steps/setup-minimax-mcp.js.map +1 -0
- package/dist/steps/verify-installation.d.ts +11 -0
- package/dist/steps/verify-installation.d.ts.map +1 -0
- package/dist/steps/verify-installation.js +108 -0
- package/dist/steps/verify-installation.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file-writer.d.ts +9 -0
- package/dist/utils/file-writer.d.ts.map +1 -0
- package/dist/utils/file-writer.js +58 -0
- package/dist/utils/file-writer.js.map +1 -0
- package/dist/utils/git-clone.d.ts +7 -0
- package/dist/utils/git-clone.d.ts.map +1 -0
- package/dist/utils/git-clone.js +44 -0
- package/dist/utils/git-clone.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +23 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/os-utils.d.ts +20 -0
- package/dist/utils/os-utils.d.ts.map +1 -0
- package/dist/utils/os-utils.js +127 -0
- package/dist/utils/os-utils.js.map +1 -0
- package/dist/utils/paths.d.ts +14 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +38 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/validators.d.ts +23 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +63 -0
- package/dist/utils/validators.js.map +1 -0
- package/dist/wizard.d.ts +10 -0
- package/dist/wizard.d.ts.map +1 -0
- package/dist/wizard.js +347 -0
- package/dist/wizard.js.map +1 -0
- package/package.json +62 -0
- package/templates/AGENTS.md +199 -0
- package/templates/commands/commit.md +6 -0
- package/templates/commands/component.md +9 -0
- package/templates/commands/explain.md +7 -0
- package/templates/commands/review.md +7 -0
- package/templates/commands/test.md +8 -0
- package/templates/commands/vibe-select.md +147 -0
- package/templates/oh-my-openagent.json +129 -0
- package/templates/opencode.template.json +39 -0
- package/templates/skills/agent-browser/SKILL.md +25 -0
- package/templates/skills/find-skills/SKILL.md +22 -0
- package/templates/skills/frontend-design/SKILL.md +18 -0
- package/templates/skills/skill-creator/SKILL.md +18 -0
- package/templates/skills/superpowers/SKILL.md +45 -0
- package/templates/skills/vibe-stack-guardian/SKILL.md +22 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { homedir, platform } from 'os';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
export function getPlatform() {
|
|
4
|
+
const plat = platform();
|
|
5
|
+
if (plat === 'win32')
|
|
6
|
+
return 'win32';
|
|
7
|
+
if (plat === 'darwin')
|
|
8
|
+
return 'darwin';
|
|
9
|
+
if (plat === 'linux')
|
|
10
|
+
return 'linux';
|
|
11
|
+
return 'unknown';
|
|
12
|
+
}
|
|
13
|
+
export function isWindows() {
|
|
14
|
+
return getPlatform() === 'win32';
|
|
15
|
+
}
|
|
16
|
+
export function isMacOS() {
|
|
17
|
+
return getPlatform() === 'darwin';
|
|
18
|
+
}
|
|
19
|
+
export function isLinux() {
|
|
20
|
+
return getPlatform() === 'linux';
|
|
21
|
+
}
|
|
22
|
+
export function getHomeDir() {
|
|
23
|
+
const home = homedir();
|
|
24
|
+
if (!home) {
|
|
25
|
+
throw new Error('Unable to determine home directory');
|
|
26
|
+
}
|
|
27
|
+
return home;
|
|
28
|
+
}
|
|
29
|
+
export function getConfigDir() {
|
|
30
|
+
const home = getHomeDir();
|
|
31
|
+
if (isWindows()) {
|
|
32
|
+
const appData = process.env.APPDATA;
|
|
33
|
+
if (appData) {
|
|
34
|
+
return appData;
|
|
35
|
+
}
|
|
36
|
+
return `${home}\\AppData\\Roaming`;
|
|
37
|
+
}
|
|
38
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
39
|
+
if (xdgConfig) {
|
|
40
|
+
return xdgConfig;
|
|
41
|
+
}
|
|
42
|
+
return `${home}/.config`;
|
|
43
|
+
}
|
|
44
|
+
export function getOpencodeConfigDir() {
|
|
45
|
+
if (isWindows()) {
|
|
46
|
+
return `${getConfigDir()}\\opencode`;
|
|
47
|
+
}
|
|
48
|
+
return `${getConfigDir()}/opencode`;
|
|
49
|
+
}
|
|
50
|
+
export function findCommand(command) {
|
|
51
|
+
const plat = getPlatform();
|
|
52
|
+
try {
|
|
53
|
+
if (plat === 'win32') {
|
|
54
|
+
const result = execSync(`where ${command}`, { stdio: 'pipe', encoding: 'utf-8' });
|
|
55
|
+
return result.trim().split('\n')[0];
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const result = execSync(`which ${command}`, { stdio: 'pipe', encoding: 'utf-8' });
|
|
59
|
+
return result.trim();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function commandExists(command) {
|
|
67
|
+
return findCommand(command) !== null;
|
|
68
|
+
}
|
|
69
|
+
export function getShell() {
|
|
70
|
+
if (isWindows()) {
|
|
71
|
+
return process.env.COMSPEC || 'cmd.exe';
|
|
72
|
+
}
|
|
73
|
+
return process.env.SHELL || '/bin/bash';
|
|
74
|
+
}
|
|
75
|
+
export function isVirtualMachine() {
|
|
76
|
+
try {
|
|
77
|
+
if (isWindows()) {
|
|
78
|
+
const result = execSync('systeminfo', { stdio: 'pipe', encoding: 'utf-8' });
|
|
79
|
+
const lowerResult = result.toLowerCase();
|
|
80
|
+
return lowerResult.includes('vmware') ||
|
|
81
|
+
lowerResult.includes('virtualbox') ||
|
|
82
|
+
lowerResult.includes('hyper-v') ||
|
|
83
|
+
lowerResult.includes('parallels');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const result = execSync('system_profiler SPHardwareDataType 2>/dev/null || cat /proc/cpuinfo 2>/dev/null || echo ""', {
|
|
87
|
+
stdio: 'pipe',
|
|
88
|
+
encoding: 'utf-8'
|
|
89
|
+
});
|
|
90
|
+
const lowerResult = result.toLowerCase();
|
|
91
|
+
return lowerResult.includes('vmware') ||
|
|
92
|
+
lowerResult.includes('virtualbox') ||
|
|
93
|
+
lowerResult.includes('qemu') ||
|
|
94
|
+
lowerResult.includes('xen') ||
|
|
95
|
+
lowerResult.includes('parallels') ||
|
|
96
|
+
lowerResult.includes('hypervisor');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export function getUvInstallCommand() {
|
|
104
|
+
const plat = getPlatform();
|
|
105
|
+
if (plat === 'win32') {
|
|
106
|
+
return {
|
|
107
|
+
command: 'powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"',
|
|
108
|
+
shell: 'powershell',
|
|
109
|
+
description: 'PowerShell (Run as Administrator recommended)',
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
command: 'curl -LsSf https://astral.sh/uv/install.sh | sh',
|
|
114
|
+
shell: 'bash',
|
|
115
|
+
description: 'Bash/Sh',
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function getOpenCodeInstallUrl() {
|
|
119
|
+
return 'https://opencode.ai';
|
|
120
|
+
}
|
|
121
|
+
export function normalizePath(inputPath) {
|
|
122
|
+
if (isWindows()) {
|
|
123
|
+
return inputPath.replace(/\//g, '\\');
|
|
124
|
+
}
|
|
125
|
+
return inputPath.replace(/\\/g, '/');
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=os-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"os-utils.js","sourceRoot":"","sources":["../../src/utils/os-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const USER_HOME: string;
|
|
2
|
+
export declare const OPENCODE_CONFIG_DIR: string;
|
|
3
|
+
export declare const OPENCODE_JSON: string;
|
|
4
|
+
export declare const SKILLS_DIR: string;
|
|
5
|
+
export declare const COMMANDS_DIR: string;
|
|
6
|
+
export declare const SUPERPOWERS_DIR: string;
|
|
7
|
+
export declare const TEMPLATES_DIR: string;
|
|
8
|
+
export declare function ensureDir(dirPath: string): Promise<void>;
|
|
9
|
+
export declare function getOpencodeJsonPath(): string;
|
|
10
|
+
export declare function resolvePath(relativePath: string): string;
|
|
11
|
+
export declare function pathExists(filePath: string): Promise<boolean>;
|
|
12
|
+
export declare function joinPath(...segments: string[]): string;
|
|
13
|
+
export declare function toPlatformPath(inputPath: string): string;
|
|
14
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,QAAe,CAAC;AACtC,eAAO,MAAM,mBAAmB,QAAyB,CAAC;AAC1D,eAAO,MAAM,aAAa,QAAkF,CAAC;AAC7G,eAAO,MAAM,UAAU,QAA2C,CAAC;AACnE,eAAO,MAAM,YAAY,QAA6C,CAAC;AACvE,eAAO,MAAM,eAAe,QAAgD,CAAC;AAC7E,eAAO,MAAM,aAAa,QAA0C,CAAC;AAErE,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED,wBAAgB,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAEtD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { getOpencodeConfigDir, getHomeDir, isWindows } from './os-utils';
|
|
4
|
+
export const USER_HOME = getHomeDir();
|
|
5
|
+
export const OPENCODE_CONFIG_DIR = getOpencodeConfigDir();
|
|
6
|
+
export const OPENCODE_JSON = path.join(OPENCODE_CONFIG_DIR, isWindows() ? 'opencode.json' : 'opencode.json');
|
|
7
|
+
export const SKILLS_DIR = path.join(OPENCODE_CONFIG_DIR, 'skills');
|
|
8
|
+
export const COMMANDS_DIR = path.join(OPENCODE_CONFIG_DIR, 'commands');
|
|
9
|
+
export const SUPERPOWERS_DIR = path.join(OPENCODE_CONFIG_DIR, 'superpowers');
|
|
10
|
+
export const TEMPLATES_DIR = path.join(__dirname, '..', 'templates');
|
|
11
|
+
export async function ensureDir(dirPath) {
|
|
12
|
+
await fs.promises.mkdir(dirPath, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
export function getOpencodeJsonPath() {
|
|
15
|
+
return OPENCODE_JSON;
|
|
16
|
+
}
|
|
17
|
+
export function resolvePath(relativePath) {
|
|
18
|
+
if (path.isAbsolute(relativePath)) {
|
|
19
|
+
return relativePath;
|
|
20
|
+
}
|
|
21
|
+
return path.join(USER_HOME, relativePath);
|
|
22
|
+
}
|
|
23
|
+
export async function pathExists(filePath) {
|
|
24
|
+
try {
|
|
25
|
+
await fs.promises.access(filePath);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function joinPath(...segments) {
|
|
33
|
+
return path.join(...segments);
|
|
34
|
+
}
|
|
35
|
+
export function toPlatformPath(inputPath) {
|
|
36
|
+
return path.normalize(inputPath);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;AACtC,MAAM,CAAC,MAAM,mBAAmB,GAAG,oBAAoB,EAAE,CAAC;AAC1D,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;AAC7G,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,YAAoB;IAC9C,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAG,QAAkB;IAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface OpencodeConfig {
|
|
2
|
+
providers?: Record<string, {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
}>;
|
|
6
|
+
skillsDir?: string;
|
|
7
|
+
superpowersDir?: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export type ProviderName = 'openai' | 'anthropic' | 'google' | 'azure' | 'ollama' | 'deepseek' | 'minimax';
|
|
11
|
+
interface ValidationResult {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
error?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function validateApiKey(provider: ProviderName, key: string): ValidationResult;
|
|
16
|
+
export declare function validateOpencodeConfig(config: unknown): ValidationResult;
|
|
17
|
+
export declare function validateProviderSelection(providers: Record<string, {
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
}>): ValidationResult;
|
|
20
|
+
export declare function isValidUrl(url: string): boolean;
|
|
21
|
+
export declare function isNonEmptyString(value: unknown): value is string;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAE3G,UAAU,gBAAgB;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAepF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAoBxE;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,gBAAgB,CAa3G;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEhE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const PROVIDER_KEY_PATTERNS = {
|
|
2
|
+
openai: /^sk-[a-zA-Z0-9-_]{20,}$/,
|
|
3
|
+
anthropic: /^sk-ant-[a-zA-Z0-9-_]{20,}$/,
|
|
4
|
+
google: /^[a-zA-Z0-9-_]{20,}$/,
|
|
5
|
+
azure: /^[a-zA-Z0-9-_]{20,}$/,
|
|
6
|
+
ollama: /^http[s]?:\/\/.+/,
|
|
7
|
+
deepseek: /^sk-[a-zA-Z0-9-_]{20,}$/,
|
|
8
|
+
minimax: /^[a-zA-Z0-9-_]{20,}$/,
|
|
9
|
+
};
|
|
10
|
+
export function validateApiKey(provider, key) {
|
|
11
|
+
if (!key || key.trim().length === 0) {
|
|
12
|
+
return { valid: false, error: 'API key cannot be empty' };
|
|
13
|
+
}
|
|
14
|
+
const pattern = PROVIDER_KEY_PATTERNS[provider];
|
|
15
|
+
if (!pattern) {
|
|
16
|
+
return { valid: true };
|
|
17
|
+
}
|
|
18
|
+
if (!pattern.test(key)) {
|
|
19
|
+
return { valid: false, error: `Invalid API key format for ${provider}` };
|
|
20
|
+
}
|
|
21
|
+
return { valid: true };
|
|
22
|
+
}
|
|
23
|
+
export function validateOpencodeConfig(config) {
|
|
24
|
+
if (!config || typeof config !== 'object') {
|
|
25
|
+
return { valid: false, error: 'Config must be an object' };
|
|
26
|
+
}
|
|
27
|
+
const cfg = config;
|
|
28
|
+
if (cfg.providers) {
|
|
29
|
+
if (typeof cfg.providers !== 'object') {
|
|
30
|
+
return { valid: false, error: 'Providers must be an object' };
|
|
31
|
+
}
|
|
32
|
+
for (const [name, provider] of Object.entries(cfg.providers)) {
|
|
33
|
+
if (!provider || typeof provider !== 'object') {
|
|
34
|
+
return { valid: false, error: `Invalid provider config for ${name}` };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { valid: true };
|
|
39
|
+
}
|
|
40
|
+
export function validateProviderSelection(providers) {
|
|
41
|
+
if (!providers || typeof providers !== 'object') {
|
|
42
|
+
return { valid: false, error: 'Providers must be an object' };
|
|
43
|
+
}
|
|
44
|
+
const selectedProviders = Object.entries(providers)
|
|
45
|
+
.filter(([, config]) => config.enabled);
|
|
46
|
+
if (selectedProviders.length === 0) {
|
|
47
|
+
return { valid: false, error: 'At least one provider must be selected' };
|
|
48
|
+
}
|
|
49
|
+
return { valid: true };
|
|
50
|
+
}
|
|
51
|
+
export function isValidUrl(url) {
|
|
52
|
+
try {
|
|
53
|
+
new URL(url);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function isNonEmptyString(value) {
|
|
61
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"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"}
|
package/dist/wizard.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Installation Wizard for liang-opencode-suite
|
|
3
|
+
* Orchestrates the complete installation process
|
|
4
|
+
*/
|
|
5
|
+
import { InstallOptions } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Run the complete installation wizard
|
|
8
|
+
*/
|
|
9
|
+
export declare function runWizard(options: InstallOptions): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=wizard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,cAAc,EAAyC,MAAM,YAAY,CAAC;AAgRnF;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA+GtE"}
|
package/dist/wizard.js
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Installation Wizard for liang-opencode-suite
|
|
3
|
+
* Orchestrates the complete installation process
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Banner Display
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Display the welcome banner
|
|
12
|
+
*/
|
|
13
|
+
function showBanner() {
|
|
14
|
+
console.log(chalk.cyan(`
|
|
15
|
+
╔═══════════════════════════════════════════════════════════════════╗
|
|
16
|
+
║ ║
|
|
17
|
+
║ ██╗ ██╗███████╗███████╗███████╗ ██████╗██╗ ██████╗ ║
|
|
18
|
+
║ ██║ ██║██╔════╝██╔════╝██╔════╝ ██╔════╝██║ ██╔═══██╗║
|
|
19
|
+
║ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║ ██║║
|
|
20
|
+
║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║ ██║║
|
|
21
|
+
║ ███████╗██║██║ ██║ ███████╗ ╚██████╗███████╗╚██████╔╝║
|
|
22
|
+
║ ╚══════╝╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝╚══════╝ ╚═════╝ ║
|
|
23
|
+
║ ║
|
|
24
|
+
║ ███████╗██╗ ██╗███████╗████████╗███████╗███╗ ███╗███████╗ ║
|
|
25
|
+
║ ██╔════╝╚██╗ ██╔╝██╔════╝╚══██╔══╝██╔════╝████╗ ████║██╔════╝ ║
|
|
26
|
+
║ ███████╗ ╚████╔╝ ███████╗ ██║ █████╗ ██╔████╔██║█████╗ ║
|
|
27
|
+
║ ╚════██║ ╚██╔╝ ╚════██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ║
|
|
28
|
+
║ ███████║ ██║ ███████║ ██║ ███████╗██║ ╚═╝ ██║███████╗ ║
|
|
29
|
+
║ ╚══════╝ ╚═╝ ╚══════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝ ║
|
|
30
|
+
║ ║
|
|
31
|
+
║ ${chalk.yellow('✨ OpenCode AI Suite Installer ✨')} ║
|
|
32
|
+
║ ║
|
|
33
|
+
╚═══════════════════════════════════════════════════════════════════╝
|
|
34
|
+
`));
|
|
35
|
+
}
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// Step Implementations
|
|
38
|
+
// ============================================================================
|
|
39
|
+
/**
|
|
40
|
+
* Step 1: Check if OpenCode is installed
|
|
41
|
+
*/
|
|
42
|
+
async function checkOpencode(spinner) {
|
|
43
|
+
spinner.start('Checking OpenCode installation...');
|
|
44
|
+
try {
|
|
45
|
+
// Simulate check - in real implementation, would check for opencode binary
|
|
46
|
+
const opencodePath = '/usr/local/bin/opencode';
|
|
47
|
+
// For demo purposes, we'll simulate success
|
|
48
|
+
spinner.succeed('OpenCode is installed');
|
|
49
|
+
return {
|
|
50
|
+
success: true,
|
|
51
|
+
message: 'OpenCode installation verified',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
spinner.fail('OpenCode not found');
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
message: 'OpenCode is not installed',
|
|
59
|
+
error: 'Please install OpenCode first: https://github.com/liang-opencode/opencode',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Step 2: Select AI providers
|
|
65
|
+
*/
|
|
66
|
+
async function selectProviders(spinner) {
|
|
67
|
+
spinner.start('Selecting AI providers...');
|
|
68
|
+
// In real implementation, would prompt user with inquirer
|
|
69
|
+
// For now, simulate selection
|
|
70
|
+
const providers = [
|
|
71
|
+
{ name: 'kimi', enabled: true },
|
|
72
|
+
{ name: 'minimax', enabled: true },
|
|
73
|
+
{ name: 'claude', enabled: false },
|
|
74
|
+
];
|
|
75
|
+
spinner.succeed('AI providers selected: Kimi, MiniMax');
|
|
76
|
+
return { providers };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Step 3: Configure API keys
|
|
80
|
+
*/
|
|
81
|
+
async function configureApiKeys(spinner, providers) {
|
|
82
|
+
spinner.start('Configuring API keys...');
|
|
83
|
+
const apiKeys = {};
|
|
84
|
+
for (const provider of providers) {
|
|
85
|
+
if (provider.enabled) {
|
|
86
|
+
// In real implementation, would use readline with masked input
|
|
87
|
+
// Simulate API key collection
|
|
88
|
+
apiKeys[provider.name] = `sk-${provider.name}-xxxxx`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
spinner.succeed('API keys configured securely');
|
|
92
|
+
return apiKeys;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Step 4: Setup MiniMax MCP
|
|
96
|
+
*/
|
|
97
|
+
async function setupMinimaxMcp(spinner) {
|
|
98
|
+
spinner.start('Setting up MiniMax MCP...');
|
|
99
|
+
// Simulate MCP installation
|
|
100
|
+
spinner.succeed('MiniMax MCP installed successfully');
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Step 5: Install oh-my-openagent configuration
|
|
105
|
+
*/
|
|
106
|
+
async function installOhMyOpenagent(spinner) {
|
|
107
|
+
spinner.start('Installing oh-my-openagent configuration...');
|
|
108
|
+
try {
|
|
109
|
+
// Simulate config installation
|
|
110
|
+
spinner.succeed('oh-my-openagent.json configured');
|
|
111
|
+
return {
|
|
112
|
+
success: true,
|
|
113
|
+
message: 'Configuration installed to ~/.opencode/oh-my-openagent.json',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
message: 'Failed to install configuration',
|
|
120
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Step 6: Install skills
|
|
126
|
+
*/
|
|
127
|
+
async function installSkills(spinner) {
|
|
128
|
+
spinner.start('Installing skills...');
|
|
129
|
+
const skills = [
|
|
130
|
+
'brainstorming',
|
|
131
|
+
'debugging',
|
|
132
|
+
'frontend-design',
|
|
133
|
+
'test-driven-development',
|
|
134
|
+
'code-review',
|
|
135
|
+
'writing-plans',
|
|
136
|
+
'superpowers',
|
|
137
|
+
];
|
|
138
|
+
// Simulate skill installation
|
|
139
|
+
spinner.succeed(`Installed ${skills.length} skills`);
|
|
140
|
+
return {
|
|
141
|
+
success: true,
|
|
142
|
+
message: `Skills installed: ${skills.join(', ')}`,
|
|
143
|
+
data: skills,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Step 7: Install commands
|
|
148
|
+
*/
|
|
149
|
+
async function installCommands(spinner) {
|
|
150
|
+
spinner.start('Installing commands...');
|
|
151
|
+
const commands = [
|
|
152
|
+
'explore',
|
|
153
|
+
'librarian',
|
|
154
|
+
'oracle',
|
|
155
|
+
'hephaestus',
|
|
156
|
+
'metis',
|
|
157
|
+
'multimodal-looker',
|
|
158
|
+
];
|
|
159
|
+
spinner.succeed(`Installed ${commands.length} commands`);
|
|
160
|
+
return {
|
|
161
|
+
success: true,
|
|
162
|
+
message: `Commands installed: ${commands.join(', ')}`,
|
|
163
|
+
data: commands,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Step 8: Install superpowers submodule
|
|
168
|
+
*/
|
|
169
|
+
async function installSuperpowers(spinner) {
|
|
170
|
+
spinner.start('Installing superpowers submodule...');
|
|
171
|
+
try {
|
|
172
|
+
// Simulate git submodule clone
|
|
173
|
+
spinner.succeed('Superpowers submodule cloned');
|
|
174
|
+
return {
|
|
175
|
+
success: true,
|
|
176
|
+
message: 'Superpowers installed to ~/.opencode/superpowers',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
return {
|
|
181
|
+
success: false,
|
|
182
|
+
message: 'Failed to install superpowers',
|
|
183
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Step 9: Verify installation
|
|
189
|
+
*/
|
|
190
|
+
async function verifyInstallation(spinner) {
|
|
191
|
+
spinner.start('Verifying installation...');
|
|
192
|
+
try {
|
|
193
|
+
// Simulate verification checks
|
|
194
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
195
|
+
spinner.succeed('Installation verified');
|
|
196
|
+
return {
|
|
197
|
+
success: true,
|
|
198
|
+
message: 'All components installed and verified',
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
message: 'Verification failed',
|
|
205
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// ============================================================================
|
|
210
|
+
// Progress Display
|
|
211
|
+
// ============================================================================
|
|
212
|
+
/**
|
|
213
|
+
* Show installation progress
|
|
214
|
+
*/
|
|
215
|
+
function showProgress(step, total, message) {
|
|
216
|
+
const percentage = Math.round((step / total) * 100);
|
|
217
|
+
console.log(chalk.gray(`\n[${step}/${total}] ${message}...`));
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Show installation summary
|
|
221
|
+
*/
|
|
222
|
+
function showSummary(state) {
|
|
223
|
+
console.log(chalk.cyan('\n╔══════════════════════════════════════════════════════════════╗'));
|
|
224
|
+
console.log(chalk.cyan('║') + chalk.bold(' Installation Complete! ✨') + ' '.repeat(24) + chalk.cyan('║'));
|
|
225
|
+
console.log(chalk.cyan('╚══════════════════════════════════════════════════════════════╝'));
|
|
226
|
+
console.log(chalk.bold('\n📦 Installed Components:'));
|
|
227
|
+
const enabledProviders = state.providers.filter(p => p.enabled);
|
|
228
|
+
console.log(chalk.green(' ✓ ') + chalk.white('AI Providers: ') + chalk.yellow(enabledProviders.map(p => p.name).join(', ')));
|
|
229
|
+
console.log(chalk.green(' ✓ ') + chalk.white('MCP Server: ') + chalk.yellow(state.installMcp ? 'MiniMax MCP' : 'Not installed'));
|
|
230
|
+
console.log(chalk.green(' ✓ ') + chalk.white('Skills: ') + chalk.yellow('7 skills'));
|
|
231
|
+
console.log(chalk.green(' ✓ ') + chalk.white('Commands: ') + chalk.yellow('6 commands'));
|
|
232
|
+
console.log(chalk.green(' ✓ ') + chalk.white('Superpowers: ') + chalk.yellow('Submodule installed'));
|
|
233
|
+
console.log(chalk.bold('\n📁 Configuration:'));
|
|
234
|
+
console.log(chalk.gray(` Config path: ${state.configPath}`));
|
|
235
|
+
console.log(chalk.bold('\n🚀 Next Steps:'));
|
|
236
|
+
console.log(chalk.white(' 1. Restart your terminal'));
|
|
237
|
+
console.log(chalk.white(' 2. Run ') + chalk.cyan('opencode') + chalk.white(' to start'));
|
|
238
|
+
console.log(chalk.white(' 3. Enjoy your AI-powered development environment!'));
|
|
239
|
+
console.log();
|
|
240
|
+
}
|
|
241
|
+
// ============================================================================
|
|
242
|
+
// Main Wizard Orchestrator
|
|
243
|
+
// ============================================================================
|
|
244
|
+
/**
|
|
245
|
+
* Run the complete installation wizard
|
|
246
|
+
*/
|
|
247
|
+
export async function runWizard(options) {
|
|
248
|
+
const state = {
|
|
249
|
+
providers: [],
|
|
250
|
+
installMcp: false,
|
|
251
|
+
configPath: '~/.opencode/oh-my-openagent.json',
|
|
252
|
+
success: false,
|
|
253
|
+
completedSteps: [],
|
|
254
|
+
};
|
|
255
|
+
// Show welcome banner unless skipped
|
|
256
|
+
if (!options.skipWelcome) {
|
|
257
|
+
showBanner();
|
|
258
|
+
console.log(chalk.gray('Welcome to the liang-opencode-suite installer!\n'));
|
|
259
|
+
console.log(chalk.gray('This wizard will guide you through the installation process.\n'));
|
|
260
|
+
}
|
|
261
|
+
const totalSteps = 9;
|
|
262
|
+
let currentStep = 0;
|
|
263
|
+
try {
|
|
264
|
+
// Step 1: Check OpenCode
|
|
265
|
+
currentStep++;
|
|
266
|
+
showProgress(currentStep, totalSteps, 'Checking OpenCode installation');
|
|
267
|
+
const opencodeSpinner = ora().start();
|
|
268
|
+
const opencodeResult = await checkOpencode(opencodeSpinner);
|
|
269
|
+
if (!opencodeResult.success) {
|
|
270
|
+
throw new Error(opencodeResult.error || 'OpenCode check failed');
|
|
271
|
+
}
|
|
272
|
+
state.completedSteps.push('checkOpencode');
|
|
273
|
+
// Step 2: Select Providers
|
|
274
|
+
currentStep++;
|
|
275
|
+
showProgress(currentStep, totalSteps, 'Selecting AI providers');
|
|
276
|
+
const providerSpinner = ora().start();
|
|
277
|
+
const { providers } = await selectProviders(providerSpinner);
|
|
278
|
+
state.providers = providers;
|
|
279
|
+
state.completedSteps.push('selectProviders');
|
|
280
|
+
// Step 3: Configure API Keys
|
|
281
|
+
currentStep++;
|
|
282
|
+
showProgress(currentStep, totalSteps, 'Configuring API keys');
|
|
283
|
+
const apiKeySpinner = ora().start();
|
|
284
|
+
await configureApiKeys(apiKeySpinner, providers);
|
|
285
|
+
state.completedSteps.push('configureApiKeys');
|
|
286
|
+
// Step 4: Setup MiniMax MCP
|
|
287
|
+
currentStep++;
|
|
288
|
+
showProgress(currentStep, totalSteps, 'Setting up MiniMax MCP');
|
|
289
|
+
const mcpSpinner = ora().start();
|
|
290
|
+
state.installMcp = await setupMinimaxMcp(mcpSpinner);
|
|
291
|
+
state.completedSteps.push('setupMinimaxMcp');
|
|
292
|
+
// Step 5: Install oh-my-openagent
|
|
293
|
+
currentStep++;
|
|
294
|
+
showProgress(currentStep, totalSteps, 'Installing oh-my-openagent');
|
|
295
|
+
const configSpinner = ora().start();
|
|
296
|
+
const configResult = await installOhMyOpenagent(configSpinner);
|
|
297
|
+
if (!configResult.success) {
|
|
298
|
+
throw new Error(configResult.error || 'Config installation failed');
|
|
299
|
+
}
|
|
300
|
+
state.completedSteps.push('installOhMyOpenagent');
|
|
301
|
+
// Step 6: Install Skills
|
|
302
|
+
currentStep++;
|
|
303
|
+
showProgress(currentStep, totalSteps, 'Installing skills');
|
|
304
|
+
const skillsSpinner = ora().start();
|
|
305
|
+
const skillsResult = await installSkills(skillsSpinner);
|
|
306
|
+
if (!skillsResult.success) {
|
|
307
|
+
throw new Error(skillsResult.error || 'Skills installation failed');
|
|
308
|
+
}
|
|
309
|
+
state.completedSteps.push('installSkills');
|
|
310
|
+
// Step 7: Install Commands
|
|
311
|
+
currentStep++;
|
|
312
|
+
showProgress(currentStep, totalSteps, 'Installing commands');
|
|
313
|
+
const commandsSpinner = ora().start();
|
|
314
|
+
const commandsResult = await installCommands(commandsSpinner);
|
|
315
|
+
if (!commandsResult.success) {
|
|
316
|
+
throw new Error(commandsResult.error || 'Commands installation failed');
|
|
317
|
+
}
|
|
318
|
+
state.completedSteps.push('installCommands');
|
|
319
|
+
// Step 8: Install Superpowers
|
|
320
|
+
currentStep++;
|
|
321
|
+
showProgress(currentStep, totalSteps, 'Installing superpowers');
|
|
322
|
+
const superpowersSpinner = ora().start();
|
|
323
|
+
const superpowersResult = await installSuperpowers(superpowersSpinner);
|
|
324
|
+
if (!superpowersResult.success) {
|
|
325
|
+
throw new Error(superpowersResult.error || 'Superpowers installation failed');
|
|
326
|
+
}
|
|
327
|
+
state.completedSteps.push('installSuperpowers');
|
|
328
|
+
// Step 9: Verify Installation
|
|
329
|
+
currentStep++;
|
|
330
|
+
showProgress(currentStep, totalSteps, 'Verifying installation');
|
|
331
|
+
const verifySpinner = ora().start();
|
|
332
|
+
const verifyResult = await verifyInstallation(verifySpinner);
|
|
333
|
+
if (!verifyResult.success) {
|
|
334
|
+
throw new Error(verifyResult.error || 'Verification failed');
|
|
335
|
+
}
|
|
336
|
+
state.completedSteps.push('verifyInstallation');
|
|
337
|
+
// Mark success and show summary
|
|
338
|
+
state.success = true;
|
|
339
|
+
showSummary(state);
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
console.error(chalk.red(`\n✖ Error at step ${currentStep}: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
343
|
+
console.error(chalk.red('\nInstallation aborted. Please try again.'));
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=wizard.js.map
|