Commit Graph

7174 Commits

Author SHA1 Message Date
Chinesezjc
612b3c7c4e Merge remote-tracking branch 'origin/master' into feat/web-terminal-card
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-07-29 14:45:23 +08:00
Chinesezjc
f378873b22 fix(web): replay cursor movements the way a terminal paints them
Carriage return and backspace only MOVE the cursor; neither erases. Both of
my earlier approximations were wrong, and I checked each case against a real
terminal rather than reasoning about it:

`100%\rOK` shows `OK0%`, not `OK` — the redraw is shorter than the frame
beneath it, so the tail stands. `abc\b` still shows `abc`, not `ab` — a
trailing backspace has nothing to overwrite. `\x1b[31mgone\rkept` paints
`kept` RED, because a carriage return does not reset the graphic state, which
one of my own tests had asserted the opposite of.

Both now replay into a per-line column buffer with SGR state stamped per
column, as a terminal stores it per cell. That gives the partial-overwrite
case its real result too: red `bad`, three backspaces, then `ok` shows `okd`
with the `d` still red, since `ok` reached only two of the three cells.

The presenter description now also renders at every site. An expanded row
draws it itself — the collapsed summary is hidden while open, so otherwise
the description was visible only collapsed, the opposite of "above the card"
— and the details panel draws it above the card as well.

Three of my own tests encoded the wrong semantics and were corrected with
their behavior, and the emit loop's gap-filling arm was removed as
unreachable: `\r` and backspace only move left, so no column can be unwritten.
2026-07-29 14:39:21 +08:00
07akioni
f14ac52901 Merge branch 'master' into feat/agent-action 2026-07-29 14:39:13 +08:00
Turtle
2e6c4e23ab Merge remote-tracking branch 'origin/master' into codex/migrate-to-oxlint 2026-07-29 14:35:39 +08:00
Turtle
7ad0849155 style: migrate merged Oxlint directives 2026-07-29 14:34:20 +08:00
Tianyi Cui
707bd8bd5d Merge pull request #840 from deepseek-harness/codex/allow-rewrite-pushed-pr-history
docs: allow rewriting pushed PR history
2026-07-29 14:34:07 +08:00
Turtle
711efc0a8e Merge remote-tracking branch 'origin/master' into codex/migrate-to-oxlint 2026-07-29 14:32:21 +08:00
Turtle
95a995968b refactor: migrate linting to Oxlint 2026-07-29 14:32:11 +08:00
07akioni
4aa1aa4a66 test(web): refresh aria goldens for message IconActions and clocks
Settled history now exposes user/assistant chrome (including date-aware
clocks) in the accessibility tree; collapse clocks via scaffold and update
keyless scenario goldens.
2026-07-29 14:30:09 +08:00
Tianyi Cui
54dfe425d5 Merge branch 'master' into codex/allow-rewrite-pushed-pr-history 2026-07-29 14:29:21 +08:00
Yichen Jiang
dbdfb8d3b7 test(tools): include persistent tool schemas 2026-07-29 14:29:16 +08:00
creatixchu
998a5f3381 fix(host): review round — host-derived separator, click-safe blur cancel, dead wide prop 2026-07-29 14:27:01 +08:00
Yichen Jiang
d5e7212b31 fix(build): refresh node-pty patch hash 2026-07-29 14:23:34 +08:00
07akioni
afab428c0c Merge branch 'master' into feat/agent-action 2026-07-29 14:21:44 +08:00
Yichen Jiang
6346c858df Merge branch 'master' into worktree/persistent-bash-str-replace-editor 2026-07-29 14:15:52 +08:00
Yichen Jiang
665c21693b feat(tools): add persistent bash and str-replace editor 2026-07-29 14:12:27 +08:00
Yif
7639f4cb68 feat(web): answerable ask_user_question flow with toolview verdict row
The pending question now owns exactly two surfaces: the redesigned
QuestionComposer takeover (footer pager, checkbox multi-select,
always-visible custom input, locale-injected bilingual chrome) collects
the answers, and a dedicated ask_user_question toolview row reports the
interaction outcome — waiting, N/M answered, cancelled (ASK_CANCELLED),
or interrupted with stopped semantics (ASK_ABORTED). PendingCard narrows
to approval waits only. Toolview leading icons and the hover chevron
unify on the tertiary label color, the checklist glyph matches the
14px figma extract, and dev-watch registers CSS modules so css-only
edits rebuild.
2026-07-29 14:12:01 +08:00
creatixchu
7714c9fa8b doc(host): document the show-hidden toggle and path-draft prefix filter; snapshot the flow 2026-07-29 13:52:44 +08:00
kingwl
d0393106cc docs: regenerate module graph for the dsh-llm declarations
verify-module-graph caught that the plan-mode/tool-tasks dependency fix
was not reflected in the generated graph.
2026-07-29 13:51:57 +08:00
creatixchu
e561c28232 feat(host): seed path editor with a trailing separator; prefix-filter levels from the draft tail 2026-07-29 13:47:56 +08:00
imccyu
665eadbc1d Merge pull request #572 from deepseek-harness/web-permission-sandbox
feat(web): permission presets and approval answering for the web UI
2026-07-29 13:46:39 +08:00
kingwl
b48c76a63a Merge remote-tracking branch 'origin/master' into xtr/dsh-source-launch-tsx-esm
# Conflicts:
#	apps/cli/README.i18n.yaml
2026-07-29 13:45:21 +08:00
07akioni
15ef747cc0 feat(ui-conversation): implement finalized IconActions with clock for user and assistant messages 2026-07-29 13:44:26 +08:00
creatixchu
60383efef9 feat(host): blur cancels path editing; scrollbar clearance in the miller columns 2026-07-29 13:42:11 +08:00
imccyu
07262d967c Merge branch 'master' into web-permission-sandbox 2026-07-29 13:41:23 +08:00
kingwl
2ca6f54c9e Merge remote-tracking branch 'origin/master' into xtr/dsh-source-launch-tsx-esm
# Conflicts:
#	apps/cli/README.i18n.yaml
2026-07-29 13:39:57 +08:00
Hypatia May
173a1a8319 fix(dev-infra): migrate copied worktree hooks 2026-07-29 13:38:55 +08:00
Turtle
d554ae3019 Merge pull request #848 from deepseek-harness/worktree/default-pi-ai-providers
feat(apps): add default OpenAI and Anthropic providers
2026-07-29 13:31:20 +08:00
creatixchu
c747f721ba feat(host): fixed-label show-hidden toggle; even divider clearance; 680x500 card 2026-07-29 13:29:17 +08:00
Yichen Jiang
0dce3f57ca Merge remote-tracking branch 'origin/master' into worktree/default-pi-ai-providers
# Conflicts:
#	apps/cli/README.i18n.yaml
2026-07-29 13:25:06 +08:00
kingwl
aebf9c863b feat(cli): launch dsh source through the tsx ESM hook
Node 26.0.0 removed --experimental-transform-types, so the native
source-launch chain cannot start anywhere on that line, and strip-only
mode rejects the vendored syntax (parameter properties, decorators,
runtime enums/namespaces). Switch bin/dsh, the root dsh/demo:tui/
demo:web scripts, and the Code Mode TUI overlay to node --import
tsx/esm: one launch vector across the whole engines range, ~0.4s faster
than the full tsx default (the CJS hook stays off; the graph is
ESM-only).

Delete scripts/tspath-loader.ts and apps/cli/src/tsconfig-paths-loader.ts:
tsx owns both transformation and tsconfig paths projection. Add
dsh-source-launch-smoke to the node-compat gates so the 22.19/26 matrix
executes the real launch vector; no CI job did, which is how the Node 26
breakage shipped silently.

Supersedes the native-TypeScript-source-launch Agent Note (new note
records the profiling evidence and rejected alternatives).
2026-07-29 13:15:24 +08:00
kingwl
6ff2c53661 fix(deps): declare dsh-llm as a peer of plan-mode and tool-tasks
Both packages import @deepseek-ai/dsh-llm at runtime (createUserMessage)
but declared it only in devDependencies; any resolver that honors
declared runtime dependencies resolves the import to a stale or missing
artifact. Found by the (since removed) source-launch declared-dependency
check.
2026-07-29 13:14:36 +08:00
Chinesezjc
bbe1481a9e fix(web): keep escapes, UNC roots, and truncated cwd honest
Four review findings. Two are defects the previous two rounds introduced,
which the existing tests did not catch:

A backspace erased raw bytes, so one landing after an SGR reset ate part of
the escape: `\x1b[31mabc\x1b[0m\b\bXY` left `\x1b[` and repainted the rest of
the line with whatever the remainder parsed as. Backspaces now resolve over
VISIBLE characters — a CSI sequence is one indivisible unit a backspace steps
over on its way to the last printed character, so the surviving text keeps
the color its run authored.

The cwd normalizer popped a UNC share root: `\\server\share` with a `..`
became `/server`, losing the separators too. A UNC path's server and share
are its root, and Windows cannot climb above a share, so they are split off
and the remainder collapses against that root.

The other two are gaps the earlier fixes left:

The render-site fallback row still passed the args-derived summary, so any
terminal-declaring tool without its own keyed row (`terminal_send`) lost the
contract's above-card description. It now prefers the description exactly as
BashRow does.

A settled call read `call?.cwd`, which cannot tell "the call omitted a cwd"
from "the paging window dropped the call head". The second case has no cwd
anywhere and the original call may have used an explicit workdir, so it now
draws a bare `$` instead of naming the session workspace.
2026-07-29 13:10:44 +08:00
imccyu
9e10ba0f15 fix(client): drop generation-scoped interaction state at generation death
Clearing waitingApprovals in handleConnected raced the reconnect replay:
mux frames flow from stream open while onConnected waits for the
readiness handshake, so a replayed approval/requested could land first
and be wiped — amber dot and answerable card lost until the next
generation. The sweep moves to generation death (onStateChange
'reconnecting'), before any next-generation frame can exist, and now
also drops buffered answerable frames (approval/question pairs) whose
dead-generation rpcIds could never be answered — a session instantiated
later no longer replays zombie takeover cards. session/queued buffering
already re-baselines per generation; this closes the same window for
the interaction frames.
2026-07-29 13:03:26 +08:00
imccyu
99b1a7e895 fix(host): settle pre-aborted asks at registration; make audit pairing callId-symmetric
Two races from the #572 review, still live in the ported registry:

An ask whose signal aborted between the service's own check and the
microtask-deferred waterfall dispatch would register its abort listener
AFTER the signal fired — never invoked, entry pending forever, zombie
frame on every mux replay. The answerer now settles 'cancelled'
synchronously before publishing anything.

The audit back-scan let a callId-less ask claim the newest unclaimed
asked record even when that record carried another call's id. Pairing is
now shape-symmetric: callId-bearing asks take exactly their call's
record, callId-less asks take only callId-less records — neither can
steal under parallel asks.
2026-07-29 13:03:26 +08:00
Yichen Jiang
8f9535af87 Merge remote-tracking branch 'origin/master' into worktree/skill-invocation-controls
# Conflicts:
#	docs/cordis-catalog/services.md
#	packages/host/apiproxy/README.i18n.yaml
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/ui/tui/README.i18n.yaml
2026-07-29 12:58:10 +08:00
creatixchu
cdcdd2221e feat(host): show-hidden toggle in the directory browser footer 2026-07-29 12:52:59 +08:00
Turtle
31189cf403 chore: drop the examples dsh-bash dep left by the removed mock-bash fixture
Nothing under examples/ references @deepseek-ai/dsh-bash now that the
tmux-context fixtures are gone; the examples workspace ignores every
@deepseek-ai/* dependency in knip, so no gate could catch it. This leaves
examples/package.json untouched by the PR.
2026-07-29 12:52:14 +08:00
imccyu
79b1ec2eae fix(host): settle pending approvals as cancelled on gateway teardown
Disposability parity with the question provider: a gateway disposed while
approvals are pending settles every registry entry as 'cancelled' (the
service's fail-closed vocabulary), so no ctx.approval ask dangles past the
proxy's lifetime and mux subscribers see the withdrawal. Spec mounts the
proxy on its own fiber and drives dispose with a live ask.

Addresses the ds-review-bot suggestion on PR #851.
2026-07-29 12:11:00 +08:00
Chinesezjc
0f70886e0c fix(web): label only the first prompt row with the working directory
A multi-line command repeated the cwd label on every prompt row, which
states something the view does not know: it carries ONE working directory —
where the call started — and a `cd` in the command moves later lines
elsewhere. `cd ~` then `ls` rendered both rows labelled with the session
workspace while `ls` actually listed the home directory.

The label now appears on the first row only, and later rows keep a bare `$`
so they still read as prompts. Same reasoning as the run-state dot: neither
a per-line directory nor a per-line exit status exists to report.

The built-bundle snapshot records the effect on fixture turn 60's two-line
command (`fixture echo done` becomes `$ echo done`).
2026-07-29 12:10:34 +08:00
imccyu
83c2115de8 refactor(client): command decorations replace the hostBacked contribution mode
A popup on a host command is not a second command — it is what that
command's BARE invocation does on this client. CommandContribution loses
hostBacked (contributions are pure client commands again; a host-name
collision fails loud, unchanged for /model), and the contract gains
CommandDecoration + command.decorate(): key = the HOST command name, no
catalog row, no claim participation. Dispatch consults decorations only on
the bare paths (menu pick / bare enter) after the host row resolves; space
and argued enter never see them — the two edges hostBacked had to guard
explicitly hold by construction in the decoration model. A decorated name
with no host row in the session's directory never fires (a decoration
cannot manufacture a command).

ui-permission switches register→decorate with zero behavior change
(options still read the permissions projection; a pick still submits
'/permission <preset>'). Specs rewrite to the decoration semantics: no
catalog row, bare-enter popup vs argued-enter host claim, space host
claim, no-host-row miss, unavailable fall-through, duplicate fail-loud.
2026-07-29 12:01:36 +08:00
_Kerman
5d0d28cd0e fix(client): refine trajectory inspection behavior 2026-07-29 11:57:13 +08:00
Chinesezjc
eba81fe1f2 Merge remote-tracking branch 'origin/master' into feat/web-terminal-card
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-07-29 11:49:10 +08:00
_Kerman
33afcc913b Revert "fix(ui-conversation): keep composer visible across views"
This reverts commit 978d035d4a8d3578a70844511a42aa793664e5de.
2026-07-29 11:46:14 +08:00
imccyu
79dbe4c6fb style: wrap the derivePhase JSDoc line 2026-07-29 11:45:01 +08:00
Chinesezjc
439c206658 fix(web): honor the terminal view's description and resolved workdir
Three review findings, each verified against the presentation contract:

The call view's `description` was dropped, so a presenter that authors one
(`terminal_send` declares `Terminal <id>`) lost the contract's above-card text
and the row fell back to an unrelated args-derived summary. It now rides the
same derivation and outranks that summary.

A relative workdir was concatenated but never normalized, while the bash
executor resolves it before running: with session cwd `/w/app` and workdir
`..` the command runs in `/w`, yet the card displayed the label `..`. The
resolved path now collapses `.`/`..` segments, drops a `..` that would climb
past a root the way a filesystem does, and keeps a Windows path's separators
since the value is only ever displayed.

`run_code` sub-dispatches carry no presenter views on the shipped wire —
`session.ts` folds `tool/code-dispatch(-start)` with null views and the host's
`viewFor` presents only top-level call/result events — so a nested bash call
cannot reach a terminal card. The existing test only passed by injecting views
that path cannot produce; it now says so, and a second arm pins the no-view
shape the wire actually delivers.

Restoring master's fixture also fixed the todo snapshot lane, which my earlier
merge had broken by dropping the projection support the todo dock reads. The
terminal sample turn moved ahead of the todo turn, because the standing plan
retires at the next `turn/start` and a turn appended after it emptied the dock.

The card props are now nested under `card` so a render site spreads exactly the
primitive's own surface, and the fixture reads each sample's authored exit
status instead of re-implementing the bash tool's `parseExitStatus`.
2026-07-29 11:43:23 +08:00
_Kerman
549315256a fix(ui-primitives): preserve raw HTML in text extraction 2026-07-29 11:43:00 +08:00
imccyu
62c1f15576 fix(client): command lifecycle rows keep the composer blank
Selecting a preset from the hero pushed the session into the conversation
view: the /permission switch logs its command/run + command/done pair, the
pair folds into flow nodes, and the composerPhase predicate counted ANY
node as conversation — so the hero (composerPhase === 'blank') collapsed.
The host-side blank bit was already correct (sessionBlank = no turn/start;
knob events open no turn), but the client derives its phase from window
content, and command rows are log-only records, not conversation.

derivePhase's hasContent now excludes command nodes — the client mirror of
the host predicate. The knob events themselves never fold (not
surface-eligible), so the pair was the only leak. Covers /plan on the hero
identically (same lifecycle pair, same predicate).

Specs: the host blank spec pins the three knob events as standalone
events; a session spec drives the /permission pair through the live path
and asserts phase stays 'blank' while the command node renders.
2026-07-29 11:33:44 +08:00
ZiyaZhang
c7076e15b8 fix(hooks): bound regex reuse across reloads 2026-07-28 20:33:08 -07:00
NI0317
f280a97c56 test(web): isolate details session lifecycle e2e 2026-07-29 11:32:03 +08:00