qwen-code/packages/cli
qqqys 6509e8de08
feat(channels): show lifecycle status in adapters (#6114)
* chore: ignore local worktrees

* docs(channels): design identity and task lifecycle p0

* docs(channels): plan identity and task lifecycle p0

* feat(channels): add identity and task lifecycle metadata

* fix(channels): suppress cancelled tool call lifecycle

* docs: add channel lifecycle status adapter design

* docs: add channel lifecycle status adapter plan

* feat(channels): map telegram lifecycle to typing

* feat(channels): map weixin lifecycle to typing

* fix(channels): reset weixin typing state after failed start

* feat(channels): map dingtalk lifecycle to reactions

* feat(channels): add feishu card status labels

* fix(channels): preserve feishu collapsible status labels

* feat(channels): show feishu lifecycle card status

* fix(channels): cover loop lifecycle metadata

* fix(channels): preserve feishu terminal card status

* chore: remove internal task reports from branch

* fix(channels): clear late lifecycle status starts

* fix(channels): harden lifecycle event edges

* fix(channels): clean adapter lifecycle state

* fix(channels): finalize cancelled lifecycle before cleanup

* fix(feishu): keep cancelled card status visible

* docs(channels): add lifecycle status no-op coverage

* fix(channels): address lifecycle review suggestions

* docs(channels): align lifecycle status documentation

* fix(channels): route adapter stop through lifecycle cancel

* fix(channels): close lifecycle cancellation races

* fix(channels): keep first feishu terminal status

* fix(telegram): guard lifecycle typing updates

* test(qqbot): cover lifecycle status no-ops

* fix(feishu): preserve completed card race status

* docs(lifecycle): align status review docs

* fix(channels): separate pending cancel state

* fix(channels): clean adapter lifecycle status edges

* fix(channels): order clear cancellation lifecycle

* fix(feishu): preserve user stop status label

* fix(channels): suppress loop chunks during pending cancel

* test(channels): use active session in cancel regression

* fix(channels): harden adapter cancellation tests

* fix(channels): sanitize lifecycle tool fields

* fix(channels): route shared tool call lifecycle

* fix(channels): preserve pending cancel intent

* fix(channels): preserve pending cancel intent

* fix(telegram): track typing by session

* fix(feishu): preserve stop status during finalization

* fix(channels): preserve responses after failed cancel

* fix(channels): tighten lifecycle cancellation reasons

* fix(channels): close lifecycle cancel races and validate identity config

Address the outstanding review findings on #6105:

- carry a typed reason on ChannelLoopSkippedError and report disabled
  loops as 'dropped' instead of 'timeout'
- treat a turn as committed once delivery starts: /cancel re-checks
  deliveryStarted after the cancel RPC settles, and neither prompt path
  lets a late-settling cancel rewrite a delivered turn into cancelled
  (or follow a /clear cancellation with completed)
- tag failed lifecycle events with phase: agent vs delivery
- validate identity/memoryScope shape at config parse time instead of
  throwing an opaque TypeError on the first prompt of every session
- guard onPromptStart hooks, pass job.id to loop onPromptStart/End,
  append the boundary block after operator instructions, gate
  /who + /status identity lines on configured identity/memoryScope,
  cache the boundary prompt, and route error logs through
  lifecycleError()

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(qqbot): keep lifecycle mock in sync

* fix(channels): unify cancel state machine and adapter lifecycle edges

Address the remaining review findings on #6114:

- /cancel now delegates to requestActivePromptCancellation — one cancel
  state machine for slash command and adapter stop buttons; the helper
  refuses to claim success once delivery started and sanitizes its logs
- share isTerminalTaskLifecycleType from channel-base instead of four
  hand-rolled terminal checks
- DingTalk: only attach reactions for message ids seen inbound (loop job
  ids no longer trigger doomed emotion API calls), log reaction API
  failures, and recall reactions when a session dies
- Feishu: track userStopped on the card state so every wind-down path
  renders 已停止生成 after a Stop click, and pass terminal labels through
  updateCard's statusLabel param at the remaining baked-text sites
- Weixin: guard the typing .then() against a racing disconnect
- document onTaskLifecycle as the canonical hook (onPromptStart/End are
  back-compat), fix TS4111 bracket access in the DingTalk test

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(channels): keep failed terminal event when cancel settles post-delivery

Self-review follow-up: once delivery started, the catch paths no longer
reconcile a pending cancel — a late-resolving cancel RPC used to flip
cancelled=true there, suppressing the failed emit while the /cancel
handler (seeing deliveryStarted) also declined to emit, leaving a
started task with no terminal lifecycle event at all.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(channels): close self-review findings on adapter lifecycle edges

- DingTalk: track inbound message ids in a capped insertion-ordered set
  instead of the TTL-swept dedup map, so a turn queued minutes behind a
  long predecessor still attaches its reaction
- Feishu: reset userStopped when the cancel RPC fails (later wind-down
  must render the real terminal status), and give handleStop's plain
  message fallback the same ---/label shape the strip regex expects

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(channels): hold streamed chunks while a cancel is pending

Chunks arriving while a /cancel RPC is in flight were pushed straight
into the BlockStreamer, which can send a block on a size/paragraph
threshold before the cancel resolves — leaking output a successful
cancel can never recall. Hold the pending-window chunks instead: replay
them (block streaming + text_chunk transcript) when the cancel fails,
discard them when it succeeds. onResponseChunk stays live through the
window so adapter-accumulated display state has no permanent hole on a
failed cancel; adapters gate visible updates on their own stop flags.

Also stop passing the loop job id to onPromptStart/onPromptEnd (and the
/clear eviction path): the hook contract is inbound platform message
ids, and adapters act on them — cards and reactions keyed to a fake id.
Lifecycle events still carry job.id for correlation.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(feishu): strip every status-label layout from quoted-reply context

Replace the two $-anchored strip regexes in extractCardText with one
line-granular status-block filter. The anchored patterns missed four
layouts the cards actually render: the two-block truncation card
(notice block + label block), terminal labels joined mid-string before
a collapsible panel body, the 停止失败,请重试 label (never in the
alternation), and label-only stopped cards where the divider leads the
text. Tests now assert the real rendered shapes.

Also update the adapter-cancellation suppression test to the new
hold-and-replay chunk semantics from the base layer.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(feishu): ignore loop job ids in prompt hooks

* fix(channels): defer adapter chunks while cancel is pending

* fix(feishu): preserve bare status text in quotes

* fix(channels): release held chunks on failed cancel

* fix(feishu): preserve generated stop fallback status

* fix(telegram): clear typing on dead sessions

* fix(feishu): share status label definitions

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-02 11:01:07 +00:00
..
src feat(channels): show lifecycle status in adapters (#6114) 2026-07-02 11:01:07 +00:00
index.ts perf(cli): Optimize serve daemon startup (#5785) 2026-06-24 17:50:31 +08:00
package.json chore(release): v0.19.4 (#6132) 2026-07-01 13:13:47 +00:00
test-setup.ts perf(cli): code-split lowlight to cut startup V8 parse cost (#4070) 2026-05-15 17:26:18 +08:00
tsconfig.json feat(cli): Add daemon-managed channel worker for serve --channel (#6031) 2026-07-01 01:40:54 +00:00
vitest.config.ts fix(cli): Guard serve fast-path bundle closure (#5995) 2026-06-29 14:38:32 +00:00