ai-summon 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/speckit.analyze.md +184 -0
- package/.claude/commands/speckit.checklist.md +294 -0
- package/.claude/commands/speckit.clarify.md +177 -0
- package/.claude/commands/speckit.constitution.md +78 -0
- package/.claude/commands/speckit.implement.md +121 -0
- package/.claude/commands/speckit.plan.md +81 -0
- package/.claude/commands/speckit.specify.md +204 -0
- package/.claude/commands/speckit.tasks.md +108 -0
- package/.claude/settings.local.json +23 -0
- package/.prettierignore +5 -0
- package/.prettierrc.json +10 -0
- package/.specify/memory/constitution.md +72 -0
- package/.specify/scripts/bash/check-prerequisites.sh +166 -0
- package/.specify/scripts/bash/common.sh +113 -0
- package/.specify/scripts/bash/create-new-feature.sh +97 -0
- package/.specify/scripts/bash/setup-plan.sh +60 -0
- package/.specify/scripts/bash/update-agent-context.sh +738 -0
- package/.specify/templates/agent-file-template.md +28 -0
- package/.specify/templates/checklist-template.md +40 -0
- package/.specify/templates/plan-template.md +111 -0
- package/.specify/templates/spec-template.md +115 -0
- package/.specify/templates/tasks-template.md +250 -0
- package/CLAUDE.md +199 -0
- package/PRD.md +268 -0
- package/README.md +171 -0
- package/dist/ai-summon.d.ts +2 -0
- package/dist/ai-summon.js +73 -0
- package/dist/commands/ide/index.d.ts +3 -0
- package/dist/commands/ide/index.js +253 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +55 -0
- package/dist/commands/url.d.ts +4 -0
- package/dist/commands/url.js +223 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.js +1 -0
- package/dist/util.d.ts +16 -0
- package/dist/util.js +109 -0
- package/eslint.config.js +47 -0
- package/package.json +47 -0
- package/specs/001-cloud-login-feature/contracts/cloud-command.ts +82 -0
- package/specs/001-cloud-login-feature/contracts/config-service.ts +170 -0
- package/specs/001-cloud-login-feature/data-model.md +269 -0
- package/specs/001-cloud-login-feature/plan.md +91 -0
- package/specs/001-cloud-login-feature/quickstart.md +366 -0
- package/specs/001-cloud-login-feature/research.md +290 -0
- package/specs/001-cloud-login-feature/spec.md +195 -0
- package/specs/001-cloud-login-feature/tasks.md +235 -0
- package/specs/001-cloud-scp-command/contracts/cloud-scp-api.ts +402 -0
- package/specs/001-cloud-scp-command/data-model.md +424 -0
- package/specs/001-cloud-scp-command/plan.md +124 -0
- package/specs/001-cloud-scp-command/quickstart.md +536 -0
- package/specs/001-cloud-scp-command/research.md +345 -0
- package/specs/001-cloud-scp-command/spec.md +248 -0
- package/specs/001-cloud-scp-command/tasks.md +434 -0
- package/src/ai-summon.ts +88 -0
- package/src/commands/ide/index.ts +322 -0
- package/src/commands/init.ts +64 -0
- package/src/commands/url.ts +262 -0
- package/src/types/index.ts +49 -0
- package/src/util.ts +146 -0
- package/tsconfig.json +21 -0
package/dist/util.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { readFileSync, existsSync, readdirSync, mkdirSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join, basename } from 'path';
|
|
3
|
+
import { dirname } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { homedir } from 'os';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
export const getPackageJson = () => {
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
|
|
11
|
+
return packageJson;
|
|
12
|
+
};
|
|
13
|
+
export const getConfigPath = () => {
|
|
14
|
+
const dir = join(homedir(), '.ai');
|
|
15
|
+
mkdirSync(dir, { recursive: true });
|
|
16
|
+
return join(dir, 'config.json');
|
|
17
|
+
};
|
|
18
|
+
export const readConfig = () => {
|
|
19
|
+
const configPath = getConfigPath();
|
|
20
|
+
if (!existsSync(configPath)) {
|
|
21
|
+
console.log(chalk.yellow(`Configuration file not found: ${configPath}\n` +
|
|
22
|
+
`Run "ai init" to create it and set your workingDirectory.`));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const configContent = readFileSync(configPath, 'utf-8');
|
|
26
|
+
const config = JSON.parse(configContent);
|
|
27
|
+
// If workingDirectory is configured but repos/yiren are not, initialize them
|
|
28
|
+
if (config.workingDirectory && !config.repos) {
|
|
29
|
+
return {
|
|
30
|
+
workingDirectory: config.workingDirectory,
|
|
31
|
+
repos: {},
|
|
32
|
+
yiren: config.yiren || {},
|
|
33
|
+
urls: config.urls,
|
|
34
|
+
urlGroups: config.urlGroups,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return config;
|
|
38
|
+
};
|
|
39
|
+
const ensureAiDir = () => {
|
|
40
|
+
const dir = join(homedir(), '.ai');
|
|
41
|
+
mkdirSync(dir, { recursive: true });
|
|
42
|
+
return dir;
|
|
43
|
+
};
|
|
44
|
+
const getIdeReposCachePath = () => {
|
|
45
|
+
const dir = ensureAiDir();
|
|
46
|
+
return join(dir, 'ide-repos-cache.json');
|
|
47
|
+
};
|
|
48
|
+
export const readIdeReposCache = (workingDirectory) => {
|
|
49
|
+
const cachePath = getIdeReposCachePath();
|
|
50
|
+
if (!existsSync(cachePath))
|
|
51
|
+
return null;
|
|
52
|
+
try {
|
|
53
|
+
const raw = readFileSync(cachePath, 'utf-8');
|
|
54
|
+
const parsed = JSON.parse(raw);
|
|
55
|
+
if (parsed.version !== 1)
|
|
56
|
+
return null;
|
|
57
|
+
if (parsed.workingDirectory !== workingDirectory)
|
|
58
|
+
return null;
|
|
59
|
+
if (!Array.isArray(parsed.repos))
|
|
60
|
+
return null;
|
|
61
|
+
return parsed.repos;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
export const writeIdeReposCache = (workingDirectory, repos) => {
|
|
68
|
+
const cachePath = getIdeReposCachePath();
|
|
69
|
+
const payload = {
|
|
70
|
+
version: 1,
|
|
71
|
+
workingDirectory,
|
|
72
|
+
updatedAt: Date.now(),
|
|
73
|
+
repos,
|
|
74
|
+
};
|
|
75
|
+
writeFileSync(cachePath, JSON.stringify(payload, null, 2), 'utf-8');
|
|
76
|
+
};
|
|
77
|
+
export const findGitRepositories = (workingDirectory) => {
|
|
78
|
+
const repositories = [];
|
|
79
|
+
const scanDirectory = (dir, topLevelFolder = '/') => {
|
|
80
|
+
try {
|
|
81
|
+
// Check if current directory contains .git folder
|
|
82
|
+
if (existsSync(join(dir, '.git'))) {
|
|
83
|
+
repositories.push({
|
|
84
|
+
name: basename(dir),
|
|
85
|
+
path: dir,
|
|
86
|
+
topLevelFolder,
|
|
87
|
+
});
|
|
88
|
+
return; // Stop recursing into this directory
|
|
89
|
+
}
|
|
90
|
+
// Continue scanning subdirectories
|
|
91
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
if (entry.isDirectory()) {
|
|
94
|
+
const fullPath = join(dir, entry.name);
|
|
95
|
+
// Determine top-level folder for this entry
|
|
96
|
+
const isTopLevel = dir === workingDirectory;
|
|
97
|
+
const currentTopLevel = isTopLevel ? entry.name : topLevelFolder;
|
|
98
|
+
scanDirectory(fullPath, currentTopLevel);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// Silently skip directories with permission errors
|
|
104
|
+
// This will be enhanced in future iterations
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
scanDirectory(workingDirectory);
|
|
108
|
+
return repositories;
|
|
109
|
+
};
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import tseslint from '@typescript-eslint/eslint-plugin';
|
|
3
|
+
import tsparser from '@typescript-eslint/parser';
|
|
4
|
+
import prettier from 'eslint-plugin-prettier';
|
|
5
|
+
import prettierConfig from 'eslint-config-prettier';
|
|
6
|
+
import globals from 'globals';
|
|
7
|
+
|
|
8
|
+
export default [
|
|
9
|
+
{
|
|
10
|
+
ignores: ['dist/**', 'node_modules/**', '**/*.js'],
|
|
11
|
+
},
|
|
12
|
+
eslint.configs.recommended,
|
|
13
|
+
{
|
|
14
|
+
files: ['src/**/*.ts'],
|
|
15
|
+
languageOptions: {
|
|
16
|
+
parser: tsparser,
|
|
17
|
+
parserOptions: {
|
|
18
|
+
ecmaVersion: 2020,
|
|
19
|
+
sourceType: 'module',
|
|
20
|
+
project: './tsconfig.json',
|
|
21
|
+
},
|
|
22
|
+
globals: {
|
|
23
|
+
...globals.node,
|
|
24
|
+
$: 'readonly',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
plugins: {
|
|
28
|
+
'@typescript-eslint': tseslint,
|
|
29
|
+
prettier: prettier,
|
|
30
|
+
},
|
|
31
|
+
rules: {
|
|
32
|
+
...tseslint.configs.recommended.rules,
|
|
33
|
+
...prettierConfig.rules,
|
|
34
|
+
'prettier/prettier': 'error',
|
|
35
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
36
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
37
|
+
'@typescript-eslint/no-unused-vars': [
|
|
38
|
+
'error',
|
|
39
|
+
{
|
|
40
|
+
argsIgnorePattern: '^_',
|
|
41
|
+
varsIgnorePattern: '^_',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
'no-console': 'off',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai-summon",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
9
|
+
"build": "rm -rf dist && tsc",
|
|
10
|
+
"build:install": "npm run build && npm uninstall -g && npm install -g",
|
|
11
|
+
"start": "node dist/bin/ai-summon.js",
|
|
12
|
+
"dev": "ts-node bin/ai-summon.ts",
|
|
13
|
+
"lint": "eslint src --ext .ts",
|
|
14
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
15
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
16
|
+
"format:check": "prettier --check \"src/**/*.ts\""
|
|
17
|
+
},
|
|
18
|
+
"bin": {
|
|
19
|
+
"ai": "./dist/ai-summon.js"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "ISC",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"chalk": "^5.3.0",
|
|
26
|
+
"commander": "^12.0.0",
|
|
27
|
+
"inquirer": "^9.2.15",
|
|
28
|
+
"inquirer-autocomplete-prompt": "^3.0.1",
|
|
29
|
+
"log-symbols": "^6.0.0",
|
|
30
|
+
"ora": "^8.0.1",
|
|
31
|
+
"zx": "^7.2.3"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/inquirer": "^9.0.7",
|
|
35
|
+
"@types/inquirer-autocomplete-prompt": "^3.0.3",
|
|
36
|
+
"@types/node": "^20.0.0",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
|
38
|
+
"@typescript-eslint/parser": "^8.48.1",
|
|
39
|
+
"eslint": "^9.39.1",
|
|
40
|
+
"eslint-config-prettier": "^10.1.8",
|
|
41
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
42
|
+
"globals": "^16.5.0",
|
|
43
|
+
"prettier": "^3.7.4",
|
|
44
|
+
"ts-node": "^10.9.0",
|
|
45
|
+
"typescript": "^5.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Command Interface Contract
|
|
3
|
+
* Defines the CLI command interface for cloud infrastructure access
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface CloudLoginOptions {
|
|
7
|
+
/** Environment to connect to: dev, staging, or prod */
|
|
8
|
+
env?: 'dev' | 'staging' | 'prod';
|
|
9
|
+
|
|
10
|
+
/** Service name to connect to (e.g., todo-mini, wuhan-mall) */
|
|
11
|
+
service?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CloudLoginCommand {
|
|
15
|
+
/**
|
|
16
|
+
* Execute cloud login SSH connection
|
|
17
|
+
* @param options Command options from CLI
|
|
18
|
+
* @returns Promise that resolves when SSH session is established or rejects on error
|
|
19
|
+
*/
|
|
20
|
+
execute(options: CloudLoginOptions): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Command signature for Commander.js integration
|
|
25
|
+
* Main command: hsh cloud (with subcommands)
|
|
26
|
+
* Usage: hsh cloud login --env dev --service todo-mini
|
|
27
|
+
*/
|
|
28
|
+
export interface CloudCommandDefinition {
|
|
29
|
+
name: 'cloud';
|
|
30
|
+
description: 'Cloud infrastructure management commands';
|
|
31
|
+
subcommands: {
|
|
32
|
+
login: {
|
|
33
|
+
description: 'SSH into cloud instances based on environment and service';
|
|
34
|
+
options: {
|
|
35
|
+
'--env <environment>': 'Environment: dev, staging, or prod';
|
|
36
|
+
'--service <service>': 'Service name (e.g., todo-mini, wuhan-mall)';
|
|
37
|
+
};
|
|
38
|
+
examples: [
|
|
39
|
+
'hsh cloud login --env dev --service todo-mini',
|
|
40
|
+
'hsh cloud login --env prod --service wuhan-mall',
|
|
41
|
+
'hsh cloud login # Interactive mode with prompts',
|
|
42
|
+
];
|
|
43
|
+
};
|
|
44
|
+
// Future subcommands can be added here
|
|
45
|
+
// scp: { ... };
|
|
46
|
+
// status: { ... };
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Error types that can be thrown during cloud login execution
|
|
52
|
+
*/
|
|
53
|
+
export enum CloudLoginError {
|
|
54
|
+
CONFIG_NOT_FOUND = 'CONFIG_NOT_FOUND',
|
|
55
|
+
INVALID_CONFIG = 'INVALID_CONFIG',
|
|
56
|
+
SERVICE_NOT_FOUND = 'SERVICE_NOT_FOUND',
|
|
57
|
+
ENVIRONMENT_NOT_FOUND = 'ENVIRONMENT_NOT_FOUND',
|
|
58
|
+
PRIVATE_KEY_NOT_FOUND = 'PRIVATE_KEY_NOT_FOUND',
|
|
59
|
+
PRIVATE_KEY_PERMISSIONS = 'PRIVATE_KEY_PERMISSIONS',
|
|
60
|
+
SSH_CONNECTION_FAILED = 'SSH_CONNECTION_FAILED',
|
|
61
|
+
NETWORK_UNREACHABLE = 'NETWORK_UNREACHABLE',
|
|
62
|
+
AUTHENTICATION_FAILED = 'AUTHENTICATION_FAILED',
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Structured error information for user feedback
|
|
67
|
+
*/
|
|
68
|
+
export interface CloudLoginErrorInfo {
|
|
69
|
+
type: CloudLoginError;
|
|
70
|
+
message: string;
|
|
71
|
+
suggestion?: string;
|
|
72
|
+
command?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Configuration validation result
|
|
77
|
+
*/
|
|
78
|
+
export interface ConfigValidationResult {
|
|
79
|
+
valid: boolean;
|
|
80
|
+
errors: CloudLoginErrorInfo[];
|
|
81
|
+
warnings: string[];
|
|
82
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Service Interface Contract
|
|
3
|
+
* Defines the interface for reading and managing hsh configuration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { HshConfig, CloudConfig, Environment } from '../data-model';
|
|
7
|
+
|
|
8
|
+
export interface ConfigService {
|
|
9
|
+
/**
|
|
10
|
+
* Read configuration from ~/.ai/config.json
|
|
11
|
+
* @returns Promise resolving to parsed configuration
|
|
12
|
+
* @throws Error if file not found or invalid JSON
|
|
13
|
+
*/
|
|
14
|
+
readConfig(): Promise<HshConfig>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Get cloud configuration for specific service and environment
|
|
18
|
+
* @param service Service name (e.g., todo-mini)
|
|
19
|
+
* @param environment Environment name (dev, staging, prod)
|
|
20
|
+
* @returns Cloud configuration or null if not found
|
|
21
|
+
*/
|
|
22
|
+
getCloudConfig(service: string, environment: Environment): Promise<CloudConfig | null>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get all available services from configuration
|
|
26
|
+
* @returns Array of service names
|
|
27
|
+
*/
|
|
28
|
+
getAvailableServices(): Promise<string[]>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get all available environments for a specific service
|
|
32
|
+
* @param service Service name
|
|
33
|
+
* @returns Array of environment names
|
|
34
|
+
*/
|
|
35
|
+
getAvailableEnvironments(service: string): Promise<Environment[]>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Validate configuration structure and content
|
|
39
|
+
* @returns Validation result with errors and warnings
|
|
40
|
+
*/
|
|
41
|
+
validateConfig(): Promise<ConfigValidationResult>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Migrate legacy configuration to new structure
|
|
45
|
+
* @param legacyConfig Legacy configuration object
|
|
46
|
+
* @returns Migrated configuration
|
|
47
|
+
*/
|
|
48
|
+
migrateConfig(legacyConfig: any): HshConfig;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check if configuration uses legacy format
|
|
52
|
+
* @returns True if configuration needs migration
|
|
53
|
+
*/
|
|
54
|
+
isLegacyConfig(): Promise<boolean>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* SSH Service Interface Contract
|
|
59
|
+
* Defines the interface for SSH connection management
|
|
60
|
+
*/
|
|
61
|
+
export interface SSHService {
|
|
62
|
+
/**
|
|
63
|
+
* Execute SSH connection to specified host
|
|
64
|
+
* @param ip Target IP address
|
|
65
|
+
* @param privateKeyFile Path to SSH private key
|
|
66
|
+
* @param username SSH username (default: root)
|
|
67
|
+
* @returns Promise that resolves when connection is established
|
|
68
|
+
*/
|
|
69
|
+
connect(ip: string, privateKeyFile: string, username?: string): Promise<void>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Validate SSH private key file
|
|
73
|
+
* @param privateKeyFile Path to private key file
|
|
74
|
+
* @returns Promise resolving to validation result
|
|
75
|
+
*/
|
|
76
|
+
validatePrivateKey(privateKeyFile: string): Promise<{
|
|
77
|
+
exists: boolean;
|
|
78
|
+
permissions: string;
|
|
79
|
+
isValid: boolean;
|
|
80
|
+
suggestions: string[];
|
|
81
|
+
}>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Test SSH connectivity without establishing full session
|
|
85
|
+
* @param ip Target IP address
|
|
86
|
+
* @param privateKeyFile Path to SSH private key
|
|
87
|
+
* @returns Promise resolving to connectivity test result
|
|
88
|
+
*/
|
|
89
|
+
testConnectivity(
|
|
90
|
+
ip: string,
|
|
91
|
+
privateKeyFile: string
|
|
92
|
+
): Promise<{
|
|
93
|
+
reachable: boolean;
|
|
94
|
+
authenticated: boolean;
|
|
95
|
+
latency: number;
|
|
96
|
+
error?: string;
|
|
97
|
+
}>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Prompt Service Interface Contract
|
|
102
|
+
* Defines the interface for interactive user prompts
|
|
103
|
+
*/
|
|
104
|
+
export interface PromptService {
|
|
105
|
+
/**
|
|
106
|
+
* Prompt user to select service when not provided
|
|
107
|
+
* @param availableServices List of available service names
|
|
108
|
+
* @returns Selected service name
|
|
109
|
+
*/
|
|
110
|
+
promptForService(availableServices: string[]): Promise<string>;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Prompt user to select environment when not provided
|
|
114
|
+
* @param availableEnvironments List of available environments
|
|
115
|
+
* @returns Selected environment
|
|
116
|
+
*/
|
|
117
|
+
promptForEnvironment(availableEnvironments: Environment[]): Promise<Environment>;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Prompt user for confirmation before connecting to production
|
|
121
|
+
* @param service Service name
|
|
122
|
+
* @returns True if user confirms
|
|
123
|
+
*/
|
|
124
|
+
confirmProductionAccess(service: string): Promise<boolean>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Prompt user for missing configuration values
|
|
128
|
+
* @param missingFields List of missing configuration fields
|
|
129
|
+
* @returns User-provided configuration values
|
|
130
|
+
*/
|
|
131
|
+
promptForConfiguration(missingFields: string[]): Promise<Record<string, string>>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Migration Service Interface Contract
|
|
136
|
+
* Defines the interface for configuration migration
|
|
137
|
+
*/
|
|
138
|
+
export interface MigrationService {
|
|
139
|
+
/**
|
|
140
|
+
* Detect if current configuration needs migration
|
|
141
|
+
* @returns Migration assessment
|
|
142
|
+
*/
|
|
143
|
+
assessMigration(): Promise<{
|
|
144
|
+
needsMigration: boolean;
|
|
145
|
+
currentVersion: string;
|
|
146
|
+
targetVersion: string;
|
|
147
|
+
changes: string[];
|
|
148
|
+
}>;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Execute configuration migration
|
|
152
|
+
* @param backupOriginal Whether to backup original config
|
|
153
|
+
* @returns Migration result
|
|
154
|
+
*/
|
|
155
|
+
executeMigration(backupOriginal?: boolean): Promise<{
|
|
156
|
+
success: boolean;
|
|
157
|
+
backupPath?: string;
|
|
158
|
+
errors: string[];
|
|
159
|
+
}>;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Rollback migration to previous configuration
|
|
163
|
+
* @param backupPath Path to backup configuration
|
|
164
|
+
* @returns Rollback result
|
|
165
|
+
*/
|
|
166
|
+
rollbackMigration(backupPath: string): Promise<{
|
|
167
|
+
success: boolean;
|
|
168
|
+
errors: string[];
|
|
169
|
+
}>;
|
|
170
|
+
}
|