Skip to content

fix(core): ObjectLogger honors NO_COLOR and TTY detection before emitting ANSI colors - #3111

Merged
os-zhuang merged 1 commit into
mainfrom
claude/hungry-burnell-c6b5e1
Jul 17, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/hungry-burnell-c6b5e1

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

问题

os serve / os dev 接线的内核插件日志(ctx.logger = ObjectLogger,默认 pretty 格式)无条件给 level 标签着色,NO_COLOR=1 也不例外:

\x1b[31m2026-07-17T07:27:53.363Z ERROR\x1b[0m OIDC provider is configured but…

违反 no-color.org 约定,且 CI 里纯文本 grep 会漏掉 ERROR 行 —— scripts/publish-smoke.sh(#3100)就是因此被迫先 strip ANSI 再扫日志(该兜底保留不动)。

修复(只动 packages/core/src/logger.ts,不动调用点/spec)

按 no-color.org 约定,pretty 格式仅在满足以下两个条件时才输出 ANSI 色码:

  1. 目标流是交互式 TTY(error/fatal 走 stderr、其余走 stdout,按各自流判定);
  2. NO_COLOR 未设置或为空 —— 任何非空值(含 0)都禁用颜色。

交互式终端默认行为不变(仍着色);管道/重定向/CI 输出恒为纯文本;可选的 file 目的地现在恒写纯文本(此前会把色码写进日志文件)。json/text 格式不受影响。浏览器 bundle(@objectstack/client 复用此模块)无 process/TTY → 纯文本,保持 browser-safe。

验证

  • 单测:logger.test.ts 新增 "Color emission (no-color.org)" 7 例(TTY 默认着色 / 非空 NO_COLOR 禁用含 '0' / 空串视为未设 / 非 TTY 无色 / stderr 门控 error 色 / 文件目的地无 ANSI)。@objectstack/core 356 测试全绿。
  • dist 探针:ESM + CJS 产物三态实测(管道→无色、NO_COLOR=1+TTY→无色、TTY→着色,红色 ERROR 头与原报告字节一致)。
  • showcase pnpm dev -- --fresh + NO_COLOR=1 冒烟,启动日志零 ESC。

相关

🤖 Generated with Claude Code

…ting ANSI colors

The kernel/plugin logger colorized pretty-format level tags unconditionally,
so NO_COLOR=1 runs and piped/CI output still carried ANSI escapes, breaking
plain-text log scanners (publish-smoke.sh had to strip ANSI before grepping).

Per no-color.org, color is now emitted only when the destination stream
(stdout, or stderr for error/fatal) is an interactive TTY and NO_COLOR is
unset or empty. Interactive terminals keep colorized output. The optional
file destination always receives plain text now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 17, 2026 10:03am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Jul 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core.

22 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/actions-as-tools.mdx (via @objectstack/core)
  • content/docs/ai/knowledge-rag.mdx (via @objectstack/core)
  • content/docs/ai/natural-language-queries.mdx (via @objectstack/core)
  • content/docs/automation/webhooks.mdx (via @objectstack/core)
  • content/docs/concepts/north-star.mdx (via packages/core)
  • content/docs/deployment/migration-from-objectql.mdx (via @objectstack/core)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/core)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/core)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/core)
  • content/docs/kernel/services.mdx (via @objectstack/core)
  • content/docs/permissions/authentication.mdx (via @objectstack/core)
  • content/docs/permissions/authorization.mdx (via packages/core)
  • content/docs/plugins/anatomy.mdx (via @objectstack/core)
  • content/docs/plugins/development.mdx (via @objectstack/core)
  • content/docs/plugins/index.mdx (via @objectstack/core)
  • content/docs/plugins/packages.mdx (via @objectstack/core)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/core)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/core)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/core)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/core)
  • content/docs/releases/implementation-status.mdx (via @objectstack/core)
  • content/docs/releases/v15.mdx (via @objectstack/core)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang merged commit 021ba4c into main Jul 17, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/hungry-burnell-c6b5e1 branch July 17, 2026 10:11
os-tesla pushed a commit that referenced this pull request Oct 25, 2026
…ectui#12724) (#13508)

<!-- claude-projects-attribution: {"github_login":"os-zhuang"} -->
_Requested by **Sam** · [project
thread](https://claude.ai/code/project/chan_01GsBogozeZG5sdpAARrN7HP?thread=cmsg_01GsBogozeZG5sdpAARrN7HPPdgXnLU8SfcQmac3AzRouL)_

Clause-②: yes (the exported `ProposedPlanCard` gains the optional
`posture`)

Closes #12724

## What

objectstack-ai/cloud declared `planCard.posture` on
`propose_blueprint`'s envelope (cloud#2924 ruling A, cloud PR #3111,
`f0ecef3a`): `{ mode: 'publish' | 'draft', liveRecords, line }`.
objectui drew nothing from it yet. The plan card now draws
`posture.line` (for example 「首次搭建直接上线;之后的修改先存草稿,由你发布」) as the **last
item of the assumptions list**, where the AiBuild artboard draws it. A
plan card without the key draws as before. If a plan has a posture but
no assumptions, the section still renders and holds the posture line
alone.

- `mapMessages.ts`: `ProposedPlanCard.posture?: { mode; line }`, lifted
in `liftPlanCard` only when `mode` is a declared value and `line` is
non-empty. `liveRecords` is already in the line, so it is not lifted.
- `ChatbotEnhanced.tsx`: one `<li data-testid="proposed-plan-posture"
data-posture={mode}>` after the assumptions.
- `fixtures/build-cards.schema.ts`: re-vendored verbatim at cloud
`f0ecef3a`. The only change from the `f7ab9cc8` copy is
`planCard.posture`, and cloud `main` `36b07fdf` has the same schema byte
for byte.
- `buildCards.fixtures.ts`: `planEnvelope(lang, { posture: 'firstBuild'
| 'draft' })`, built with cloud's own `postureFirstBuild` /
`postureIntoLiveApp` wording.
- The docs paragraph in `content/docs/plugins/plugin-chatbot.mdx`, and a
changeset (`@object-ui/plugin-chatbot` minor).

## Why this closes #12724

The card's two remaining artboard rows have no producer key at cloud
`main` `36b07fdf`, and no cloud card plans one:
- the plan card's 「确认后约 1 分钟搭好」 and 「也可以直接回复:…」
- the result card's subtitle 「应用已进启动台 · 包 … · 以下每一条都按方案核对过」

The maintainer ruled in the project thread on 2026-10-25 to drop both
from the artboard rather than wait for cloud. This posture row was the
last declared key still undrawn.

## Tests

- `pnpm exec vitest run packages/plugin-chatbot/`: 83 files, 795 tests,
all passed, including the new
`ChatbotEnhanced.planCardPosture-12724.test.tsx`. It covers zh and en
first-build lines, the draft line, posture without assumptions, and two
controls: no key, and an undeclared mode.
- `buildCards.contract-12724.test.ts` checks both new fixture payloads
against the vendored schema.
- `node scripts/check-changeset-presence.mjs` ✅. `pnpm
check:new-line-citations`: 0 new.

- [x] Adds no product-specific widget, dialog, hook or string (see
AGENTS.md › Product-neutral renderer)

---
_Generated by [Claude
Code](https://claude.ai/code/session_01R3ARF6ZEyBWW8EBT9we3eX)_

Co-authored-by: Claude <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview — fd528d12 Deployed Jul 17, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant