@haposoft/cafekit 0.9.3 → 0.9.4
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/bin/install.js +133 -0
- package/package.json +1 -1
- package/src/claude/CLAUDE.md +15 -0
package/bin/install.js
CHANGED
|
@@ -1018,6 +1018,135 @@ function configureGeminiKey(apiKey, platforms = ['claude']) {
|
|
|
1018
1018
|
return success;
|
|
1019
1019
|
}
|
|
1020
1020
|
|
|
1021
|
+
async function promptAddressingConfig() {
|
|
1022
|
+
const rl = readline.createInterface({
|
|
1023
|
+
input: process.stdin,
|
|
1024
|
+
output: process.stdout
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
console.log('\n🎯 Xưng hô (Addressing Configuration)');
|
|
1028
|
+
console.log(' CafeKit có thể cấu hình cách AI xưng hô khi giao tiếp tiếng Việt');
|
|
1029
|
+
console.log(' • Mục đích: Phát hiện context overflow (khi AI đột nhiên đổi cách xưng hô)');
|
|
1030
|
+
console.log(' • Để trống = dùng mặc định (em/anh)');
|
|
1031
|
+
console.log();
|
|
1032
|
+
|
|
1033
|
+
return new Promise((resolve) => {
|
|
1034
|
+
rl.question('AI xưng gì? (ví dụ: em, mình, tôi, con - Enter=em): ', (firstAnswer) => {
|
|
1035
|
+
let firstPerson = firstAnswer.trim();
|
|
1036
|
+
|
|
1037
|
+
// Validate: không rỗng và chỉ chứa chữ cái tiếng Việt
|
|
1038
|
+
if (!firstPerson || firstPerson.length === 0 || /[^a-zA-ZÀ-ỹ\s]/.test(firstPerson)) {
|
|
1039
|
+
if (firstAnswer.trim().length > 0) {
|
|
1040
|
+
console.log(' ⚠ Xưng hô không hợp lệ, dùng mặc định: em');
|
|
1041
|
+
}
|
|
1042
|
+
firstPerson = 'em';
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
rl.question('AI hô user là gì? (ví dụ: anh, bạn, thầy - Enter=anh): ', (secondAnswer) => {
|
|
1046
|
+
let secondPerson = secondAnswer.trim();
|
|
1047
|
+
|
|
1048
|
+
// Validate: không rỗng và chỉ chứa chữ cái tiếng Việt
|
|
1049
|
+
if (!secondPerson || secondPerson.length === 0 || /[^a-zA-ZÀ-ỹ\s]/.test(secondPerson)) {
|
|
1050
|
+
if (secondAnswer.trim().length > 0) {
|
|
1051
|
+
console.log(' ⚠ Xưng hô không hợp lệ, dùng mặc định: anh');
|
|
1052
|
+
}
|
|
1053
|
+
secondPerson = 'anh';
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
rl.question('Bật xưng hô? (Y/n, Enter=Y): ', (enableAnswer) => {
|
|
1057
|
+
rl.close();
|
|
1058
|
+
const enabled = enableAnswer.trim().toLowerCase();
|
|
1059
|
+
const isEnabled = enabled === '' || enabled === 'y' || enabled === 'yes';
|
|
1060
|
+
|
|
1061
|
+
resolve({
|
|
1062
|
+
enabled: isEnabled,
|
|
1063
|
+
firstPerson: firstPerson,
|
|
1064
|
+
secondPerson: secondPerson
|
|
1065
|
+
});
|
|
1066
|
+
});
|
|
1067
|
+
});
|
|
1068
|
+
});
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
function configureAddressing(addressingConfig, platforms = ['claude']) {
|
|
1073
|
+
const targets = platforms
|
|
1074
|
+
.filter(key => PLATFORMS[key])
|
|
1075
|
+
.map(key => PLATFORMS[key].folder);
|
|
1076
|
+
|
|
1077
|
+
if (targets.length === 0) {
|
|
1078
|
+
targets.push('.claude');
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// Helper function to safely capitalize
|
|
1082
|
+
function capitalize(str) {
|
|
1083
|
+
if (!str || str.length === 0) return str;
|
|
1084
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
const firstPersonCap = capitalize(addressingConfig.firstPerson);
|
|
1088
|
+
const secondPersonCap = capitalize(addressingConfig.secondPerson);
|
|
1089
|
+
|
|
1090
|
+
for (const folder of targets) {
|
|
1091
|
+
try {
|
|
1092
|
+
const targetDir = path.join(process.cwd(), folder);
|
|
1093
|
+
const claudeMdFile = path.join(targetDir, 'CLAUDE.md');
|
|
1094
|
+
|
|
1095
|
+
if (!fs.existsSync(claudeMdFile)) {
|
|
1096
|
+
console.log(` ⚠ CLAUDE.md not found in ${folder}/`);
|
|
1097
|
+
continue;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
let content = fs.readFileSync(claudeMdFile, 'utf8');
|
|
1101
|
+
|
|
1102
|
+
// Build the addressing section
|
|
1103
|
+
const addressingSection = `## Xưng hô (Addressing - Context Overflow Indicator)
|
|
1104
|
+
|
|
1105
|
+
Khi giao tiếp bằng tiếng Việt:
|
|
1106
|
+
- Luôn xưng "${addressingConfig.firstPerson}" (bản thân AI)
|
|
1107
|
+
- Luôn hô "${addressingConfig.secondPerson}" (người dùng)
|
|
1108
|
+
- Duy trì xưng hô nhất quán trong toàn bộ conversation
|
|
1109
|
+
|
|
1110
|
+
**Ví dụ:** "${firstPersonCap} đã đọc file này và ${addressingConfig.firstPerson} thấy ${addressingConfig.secondPerson} cần sửa dòng 45."
|
|
1111
|
+
|
|
1112
|
+
**⚠️ Context Overflow Detection:**
|
|
1113
|
+
Nếu bạn (AI) đột nhiên không thể nhớ hoặc tuân thủ quy tắc xưng hô này, đây là dấu hiệu context window đã bị compact/truncate. Hãy thông báo ngay:
|
|
1114
|
+
"${firstPersonCap} nhận thấy context có thể đã bị compact. ${secondPersonCap} có thể cần /clear để reset session."
|
|
1115
|
+
|
|
1116
|
+
**Lưu ý:** Xưng hô được thiết lập khi cài đặt CafeKit và lưu trực tiếp trong file CLAUDE.md này. Để thay đổi, chỉnh sửa section này hoặc chạy lại installer.`;
|
|
1117
|
+
|
|
1118
|
+
// Match from ## Xưng hô to the end of section (including any trailing newlines)
|
|
1119
|
+
// This regex matches the entire section including the final newline after "Lưu ý:" paragraph
|
|
1120
|
+
const regex = /## Xưng hô \(Addressing - Context Overflow Indicator\)[\s\S]*?(?=\n##|\n*$)/;
|
|
1121
|
+
|
|
1122
|
+
if (regex.test(content)) {
|
|
1123
|
+
// Replace existing section
|
|
1124
|
+
content = content.replace(regex, addressingSection);
|
|
1125
|
+
} else {
|
|
1126
|
+
// Append at the end
|
|
1127
|
+
if (!content.endsWith('\n')) {
|
|
1128
|
+
content += '\n';
|
|
1129
|
+
}
|
|
1130
|
+
content += '\n' + addressingSection + '\n';
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
fs.writeFileSync(claudeMdFile, content, 'utf8');
|
|
1134
|
+
|
|
1135
|
+
if (addressingConfig.enabled) {
|
|
1136
|
+
console.log(` ✓ Xưng hô configured in CLAUDE.md: ${addressingConfig.firstPerson}/${addressingConfig.secondPerson}`);
|
|
1137
|
+
} else {
|
|
1138
|
+
console.log(` ✓ Xưng hô disabled in CLAUDE.md`);
|
|
1139
|
+
}
|
|
1140
|
+
} catch (error) {
|
|
1141
|
+
console.error(` ✗ Failed to configure addressing in ${folder}/CLAUDE.md`);
|
|
1142
|
+
console.error(` Error: ${error.message}`);
|
|
1143
|
+
if (process.env.DEBUG) {
|
|
1144
|
+
console.error(error.stack);
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1021
1150
|
async function setupGeminiCLI(platforms) {
|
|
1022
1151
|
const hasGemini = checkGeminiCLI();
|
|
1023
1152
|
|
|
@@ -1147,6 +1276,10 @@ async function main() {
|
|
|
1147
1276
|
await setupOpenCodeModel(platforms, results);
|
|
1148
1277
|
await setupGeminiCLI(platforms);
|
|
1149
1278
|
|
|
1279
|
+
// Setup addressing configuration
|
|
1280
|
+
const addressingConfig = await promptAddressingConfig();
|
|
1281
|
+
configureAddressing(addressingConfig, platforms);
|
|
1282
|
+
|
|
1150
1283
|
// Summary
|
|
1151
1284
|
console.log('╔════════════════════════════════════════════════════════╗');
|
|
1152
1285
|
console.log('║ Installation Complete! ║');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haposoft/cafekit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "Claude Code-first spec-driven workflow for AI coding assistants. Bundles CafeKit hapo: skills, runtime hooks, agents, and installer scaffolding.",
|
|
5
5
|
"author": "Haposoft <nghialt@haposoft.com>",
|
|
6
6
|
"license": "MIT",
|
package/src/claude/CLAUDE.md
CHANGED
|
@@ -126,3 +126,18 @@ When generating specs or structured project output, use the user's preferred lan
|
|
|
126
126
|
- State tradeoffs and assumptions when they affect decisions.
|
|
127
127
|
- Do not provide unsolicited code explanations unless asked.
|
|
128
128
|
- Do not apologize; correct the issue and continue.
|
|
129
|
+
|
|
130
|
+
## Xưng hô (Addressing - Context Overflow Indicator)
|
|
131
|
+
|
|
132
|
+
Khi giao tiếp bằng tiếng Việt:
|
|
133
|
+
- Luôn xưng "em" (bản thân AI)
|
|
134
|
+
- Luôn hô "anh" (người dùng)
|
|
135
|
+
- Duy trì xưng hô nhất quán trong toàn bộ conversation
|
|
136
|
+
|
|
137
|
+
**Ví dụ:** "Em đã đọc file này và em thấy anh cần sửa dòng 45."
|
|
138
|
+
|
|
139
|
+
**⚠️ Context Overflow Detection:**
|
|
140
|
+
Nếu bạn (AI) đột nhiên không thể nhớ hoặc tuân thủ quy tắc xưng hô này, đây là dấu hiệu context window đã bị compact/truncate. Hãy thông báo ngay:
|
|
141
|
+
"Em nhận thấy context có thể đã bị compact. Anh có thể cần /clear để reset session."
|
|
142
|
+
|
|
143
|
+
**Lưu ý:** Xưng hô được thiết lập khi cài đặt CafeKit và lưu trực tiếp trong file CLAUDE.md này. Để thay đổi, chỉnh sửa section này hoặc chạy lại installer.
|