Commit Graph

4642 Commits

Author SHA1 Message Date
creatixchu
5e4922a761 Merge remote-tracking branch 'origin/feat/directory-picker-quiet-navigation' into feat/dir-selector-adaptive-default
# Conflicts:
#	apps/cli/cordis.yml
#	packages/host/README.i18n.yaml
2026-07-30 18:41:41 +08:00
creatixchu
12b55adf6b fix(web): keyboard reach and resting metrics on the approval scroll region
Review follow-ups on the approval takeover:

The scroll region is now a tab stop (tabIndex + named role="group"). The
question composer's scroll body needs none — its option rows are focusable and
pull the container along — but this one holds nothing but text, so a
keyboard-only user could reach the buttons and never the command's tail, and
approve what they could not finish reading.

The action row's padding reproduces the 14px gap it had inside the body: the
flex gap of 6 plus its 8px top margin, neither of which reaches it now that the
row sits outside the scroll region. The resting card is unchanged again.
2026-07-30 18:35:20 +08:00
Tianyi Cui
ff364c53a2 Merge master into worktree-config-settings-seam 2026-07-30 18:31:50 +08:00
creatixchu
18abd8ecd7 Merge remote-tracking branch 'origin/feat/directory-picker-show-hidden' into feat/directory-picker-quiet-navigation 2026-07-30 18:30:39 +08:00
Yichen Jiang
9f996be8e3 fix(web-config): close the wire boundary, the redacted-replace data loss, and three P2s
Five findings from the #939 review, each reproduced before being fixed.

**Configuration reads are as privileged as writes.** `settings.describe`
returns every exposed namespace's configuration and `credentials.describe`
reports whether an arbitrary environment-variable name is configured and from
where — reconnaissance no anonymous caller should have. Both join
PRIVILEGED_METHODS, so the whole configuration plane is loopback-only until
real authentication exists; `trustedHosts` was never authentication. The model
catalog stays reachable: it carries no endpoints or key state, and a LAN
client's model picker legitimately needs it. Asserted over a real HTTP server,
because the Host header a browser actually sends is what decides this.

**The proxy serves only namespaces a registered model provider addresses.**
The settings seam is general — any plugin may register one — but the Web
configuration plane is the model-provider surface. Without the gate, every
future `settings.register()` would silently become remotely readable and
writable configuration. An unregistered namespace and an unexposed one answer
identically, so no caller can enumerate the registry one probe at a time.

**Path-addressed writes replace the redacted-document rebuild.** The editor
reads the REDACTED descriptor, so rebuilding a section from it and replacing
wholesale deleted every literal secret the wire never returned — reproduced as
`{baseURL, reasoning}` in, stored `apiKey` gone out. `settings.mutate` applies
set/unset ops to the section as it stands at the front of the seam's write
queue, and the client names only fields it can see, so an unseen secret is
untouched by construction rather than by care.

P2s in the same pass: `llm/adapters-updated` now contains async listener
rejections (an uncontained one escaped as unhandledRejection, contradicting
the documented "observer failures are contained"); llm-deepseek's retry-policy
swap uses the atomic `registration.replace` instead of dispose-then-register,
which published `[]` then `["deepseek-official"]` so an observer saw the
provider disappear and come back; and a transport rejection no longer strands
the page in `loading` or a card in `busy`, with removal failures surfaced on
the page banner instead of swallowed.
2026-07-30 18:30:15 +08:00
creatixchu
33bb266932 Merge remote-tracking branch 'origin/master' into feat/directory-picker-show-hidden 2026-07-30 18:29:37 +08:00
kingwl
1f5d09c2d7 Merge origin/master into codex/figma-context-injection-row
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-07-30 18:27:49 +08:00
kingwl
cdd1074805 Merge remote-tracking branch 'origin/master' into codex/queue-collapse
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-07-30 18:21:07 +08:00
creatixchu
a60b25c528 Merge remote-tracking branch 'origin/feat/directory-picker-quiet-navigation' into feat/dir-selector-adaptive-default 2026-07-30 18:11:21 +08:00
creatixchu
cf21f0a1ea Merge remote-tracking branch 'origin/master' into feat/directory-picker-show-hidden 2026-07-30 18:08:30 +08:00
creatixchu
e080ff2c34 fix(directory-picker-browse): resolve quiet-navigation review 2026-07-30 18:08:22 +08:00
creatixchu
3d26b8a696 fix(directory-picker-browse): bot round 1 — pill cascade+corner, slow-scan close reset, asymmetry+calibration recorded
- .loadingFloat moved after the .status/.error block (its padding was
  losing the same-specificity race) and re-anchored bottom-right: the
  truncated/error rows own the bottom left and keep rendering through a
  scan, so the pill can never cover them; confirmCreate's relist now
  clears the stale failure text like every other scan launch.
- The close edge resets loading, so the slow-scan effect disarms while
  hidden and a reopened dialog waits out a fresh silence window
  (regression test added).
- The truncated note's survival through a scan is now asserted in the
  slow-scan test; the wait-bound test moved to fake timers with the
  200ms bound explicit.
- select()'s exemption from the one-frame rule and the constants' local
  calibration premise are recorded in JSDoc and the capability-seam
  Agent Note; the themed-scrollbars note's rebinding enumeration is
  replaced by a pointer to the mechanical gate (it had drifted twice).
  Both pairs re-recorded.
2026-07-30 18:08:22 +08:00
creatixchu
7895754ae9 fix(directory-picker-browse): rebind the scrollbar elevation pair on the browser card
The loading pill's layer-2 background made the sheet an
elevated-surface painter, and the ui-theme scrollbar invariant rightly
flagged what was already latent: the dialog's columns scroll on an l2
card while the thumbs rendered in the base-surface pair. Rebind the
indirection on the card rule so it inherits to the scrolling columns.
2026-07-30 18:08:22 +08:00
creatixchu
101c3908f3 feat(directory-picker-browse): quiet navigation — one-frame landings and a slow-scan loading pill
Navigations keep the previous view rendering while scanning: target and
parent legs land as one two-pane frame when the parent leg settles within
a 200ms wait bound (past it the target lands alone and the late leg
upgrades in place; Escape inside the landing window withdraws the
navigation). The loading indicator floats over the content on the card
background and appears only once a scan outlives a 300ms silence window,
so navigation never shifts the columns or flashes an intermediate frame.
The truncated note now describes the on-screen panes instead of hiding
during scans.
2026-07-30 18:08:22 +08:00
imccyu
d4d5a11e8d Merge remote-tracking branch 'origin/master' into feat/directory-picker-show-hidden 2026-07-30 18:07:42 +08:00
Tianyi Cui
53ff5c6ef2 Merge branch 'master' into feature/shared-cli-config-foundation 2026-07-30 18:02:07 +08:00
Chinesezjc
dd56f6c646 docs: regenerate config/cordis/event catalogs for the web card tag
The re-exports for WebResultView shift line numbers in packages/core/tools;
regenerate the generated catalogs the static gate checks.
2026-07-30 17:54:15 +08:00
creatixchu
c0679f42b5 fix(web): cap the approval takeover at the composer's text height
The approval panel replaces the InputBar while a sandbox escalation waits,
and its justification and command are unbounded model text. With no height
cap, a long command grew the card until the refuse/allow row went under the
fold: at 900x700 the action row's bottom landed at y=749, so the user could
read the request and not answer it.

Justification and command now scroll in one region capped at the same height
as the composer's draft area, with the amber strip and the action row outside
it. The cap is one value with two consumers — declared as
--dsh-composer-text-max-height on ConversationRoot's .composerSeat, the
composer chain's only shared ancestor — so the seat cannot cap its two states
differently. The card rebinds the l2 scrollbar pair like every other scrolling
surface on an elevated background.

Covered by a new web e2e scenario that drives the real composition (read-only
session, denied write, the model's escalation retry, answer clicked through
the panel) and measures the live panel at two viewport heights against the
composer's own cap, read off the textarea rather than hardcoded.
2026-07-30 17:50:04 +08:00
Yichen Jiang
b73e1811ff Merge branch 'worktree-llm-dynamic-config' into worktree-llm-web-config 2026-07-30 17:39:26 +08:00
Yichen Jiang
caf2db0929 Merge branch 'worktree-config-settings-seam' into worktree-llm-dynamic-config
# Conflicts:
#	packages/settings/settings-local/src/index.ts
2026-07-30 17:39:07 +08:00
Tianyi Cui
66e182b516 Merge branch 'master' into feature/shared-cli-config-foundation 2026-07-30 17:35:47 +08:00
kingwl
3d6cacc59b Merge remote-tracking branch 'origin/master' into codex/composer-dock-stacking
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-07-30 17:35:22 +08:00
kingwl
0f0564b3d0 Merge origin/master into codex/figma-context-injection-row 2026-07-30 17:35:04 +08:00
creatixchu
eba513340c Merge remote-tracking branch 'origin/feat/directory-picker-quiet-navigation' into feat/dir-selector-adaptive-default 2026-07-30 17:34:59 +08:00
kingwl
f5228e7c71 Merge origin/master into codex/figma-context-injection-row
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/src/client/chat/ToolRow.module.css
#	packages/client/ui-conversation/src/client/chat/ToolRow.tsx
2026-07-30 17:34:14 +08:00
creatixchu
d9fb03deec Merge remote-tracking branch 'origin/feat/directory-picker-show-hidden' into feat/directory-picker-quiet-navigation 2026-07-30 17:34:09 +08:00
creatixchu
295813f6eb Merge remote-tracking branch 'origin/master' into feat/directory-picker-show-hidden 2026-07-30 17:32:46 +08:00
Hypatia May
47d2bcb18c Merge remote-tracking branch 'origin/master' into fix/human-transcript-projection 2026-07-30 17:28:49 +08:00
Hypatia May
82817570b0 Merge remote-tracking branch 'origin/master' into fix/human-transcript-projection
# Conflicts:
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/session.i18n.yaml
#	packages/host/apiproxy/README.i18n.yaml
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/ui/tui/src/index.ts
2026-07-30 17:28:26 +08:00
kingwl
abf498b8dc fix(web): align composer context stack 2026-07-30 17:26:44 +08:00
Yichen Jiang
0a263941ef Merge branch 'worktree-llm-dynamic-config' into worktree-llm-web-config
# Conflicts:
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.i18n.yaml
#	docs/event-producer-consumer.md
#	examples/headless-agent/tests/headless.snapshot.ts
#	examples/headless-agent/tests/snapshots/missing-credential/stream-json.expected.jsonl
#	packages/llm/llm-deepseek/README.i18n.yaml
#	packages/llm/llm-deepseek/src/index.ts
#	packages/llm/llm-pi-ai/README.i18n.yaml
#	packages/llm/llm-pi-ai/src/index.ts
#	packages/llm/llm/README.i18n.yaml
#	packages/llm/llm/src/index.ts
2026-07-30 17:22:44 +08:00
creatixchu
8cf1603d56 Merge remote-tracking branch 'origin/feat/directory-picker-quiet-navigation' into feat/dir-selector-adaptive-default 2026-07-30 17:18:43 +08:00
creatixchu
e7f35ccf18 Merge remote-tracking branch 'origin/feat/directory-picker-show-hidden' into feat/directory-picker-quiet-navigation 2026-07-30 17:17:49 +08:00
Tianyi Cui
d8f4a0efda chore(docs): refresh merged generated records 2026-07-30 17:17:38 +08:00
creatixchu
b8d9fb1ede Merge remote-tracking branch 'origin/master' into feat/directory-picker-show-hidden 2026-07-30 17:17:03 +08:00
imccyu
4cd5745b94 Merge branch 'master' into codex/details-default-closed 2026-07-30 17:14:51 +08:00
creatixchu
85a2789833 Merge remote-tracking branch 'origin/feat/directory-picker-quiet-navigation' into feat/dir-selector-adaptive-default 2026-07-30 17:10:36 +08:00
Yichen Jiang
a90ccc4453 revert(sandbox): withdraw the credential-document read denial
The `readDenyPaths` policy field shipped in the previous commit broke Linux
confinement outright. bwrap has to create the `/dev/null` bind's mount point
inside a tree its own profile has already made read-only, so it refused the
entire confinement whenever the parent directory was absent — every host that
has not stored a credential yet, including a fresh install:

  bwrap: Can't mkdir parents for /home/runner/.dsh/.env: Read-only file system

which the executor correctly classifies as SANDBOX_UNAVAILABLE, so every
confined bash call failed closed. Landlock cannot subtract from its own `/`
read grant, so it reported `partial` enforcement on every confined call for a
file it never hid, with no way to switch the denial off (schemastery fills an
omitted array with `[]`, so empty and omitted were indistinguishable).

A protection that breaks confinement where it works and misreports it where it
does not is worse than a documented absence. Revert the field, both expressible
backends, the enforcement downgrade, and the policy default; state the residue
plainly in the credentials-local READMEs — file mode stops other OS users, not
the model — and keep the OS-keychain provider recorded as the real answer.

The narrower discipline stands: no surface hoists the credential document into
`process.env`, and the model is never handed a resolved path to it.
2026-07-30 17:09:42 +08:00
Tianyi Cui
abd7d57358 Merge branch 'master' into feature/shared-cli-config-foundation 2026-07-30 17:08:42 +08:00
Tianyi Cui
07e3d15d42 docs(settings): mark deferred review follow-ups 2026-07-30 17:07:29 +08:00
creatixchu
893a1a8d51 Merge remote-tracking branch 'origin/feat/directory-picker-show-hidden' into feat/directory-picker-quiet-navigation 2026-07-30 17:06:07 +08:00
Chinesezjc
ba0757223d feat(web): add a web render-intent card for web_search and web_fetch results
web_search and web_fetch returned only model-facing text, whose markdown source
list is lossy (title-or-hostname label, snippet and date concatenated), so a
client could not recover the structured sources. Add a card:'web' result view
with a kind discriminant ('search' carrying structured sources + answer +
truncated, 'fetch' carrying url + statusCode + truncated), projected through
each tool's output.presentationMeta and read back in presentResult. A UI
without the web card falls back to content; the TUI is unchanged. The web
consumer is a follow-up.
2026-07-30 17:04:09 +08:00
creatixchu
3809795fd5 Merge remote-tracking branch 'origin/master' into feat/directory-picker-show-hidden 2026-07-30 17:02:33 +08:00
imccyu
34d5f8f2e2 Merge branch 'master' into feat/ask-question-gui 2026-07-30 16:55:54 +08:00
Turtle
3c620a0cb6 Merge remote-tracking branch 'origin/master' into feature/shared-cli-config-foundation
# Conflicts:
#	docs/cordis-catalog/services.md
#	packages/host/apiproxy/README.i18n.yaml
2026-07-30 16:53:55 +08:00
imccyu
34c124585a fix: test 2026-07-30 16:46:50 +08:00
kingwl
0a25c0d237 feat(web): add queue collapse control 2026-07-30 16:41:55 +08:00
Yichen Jiang
8707f324c6 refactor(ui-models): render the curated fields from a narrowed adapter family
The effort field's existence check was unreachable — EFFORT_FIELD is
total over the two known families — and a coverage exemption was papering
over the branch, which the merged toolchain no longer honored. Taking the
narrowed family as a parameter makes the lookup total at the type level,
so the check and its exemption both disappear. The rendered output is
unchanged: the browser goldens replay byte-identical.
2026-07-30 16:41:44 +08:00
Yichen Jiang
e7894f4152 docs(credentials): record the third-review contracts across READMEs, catalogs, and a new Agent Note
Both provider READMEs state what actually holds: credentials-local now
documents the physical-line editor, the read-modify-write under the
writer lock, and a Security boundary section saying plainly that the file
mode stops other OS users and not the model. sandbox-policy documents
readDenyPaths and its per-backend enforcement. The llm READMEs carry the
registration handle, pi-ai's credential-miss semantics, and DeepSeek's
same-generation snapshot; app-boot and the CLI README stop describing
$DSH_HOME/.env as an environment layer.

A new Agent Note records the round (and the prior seam note cross-links
it); the sandbox and core catalog pages gain readDenyPaths and
AdapterRegistrationHandle with their manifest entries. The headless
missing-credential snapshot re-records for the reworded guidance, pi-ai
gains the Loader-composition guard its twin already had, and the
deliberate provider symmetry is marked for the clone detector.
2026-07-30 16:37:28 +08:00
Tianyi Cui
9e679c89b6 Merge branch 'master' into feat/session-inherited-boundary 2026-07-30 16:30:42 +08:00