@qqq123456789/codex-doctor 0.8.0 → 0.9.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/docs/13-codex-doctor.en.md +2 -0
- package/docs/13-codex-doctor.md +2 -0
- package/package.json +6 -1
- package/tool/cli.mjs +12 -2
- package/tool/sessions.mjs +27 -1
|
@@ -32,6 +32,8 @@ node codex-troubleshooting/tool/cli.mjs --help
|
|
|
32
32
|
| `archive delete <name\|--all>` | Delete archives (interactive confirm by default, `--yes` to skip) | medium (deletes, requires confirm) |
|
|
33
33
|
| `versions [-n 10]` | List the latest openai/codex releases (prerelease flagged) | read-only |
|
|
34
34
|
| `sessions [-n 10] [--dir keyword]` | Browse past sessions: time, workdir, source, first-prompt preview; `--dir` filters by directory — find "that conversation" | read-only |
|
|
35
|
+
| `sessions --search keyword [--deep]` | Search sessions by keyword (first 256KB of each file by default, `--deep` scans fully) | read-only |
|
|
36
|
+
| `sessions --show [--search keyword] [--pick N] [--full]` | Print a session's full transcript (latest by default; messages truncated to 400 chars unless `--full`) | read-only |
|
|
35
37
|
| `update` | Check the latest npm version and how to update | read-only |
|
|
36
38
|
|
|
37
39
|
## Design principles
|
package/docs/13-codex-doctor.md
CHANGED
|
@@ -32,6 +32,8 @@ node codex-troubleshooting/tool/cli.mjs --help
|
|
|
32
32
|
| `archive delete <名称\|--all>` | 删除归档(默认需交互确认,`--yes` 跳过) | 中(删除,需确认) |
|
|
33
33
|
| `versions [-n 10]` | 查看 openai/codex 最近 N 个版本(含预发布标记) | 只读 |
|
|
34
34
|
| `sessions [-n 10] [--dir 关键字]` | 浏览历史会话:时间、工作目录、来源、首条提问预览;`--dir` 按目录过滤,找回「上次那个对话」 | 只读 |
|
|
35
|
+
| `sessions --search 关键词 [--deep]` | 按关键词搜索会话(默认搜每个文件开头 256KB,`--deep` 全文扫描) | 只读 |
|
|
36
|
+
| `sessions --show [--search 关键词] [--pick N] [--full]` | 查看会话完整对话(默认最近一次;默认单条截断 400 字) | 只读 |
|
|
35
37
|
| `update` | 查询 npm 上工具的最新版本与更新方式 | 只读 |
|
|
36
38
|
|
|
37
39
|
## 设计原则
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qqq123456789/codex-doctor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"test": "bash scripts/test-codex-doctor.sh",
|
|
6
|
+
"check:links": "bash scripts/check-links.sh",
|
|
7
|
+
"check:consistency": "bash scripts/check-consistency.sh"
|
|
8
|
+
},
|
|
4
9
|
"description": "Codex CLI 维护与排障工具:环境自检、会话/日志归档、配置与凭据备份恢复、版本追踪(零依赖)",
|
|
5
10
|
"keywords": [
|
|
6
11
|
"codex",
|
package/tool/cli.mjs
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
import { collectChecks, summarize, renderHuman } from './checks.mjs';
|
|
4
4
|
import { cleanTarget } from './clean.mjs';
|
|
5
5
|
import { backupConfig, restoreBackup, resetAuth, listVersions, listArchives, deleteArchive, checkUpdate } from './ops.mjs';
|
|
6
|
-
import { listSessions, searchSessions, readTranscript } from './sessions.mjs';
|
|
6
|
+
import { listSessions, searchSessions, readTranscript, exportTranscriptMarkdown } from './sessions.mjs';
|
|
7
7
|
import { CODEX_DIR } from './util.mjs';
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
|
|
10
|
-
const VERSION = '0.
|
|
10
|
+
const VERSION = '0.9.0';
|
|
11
11
|
|
|
12
12
|
const HELP = `codex-doctor v${VERSION} — Codex CLI 维护与排障工具(零依赖)
|
|
13
13
|
|
|
@@ -151,6 +151,16 @@ async function main() {
|
|
|
151
151
|
const item = items[pick - 1];
|
|
152
152
|
console.log(`== 会话 ${item.date} @ ${item.dirName} ==`);
|
|
153
153
|
console.log(`文件: ${item.file}\n`);
|
|
154
|
+
if (flags.out) {
|
|
155
|
+
// 导出为 Markdown 文件
|
|
156
|
+
const r = exportTranscriptMarkdown(item.file, flags.out, { maxLen: flags.full ? Infinity : 400 });
|
|
157
|
+
if (!r) {
|
|
158
|
+
console.log('(该会话没有可导出的对话消息)');
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
console.log(`已导出 ${r.count} 条消息 → ${r.outFile}`);
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
154
164
|
const transcript = readTranscript(item.file, { maxLen: flags.full ? Infinity : 400 });
|
|
155
165
|
if (!transcript || transcript.length === 0) {
|
|
156
166
|
console.log('(该会话没有可展示的对话消息)');
|
package/tool/sessions.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// sessions:浏览 ~/.codex/sessions 下的历史会话(只读)
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { CODEX_DIR, exists, walkFiles } from './util.mjs';
|
|
4
|
+
import { CODEX_DIR, exists, walkFiles, ensureDir } from './util.mjs';
|
|
5
5
|
|
|
6
6
|
// 只读每个文件头部 64KB:meta 在第 1 行,真实提问通常也在最前面
|
|
7
7
|
function readHead(file, bytes = 65536) {
|
|
@@ -154,3 +154,29 @@ export function readTranscript(file, { maxLen = 400 } = {}) {
|
|
|
154
154
|
}
|
|
155
155
|
return out;
|
|
156
156
|
}
|
|
157
|
+
|
|
158
|
+
// 把会话导出为 Markdown 文件(找回的对话可存档分享)
|
|
159
|
+
export function exportTranscriptMarkdown(file, outFile, { maxLen = 400 } = {}) {
|
|
160
|
+
if (!exists(file)) return null;
|
|
161
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
162
|
+
const { meta } = extract(content);
|
|
163
|
+
const transcript = readTranscript(file, { maxLen });
|
|
164
|
+
if (!transcript || transcript.length === 0) return null;
|
|
165
|
+
|
|
166
|
+
const lines = ['# Codex 会话记录', ''];
|
|
167
|
+
lines.push(`- 时间:${meta?.date || '?'}`);
|
|
168
|
+
lines.push(`- 工作目录:${meta?.cwd || '?'}`);
|
|
169
|
+
lines.push(`- 来源:${meta?.originator || '?'}`);
|
|
170
|
+
lines.push(`- 导出自:${file}`);
|
|
171
|
+
lines.push('');
|
|
172
|
+
for (const msg of transcript) {
|
|
173
|
+
lines.push(`## ${msg.role === 'user' ? '用户' : 'Codex'}`);
|
|
174
|
+
lines.push('');
|
|
175
|
+
lines.push(msg.text);
|
|
176
|
+
lines.push('');
|
|
177
|
+
}
|
|
178
|
+
const dest = path.resolve(outFile);
|
|
179
|
+
ensureDir(path.dirname(dest));
|
|
180
|
+
fs.writeFileSync(dest, lines.join('\n'), 'utf8');
|
|
181
|
+
return { outFile: dest, count: transcript.length };
|
|
182
|
+
}
|