Commit graph

9 commits

Author SHA1 Message Date
pomelo
e92fcbab46
fix(cli): switch TUI prefix ✦→◆ to fix glyph overflow on some terminals (#5974)
* fix(cli): replace ✦ (U+2726) with ◆ (U+25C6) and add ∵/∴ thinking icons

- Replace ✦ with ◆ across all TUI components to fix East Asian
  Ambiguous width misalignment (string-width reports 1 but terminals
  render 2 columns).
- Use ∵ (because) during thinking streaming, ∴ (therefore) when
  thinking is complete — matches the mathematical reasoning pair.

Co-Authored-By: Qwen Code <noreply@alibaba-inc.com>

* fix(cli): reduce STATUS_INDICATOR_WIDTH from 3 to 2 after ◆ replacement

◆ (U+25C6) is a consistent width-1 character across all terminals,
so the tool status indicator no longer needs the extra column that
was reserved for the ambiguous-width ✦ (U+2726).

Co-Authored-By: Qwen Code <noreply@alibaba-inc.com>

* fix(cli): catch missed ✦→◆ references in tests, docs, and scenarios

* fix(cli): shorten tmux spinner frames from 3 to 2 chars to match STATUS_INDICATOR_WIDTH=2

TMUX_SPINNER_FRAMES changed from ['.  ', '.. ', '...'] to ['· ', '··']
to prevent 1-column overflow in tmux when STATUS_INDICATOR_WIDTH was
reduced from 3 to 2 after the ◆ replacement.

* revert(cli): keep narrow '.' tmux spinner frames instead of ambiguous '·'

'.' (U+002E) is Narrow (always 1 col), giving a guaranteed fixed-width
tmux spinner. '·' (U+00B7) is East Asian Ambiguous, so on ambiguous-width=2
terminals the frames become 3/4 cols and the spinner jitters — the opposite
of the "fixed-width frames" the surrounding comment promises.

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

---------

Co-authored-by: Qwen Code <noreply@alibaba-inc.com>
Co-authored-by: pomelo.lcw <pomelo.lcw@alibaba-inc.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-06-30 22:44:34 +00:00
易良
e00fe6a27e
test(ci): stabilize cron interactive release check (#6016)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
2026-06-29 17:07:50 +00:00
tanzhenxin
9fc7b07602
feat(core): enable loop/cron tools by default (#4950)
Graduate cron/loop from experimental opt-in to enabled-by-default.
Flip env var polarity from QWEN_CODE_ENABLE_CRON to
QWEN_CODE_DISABLE_CRON for users who want to opt out.
Update integration tests, docs, and VS Code schema accordingly.
2026-06-10 23:21:53 +08:00
顾盼
c03610b7a7
feat(core,cli): auto-compact follow-up — /compress instructions, PreCompact hook plumb, plan/subagent attachments (#4688)
* feat(cli,core): /compress accepts custom focus instructions

Extends /compress to take a trailing instruction string (max 2000 chars)
that is passed through tryCompressChat → tryCompress → CompressOptions
and appended to the compression side-query system prompt as an
"Additional Instructions:" block. Mirrors claude-code /compact <text>.

Empty / whitespace-only args fall back to the prior behaviour.

* test(core): cover /compress customInstructions + PreCompact hook merge

* feat(core): restore plan-mode + subagent snapshot after compaction

Adds two optional ComposePostCompactOptions:
- planModeActive: when true, emits a <plan-mode-active> reminder so the
  post-compact agent does not forget destructive tools remain gated.
- runningSubagents: when non-empty, emits a <background-tasks> block
  listing each running/paused task by id, status, and description.

Both blocks are spliced into the merged user attachment Content before
file/image restorations. XML-significant characters in descriptions are
escaped to prevent an adversarial subagent description from closing the
wrapper tag.

Wiring at the call site arrives in the next commit.

* feat(core): wire plan-mode + subagent snapshot into post-compact attachments

ChatCompressionService.compress now passes:
- planModeActive: derived from config.getApprovalMode() === ApprovalMode.PLAN
- runningSubagents: filtered from BackgroundTaskRegistry to agent-kind tasks
  in 'running' or 'paused' state

into composePostCompactHistory. Adds collectActiveSubagents() helper that
returns [] when the registry is absent so older SDK consumers without it
keep working.

* fix(core,test): use HookSystem.getAdditionalContext accessor; smoke-test /compress

- chatCompressionService: read PreCompact hook output via
  result.getAdditionalContext() — the wrapper returns DefaultHookOutput
  (not the raw AggregatedHookResult), and the accessor sanitises < / >
  consistently with every other call-site in the repo.
- Test mocks now return a DefaultHookOutput-shaped stub via a tiny
  makeHookOutput() helper rather than the aggregator shape.
- New integration smoke test for `/compress focus on the scientist
  mentioned` exercising the args plumbing end-to-end.

* test(core): update client.test.ts to match new tryCompressChat signature

* feat(core): cap subagent snapshot at 30 entries with overflow notice

Code-review follow-up. Pathological sessions with hundreds of
backgrounded agents could otherwise produce a multi-KB block. Newest 30
rows are kept (highest startTime); older ones are summarised on a
trailing line so the model knows the snapshot is partial.

* fix(core,test): flatten subagent description newlines; type-safe ApprovalMode in tests

Second code-review pass found two real issues:

1. Subagent descriptions containing `\n`/`\r`/`\t` would split across
   multiple lines inside the `<background-tasks>` bullet list, letting
   the second line read as a sibling row (or worse, an orphan paragraph
   between two `- [..]` entries). Flatten whitespace before the slice so
   each task stays on one line.

2. The plan-mode wiring tests passed `'plan'` / `'auto-edit'` as plain
   strings instead of `ApprovalMode.PLAN` / `ApprovalMode.AUTO_EDIT`.
   Source code compares against the enum; a future enum value change
   would have silently passed the tests. Import and use the enum.

* fix(core): move PreCompact hook fire after length-guard; align plan-mode tool names

Round 3 code review surfaced two issues:

1. PreCompact hook fired BEFORE the curatedHistory.length < 2 guard, so
   a single-message session would trigger any hook side effects
   (transcript dump, external notification, etc.) and then NOOP. Move
   the hook fire below the guard so hooks only run when compression is
   actually possible. New regression test asserts the contract.

2. PLAN_MODE_REMINDER_TEXT said "shell mutations" but the real qwen-code
   tool is `run_shell_command` (tool-names.ts:26). Use the verbatim
   tool names so a future rename is grep-discoverable.

* refactor(core): share escapeXml, drive plan-mode names from ToolNames, extract reminder builder

Code-review follow-ups on post-compact attachments:
- Replace the local 3-char escapeForXmlText with the shared 5-char
  escapeXml from utils/xml.ts, and apply it to the subagent id and
  status as well as the description. Subagent ids derive from a
  user-configurable subagentConfig.name, so an unescaped `<`/`&` there
  could close the <background-tasks> wrapper or forge sibling markup.
- PLAN_MODE_REMINDER_TEXT now interpolates ToolNames.WRITE_FILE / .EDIT /
  .SHELL instead of retyping the names, so a future rename stays in sync.
- Extract buildStateReminderParts() as the single source of truth for the
  plan-mode + subagent reminder blocks, used by both composePostCompactHistory
  and (next commit) its catch-fallback so the two paths can't drift.

* fix(core): scope subagent snapshot to backgrounded tasks; restore reminders on fallback; cap hook context

Three code-review fixes in the compaction service:
- collectActiveSubagents now also requires isBackgrounded — foreground
  agents are the parent's synchronously-awaited tool call and don't belong
  in a <background-tasks> roster. Mirrors getRunningBackgroundCount.
- The composePostCompactHistory catch-fallback re-applies the plan-mode +
  subagent reminders via the shared buildStateReminderParts (pure, no I/O),
  so a restoration failure no longer silently drops plan-mode enforcement
  and the subagent roster.
- The PreCompact hook's additionalContext is capped at
  MAX_HOOK_INSTRUCTIONS_CHARS before entering the side-query prompt,
  closing the unbounded-input hole the user-text cap was meant to prevent.

The fallback and hook-cap fixes have RED-verified regression tests.

* feat(cli): warn on /compress instruction truncation; fix integration-test pty typing

- /compress now emits an INFO notice (interactive), a stream message (acp),
  and a prefixed return message (non-interactive) when the instruction
  string exceeds MAX_COMPRESS_INSTRUCTIONS_CHARS, so the silent 2000-char
  clip is no longer invisible to the user.
- Annotate the three `ptyProcess.onData((data: string) => ...)` callbacks
  in the compress integration test to clear the TS7006 implicit-any the
  reviewer's typecheck flagged (fixed all three occurrences, not only the
  one inside this PR's diff).
2026-06-03 09:23:00 +08:00
易良
04729d646c
test: stabilize main e2e flakes (#3992)
* test: stabilize main e2e flakes

* test: stabilize macos e2e assertions
2026-05-10 21:50:04 +08:00
tanzhenxin
cbf409840d
test(integration): match new cron notification format in interactive tests (#3402)
Cron prompts are rendered as `● Cron: …` notifications since the
distinct Cron message type was added; the interactive tests still
waited for the legacy `> …` user-message line and timed out.
2026-04-17 22:56:34 +08:00
tanzhenxin
7e490ddc65 test(integration): skip cron interactive tests in sandbox environment
- Add IS_SANDBOX environment detection
- Skip cron interactive tests when running in Docker sandbox
- Move timeout options inline with test definitions
- Add comment explaining flaky test workaround

This prevents flaky test failures in the Docker sandbox environment while preserving test coverage in local development.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-04-01 19:51:49 +08:00
tanzhenxin
314a9ded78 refactor(tests): replace Playwright with @xterm/headless in cron tests
Use @xterm/headless (pure Node.js terminal emulator) instead of
Playwright + browser-based xterm.js for cron interactive tests.
Add InteractiveSession utility for future interactive tests.
2026-03-29 06:15:31 +00:00
tanzhenxin
ded89618ec refactor(tests): reorganize integration tests by execution mode
Move non-interactive tests to cli/, interactive tests to interactive/.
Add cron-interactive.test.ts wrapping terminal-capture E2E in vitest.
Update npm scripts and release workflow for new directory layout.
2026-03-29 05:49:17 +00:00