clawkit-doctor 2.2.0 → 3.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 +6 -0
- package/bin/index.js +139 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,6 +10,12 @@ Maintainer: **@branzoom**
|
|
|
10
10
|
npx clawkit-doctor@latest
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
When run without arguments in an interactive terminal, Doctor now shows:
|
|
14
|
+
|
|
15
|
+
1. language selector (`en/zh/ja`)
|
|
16
|
+
2. welcome menu (quick diagnose / paste error / tutorial / exit)
|
|
17
|
+
3. guided recovery loop (`y/n` solved confirmation)
|
|
18
|
+
|
|
13
19
|
### Common modes
|
|
14
20
|
|
|
15
21
|
```bash
|
package/bin/index.js
CHANGED
|
@@ -29,7 +29,7 @@ function getArgValue(flag) {
|
|
|
29
29
|
|
|
30
30
|
const requestedLang = (getArgValue('--lang') || process.env.LANG || 'en').toLowerCase();
|
|
31
31
|
const LANG = requestedLang.startsWith('zh') ? 'zh' : requestedLang.startsWith('ja') ? 'ja' : 'en';
|
|
32
|
-
const
|
|
32
|
+
const CLI_PASTE_TEXT = (getArgValue('--paste') || '').trim();
|
|
33
33
|
const FULL_MODE = args.has('--full');
|
|
34
34
|
const FIX_MODE = args.has('--fix');
|
|
35
35
|
const JSON_MODE = args.has('--json');
|
|
@@ -51,6 +51,25 @@ const report = {
|
|
|
51
51
|
const i18n = {
|
|
52
52
|
en: {
|
|
53
53
|
subtitle: 'Reliable OpenClaw diagnostics and repair',
|
|
54
|
+
welcomeTitle: 'Welcome to ClawKit Doctor',
|
|
55
|
+
welcomeHint: 'Choose what you want to do first.',
|
|
56
|
+
langChoose: 'Select language: 1=English 2=简体中文 3=日本語',
|
|
57
|
+
slashHint: 'Type "/" to show command palette.',
|
|
58
|
+
slashTitle: 'Command palette',
|
|
59
|
+
slashItemMenu: '/menu open main menu',
|
|
60
|
+
slashItemLang: '/lang switch language',
|
|
61
|
+
slashItemDiag: '/diag run quick diagnose',
|
|
62
|
+
slashItemPaste: '/paste paste an error now',
|
|
63
|
+
slashItemGuide: '/guide show tutorial',
|
|
64
|
+
slashItemExit: '/exit quit',
|
|
65
|
+
menu: 'Menu: 1=Quick diagnose 2=Paste an error 3=How to use 4=Exit',
|
|
66
|
+
menuPaste: 'Paste your error log/message:',
|
|
67
|
+
menuGuideTitle: 'Quick tutorial',
|
|
68
|
+
menuGuide1: '1) Paste the exact error text.',
|
|
69
|
+
menuGuide2: '2) Run suggested fix steps.',
|
|
70
|
+
menuGuide3: '3) Confirm solved with y/n.',
|
|
71
|
+
menuGuide4: '4) If still failing, use fallback + docs link.',
|
|
72
|
+
menuGuideNext: 'Next: 1=Run diagnose 2=Paste error 4=Exit',
|
|
54
73
|
docs: 'Troubleshooting index',
|
|
55
74
|
prevent: 'Prevention guide',
|
|
56
75
|
explore: 'Explore more skills & workflows',
|
|
@@ -76,6 +95,25 @@ const i18n = {
|
|
|
76
95
|
},
|
|
77
96
|
zh: {
|
|
78
97
|
subtitle: 'OpenClaw 环境诊断与安全修复',
|
|
98
|
+
welcomeTitle: '欢迎使用 ClawKit Doctor',
|
|
99
|
+
welcomeHint: '请先选择你要做的事。',
|
|
100
|
+
langChoose: '选择语言:1=English 2=简体中文 3=日本語',
|
|
101
|
+
slashHint: '输入“/”可查看命令面板。',
|
|
102
|
+
slashTitle: '命令面板',
|
|
103
|
+
slashItemMenu: '/menu 回到主菜单',
|
|
104
|
+
slashItemLang: '/lang 切换语言',
|
|
105
|
+
slashItemDiag: '/diag 运行快速检测',
|
|
106
|
+
slashItemPaste: '/paste 直接粘贴错误',
|
|
107
|
+
slashItemGuide: '/guide 查看教程',
|
|
108
|
+
slashItemExit: '/exit 退出',
|
|
109
|
+
menu: '菜单:1=快速检测 2=粘贴错误 3=使用教程 4=退出',
|
|
110
|
+
menuPaste: '请粘贴你的错误日志/报错信息:',
|
|
111
|
+
menuGuideTitle: '快速使用教程',
|
|
112
|
+
menuGuide1: '1) 粘贴完整错误文本。',
|
|
113
|
+
menuGuide2: '2) 按步骤执行修复命令。',
|
|
114
|
+
menuGuide3: '3) 用 y/n 确认是否已解决。',
|
|
115
|
+
menuGuide4: '4) 未解决就走补救步骤和详情文档。',
|
|
116
|
+
menuGuideNext: '下一步:1=直接检测 2=粘贴错误 4=退出',
|
|
79
117
|
docs: '故障排查总览',
|
|
80
118
|
prevent: '预防建议',
|
|
81
119
|
explore: '继续探索 skills 与 workflows',
|
|
@@ -101,6 +139,25 @@ const i18n = {
|
|
|
101
139
|
},
|
|
102
140
|
ja: {
|
|
103
141
|
subtitle: 'OpenClaw 環境の診断と安全な修復',
|
|
142
|
+
welcomeTitle: 'ClawKit Doctor へようこそ',
|
|
143
|
+
welcomeHint: '最初に実行内容を選んでください。',
|
|
144
|
+
langChoose: '言語を選択: 1=English 2=简体中文 3=日本語',
|
|
145
|
+
slashHint: '「/」でコマンドパレットを表示。',
|
|
146
|
+
slashTitle: 'コマンドパレット',
|
|
147
|
+
slashItemMenu: '/menu メインメニューへ',
|
|
148
|
+
slashItemLang: '/lang 言語を切替',
|
|
149
|
+
slashItemDiag: '/diag クイック診断',
|
|
150
|
+
slashItemPaste: '/paste エラー貼り付け',
|
|
151
|
+
slashItemGuide: '/guide チュートリアル',
|
|
152
|
+
slashItemExit: '/exit 終了',
|
|
153
|
+
menu: 'メニュー: 1=クイック診断 2=エラー貼り付け 3=使い方 4=終了',
|
|
154
|
+
menuPaste: 'エラーログ/メッセージを貼り付けてください:',
|
|
155
|
+
menuGuideTitle: 'クイックチュートリアル',
|
|
156
|
+
menuGuide1: '1) 正確なエラー文を貼り付ける。',
|
|
157
|
+
menuGuide2: '2) 提案された修正手順を実行する。',
|
|
158
|
+
menuGuide3: '3) y/n で解決確認する。',
|
|
159
|
+
menuGuide4: '4) 未解決ならフォールバックと詳細ドキュメントへ。',
|
|
160
|
+
menuGuideNext: '次へ: 1=診断実行 2=エラー貼り付け 4=終了',
|
|
104
161
|
docs: 'トラブルシューティング一覧',
|
|
105
162
|
prevent: '再発防止ガイド',
|
|
106
163
|
explore: 'skills と workflows を探す',
|
|
@@ -125,7 +182,10 @@ const i18n = {
|
|
|
125
182
|
nonInteractive: '対話端末ではないため追跡質問をスキップしました。',
|
|
126
183
|
},
|
|
127
184
|
};
|
|
128
|
-
|
|
185
|
+
let currentLang = LANG;
|
|
186
|
+
let t = i18n[currentLang];
|
|
187
|
+
let languagePrompted = false;
|
|
188
|
+
const LANGUAGE_PROMPT = 'Select language / 选择语言 / 言語を選択: 1=English 2=简体中文 3=日本語';
|
|
129
189
|
|
|
130
190
|
if (args.has('--help') || args.has('-h')) {
|
|
131
191
|
console.log(`
|
|
@@ -577,6 +637,75 @@ async function askBinary(question, fallback = 'n') {
|
|
|
577
637
|
return fallback;
|
|
578
638
|
}
|
|
579
639
|
|
|
640
|
+
async function chooseLanguageIfNeeded() {
|
|
641
|
+
if (!INTERACTIVE_MODE || languagePrompted) return;
|
|
642
|
+
const choice = await ask(LANGUAGE_PROMPT);
|
|
643
|
+
if (choice === '1') currentLang = 'en';
|
|
644
|
+
if (choice === '2') currentLang = 'zh';
|
|
645
|
+
if (choice === '3') currentLang = 'ja';
|
|
646
|
+
t = i18n[currentLang];
|
|
647
|
+
languagePrompted = true;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function printSlashPalette() {
|
|
651
|
+
console.log(chalk.bold(`\n${t.slashTitle}`));
|
|
652
|
+
console.log(chalk.gray(` ${t.slashItemMenu}`));
|
|
653
|
+
console.log(chalk.gray(` ${t.slashItemLang}`));
|
|
654
|
+
console.log(chalk.gray(` ${t.slashItemDiag}`));
|
|
655
|
+
console.log(chalk.gray(` ${t.slashItemPaste}`));
|
|
656
|
+
console.log(chalk.gray(` ${t.slashItemGuide}`));
|
|
657
|
+
console.log(chalk.gray(` ${t.slashItemExit}\n`));
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
async function runWelcomeMenu(initialPasteText) {
|
|
661
|
+
const showMenu = INTERACTIVE_MODE && !JSON_MODE && !FIX_MODE && !FULL_MODE && !initialPasteText;
|
|
662
|
+
if (!showMenu) return { pasteText: initialPasteText, exit: false };
|
|
663
|
+
|
|
664
|
+
await chooseLanguageIfNeeded();
|
|
665
|
+
console.log(chalk.cyan.bold(`\n${t.welcomeTitle}`));
|
|
666
|
+
console.log(chalk.gray(`${t.welcomeHint}`));
|
|
667
|
+
console.log(chalk.gray(`${t.slashHint}\n`));
|
|
668
|
+
|
|
669
|
+
while (true) {
|
|
670
|
+
let choice = (await ask(t.menu)).trim().toLowerCase();
|
|
671
|
+
if (choice === '/') {
|
|
672
|
+
printSlashPalette();
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
if (choice === '/lang') {
|
|
676
|
+
languagePrompted = false;
|
|
677
|
+
await chooseLanguageIfNeeded();
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
if (choice === '4' || choice === 'q' || choice === 'exit' || choice === '/exit') {
|
|
681
|
+
return { pasteText: '', exit: true };
|
|
682
|
+
}
|
|
683
|
+
if (choice === '1' || choice === '/diag' || choice === '/menu') {
|
|
684
|
+
return { pasteText: '', exit: false };
|
|
685
|
+
}
|
|
686
|
+
if (choice === '2' || choice === '/paste') {
|
|
687
|
+
const pasted = await ask(t.menuPaste);
|
|
688
|
+
return { pasteText: pasted.trim(), exit: false };
|
|
689
|
+
}
|
|
690
|
+
if (choice === '3' || choice === '/guide') {
|
|
691
|
+
console.log(chalk.bold(`\n${t.menuGuideTitle}`));
|
|
692
|
+
console.log(chalk.gray(` ${t.menuGuide1}`));
|
|
693
|
+
console.log(chalk.gray(` ${t.menuGuide2}`));
|
|
694
|
+
console.log(chalk.gray(` ${t.menuGuide3}`));
|
|
695
|
+
console.log(chalk.gray(` ${t.menuGuide4}\n`));
|
|
696
|
+
choice = (await ask(t.menuGuideNext)).trim().toLowerCase();
|
|
697
|
+
if (choice === '2' || choice === '/paste') {
|
|
698
|
+
const pasted = await ask(t.menuPaste);
|
|
699
|
+
return { pasteText: pasted.trim(), exit: false };
|
|
700
|
+
}
|
|
701
|
+
if (choice === '4' || choice === '/exit' || choice === 'q' || choice === 'exit') {
|
|
702
|
+
return { pasteText: '', exit: true };
|
|
703
|
+
}
|
|
704
|
+
return { pasteText: '', exit: false };
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
|
|
580
709
|
function getFallbackSteps(reason, match) {
|
|
581
710
|
if (reason === '1') {
|
|
582
711
|
return [
|
|
@@ -607,16 +736,21 @@ function getFallbackSteps(reason, match) {
|
|
|
607
736
|
}
|
|
608
737
|
|
|
609
738
|
async function run() {
|
|
739
|
+
await chooseLanguageIfNeeded();
|
|
610
740
|
if (!QUIET_MODE) {
|
|
611
741
|
console.log(chalk.cyan.bold('\nClawKit Doctor'));
|
|
612
742
|
console.log(chalk.gray(`v${pkg.version} • @branzoom (GitHub)`));
|
|
613
743
|
console.log(chalk.gray(`${t.subtitle}\n`));
|
|
614
744
|
}
|
|
615
745
|
|
|
746
|
+
const menuState = await runWelcomeMenu(CLI_PASTE_TEXT);
|
|
747
|
+
if (menuState.exit) return;
|
|
748
|
+
const pasteText = menuState.pasteText;
|
|
749
|
+
|
|
616
750
|
let shouldContinueToFull = FULL_MODE;
|
|
617
|
-
if (
|
|
618
|
-
const match = diagnosePastedError(
|
|
619
|
-
report.pastedError = { input:
|
|
751
|
+
if (pasteText) {
|
|
752
|
+
const match = diagnosePastedError(pasteText);
|
|
753
|
+
report.pastedError = { input: pasteText.slice(0, 600), matchId: match?.id || null };
|
|
620
754
|
|
|
621
755
|
if (JSON_MODE) {
|
|
622
756
|
report.pasteDiagnosis = match
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawkit-doctor",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Guided OpenClaw diagnostic CLI with issue-first recovery flow",
|
|
5
5
|
"main": "bin/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "https://github.com/branzoom/getclawkit-web.git",
|
|
23
|
+
"url": "git+https://github.com/branzoom/getclawkit-web.git",
|
|
24
24
|
"directory": "packages/clawkit-doctor"
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://getclawkit.com/tools/doctor",
|