Skip to content

#163 AI activity: external CPU probe for real busy/idle (Claude/Codex/Kimi/VS Code)#165

Merged
AlvinShenSSW merged 3 commits into
mainfrom
afk/163-ai-activity-real-capture
Jul 2, 2026
Merged

#163 AI activity: external CPU probe for real busy/idle (Claude/Codex/Kimi/VS Code)#165
AlvinShenSSW merged 3 commits into
mainfrom
afk/163-ai-activity-real-capture

Conversation

@AlvinShenSSW

Copy link
Copy Markdown
Owner

Closes #163.

What

Turn "present (unreported)" into real busy/idle for Claude Code / Codex / Kimi / VS Code via an external CPU probe — pure psutil observation, no writes to / no impact on the tools.

Precedence: hook state (P2) > observed (new) > presence (P1). When a tool is present but has no fresh hook state, infer busy/idle from the CPU of its process subtree. This is what finally gives Kimi (no hooks) and any un-wired Claude/Codex/VS Code real busy/idle.

How

  • process_util.scan_activity(): one sweep, sum cpu_times over each tool's process subtree (union of matching roots, each pid once — no double-count; bounded + cycle-safe). cpu_percents(): two snapshots → per-tool %, first sample 0, exited-child delta clamped to 0.
  • dev_activity: observe (default on) + busy_cpu_percent (8) config; instance keeps the prev CPU snapshot; observation fills state only when there's no hook state. aggregate() counts AI tools only for busy/waiting/idle, so an observed-busy VS Code (context editor) shows in its row but never drives the machine "AI busy" headline.
  • UI: observed rows show ~<cpu>% to distinguish probe-derived from hook-reported.
  • Design doc (docs/specs/2026-07-03-163-...) + guide updated.

Known limitation (documented)

A pure model-wait (network, low local CPU) can briefly read idle — the hook signal covers that phase, so the two are complementary.

Gates

  • pytest 514 pass; ruff/mypy clean; UI tsc/eslint/vitest clean.
  • Codex 外门 clean; Kimi 终审 APPROVE.

🤖 Generated with Claude Code

AlvinShenSSW and others added 3 commits July 3, 2026 01:10
…s + tests)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…/Kimi/VS Code)

When a tool is present but has no fresh hook state, infer busy/idle from the CPU of its
process subtree — a pure external psutil read (no writes to / no impact on the tool).
This turns "present (unreported)" into real busy/idle for Kimi (no hooks) and any
un-wired Claude/Codex/VS Code. Precedence: hook state > observed > presence.

- process_util.scan_activity(): one sweep, sum cpu_times over each matched tool's
  process subtree (bounded, cycle-safe). cpu_percents(): two snapshots → per-tool %,
  first sample 0, exited-child delta clamped to 0.
- dev_activity: observe (default on) + busy_cpu_percent (8) config; instance holds the
  prev CPU snapshot; observation fills state only when there's no hook state. aggregate
  now counts AI tools only for busy/waiting/idle so an observed-busy VS Code (context)
  shows in its row but never drives the machine "AI busy" headline.
- UI: observed rows show ~<cpu>% to distinguish probe-derived from hook-reported.
- Design doc + guide updated. Tests: scan_activity subtree/degrade, cpu delta,
  observe busy/idle, hook-wins, vscode-not-headline, observe-off.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A matching descendant (claude → claude-worker) was double-counted through both its own
root and its parent's subtree, inflating cpu_seconds. Collect all matching roots per
tool, then sum over the UNION of their subtrees with a shared seen-set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AlvinShenSSW AlvinShenSSW merged commit a23f0bc into main Jul 2, 2026
7 checks passed
@AlvinShenSSW AlvinShenSSW deleted the afk/163-ai-activity-real-capture branch July 2, 2026 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AI 活动监控:外部探针「真实捕捉」Claude/Codex/Kimi/VS Code 忙碌·空闲(不止在场未上报)

1 participant