english-optimizer-cli 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/README.md +487 -0
- package/config.yaml +38 -0
- package/dist/ai/api-provider.js +138 -0
- package/dist/ai/ollama.js +103 -0
- package/dist/ai/provider.js +26 -0
- package/dist/config/config.js +223 -0
- package/dist/core/batch.js +45 -0
- package/dist/core/editor.js +175 -0
- package/dist/core/instant-editor.js +149 -0
- package/dist/core/optimizer.js +74 -0
- package/dist/history/logger.js +57 -0
- package/dist/index.js +279 -0
- package/dist/prompts/custom.js +75 -0
- package/dist/prompts/templates.js +59 -0
- package/dist/prompts/translation-prompt.js +57 -0
- package/dist/prompts/yaml-prompt.js +101 -0
- package/dist/types/index.js +11 -0
- package/dist/utils/display.js +80 -0
- package/docker-compose.yml +22 -0
- package/package.json +54 -0
- package/prompt.yaml +48 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PROMPT_TEMPLATES = void 0;
|
|
4
|
+
exports.getPromptTemplate = getPromptTemplate;
|
|
5
|
+
exports.getAllModes = getAllModes;
|
|
6
|
+
exports.getModeInfo = getModeInfo;
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
exports.PROMPT_TEMPLATES = {
|
|
9
|
+
[types_1.OptimizationMode.PROFESSIONAL]: {
|
|
10
|
+
name: 'Professional',
|
|
11
|
+
description: 'Make the text sound more professional and formal',
|
|
12
|
+
template: (text) => `Please rewrite the following text to make it sound more professional and formal, while maintaining the original meaning. Use appropriate business language and tone.
|
|
13
|
+
|
|
14
|
+
Original text:
|
|
15
|
+
"${text}"
|
|
16
|
+
|
|
17
|
+
Rewritten text:`,
|
|
18
|
+
},
|
|
19
|
+
[types_1.OptimizationMode.CONCISE]: {
|
|
20
|
+
name: 'Concise',
|
|
21
|
+
description: 'Make the text more concise while keeping the meaning',
|
|
22
|
+
template: (text) => `Please rewrite the following text to be more concise and to the point, while preserving all the key information and meaning.
|
|
23
|
+
|
|
24
|
+
Original text:
|
|
25
|
+
"${text}"
|
|
26
|
+
|
|
27
|
+
Rewritten text:`,
|
|
28
|
+
},
|
|
29
|
+
[types_1.OptimizationMode.GRAMMAR]: {
|
|
30
|
+
name: 'Grammar',
|
|
31
|
+
description: 'Fix grammar and spelling errors only',
|
|
32
|
+
template: (text) => `Please fix any grammar, spelling, or punctuation errors in the following text. Do not change the style or meaning - only correct mistakes.
|
|
33
|
+
|
|
34
|
+
Original text:
|
|
35
|
+
"${text}"
|
|
36
|
+
|
|
37
|
+
Corrected text:`,
|
|
38
|
+
},
|
|
39
|
+
[types_1.OptimizationMode.SENIOR_DEVELOPER]: {
|
|
40
|
+
name: 'Senior Developer',
|
|
41
|
+
description: 'Rewrite as a senior software engineer would write it',
|
|
42
|
+
template: (text) => `Please rewrite the following text as a senior software engineer would write it in a professional context (e.g., code review, technical discussion, or documentation). Use clear, precise technical language and follow industry best practices for communication.
|
|
43
|
+
|
|
44
|
+
Original text:
|
|
45
|
+
"${text}"
|
|
46
|
+
|
|
47
|
+
Rewritten text:`,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
function getPromptTemplate(mode, text) {
|
|
51
|
+
return exports.PROMPT_TEMPLATES[mode].template(text);
|
|
52
|
+
}
|
|
53
|
+
function getAllModes() {
|
|
54
|
+
return Object.values(types_1.OptimizationMode);
|
|
55
|
+
}
|
|
56
|
+
function getModeInfo(mode) {
|
|
57
|
+
return exports.PROMPT_TEMPLATES[mode];
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TranslationPromptLoader = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const os_1 = require("os");
|
|
7
|
+
class TranslationPromptLoader {
|
|
8
|
+
constructor(promptPath) {
|
|
9
|
+
this.promptPath = promptPath || (0, path_1.join)((0, os_1.homedir)(), '.english-optimizer', 'translation-prompt.txt');
|
|
10
|
+
}
|
|
11
|
+
getPrompt() {
|
|
12
|
+
if ((0, fs_1.existsSync)(this.promptPath)) {
|
|
13
|
+
try {
|
|
14
|
+
return (0, fs_1.readFileSync)(this.promptPath, 'utf-8');
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// Fall back to default
|
|
18
|
+
return this.getDefaultPrompt();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Create default prompt file
|
|
22
|
+
this.createDefaultPromptFile();
|
|
23
|
+
return this.getDefaultPrompt();
|
|
24
|
+
}
|
|
25
|
+
getDefaultPrompt() {
|
|
26
|
+
return `You are a professional translator and editor for software developers.
|
|
27
|
+
|
|
28
|
+
Your task is to:
|
|
29
|
+
1. Detect if the text is Chinese or English
|
|
30
|
+
2. If Chinese: Translate to natural, professional English
|
|
31
|
+
3. If English: Optimize the English to be more natural and professional
|
|
32
|
+
4. Use terminology and phrasing common in software development
|
|
33
|
+
5. Make it sound like a native English-speaking developer
|
|
34
|
+
6. Preserve technical terms, API names, and code snippets
|
|
35
|
+
7. For multi-line text, maintain the paragraph structure
|
|
36
|
+
|
|
37
|
+
Text to process:
|
|
38
|
+
"{text}"
|
|
39
|
+
|
|
40
|
+
Provide ONLY the translated/optimized English text, nothing else.
|
|
41
|
+
Do not include any explanations, notes, or additional text.`;
|
|
42
|
+
}
|
|
43
|
+
createDefaultPromptFile() {
|
|
44
|
+
const { dirname } = require('path');
|
|
45
|
+
const { mkdirSync, writeFileSync } = require('fs');
|
|
46
|
+
const dir = require('path').dirname(this.promptPath);
|
|
47
|
+
if (!require('fs').existsSync(dir)) {
|
|
48
|
+
mkdirSync(dir, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
writeFileSync(this.promptPath, this.getDefaultPrompt(), 'utf-8');
|
|
51
|
+
}
|
|
52
|
+
getPromptPath() {
|
|
53
|
+
return this.promptPath;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.TranslationPromptLoader = TranslationPromptLoader;
|
|
57
|
+
//# sourceMappingURL=translation-prompt.js.map
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.YAMLPromptLoader = void 0;
|
|
37
|
+
const fs_1 = require("fs");
|
|
38
|
+
const path_1 = require("path");
|
|
39
|
+
const yaml = __importStar(require("js-yaml"));
|
|
40
|
+
class YAMLPromptLoader {
|
|
41
|
+
constructor(promptPath) {
|
|
42
|
+
this.promptPath = promptPath || (0, path_1.join)(process.cwd(), 'prompt.yaml');
|
|
43
|
+
}
|
|
44
|
+
loadConfig() {
|
|
45
|
+
if (!(0, fs_1.existsSync)(this.promptPath)) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const content = (0, fs_1.readFileSync)(this.promptPath, 'utf-8');
|
|
50
|
+
const config = yaml.load(content);
|
|
51
|
+
return config;
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.warn('Failed to load YAML prompt config:', error);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
buildPrompt(text) {
|
|
59
|
+
const config = this.loadConfig();
|
|
60
|
+
if (!config) {
|
|
61
|
+
throw new Error('YAML prompt config not found');
|
|
62
|
+
}
|
|
63
|
+
const sections = [];
|
|
64
|
+
sections.push(`## Role\n${config.role.name}\n${config.role.description}`);
|
|
65
|
+
if (config.goals && config.goals.length > 0) {
|
|
66
|
+
sections.push(`## Goals\n${config.goals.map((g) => `- ${g}`).join('\n')}`);
|
|
67
|
+
}
|
|
68
|
+
if (config.user_profile) {
|
|
69
|
+
sections.push(`## User Profile\n` +
|
|
70
|
+
`Background: ${config.user_profile.background}\n` +
|
|
71
|
+
`Native Language: ${config.user_profile.native_language}\n` +
|
|
72
|
+
`Learning Goal: ${config.user_profile.learning_goal}`);
|
|
73
|
+
}
|
|
74
|
+
if (config.instructions && config.instructions.length > 0) {
|
|
75
|
+
sections.push(`## Instructions\n${config.instructions.map((i) => `- ${i}`).join('\n')}`);
|
|
76
|
+
}
|
|
77
|
+
if (config.output_format) {
|
|
78
|
+
sections.push(`## Output Format\n` +
|
|
79
|
+
`Style: ${config.output_format.style}\n` +
|
|
80
|
+
`Structure: ${config.output_format.structure.join(', ')}`);
|
|
81
|
+
}
|
|
82
|
+
if (config.examples && config.examples.length > 0) {
|
|
83
|
+
sections.push(`## Examples\n` +
|
|
84
|
+
config.examples.map((ex) => `Input: "${ex.input}"\nOutput: ${ex.output}`).join('\n\n'));
|
|
85
|
+
}
|
|
86
|
+
if (config.constraints && config.constraints.length > 0) {
|
|
87
|
+
sections.push(`## Constraints\n${config.constraints.map((c) => `- ${c}`).join('\n')}`);
|
|
88
|
+
}
|
|
89
|
+
sections.push(`\n## Input to Optimize\n"${text}"`);
|
|
90
|
+
sections.push('\n## Output\nProvide ONLY the optimized English text, nothing else.');
|
|
91
|
+
return sections.join('\n\n');
|
|
92
|
+
}
|
|
93
|
+
hasYAMLPrompt() {
|
|
94
|
+
return this.loadConfig() !== null;
|
|
95
|
+
}
|
|
96
|
+
getPromptPath() {
|
|
97
|
+
return this.promptPath;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.YAMLPromptLoader = YAMLPromptLoader;
|
|
101
|
+
//# sourceMappingURL=yaml-prompt.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OptimizationMode = void 0;
|
|
4
|
+
var OptimizationMode;
|
|
5
|
+
(function (OptimizationMode) {
|
|
6
|
+
OptimizationMode["PROFESSIONAL"] = "professional";
|
|
7
|
+
OptimizationMode["CONCISE"] = "concise";
|
|
8
|
+
OptimizationMode["GRAMMAR"] = "grammar";
|
|
9
|
+
OptimizationMode["SENIOR_DEVELOPER"] = "senior_developer";
|
|
10
|
+
})(OptimizationMode || (exports.OptimizationMode = OptimizationMode = {}));
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.displayWelcome = displayWelcome;
|
|
7
|
+
exports.displayModeInfo = displayModeInfo;
|
|
8
|
+
exports.displayOptimization = displayOptimization;
|
|
9
|
+
exports.displayDiff = displayDiff;
|
|
10
|
+
exports.displayError = displayError;
|
|
11
|
+
exports.displaySuccess = displaySuccess;
|
|
12
|
+
exports.displayInfo = displayInfo;
|
|
13
|
+
exports.displayWarning = displayWarning;
|
|
14
|
+
exports.displayHelp = displayHelp;
|
|
15
|
+
exports.displayHistoryEntry = displayHistoryEntry;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const diff_1 = require("diff");
|
|
18
|
+
const templates_1 = require("../prompts/templates");
|
|
19
|
+
function displayWelcome() {
|
|
20
|
+
console.log(chalk_1.default.cyan.bold('\n🚀 English Optimizer CLI\n'));
|
|
21
|
+
}
|
|
22
|
+
function displayModeInfo(mode) {
|
|
23
|
+
const modeInfo = (0, templates_1.getModeInfo)(mode);
|
|
24
|
+
console.log(chalk_1.default.yellow(`\n[${modeInfo.name} Mode]`));
|
|
25
|
+
console.log(chalk_1.default.gray(modeInfo.description));
|
|
26
|
+
}
|
|
27
|
+
function displayOptimization(original, optimized) {
|
|
28
|
+
console.log(chalk_1.default.gray('\n' + '─'.repeat(60)));
|
|
29
|
+
// Show original
|
|
30
|
+
console.log(chalk_1.default.red('\n❌ Original:'));
|
|
31
|
+
console.log(chalk_1.default.gray(original));
|
|
32
|
+
// Show optimized
|
|
33
|
+
console.log(chalk_1.default.green('\n✅ Optimized:'));
|
|
34
|
+
console.log(chalk_1.default.white(optimized));
|
|
35
|
+
console.log(chalk_1.default.gray('\n' + '─'.repeat(60)));
|
|
36
|
+
}
|
|
37
|
+
function displayDiff(original, optimized) {
|
|
38
|
+
const differences = (0, diff_1.diffLines)(original, optimized);
|
|
39
|
+
differences.forEach((part) => {
|
|
40
|
+
const color = part.added ? chalk_1.default.green : part.removed ? chalk_1.default.red : chalk_1.default.gray;
|
|
41
|
+
const prefix = part.added ? '+ ' : part.removed ? '- ' : ' ';
|
|
42
|
+
process.stdout.write(color(prefix + part.value));
|
|
43
|
+
});
|
|
44
|
+
console.log();
|
|
45
|
+
}
|
|
46
|
+
function displayError(error) {
|
|
47
|
+
const message = typeof error === 'string' ? error : error.message;
|
|
48
|
+
console.log(chalk_1.default.red('\n❌ Error:'), chalk_1.default.white(message));
|
|
49
|
+
}
|
|
50
|
+
function displaySuccess(message) {
|
|
51
|
+
console.log(chalk_1.default.green('\n✅'), chalk_1.default.white(message));
|
|
52
|
+
}
|
|
53
|
+
function displayInfo(message) {
|
|
54
|
+
console.log(chalk_1.default.cyan('\nℹ️'), chalk_1.default.white(message));
|
|
55
|
+
}
|
|
56
|
+
function displayWarning(message) {
|
|
57
|
+
console.log(chalk_1.default.yellow('\n⚠️'), chalk_1.default.white(message));
|
|
58
|
+
}
|
|
59
|
+
function displayHelp() {
|
|
60
|
+
console.log(chalk_1.default.cyan('\n📖 Hotkeys:\n'));
|
|
61
|
+
console.log(chalk_1.default.gray(' Ctrl+P - Professional tone'));
|
|
62
|
+
console.log(chalk_1.default.gray(' Ctrl+C - Concise version'));
|
|
63
|
+
console.log(chalk_1.default.gray(' Ctrl+G - Grammar fix'));
|
|
64
|
+
console.log(chalk_1.default.gray(' Ctrl+D - Senior developer style'));
|
|
65
|
+
console.log(chalk_1.default.gray(' Ctrl+R - Reset to original'));
|
|
66
|
+
console.log(chalk_1.default.gray(' Ctrl+H - View history'));
|
|
67
|
+
console.log(chalk_1.default.gray(' Ctrl+Q - Quit\n'));
|
|
68
|
+
}
|
|
69
|
+
function displayHistoryEntry(entry) {
|
|
70
|
+
console.log(chalk_1.default.gray('\n' + '─'.repeat(60)));
|
|
71
|
+
console.log(chalk_1.default.cyan(`\nID: ${entry.id}`));
|
|
72
|
+
console.log(chalk_1.default.gray(`Time: ${entry.timestamp.toLocaleString()}`));
|
|
73
|
+
console.log(chalk_1.default.yellow(`Mode: ${(0, templates_1.getModeInfo)(entry.mode).name}`));
|
|
74
|
+
console.log(chalk_1.default.red('\n❌ Original:'));
|
|
75
|
+
console.log(chalk_1.default.gray(entry.original));
|
|
76
|
+
console.log(chalk_1.default.green('\n✅ Optimized:'));
|
|
77
|
+
console.log(chalk_1.default.white(entry.optimized));
|
|
78
|
+
console.log(chalk_1.default.gray('\n' + '─'.repeat(60)));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=display.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
ollama:
|
|
5
|
+
image: ollama/ollama:latest
|
|
6
|
+
container_name: english-optimizer-ollama
|
|
7
|
+
ports:
|
|
8
|
+
- "11434:11434"
|
|
9
|
+
volumes:
|
|
10
|
+
- ollama_data:/root/.ollama
|
|
11
|
+
environment:
|
|
12
|
+
- OLLAMA_HOST=0.0.0.0
|
|
13
|
+
restart: unless-stopped
|
|
14
|
+
healthcheck:
|
|
15
|
+
test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
|
|
16
|
+
interval: 30s
|
|
17
|
+
timeout: 10s
|
|
18
|
+
retries: 5
|
|
19
|
+
|
|
20
|
+
volumes:
|
|
21
|
+
ollama_data:
|
|
22
|
+
driver: local
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "english-optimizer-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool to help non-native English speakers improve their writing using AI",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"fuck-abc": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"start": "node dist/index.js",
|
|
12
|
+
"dev": "ts-node src/index.ts",
|
|
13
|
+
"watch": "tsc --watch",
|
|
14
|
+
"install-config": "node scripts/install-config.js"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"cli",
|
|
18
|
+
"english",
|
|
19
|
+
"learning",
|
|
20
|
+
"ai",
|
|
21
|
+
"optimizer"
|
|
22
|
+
],
|
|
23
|
+
"author": "",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"axios": "^1.6.0",
|
|
27
|
+
"chalk": "^5.3.0",
|
|
28
|
+
"cli-cursor": "^4.0.0",
|
|
29
|
+
"clipboardy": "^3.0.0",
|
|
30
|
+
"commander": "^12.0.0",
|
|
31
|
+
"diff": "^5.1.0",
|
|
32
|
+
"dotenv": "^16.3.0",
|
|
33
|
+
"inquirer": "^9.2.0",
|
|
34
|
+
"js-yaml": "^4.1.0",
|
|
35
|
+
"keypress": "^0.2.1",
|
|
36
|
+
"ora": "^8.0.0",
|
|
37
|
+
"uuid": "^9.0.0",
|
|
38
|
+
"zod": "^3.22.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/diff": "^5.0.0",
|
|
42
|
+
"@types/inquirer": "^9.0.0",
|
|
43
|
+
"@types/js-yaml": "^4.0.9",
|
|
44
|
+
"@types/node": "^20.10.0",
|
|
45
|
+
"@types/uuid": "^9.0.0",
|
|
46
|
+
"eslint": "^8.55.0",
|
|
47
|
+
"prettier": "^3.1.0",
|
|
48
|
+
"ts-node": "^10.9.0",
|
|
49
|
+
"typescript": "^5.3.0"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18.0.0"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/prompt.yaml
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
role:
|
|
2
|
+
name: Native English Full-Stack Engineer Coach
|
|
3
|
+
description: >
|
|
4
|
+
You are a senior full-stack software engineer who is a native English speaker.
|
|
5
|
+
You have strong experience in frontend, backend, system design, and real-world
|
|
6
|
+
engineering collaboration. You communicate naturally, clearly, and professionally,
|
|
7
|
+
just like in daily standups, design reviews, and team discussions.
|
|
8
|
+
|
|
9
|
+
goals:
|
|
10
|
+
- Help the user learn natural, spoken English used by software engineers
|
|
11
|
+
- Translate the user's input into idiomatic, native-level English
|
|
12
|
+
- Optimize wording to sound natural, confident, and professional
|
|
13
|
+
- Match the tone of real workplace communication (meetings, chats, reviews)
|
|
14
|
+
|
|
15
|
+
user_profile:
|
|
16
|
+
background: Software Engineer
|
|
17
|
+
native_language: Chinese
|
|
18
|
+
learning_goal: Improve practical English for daily engineering communication
|
|
19
|
+
|
|
20
|
+
instructions:
|
|
21
|
+
- Always assume the user wants to improve their English, not just get a literal translation
|
|
22
|
+
- Rewrite the input in a way a native English-speaking engineer would naturally say it
|
|
23
|
+
- Prefer conversational, work-friendly language over academic or overly formal English
|
|
24
|
+
- Keep sentences concise and clear, like real team communication
|
|
25
|
+
- Avoid textbook-style translations or unnatural phrasing
|
|
26
|
+
- If multiple natural expressions are possible, choose the most commonly used one
|
|
27
|
+
|
|
28
|
+
output_format:
|
|
29
|
+
style: >
|
|
30
|
+
Natural, spoken English commonly used in engineering teams.
|
|
31
|
+
Sounds like real conversations in meetings, Slack, or code reviews.
|
|
32
|
+
structure:
|
|
33
|
+
- Optimized English version
|
|
34
|
+
- (Optional) A brief explanation of why this phrasing is more natural
|
|
35
|
+
|
|
36
|
+
examples:
|
|
37
|
+
- input: '这个需求我已经完成了,但是还需要再测试一下'
|
|
38
|
+
output: >
|
|
39
|
+
I've finished this feature, but I still need to do some more testing.
|
|
40
|
+
|
|
41
|
+
- input: '这个问题我稍后再跟进'
|
|
42
|
+
output: >
|
|
43
|
+
I'll follow up on this later.
|
|
44
|
+
|
|
45
|
+
constraints:
|
|
46
|
+
- Do not over-explain unless the user explicitly asks
|
|
47
|
+
- Do not change the original meaning
|
|
48
|
+
- Do not use overly complex vocabulary unless it fits real engineering conversations
|