MoonshotAI / MoonshotAI/kimi-cli

将 SessionStart Hook 的 stdout 展示给用户 || Display the stdout of SessionStart Hook to the user

Open
#2,347 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Python
Stars
11.4k
Forks
1.3k
Avg merge
9h 47m
Merged PRs (30d)
2

Description

What feature would you like to see?

功能请求:将 SessionStart Hook 的 stdout 展示给用户

问题

目前 SessionStart hook 执行后会捕获 stdout/stderr,但不会展示给用户。这限制了 hook 在以下场景中的实用性:

  • 进入工作空间时显示欢迎语 / 项目仪表盘
  • 在用户开始输入前展示项目健康度/状态
  • 运行快速诊断并立即展示结果

使用场景

我的项目使用 AGENTS.md 文件,其中有一条规则:

"AI 进入时,必须先读取 WELCOME.md,向 owner 展示问候语和菜单,再等待输入。"

我尝试配置了一个 SessionStart hook:

[[hooks]]
event = "SessionStart"
command = "cat WELCOME.md"
timeout = 5

Hook 执行成功了,但输出被 hook 引擎吞掉了,用户永远看不到。我只能退而求其次用 shell 别名来包装,但这终究是个 workaround。

建议方案

提供一种机制,将 hook 的 stdout 输出到用户界面。有几种可能的实现方式:

方案 A:直接展示所有 SessionStart hook 的 stdout(最简单)

SessionStart hook 执行时,在进入交互式提示符之前,直接把它的 stdout 打印到终端。

方案 B:在 hook 配置中增加 display_output 开关(推荐)
[[hooks]]
event = "SessionStart"
command = "cat WELCOME.md"
timeout = 5
display_output = true   # 新增:将 stdout 透传给用户界面

向后兼容,默认关闭,显式开启。

方案 C:支持结构化输出并声明展示意图

允许 hook 返回一个 JSON 响应,指明哪些内容需要展示:

{
  "action": "allow",
  "display": {
    "text": "...hook 的 stdout 内容...",
    "format": "markdown"
  }
}

为什么不用 Shell 别名?

Shell 包装确实能用,但:

  1. 不便携 — 团队成员需要各自配置别名
  2. 丢失上下文 — Hook 在 kimi 的工作目录上下文中执行(通过 stdin 接收 cwdsession_id 等 JSON),而 shell 别名做不到
  3. 无法利用 matcher — Shell 别名每次必跑;kimi hook 支持正则 matcher,可按条件触发
  4. 像是 workaround — 既然 hooks 系统已经如此强大,理应原生支持这种场景

环境

  • kimi-cli 版本: 1.30.0
  • 操作系统: Ubuntu 22.04
  • 配置文件: ~/.kimi/config.toml

相关代码

Hook 的执行逻辑在 kimi_cli/hooks/runner.py 中,stdout 当前仅用于:

  • 退出码 2 → block 操作
  • 退出码 0 + JSON → 结构化权限决策

stdout 字符串在 HookResult.stdout 中已有,但从未被转发到用户界面层。


你们是否接受针对方案 B(opt-in display_output 开关)的 PR? 如果方案被认可,我很乐意实现并提交。

Additional information

No response


What feature would you like to see?

Feature request: Display the stdout of SessionStart Hook to the user

Question

Currently, SessionStart hook will capture stdout/stderr after execution, but will not be displayed to the user. This limits the hook's usefulness in the following scenarios:

  • Show welcome/project dashboard when entering workspace
  • Show project health/status before user starts typing
  • Run quick diagnostics and display results instantly

Usage scenarios

My project uses the AGENTS.md file, which has a rule:

"When the AI enters, it must first read WELCOME.md, show the greeting and menu to the owner, and then wait for input."

I tried configuring a SessionStart hook:

[[hooks]]
event = "SessionStart"
command = "cat WELCOME.md"
timeout=5

Hook execution is successful, but the output is swallowed by the hook engine and the user will never see it. I had to fall back on wrapping it with a shell alias, but this is a workaround after all.

Suggestions

Provides a mechanism to output the hook's stdout to the user interface. There are several possible implementations:

Solution A: Directly display the stdout of all SessionStart hooks (the simplest)

When the SessionStart hook executes, print its stdout directly to the terminal before entering the interactive prompt.

Solution B: Add the display_output switch in the hook configuration (recommended)
[[hooks]]
event = "SessionStart"
command = "cat WELCOME.md"
timeout=5
display_output = true # New: Transparently pass stdout to the user interface

Backward compatibility, off by default, enabled explicitly.

Solution C: Support structured output and declare display intent

Allow the hook to return a JSON response indicating what content needs to be displayed:

{
  "action": "allow",
  "display": {
    "text": "...hook's stdout content...",
    "format": "markdown"
  }
}

Why not use Shell aliases?

Shell wrapping does work, but:

  1. Not portable — Team members need to configure their own aliases
  2. Lost context — Hook is executed in the context of kimi's working directory (receiving cwd, session_id, etc. JSON via stdin), while shell aliases cannot do this
  3. Unable to use matcher - Shell alias must be run every time; kimi hook supports regular matcher and can be triggered according to conditions
  4. Like a workaround — Since the hooks system is so powerful, it should natively support this scenario

Environment

  • kimi-cli version: 1.30.0
  • Operating system: Ubuntu 22.04
  • Configuration file: ~/.kimi/config.toml

Related code

The execution logic of Hook is in kimi_cli/hooks/runner.py. stdout is currently only used for:

  • Exit code 2 → block operation
  • Exit code 0 + JSON → Structured permission decisions

The stdout string is present in HookResult.stdout but is never forwarded to the user interface layer.


**Do you accept PRs for option B (opt-in display_output switch)? ** If the proposal is approved, I will be happy to implement it and submit it.

Additional information

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with kimi_cli/hooks/runner.py and trace HookResult.stdout toward the user interface layer. Clarify whether the accepted design is opt-in display_output or another approach, then define how SessionStart output should appear while preserving existing exit-code and JSON decision handling. Done means the chosen behavior is covered and existing hook semantics remain intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.