Commit Graph
9072 Commits
Author SHA1 Message Date
imccyu db0292ffdb docs: regenerate catalogs and sync bilingual READMEs for the permission surfaces
gen-cordis-catalog/api, config/persistence catalogs, module graph, and doc
graphs pick up the ui-permission package, the permissions projection key,
and the /permission command; KnobState and PermissionSelect join the
type-link exemptions (owned by the permission package's own docs), and
ui-permission joins the sentence Model Experience allowlist (indirect via
the host command). The ui-conversation and dsh-permission READMEs gain
their zh halves for the approval/chip and projection/command paragraphs;
all three touched pairs re-record.
2026-07-28 23:55:00 +08:00
imccyu 3e6a7fea43 test(ui-sidebar): pin the shell chrome with local DOM snapshots
First consumer of the runtime's single-slot mounting: the real apply mounts
on its own fiber, renderSlot('sidebar', ...) captures exactly the sidebar
slot's output, and update() re-renders the collapsed rail in place. The
.snap files carry semantic class names and svg fingerprints only.
2026-07-28 23:54:14 +08:00
imccyu a3f9a4d3ee test(client): migrate the ui-conversation and web benches onto SlotTestRuntime
The five ui-conversation machinery specs (apply-inject, chat-apply,
chat-toolview-slot, service-orchestration, selection-survival — now .tsx)
and the web app/app-shell specs assemble through the runtime instead of
hand-built Context + SlotsService + fake-session scaffolding per suite.
Session behavior mocks are typed against ISession, so incomplete fakes
fail at compile time.
2026-07-28 23:54:14 +08:00
imccyu 3f7a8c6f8e feat(client): add the dsh-client-test-runtime package
A jsdom slot test runtime for feature specs: a real Cordis Context, the
production SlotsService and web-react renderer, and typed session/workspace
doubles (TestSessions implements ISessions with FixtureSession sessions;
TestWorkspaces implements IWorkspaces), so the compiler flags fixture drift
when a production face changes. Fixtures feed plain data: list rows,
conversation snapshots, and ISession-typed behavior stubs; provide-bundle
materialization runs the shared SessionProvideChannel.

DOM snapshot support: declare()/renderSlot() mount a single slot inside a
data-slot wrapper for local .snap capture, and a snapshot serializer folds
CSS-module class hashes to their semantic locals and collapses svg internals
to a content fingerprint. The typed provide() constrains declared-service
fakes to Partial of the service's outward face.
2026-07-28 23:54:13 +08:00
creatixchu af049cceaf fix(host): native button semantics for rows; path editor inert under the create dialog
Rows keep their NATIVE button role inside a listitem seat (role overrides
exposed selectable folders as passive list items to assistive technology),
the crumb trail becomes a navigation landmark, and the path-edit input joins
the parentInert derivation so the nested create dialog cannot be undercut
through it.
2026-07-28 23:50:05 +08:00
imccyu cb8968c80e test(plan): cover the final-state tails and refresh the TUI golden
The idle /plan and /plan off command paths pin the immediate-commit copy;
the chip's dead leaving/locked guard is deleted (both states disable the
button, so no click reaches the handler); the multi-turn TUI golden is
re-recorded keyless over the idle-commit wording and the standalone
plan/mode narration ordering.
2026-07-28 23:49:38 +08:00
imccyu 1c43ff3061 test(goal): close the per-file coverage gaps for the goal surface
- projection.spec covers applyGoalProjection's non-message early return and
  the foreign-change-kind arm directly (the pure-function posture the unit
  requires — a throwing apply would tear down the registry drive).
- New ui-goal browser-plugin spec exercises the plugin body over a real
  cordis Context with fake faces: dock registration (id/order), verbs
  reading the CAS ref from the current projected value, the
  no-current-goal short circuit, RPC-error mapping, HMR disposal, the
  GoalDock adapter's three projection states, and the inert node half.
2026-07-28 23:48:24 +08:00
Tianyi Cui a65e13cd25 Merge branch 'master' into worktree/normalize-snapshot-tmpdir 2026-07-28 23:47:22 +08:00
Tianyi Cui c3d9f132e8 test(snapshot): canonicalize generated cwd tokens 2026-07-28 23:46:01 +08:00
Tianyi Cui 064205b54d Merge pull request #845 from deepseek-harness/worktree/pr623-policy-inheritance-simplify-20260728
subagent: simplify policy inheritance to seeded events
2026-07-28 23:44:01 +08:00
imccyu 0efc7f045e refactor(client): carve outward interfaces for the session, workspace, layout, slash, and conversation services
Feature packages now reach these domains through interface types only:
ISession/SessionFace (identity + prompt/cancel/loadOlder + the useSession
snapshot source), ISessions, IWorkspaces, ILayout, IConversation, and the
existing SlashServiceContract now actually mounted on Context.slash. The
concrete services implement their face; wire-pump and assembly entry
points stay on the classes. The provide-channel materialization and
current-projection logic moves into SessionProvideChannel so the
production service and the client test runtime share one implementation.
The workspaces service consumes sessions through the narrow SessionsPort.
2026-07-28 23:43:32 +08:00
imccyu 431c2180c1 fix(cli): harden native source resolution 2026-07-28 23:42:54 +08:00
imccyu a39bd9035e feat(web): replace the plan select with a status chip and placeholder swap
Plan mode is entered through /plan only — the select control is retired.
The conversation.input.plan seat (now right of the access-mode control)
renders a read-only Plan chip while the projection's effective target is
plan mode; its hover x executes /plan off, and the chip follows the folded
target (appears on /plan immediately, disappears on /plan off) with frames
correcting either way. While plan mode is targeted the composer textarea's
placeholder switches to the plan-task wording — InputBar reads the same
projection through the standard-kit useProjection (the TodoDock posture:
a type-only key merge, no domain service edge), and owner placeholders
still win.
2026-07-28 23:39:50 +08:00
imccyu ff06272774 feat(web): /permission popup picker (hostBacked contribution)
Bare /permission now opens a flat popupSelect of presets (current value
active, custom excluded) instead of returning a text report — the /model
pattern on a single-level list. The new dsh-client-ui-permission package
registers the contribution; a pick submits '/permission <preset>' through
Session.command, so the picker, the composer chip, and the argued line all
write through the one host command and follow the one pushed projection
frame. Options and availability read the 'permissions' projection.

ui-command gains the hostBacked contribution mode: a same-named host
command is cooperation, not a collision — the host keeps the catalog row,
the argument claim (space and argued-enter fall through to the host path),
and the lifecycle logging, while the contribution supplies only the
bare-invocation popup. The /permission command handler keeps its bare-line
text report for host surfaces without a popup layer (TUI, raw execute).
2026-07-28 23:38:22 +08:00
creatixchu 6add9a8eef fix(host): harden the browser dialog against review round-2 races
- Dismissal (Escape/mask) is ignored while adoption is busy: the owner's
  in-flight createWorkspace must not land behind an apparent cancel.
- Every parent control goes inert while the nested create dialog is open
  (Modal traps no focus, so Shift-Tab/AT could close, adopt, or retarget
  underneath the child).
- Creation settlements are gated on an open-generation ref: a create that
  resolves or rejects after the flow closed (and possibly reopened) can no
  longer relist the stale target or surface its alert in the fresh dialog.
- The keyless snapshot waits for the Open button's enabled state before
  clicking — on slow runners the selection's child listing was still in
  flight and the click landed on a disabled button.
2026-07-28 23:37:07 +08:00
imccyu da4e54b515 docs: regenerate catalogs and settle the static gates for the goal surface
- Regenerate the cordis/config catalogs, doc graphs, and module graph for
  the four newly mounted plugins and the goal projection key.
- ui-goal README pair (Model Experience indirect + Known Limitations) with
  its i18n record; sentence-allowlist entry for the indirect form.
- knip workspace entry for ui-goal (tsx test pattern).
- type-equiv manifest follows the seven host-coupled goal symbols to
  domain.ts.
- The web-slash-command-dispatch note documents the dropped prompt
  interception and leaves with it; the goal-bar note's code paths follow the
  component into ui-goal (pairing re-recorded).
2026-07-28 23:34:19 +08:00
imccyu b6b4a66da0 pkg: add build:lib script 2026-07-28 23:31:28 +08:00
creatixchu 6cd63f741c fix(host): address review — Escape scoping, relist gating, crumb overflow, aria golden
- Escape (and the mask) now reaches only the topmost dialog: while the
  nested New-folder dialog is up the browser ignores its own Modal close,
  and the nested dialog's in-flight fence keeps both open during creation.
- New folder disables while any listing loads, so a slow post-create
  relist/select sequence cannot host a second create against a target the
  pending listing is about to change.
- Deep ancestry scrolls inside a dedicated crumb trail whose tail is pinned
  into view; the path-edit zone keeps its reserved width instead of being
  clipped by the card, preserving cross-drive path entry.
- The workspace-management e2e records a directory-browser aria golden at a
  staged tree (host HOME pointed at the scaffold cwd collapses ancestry into
  the Home crumb, keeping the artifact machine-independent), and the keyless
  snapshot's row targeting goes through visible label text — listitem
  accessible-name computation differs across dom-accessibility-api
  environments (the CI-only miss).
2026-07-28 23:21:27 +08:00
imccyu e5218217c3 chore: raise lint heap limit 2026-07-28 23:20:18 +08:00
ZiyaZhang a7992cea6c Merge remote-tracking branch 'upstream/master' into fix/translation-brief-uncommitted-pair 2026-07-28 08:18:32 -07:00
imccyu d804c9c94d fix(web): blank means the conversation has not started
The summary blank bit switches from log emptiness to the absence of any
turn/start: standalone plugin events — command lifecycle records,
plan/mode, session titles, goal metadata — no longer surface a fresh
session in lists or steal the New Session view. Running /plan (or /goal)
on a blank session keeps it blank and reusable; the first accepted
prompt's turn clears it. Both carriers share one predicate (summarize +
the host/session-added frame); the cold path keeps its constant false
with the index-read rationale; the client mirror already flips only on
prompt acceptance and needed no change.
2026-07-28 23:17:46 +08:00
Yichen Jiang c5d4f1b7e6 Merge branch 'master' into worktree/default-pi-ai-providers 2026-07-28 23:16:55 +08:00
ZiyaZhang 0626b6656c Merge remote-tracking branch 'origin/master' into fix/hook-matcher-validation 2026-07-28 08:15:28 -07:00
ZiyaZhang 8d77e5149c Merge remote-tracking branch 'upstream/master' into fix/subprocess-password-scrub 2026-07-28 08:15:08 -07:00
imccyu c804dfde3e docs: document native TypeScript source launch 2026-07-28 23:13:28 +08:00
imccyu 970b432227 fix(plan): commit an idle selection immediately
set() on an idle agent appends plan/mode at once — no request boundary
would arrive until the next prompt, so a queued intent used to hang as
pending forever (the composer showed a dead pending target). A running
agent keeps the boundary-flush path unchanged. set() now reports which
branch ran (committed/queued/cancelled/noop); the /plan handler's copy
follows the branch (idle: "Plan mode on/off", mid-turn: the next-step
wording), and both commit paths share the header-delta narration. The
invariant drops turn enclosure: plan/mode is a standalone whole-value
event (the synthetic log-only turns removal already established the
between-turns append shape). The fixture mirrors the idle commit.
2026-07-28 23:09:15 +08:00
imccyu db3b12a0f7 feat: launch dsh source with native TypeScript 2026-07-28 23:06:27 +08:00
imccyu 5ea161fa68 vendor: support native TypeScript source loading 2026-07-28 23:06:10 +08:00
creatixchu 0d9ac53fb0 test(web): give the browse-dialog snapshot finds the lane's standard 10s timeout
CI's cold jsdom needs more than findByRole's 1s default between opening the
dialog and the fixture listing's first paint; the surrounding helpers already
wait 10s.
2026-07-28 23:04:33 +08:00
imccyu c0e7c008cf feat(web): sandboxed executor family on the web roster
apps/cli/cordis.yml swaps bash-local/fs-local for the acp-agent composition
(sandbox-local + sandbox-policy + bash-sandbox + user-approval + permission
+ fs-sandbox; fs-policy composes on top unchanged). The deployment default
stays danger-full-access + never — byte-for-byte the old unconfined
behavior, so the replay e2e lane and demos are unaffected — while
DSH_PERMISSION_MODE opts a process into a confined default and the
/permission command switches per session. The permission preset table ships
the three product presets (read-only/ask, workspace-write/ask,
danger-full-access/never) explicitly in the deployment config.
2026-07-28 22:59:12 +08:00
_Kerman 95574a8ec1 Merge remote-tracking branch 'github/master' into xtr/trajectory-inspection-ui 2026-07-28 22:58:46 +08:00
creatixchu a19ea11cfd doc: regenerate the module graph after ui-workspace dropped its locale edge 2026-07-28 22:58:39 +08:00
imccyu 25265b312c feat(web): projection-fed permission chip replaces the Access placeholder
PermissionSelect returns as the Access seat's wired occupant: options and
the current value read from the 'permissions' projection through the
standard-kit useProjection (no fetch, no mount timing — the resident
composer's mount-once fetch bug dies with the fetch), key absence renders
nothing (permission-less host, or a Draft with no session), and a pick
submits the '/permission <preset>' command line through the new
ComposerBarInjected.command callback (Session.command = command.execute
admission; the pushed projection frame lands the confirmed value). The
READONLY_OPTIONS placeholder and its local state leave InputBar.

The connection fixture mirrors the host: a permissions unit fold (three
knob events over the fixture preset table), the projections block +
baseline/push frames carry the key, and /permission joins the command
catalog with the same switch-through-knob-events handler shape.
2026-07-28 22:56:43 +08:00
Tianyi Cui eb38a365dc Merge pull request #791 from deepseek-harness/worktree-projcache
feat: persisted projection cache — durable checkpoints, tail reads, and cold listing columns
2026-07-28 22:55:30 +08:00
_Kerman 943ef7403e fix(client): resolve trajectory review follow-ups 2026-07-28 22:54:46 +08:00
imccyu b4bc4f382e refactor(session-projection): compact checkpoint row fields to ver/seq/val
The persisted row (sessionId, key, stateVersion, observedSeq, state)
becomes (sessionId, key, ver, seq, val) — the cache medium repeats these
three names for every unit of every session, so the long forms dominated
the JSON payload. ProjectionCheckpointRow and the checkpointRow zod spec
rename together; the domain spec bumps to v3 (cache semantics: the old
medium is discarded, not migrated). The unit-facing declaration keeps
stateVersion — only the persisted/checkpoint row shape changes.
2026-07-28 22:45:35 +08:00
creatixchu 5f4b809f42 Merge remote-tracking branch 'origin/feat/directory-picker' into feat/workspace-directory-browser 2026-07-28 22:37:44 +08:00
creatixchu 7c9d688a82 test(host): cover the native flow's re-arm guard
A fresh injected face while the same request is open re-fires the effect;
the armed guard must not relaunch the chooser (the uncovered branch CI's
per-file gate flagged).
2026-07-28 22:37:19 +08:00
imccyu afaa9ad828 style: satisfy the eslint lane on the plan surfaces
Drop the assertions eslint proved unnecessary (getByRole gains the element
type parameter instead, keeping tsc satisfied), declare the injected
setPlanMode as a function property (the seat face is this-free), and narrow
the fixture's command args without String()'s object stringification arm.
2026-07-28 22:36:35 +08:00
creatixchu 26ab28083e Merge remote-tracking branch 'origin/feat/directory-picker' into feat/workspace-directory-browser
# Conflicts:
#	packages/host/directory-picker-browse/README.i18n.yaml
2026-07-28 22:31:24 +08:00
Turtle 2f3ac10da0 docs: implement experimental and internal package group 2026-07-28 22:30:12 +08:00
Yichen Jiang c146304797 Merge remote-tracking branch 'origin/master' into worktree/default-pi-ai-providers 2026-07-28 22:29:48 +08:00
Yichen Jiang 152f3e9596 feat(apps): register OpenAI and Anthropic providers 2026-07-28 22:29:41 +08:00
creatixchu 95a8e3f949 fix(client,doc): address review — flow-open busy gating, seam on the architecture map, browse gap documented
- While a picking flow is open (native chooser pending, browse dialog up) or
  its pick is being adopted, every other menu action disables: a late outcome
  must not race a concurrent selection or creation (ds-review-bot warning).
- ctx.directoryPicker joins the architecture Capability Services map (both
  languages); neighboring rows condensed to keep the doc inside its ceiling.
- directory-picker-browse documents that its client half lands in the next
  stacked PR: a -browse composition today hides the picking affordance (the
  documented empty-hole default) rather than misbehaving (ds-review-bot
  critical; the dialog itself ships in #821).
2026-07-28 22:29:34 +08:00
imccyu 931dd934e3 style: clear the lint lane — drop redundant assertions and non-thenable awaits
eslint --fix removed the no-unnecessary-type-assertion hits the review
knives introduced; the two await-thenable errors were vi.runAllTicks()
awaits in the cache spec, replaced with advanceTimersByTimeAsync(0) (the
fake-timer-safe microtask drain). Repo-wide eslint, dual-aggregate tsc,
and the focused 100% coverage set all green.
2026-07-28 22:26:12 +08:00
imccyu 019dd7d894 test,chore: clear the static and coverage lanes for the cache stack
Static: the cache package.json files array matches the workspace
constraint shape, the unused dsh-storage-json devDependency is dropped
(tests run on the memory backend), and docs/module-graph.md is
regenerated for the new package edge.

Coverage: two unreachable branches deleted rather than tested —
coldSnapshot's floor-0 tail reuse (a baseSeq-0 restore never throws and
an unrelated record still carries a usable watermark) and flushSoft's
non-mandatory clean-skip (throttle triggers only fire dirty). New tests
close the real gaps: write() on a never-dirty session and the non-JSON
unit-state rejection, plugin disposal clearing armed interval timers,
cachedSnapshot's all-version-mismatched and cwd-identity arms, the
zero-units empty-log cut, the coordinator seek-hook ladder (suffix /
not-found / plain failure / abort-reason relay), and the superseded-
retirement race proving forget()'s exact-entry guard.
2026-07-28 22:26:12 +08:00
imccyu ee79b7a73a docs: regenerate the cordis catalogs for the reshaped cache read faces
cachedSnapshot/coldSnapshot signature and JSDoc changes from the review
fixes flow into the generated service catalog and model-facing api-catalog.
2026-07-28 22:26:11 +08:00
imccyu c46419cf5c fix(apiproxy,client): the list projection column becomes a seedable watermarked block
Review finding (PR #791): the column carried bare values (no seq), so the
client could not seed its value store without risking a stale list block
outranking newer push frames — and nothing consumed the column at all,
leaving cold titles absent after a restart. SessionSummary.projections is
now the same SessionProjectionsBlock as the history tail (values +
asOfSeq; attached rows cut the live registry, cold rows serve the cache's
identity-checked cachedSnapshot whose asOfSeq is the lowest served-row
watermark). SessionManager.refreshList seeds each row's block into the
per-session projection store via per-key apply — partial-baseline
semantics: an absent key never clears, and higher-seq-wins keeps stale
list blocks beneath push frames and tail baselines — so cold titles
surface in the sidebar without opening a session.
2026-07-28 22:26:11 +08:00
imccyu 27198d3091 fix(session-projection-cache): bind records to the log lifecycle; flush before checkpoint
Review finding (PR #791): rows carried only version/watermark/state, so a
recreated session id, or a persistence store replaced under a surviving
cache, could pass every watermark check and seed state folded from an
unrelated log; a checkpoint racing ahead of an eager log flush could
likewise expose values no stored log contains. Records now store the
header identity (createdAt, cwd) they were folded from — reads validate it
against the live header (listing) or the tail's stored header (cold read)
and discard unrelated records whole (domain version 2 discards v1 media by
the pre-release stance). A live checkpoint additionally flushes the
session's buffered events durably before the cache row lands: the cache
can trail the log, never lead it. cachedValues is reshaped into
cachedSnapshot(meta): the identity witness plus the {asOfSeq, values} cut
the list carrier serves.
2026-07-28 22:26:10 +08:00
imccyu 1ef7c9473c fix(session-projection-cache): coldSnapshot honors not-found with zero registered units
Review finding (PR #791): with no projection definitions registered,
restoreFloor() is undefined and the fast path returned a successful empty
snapshot without touching persistence — a nonexistent session 'succeeded',
violating the documented not-found contract in that supported topology.
The no-unit branch now probes readFrom(id, 0): an absent log rejects with
the seam's not-found, a present one dates the empty cut at its stored end.
2026-07-28 22:26:10 +08:00