去 https://github.com/MoonshotAI/kimi-cli 仓库看下
有没人提出关于 /usage 命令中,重置日期直接显示日期时间点,而不是提示 resets in 4d 这种模糊
kimi-cli /usage 重置
The user wants to check the GitHub repo MoonshotAI/kimi-cli for issues/PRs about the /usage command showing reset date as a specific datetime instead of "resets in 4d". Use github MCP search_issues. Need to load the tool first via select_tools.
تحديد الأدوات
استخدام مكوّن إضافي
搜索Issue #2150与重置关键词相关
Issue #2150 was referenced as "Quota / usage display UX" — worth reading it. Also search for "resets in" specifically.
查到了几个相关 issue,其中 #2486 提到了 #2150(Quota / usage display UX),我再读一下 #2150 的正文,并再搜一轮更精确的关键词。
استخدام مكوّن إضافي
显示绝对重置时间而非相对
None of these directly ask to show absolute reset datetime instead of "resets in 4d". Issue #2150 is closest on /usage UX, but doesn't mention reset time format. Maybe search "reset date" or "重置" in Chinese, or "reset time". Let me do one more search round.
这几个都不完全对口,我再用「重置时间/绝对时间」方向搜一轮。
استخدام مكوّن إضافي
未发现请求显示绝对重置时间的 issue
No issue directly requests showing absolute reset datetime instead of "resets in 4d". The closest ones:
- #2486 — Feature Request: expose reset times through ACP (wants resetAt absolute timestamps, but about ACP API, not /usage display text).
- #2150 — /usage UX confusion issue (percentages, absolute numbers), doesn't mention reset time format.
- #2149 — statusline feature with resets_at timestamps.
Answer: nobody has filed exactly this request. Offer to draft/file one.
看完了
MoonshotAI/kimi-cli 的 issues 和 PR,结论:目前没有人明确提出这个需求——即把 /usage 里的 "resets in 4d" 改成直接显示具体日期时间点。搜了三轮关键词(
/usage reset、"resets in"、reset time usage、中文「重置 时间」),最接近的只有这几个,都不完全对口:- #2486(open) — 希望 ACP 接口暴露
resetAt绝对时间戳(如"2026-08-01T00:00:00Z"),但这是给 IDE 集成的 API 层面需求,不是改/usage的终端显示文案。 - #2150(open) —
/usage显示体验大吐槽:两套配额体系混淆、百分比语义相反(% left vs % used)、只有百分比没有绝对数值。提了显示 token 绝对数,但没提重置时间格式。 - #2149(open,4 个 👍) — 想要 Claude Code 式 statusline,里面提到
resets_at时间戳,同样是数据暴露需求,不是显示格式。
也就是说「
resets in 4d 太模糊、直接给我具体时间」这个点是个空白。这其实是个很小且合理的改动(把相对时间旁边补一个绝对时间,比如 resets in 4d (Aug 1, 09:00)),你想的话我可以帮你:- 起草一份英文 feature request issue 文案,你直接贴到 GitHub 上发;
- 或者如果你的 GitHub 账号已授权,我可以直接帮你提交这个 issue。
要哪个?
如果要改代码的话,变动大吗
اكتمل التفكير
The user asks: if we were to change the code, how big is the change? Need to look at the kimi-cli repo source code for /usage command implementation. Search code in the repo for "resets in" or the usage command rendering.
I have github search_code available? tools_added includes mcp__plugin-github_github__search_code. Need to load it via select_tools first.
我去看下仓库里
/usage 的实现代码,评估改动量。 تحديد الأدوات
استخدام مكوّن إضافي
将重置时间显示改为绝对时间格式
The change is tiny. The whole "resets in Xd" string is produced in two spots:
_reset_hint (for seconds-based fields) and _format_reset_time (for ISO timestamps). The backend already returns absolute timestamps (reset_at etc. — the code even parses ISO). So changing display to show absolute datetime is a ~5-10 line change in one file, plus updating tests in tests/ui/test_usage.py.Also note the funny docstring "This file is pure vibe-coded."
Estimate the change:
Python
نسخ
return f"resets {dt.astimezone().strftime('%b %d %H:%M')} (in {format_duration(...)})"Timezone consideration — local tz vs UTC.
Answer concisely: very small, single file, ~10 lines, plus tests. Offer to write the patch/PR.
变动很小,基本是一个文件、十来行的事。
现状:
resets in 4d 这种文案全部来自一个文件 src/kimi_cli/ui/shell/usage.py(文件开头还自嘲写着 "This file is pure vibe-coded")。关键在这两个函数:_reset_hint()(L195 附近):从 API 响应里取reset_at/resetAt等字段_format_reset_time()(L215 附近):把 ISO 时间戳(如2026-08-01T05:24:18Z)解析成datetime,然后只算了个相对时长,拼出resets in {format_duration(...)}
也就是说,后端本来就返回了绝对时间戳,代码里也已经解析成了
datetime 对象,只是在最后一步把它转成了相对时间扔掉了。要显示绝对时间,就是在 return 那里把 dt 格式化出来。最小改动示例(
_format_reset_time 里改一行):Python
نسخ
# 现在
return f"resets in {format_duration(int(delta.total_seconds()))}"
# 改成(本地时区 + 保留相对时间,两者兼顾)
local_dt = dt.astimezone()
return f"resets {local_dt.strftime('%m-%d %H:%M')} (in {format_duration(int(delta.total_seconds()))})"涉及范围:
جدول
نسخ
| 项 | 内容 |
|---|---|
| 主代码 | usage.py 1~2 行核心改动 |
| 测试 | tests/ui/test_usage.py 里有一个 test_format_row_renders_reset_hint 断言 "resets in 1h",需要同步更新 |
| 唯一要想清楚的点 | 时区——用 astimezone() 显示用户本地时间即可;以及 _reset_hint 里 reset_in/ttl 秒数路径没有绝对时间可显示,只能保持相对时间或算出 now + seconds |
结论:这是个 good-first-issue 级别的 PR,半个小时能搞定(含跑测试)。要我直接把完整 patch 写出来吗?写好你可以自己提 PR,或者我可以 fork 后帮你提交。
好,帮我fork后提交
Fork仓库修改文件并提交PR
The user wants me to fork the repo, make the change, and submit a PR. I need to:
- Fork the repo (mcp__plugin-github_github__fork_repository)
- Get the current file contents SHA
- Modify usage.py and test file
- Create branch, commit files, create PR
Let me load fork_repository, create_branch, create_or_update_file, create_pull_request tools. Also get_me to know the username.
Let me first check get_me and fork.
تحديد الأدوات
استخدام مكوّن إضافي
Fork 创建分支并检查测试文件
Fork in progress for versun/kimi-cli. Wait a moment then create branch. Also I need to check the test file content to update the test. Let me fetch tests/ui/test_usage.py and also check whether format_duration exists and check the reset_hint seconds path. Also check whether _format_reset_time is used in tests directly.
First create branch in the fork from main. Need fork to finish — give it a few seconds. Meanwhile fetch test file contents.
استخدام مكوّن إضافي
format_reset_time测试
The test
test_format_row_renders_reset_hint just passes a reset_hint string directly to UsageRow — it doesn't test _format_reset_time, so it stays valid as long as I keep the "resets" wording... Actually I'm changing the hint text format. The test uses reset_hint="resets in 1h" and asserts that string appears. That test only checks rendering, not generation, so it will still pass. But I could add a test for _format_reset_time.Design decision for the new format: show absolute local time plus relative. Something like
resets Aug 01 09:00 (in 4d). Keep wording "resets in Xd" replaced or appended?User's ask: 直接显示日期时间点,而不是提示 resets in 4d 这种模糊. So replace relative with absolute datetime. But keeping the relative as supplementary is nice. I'll make it:
resets 2026-08-01 09:00 (in 4d). Hmm, panel width might be limited but it's in parentheses already.For the seconds-based path (
reset_in, ttl, etc.), compute now + seconds to get absolute time too.Implementation in _reset_hint:
Python
نسخ
def _reset_hint(data):
for key in ("reset_at", ...):
if val := data.get(key):
return _format_reset_time(str(val))
for key in ("reset_in", ...):
seconds = _to_int(data.get(key))
if seconds:
from datetime import UTC, datetime, timedelta
dt = datetime.now(UTC) + timedelta(seconds=seconds)
return _format_reset_dt(dt, int(seconds))
return NoneAnd _format_reset_time parses then calls shared helper:
Python
نسخ
def _format_reset_hint(dt: datetime, seconds: int) -> str:
if seconds <= 0:
return "reset"
local = dt.astimezone()
return f"resets {local.strftime('%Y-%m-%d %H:%M')} (in {format_duration(seconds)})"Format choice:
%m-%d %H:%M or include year? Within same year maybe omit year to keep short: Aug 01 09:00? Chinese users read 08-01 09:00 fine. I'll use %m-%d %H:%M for brevity, but if the reset is > 300 days away include year? Overkill. Keep %Y-%m-%d %H:%M unambiguous? Panel has room; I'll go %m-%d %H:%M since quotas reset within days. Actually for the monthly/total window reset could be weeks away, still same year presumably. Keep it simple: %m-%d %H:%M.Also update test: test_format_row_renders_reset_hint passes a raw string, still passes. Add a new test for _format_reset_time showing absolute date. Add to test file import _format_reset_time.
Now create branch in fork versun/kimi-cli. Fork may still be processing; try create_branch from main.
Fork 进行中。现在创建分支并提交修改。
استخدام مكوّن إضافي
按顺序提交文件并推送 PR 到远程分支
Branch created. Now prepare the modified usage.py. I have full content. Make edits:
- Move
from datetime import UTC, datetime, timedelta— currently imported inside function; keep style but add timedelta.
Replace
_reset_hint seconds path and _format_reset_time.Original:
Python
نسخ
def _reset_hint(data: Mapping[str, Any]) -> str | None:
for key in ("reset_at", "resetAt", "reset_time", "resetTime"):
if val := data.get(key):
return _format_reset_time(str(val))
for key in ("reset_in", "resetIn", "ttl", "window"):
seconds = _to_int(data.get(key))
if seconds:
return f"resets in {format_duration(seconds)}"
return None
def _format_reset_time(val: str) -> str:
"""Format ISO timestamp to a readable duration."""
from datetime import UTC, datetime
try:
# Parse ISO format like "2025-12-23T05:24:18.443553353Z"
# Truncate nanoseconds to microseconds for Python compatibility
if "." in val and val.endswith("Z"):
base, frac = val[:-1].split(".")
frac = frac[:6] # Keep only microseconds
val = f"{base}.{frac}Z"
dt = datetime.fromisoformat(val.replace("Z", "+00:00"))
now = datetime.now(UTC)
delta = dt - now
if delta.total_seconds() <= 0:
return "reset"
return f"resets in {format_duration(int(delta.total_seconds()))}"
except (ValueError, TypeError):
return f"resets at {val}"New:
Python
نسخ
def _reset_hint(data: Mapping[str, Any]) -> str | None:
for key in ("reset_at", "resetAt", "reset_time", "resetTime"):
if val := data.get(key):
return _format_reset_time(str(val))
for key in ("reset_in", "resetIn", "ttl", "window"):
seconds = _to_int(data.get(key))
if seconds:
from datetime import UTC, datetime, timedelta
reset_at = datetime.now(UTC) + timedelta(seconds=seconds)
return _format_reset_hint(reset_at, seconds)
return None
def _format_reset_time(val: str) -> str:
"""Format ISO timestamp to an absolute local time with a relative duration."""
from datetime import UTC, datetime
try:
# Parse ISO format like "2025-12-23T05:24:18.443553353Z"
# Truncate nanoseconds to microseconds for Python compatibility
if "." in val and val.endswith("Z"):
base, frac = val[:-1].split(".")
frac = frac[:6] # Keep only microseconds
val = f"{base}.{frac}Z"
dt = datetime.fromisoformat(val.replace("Z", "+00:00"))
delta = dt - datetime.now(UTC)
return _format_reset_hint(dt, int(delta.total_seconds()))
except (ValueError, TypeError):
return f"resets at {val}"
def _format_reset_hint(dt: datetime, seconds: int) -> str:
"""Show the absolute local reset time, with the relative duration as a hint."""
if seconds <= 0:
return "reset"
local_dt = dt.astimezone()
return f"resets {local_dt.strftime('%m-%d %H:%M')} (in {format_duration(seconds)})"Test file update: existing test passes raw string so fine. Add a test for _format_reset_time:
Python
نسخ
def test_format_reset_time_shows_absolute_local_time() -> None:
from datetime import UTC, datetime, timedelta
future = datetime.now(UTC) + timedelta(hours=1)
hint = _format_reset_time(future.strftime("%Y-%m-%dT%H:%M:%SZ"))
assert "resets " in hint
assert future.astimezone().strftime("%m-%d %H:%M") in hint
assert "(in " in hintAnd import _format_reset_time in the import line.
Edge: "resets at {val}" fallback unchanged.
Now push files. Need SHAs of files in the fork at the new branch — same SHAs as upstream since fork copied: usage.py SHA 0c46a31dccb99a9bb9007786de5556127620ed31, test 489b2c2cf8acac602880184e3cec1bf4b0b7ac6e.
Commit usage.py first, then test file, then PR.
分支已建好,现在提交修改后的
usage.py。 استخدام مكوّن إضافي
更新测试文件导入并新增功能测试
Now update the test file: add import of _format_reset_time and a new test. Existing test stays valid.
主代码已提交,接着补充测试。
استخدام مكوّن إضافي
提交 PR 显示绝对重置时间
Both files committed. One concern:
test_format_reset_time_shows_absolute_local_time — strftime %Y-%m-%dT%H:%M:%SZ drops sub-second and the timedelta; future.astimezone().strftime("%m-%d %H:%M") should match since _format_reset_time parses and converts to local. Good.Now create PR to MoonshotAI/kimi-cli main. Check whether repo prefers a linked issue — I could reference the discussion. PR body in English. head: "versun:usage-show-absolute-reset-time".
两个文件都已提交,现在向上游仓库发起 PR。
استخدام مكوّن إضافي
اكتمل التفكير
PR created: https://github.com/MoonshotAI/kimi-cli/pull/2567. Report concisely.
流程摘要:
- Fork 到了你的账号
versun/kimi-cli,新建分支usage-show-absolute-reset-time - 改了
src/kimi_cli/ui/shell/usage.py:新增_format_reset_hint()辅助函数,把重置时间显示为本地时区的绝对时间 + 相对时长辅助提示;秒数路径(reset_in/ttl)也用now + seconds算出绝对时间,两条路径格式统一 - 更新
tests/ui/test_usage.py:同步了渲染测试,并新增 3 个_format_reset_time的用例(绝对时间输出、过期时间戳返回reset、非法输入回退) - PR 描述里附了 Before/After 对比,并关联了 #2150
效果变化:
plain
نسخ
之前:Weekly limit ██████░░ 50% left (resets in 4d)
之后:Weekly limit ██████░░ 50% left (resets 08-01 09:00 (in 4d))一个提醒:我只在分支上提交了代码,没有在本地跑过测试套件(环境里没装 kimi-cli 的依赖)。逻辑很直白,但建议等 CI 跑完确认绿灯;如果 CI 挂了告诉我报错,我来修。另外显示格式我选了紧凑的
MM-DD HH:MM,如果维护者想换格式(比如带年份或 12 小时制),PR 里我也留了话,随时可改。