Commit Graph
100 Commits
Author SHA1 Message Date
imccyu 93cbb3799d feat(client): inject public build environment 2026-08-19 18:21:26 +08:00
imccyu 2bff588f3d Merge pull request #2756 from deepseek-harness/fix/oxlint-ci-diagnostic-locations
fix(ci): preserve oxlint diagnostic locations
2026-08-19 15:56:36 +08:00
imccyu 3b9edc2939 fix(ci): preserve oxlint diagnostic locations 2026-08-19 15:47:43 +08:00
imccyu c1eac0ba54 Merge pull request #2635 from deepseek-harness/perf/partitioned-coverage
perf(ci): parallelize coverage and web snapshots in-job
2026-08-18 22:13:16 +08:00
imccyu 45a73e3ed5 fix(ci): preserve Windows gate ordering 2026-08-18 22:03:20 +08:00
imccyu d54f6382c8 fix(ci): preserve Windows coverage failures 2026-08-18 21:45:25 +08:00
imccyu ce128804e3 fix(test): restore Codex fixture command path 2026-08-18 21:34:55 +08:00
imccyu 975bf864ef fix(ci): make Windows fixtures portable 2026-08-18 21:19:06 +08:00
imccyu 5ba9e50bb0 fix(ci): stabilize native Windows coverage 2026-08-18 21:15:21 +08:00
imccyu ef75b6ff2f perf(ci): parallelize coverage and web snapshots in-job 2026-08-18 21:15:20 +08:00
imccyu 68f519a74c test(web): make Cordis continuation turn deterministic 2026-08-18 11:58:11 +08:00
imccyu dedb730a68 Merge pull request #2592 from deepseek-harness/worktree-reducepkg2
refactor(client): separate shell and dynamic package boundaries
2026-08-18 02:17:04 +08:00
imccyu d9ea5da2ff fix(ci): satisfy client script quality gates 2026-08-18 02:07:09 +08:00
imccyu 3c2d2d3cc9 test(web): hold the theme bundle during boot 2026-08-18 01:50:23 +08:00
imccyu e0e529547b docs(client): refresh module catalog source link 2026-08-18 01:34:56 +08:00
imccyu d419b722bb test(web): derive assembled graph from bundle config 2026-08-18 01:34:55 +08:00
imccyu c60f132b9c refactor(client): close module loader bootstrap loop 2026-08-18 01:34:55 +08:00
imccyu 8088d2a6a0 fix(client): harden bootstrap invariants 2026-08-18 01:34:55 +08:00
imccyu 1c94446a56 fix(client): preserve dependency boundary cleanup 2026-08-18 01:34:54 +08:00
imccyu 885df835a1 docs: refresh module dependency graph 2026-08-18 01:34:54 +08:00
imccyu 4ad6e28663 fix(client): consume bootstrap handoff queue 2026-08-18 01:34:54 +08:00
imccyu 85bfc7bb22 chore(ci): refresh checks after stack link 2026-08-18 01:34:54 +08:00
imccyu cf603b847f fix(client): complete dynamic module bootstrap 2026-08-18 01:34:53 +08:00
imccyu aa03eff500 build(client): enforce client package boundaries 2026-08-18 01:34:53 +08:00
imccyu ed35d11dde fix: keep test runtime declarations on public types 2026-08-18 01:34:25 +08:00
imccyu 23c11e6ec8 test: stabilize Cordis replay and Windows paths 2026-08-18 01:34:25 +08:00
imccyu e1777b7891 fix(client): tighten UI ownership boundaries 2026-08-18 01:34:25 +08:00
imccyu 07484b9474 fix(build): preserve package metadata across rebase 2026-08-18 01:34:24 +08:00
imccyu 2f974ca9b0 feat(web): show plugin loading progress 2026-08-18 01:34:24 +08:00
imccyu 0fda2a26b7 fix(web): preserve boot page through React handoff 2026-08-18 01:34:24 +08:00
imccyu c065ba34d1 fix(client): tighten UI service boundaries 2026-08-18 01:34:24 +08:00
imccyu 85fa5b6943 docs(client): synchronize UI boundary references 2026-08-18 01:34:23 +08:00
imccyu cf5e686408 refactor(client): merge React bindings into UI renderer 2026-08-18 01:34:23 +08:00
imccyu f37bc082c5 refactor(client): move web rendering into a dynamic plugin 2026-08-18 01:34:21 +08:00
imccyu 3e4ad10d05 refactor(client): make attachment UI a client plugin 2026-08-18 01:34:20 +08:00
imccyu 56dff07c4e refactor(client): move schema handling into ui-settings 2026-08-18 01:34:20 +08:00
imccyu 027bd013bc Merge pull request #2634 from deepseek-harness/fix/ci-081800
fix: dep version issue from #1083
2026-08-18 01:26:39 +08:00
imccyu bace780458 fix: windows ci 2026-08-18 01:03:57 +08:00
imccyu 9705290fe4 fix: dep version 2026-08-18 00:42:26 +08:00
imccyu 99f6f02fec Merge pull request #2620 from deepseek-harness/release/dsh-0.1.0-rc.7
release: dsh@0.1.0-rc.7
2026-08-17 19:03:17 +08:00
imccyu 5bb600f9fb Merge pull request #2577 from deepseek-harness/revert-2571-worktree-reducepkg
Revert "fix(client): declare browser-only externals as devDependencies"
2026-08-15 02:49:25 +08:00
imccyu f2830fec6d Revert "fix(client): declare browser-only externals as devDependencies" 2026-08-15 02:19:09 +08:00
imccyu 6c18b04a6b Merge pull request #2571 from deepseek-harness/worktree-reducepkg
fix(client): declare browser-only externals as devDependencies
2026-08-15 01:57:43 +08:00
imccyu ef249da2e9 perf(web): remove the module preload polyfill
The preload links stay; browsers that ignore them fetch vendor when index imports it.
2026-08-15 01:41:15 +08:00
imccyu b6d0195d5f fix(scripts): resolve workspace names to source in the notices dry run
The shell's Vite config aliases a few workspace packages to source; every other
workspace name resolved through node_modules to a lib/ entry the real build has
emitted but a clean checkout has not, so the generator only worked on a built
tree — and a static gate has to pass on a clean one. The dry run now supplies
source aliases for the names the shell leaves out.

Aliases rather than the recorder's resolveId hook, because Vite resolves a
stylesheet @import through aliases alone, and the theme package publishes its
stylesheets from lib/styles/. lib/ is compiled from src/, and the recorded set is
identical either way: 24 packages on a built tree and on a clean one.
2026-08-14 22:35:11 +08:00
imccyu 1fae5dc40e fix(scripts): disclose browser-bundled packages as shipped
Moving react, shiki, katex and the markdown pipeline to devDependencies took
them out of the notices runtime tier, which tiers by declaring section — yet
their code is inside lib/client.js and the shell dist. The generator now learns
what the browser artifacts carry from the real build configs: each client bundle
through its own tsdown config, the shell through apps/web's Vite config, with a
recorder that resolves each bare specifier, notes the package behind it, and
stops there. About three seconds, and only packages a resolved file backs, so a
bundler's virtual module is not mistaken for a shipped one.

Net effect on the file: the type-only packages @types/mdast and
micromark-util-types move to the development tier, because neither ships code.
2026-08-14 22:24:23 +08:00
imccyu 7d59006fd1 docs(notes): record how the notices tier learns what ships
A package a published browser artifact carries is a runtime disclosure whatever
section declares it, and the build answers which ones those are. Record that
clause, the dry run behind it, why a bundler's virtual module is not a shipped
package, why a types-only package is not either, and the generator run cost the
dry run adds.
2026-08-14 22:24:23 +08:00
imccyu 93a95e838d fix(client): declare browser-only externals as devDependencies
react, react-dom, shiki, katex, clsx, the micromark and mdast families and nine
more reach only browser artifacts, which resolve nothing on a user's machine.
Moving 79 declarations out of dependencies and non-optional peerDependencies
drops 103 tarballs and 6.05 MB from an install of the published CLI.
2026-08-14 20:18:39 +08:00
imccyu 6e77499326 feat(scripts): gate browser-only dependencies out of the install face
verify-client-runtime-deps walks each package's host and browser faces from the
entries its manifest publishes, over the bound host and client Programs, and
reports an external package no host-face reference reaches. Wired into hygiene.

A workspace name is out of scope: it also states which package supplies an
injected service or a mounted Remote contribution, and the app installs it
either way. A package whose published Node entry has no source counterpart is
skipped and named, because a generated artifact carries imports no source
states.
2026-08-14 20:18:35 +08:00
imccyu 48d14b4a7c docs(client): state where a browser-only dependency is declared
Browser artifacts resolve nothing on a user's machine: tsdown inlines every
non-platform specifier, the shell dist answers the rest from its frozen module
table, and Vite inlines the shell's own imports into the published dist. Record
the resulting declaration rule, and the Agent Note behind it.
2026-08-14 20:17:50 +08:00
imccyu 887c4977db Merge pull request #2546 from deepseek-harness/fix/publish-deporder
fix(release): order publication by installed dependencies and keep npm's output
2026-08-14 17:24:48 +08:00
imccyu d5be1d62c9 feat(release): count publish progress against the whole release set
A dsh publication uploads 221 packages one at a time, spaced apart, and
the log gave no way to tell how far along a run was: every line named a
package, none said where that package sat in the set.

Each per-package line now carries [n/total]. Every entry in the order
settles as either published or already present, so the counter is both
"packages settled" and "position in the publish order", and the closing
summary names the member count alongside the published and skipped
totals.
2026-08-14 16:10:06 +08:00
imccyu 0e50fa290c fix(release): state what the echo helper does, and drop two dead claims
Three corrections from review, none of which change behaviour.

attemptStreaming promised output "as the command produces it", which
spawnSync cannot do: it returns only after the child exits, and the two
streams are echoed one after the other, so their interleaving is lost.
For an npm publish that is visible — notices go to stderr while the
`+ name@version` confirmation goes to stdout, so the confirmation prints
first. The helper is now attemptEchoed and its contract says buffered,
echoed after exit, stdout before stderr; live progress would need an
asynchronous spawn with data listeners.

The traversal comment claimed a node on the stack is a cycle only peer
edges can form, and that skipping it drops just that edge. The cycle does
carry a peer edge, because the install edges were proved acyclic a moment
earlier, but the back edge that reaches the stacked node need not be the
peer one — which is what the post-condition exists to catch, so the
comment now points at it instead of asserting an invariant the traversal
does not have.

The `if (placed.has(member.name)) return` after leaving the stack was
unreachable: a re-entrant visit returns at the top guard while the member
is on the stack, so it can never be placed by the time the recursion
unwinds.
2026-08-14 16:10:06 +08:00
imccyu 7b973e27c8 feat(release): reject a module-scope load of an optional dependency
A dependency in optionalDependencies, or a peer carrying
peerDependenciesMeta.<name>.optional, may be absent from an installed
tree — that absence is the whole promise of "optional". A static import
is evaluated when the importing module loads, so one absent package
stops being "this capability is unavailable" and becomes a load failure
for everything that reaches the importing module.

Nothing checked it, and nothing here could: the failure needs an
installed tree missing that package, and a workspace install always has
every package, so the unit tests, the snapshots, and the packed-install
probe all pass while the published package is broken for the consumer
who declined the optional peer.

verify-optional-dependency-imports reads each package's own manifest for
what it allows to be absent, then scans the files that ship across both
compiler faces. Value-versus-type is decided against a bound Program
rather than the import syntax, because verbatimModuleSyntax is off: the
compiler already erases an import whose bindings resolve to types, so a
syntactic rule would report four forms that emit nothing. Only the type
phase erases an import — `import defer` still resolves and links its
module, deferring evaluation alone — which is what phaseModifier
expresses and the deprecated isTypeOnly cannot.

A violation names the package, the declaration that made it optional,
and the way out in order: import it as a type, or restructure so module
scope does not need it. A dynamic import() only moves the failure to
first use, so the gate does not offer it as the remedy.

The gate runs in ci-static and ci-primary through ciSharedStaticGates
and locally in hygiene; it needs no build. TypeScriptProject gained a
face parameter so a repository-wide gate can seed the client aggregate,
which was previously unreachable; the constraint it was built with is
unchanged, a face config and never the root solution.

The tree has no violation today, so this guards the rule rather than
fixing a defect. The spec pins all seven import forms against what tsc
emits, including the four a syntactic rule would misreport.
2026-08-14 16:10:06 +08:00
imccyu 9fa0575ccc fix(release): print the publish order and the peer edges it drops
The verify step resolved the publish order and said only that it had:
the order a release actually follows, and the ordering it could not
honour, stayed invisible until a publication was already running.

publishOrder now returns that order together with the peer edges it
dropped, verify prints both, and pack reads the order off the plan. The
dropped edges are part of the result rather than a detail of forming it:
the dsh family drops one (dsh-api-remotes -> dsh-api-gateway) and the
vendored family drops two (cordis-plugin-include and
cordis-plugin-loader, which cordis declares as peers in return), and
only whoever reads the log can judge whether a newly dropped edge is
expected.

Because pack runs on every pull request and master push, a change to the
order is now reviewable there rather than observable only at publish
time.

The order is also checked against the edges it exists to honour. A cycle
mixing peer and dependency declarations can put a dependency on the
traversal stack, where it is skipped like a peer edge, emitting a
consumer before something it installs; no later step can detect that,
and it would surface as an unresolvable install for a consumer of the
published packages. No family has that shape today, and the new test
pins the three-package case that would.
2026-08-14 16:10:06 +08:00
imccyu 70eb76eaec fix(release): keep npm's own output in the publish log
Retry classification needs npm's failure text, so the publish call captured its
streams instead of inheriting them. That silenced npm on the success path: the
log lost the tarball contents, the notices, and the '+ name@version'
confirmation for every package.

Pipe the streams and echo them, so the log shows what npm reported and the
caller still gets the text it classifies. The registry probe behind it keeps its
streams captured, since its JSON and its E404 are internal queries rather than
progress.
2026-08-14 16:10:06 +08:00
imccyu 47399764c5 fix(release): order publication by every installed dependency section
Publish order exists to make a partial publication self-consistent: an
interrupted run should leave a prefix whose packages never point at a version
absent from the registry. It read only dependencies and optionalDependencies, so
peer declarations — how sibling harness packages reference each other, 1088 edges
in the dsh family — constrained nothing.

Peer edges now order the publication too. devDependencies still do not: a dev
dependency is absent from the published package.

Peers cannot constrain it absolutely. Sibling packages declare each other as
peers, which is what closes the two cycles here, and npm treats an unmet peer as
a warning rather than a resolution failure. Install edges therefore win: a peer
edge is dropped where the peer installs the member declaring it, or where
following it would revisit a member already being visited. One peer edge is
dropped in the dsh family and two in the vendored family; every install edge is
honoured.

A cycle among install edges stays a defect rather than something to order
around, and release:verify now reports it before the build instead of letting it
surface once pack is already writing tarballs. Install-edge acyclicity is checked
on its own graph, because a peer edge leading into an install edge otherwise
reads as a cycle where the install edges are perfectly orderable.
2026-08-14 16:10:06 +08:00
imccyu fb82698709 Merge pull request #2531 from deepseek-harness/release/dsh-0.1.0-rc.6
release: dsh@0.1.0-rc.6
2026-08-13 19:56:40 +08:00
imccyu fdab3aadb3 Merge pull request #2529 from deepseek-harness/fix/npm-import
fix: SessionPersistenceCorruptionError
2026-08-13 19:51:52 +08:00
imccyu 47f943859b Merge pull request #2519 from deepseek-harness/feat/npm-public
release: dsh@0.1.0-rc.5 & publish the dsh family publicly
2026-08-13 19:38:46 +08:00
imccyu abe560f81e release(dsh): 0.1.0-rc.5 2026-08-13 18:49:33 +08:00
imccyu 8c1e8d9890 build(release): publish the dsh family publicly
Every release member now declares publishConfig.access: public, so the scope no
longer mixes levels: the 221 packages/*/* and apps/* manifests join the vendored
framework and the native packages.

check-workspace-constraints drops the per-sequence expectation and holds every
release member to public, which is what stops a member from drifting back.

Access is a property of the package, not of a version: the dsh packages already
published as restricted become world-readable at their next publication.
2026-08-13 18:49:32 +08:00
imccyu 124aa5f01a Merge pull request #2521 from deepseek-harness/release/dsh-0.1.0-rc.3
release: dsh@0.1.0-rc.3
2026-08-13 18:40:08 +08:00
imccyu 71fa4c50d1 Merge pull request #2512 from deepseek-harness/codex/2503-english-onboarding-copy
fix(web): add English onboarding copy
2026-08-13 18:38:26 +08:00
imccyu 908f1afc42 ci: skip 2026-08-13 18:29:09 +08:00
imccyu a41085dfd4 ci: skip 2026-08-13 18:25:49 +08:00
imccyu 81cf740c4f Merge branch 'master' into codex/2503-english-onboarding-copy 2026-08-13 18:15:53 +08:00
imccyu 42c359e57b fix: ci 2026-08-13 18:14:13 +08:00
imccyu 5a16a5eaf5 Merge pull request #2507 from deepseek-harness/release/dsh-0.1.0-rc.2
Release: dsh@0.1.0-rc.2
2026-08-13 17:23:52 +08:00
imccyu d8f5b0507d Merge pull request #2495 from deepseek-harness/release/dsh-0.1.0-rc.1
release(dsh): 0.1.0-rc.1
2026-08-13 16:51:36 +08:00
imccyu df9ea1681f fix: snapshot 2026-08-13 16:20:19 +08:00
imccyu fb0f0ba799 Merge pull request #2499 from deepseek-harness/fix/static-ci-081316
fix: static ci
2026-08-13 16:08:16 +08:00
imccyu 944a0260ca fix: static ci 2026-08-13 16:05:57 +08:00
imccyu 7913fc510b Merge pull request #2489 from deepseek-harness/fix/publish-retry-idempotence
fix(release): make publication retry, space out, and skip what already landed
2026-08-13 15:42:39 +08:00
imccyu 6e05cb7ff5 release(landlock-run): 0.1.1 2026-08-13 15:32:17 +08:00
imccyu f1e8187974 fix: static
fix: tar
2026-08-13 15:32:13 +08:00
imccyu 8d6f5164ab fix(release): make publication retry, space out, and skip what landed
A landlock publication failed with `E409 Failed to save packument` on the
second of three packages. The registry answers a write it could not commit that
way, and publishing several packages back to back is what provokes it.

Neither publish path could recover. The native sequence published from a shell
loop of bare `npm publish` calls: no retry, and no way to resume, because the
registry rejects a repeat of an existing version permanently — so a failure
partway through left the release stuck. publish.ts skipped versions already
present, which made a re-run safe, but had no retry either.

Both paths now attempt a tarball up to four times, space writes at least two
seconds apart, and back off 2s/4s/8s between attempts. Every retry re-reads the
registry first, because a reported failure can answer a write that landed
anyway: a version that now exists with this tarball's integrity counts as
published rather than as one to place again. That same re-read is what turns a
mid-run `E403 cannot publish over the previously published versions` into a
skip when the bytes match, and leaves it a hard failure when they do not.

The native sequence gets the registry comparison publish.ts already had, through
its own script rather than shared code — the two sequences keep separate
publication paths. Its publish job now checks out the repository, which the
shell loop did not need.

Verified against a scripted registry: a clean publish, one E409 then success, an
E409 whose write landed anyway, E409 on every attempt (fails after four), and a
version already present with matching integrity (publishes nothing).
2026-08-13 15:31:09 +08:00
imccyu be96840412 Merge pull request #2473 from deepseek-harness/publish/npm-packagejson
build(release): publish the vendored framework and the native packages publicly
2026-08-13 14:17:16 +08:00
imccyu a213befd0f build(release): publish the vendored framework and the native packages publicly
The three release sequences shipped with publishConfig.access: restricted, so
nothing in the @deepseek-ai scope was installable from outside the organization.

A restricted dependency is what actually blocks a public consumer: every harness
package declares the vendored framework as a peerDependency, and
dsh-sandbox-local declares the Landlock entry as a dependency. Those two
sequences therefore go public first — the nine vendor/* packages and the three
native/landlock-run packages — while the dsh family stays restricted until its
own sequence is opened deliberately. No public package requires a restricted one
in this arrangement.

Access is now per sequence, so no publish path can pass --access: one flag
cannot express two levels and would override the manifest that owns the fact.
publish.ts stops passing it, matching the native workflow, and
check-workspace-constraints holds each manifest to its own sequence's level,
which is what stops the scope from drifting one package at a time.

Harness consumers reference the Landlock entry as workspace:^ instead of
workspace:*, so a published harness package accepts the entry's patch and minor
releases. The entry keeps workspace:* for its platform packages, where the
binary must match the entry version exactly.

Two rationales that named a private registry no longer describe the vendored
sequence; they now state the durable reason, which is that the verification must
not depend on the registry already carrying matching versions.
2026-08-13 14:05:48 +08:00
imccyu 1646b7617e fix(bundle): exclude product subagents from base
The Codex and Claude Code subagent providers were production dependencies of
@deepseek-ai/dsh-base and mounted by its Cordis composition, so every install of
the base bundle carried two providers that only some products want.

Drop both from the base bundle's dependencies and composition. The examples keep
them as explicit dependencies, base's tests lock their absence, and the product
preset e2e mounts the providers it needs explicitly.

Cherry-picked from #2387 (two commits squashed into one).
2026-08-13 14:05:46 +08:00
imccyu 3083461524 Merge pull request #2447 from deepseek-harness/release/dsh-0.0.1-rc.5
Release: dsh@0.0.1-rc.5
2026-08-13 06:18:58 +08:00
imccyu 5f3a9c82e8 Merge pull request #2449 from deepseek-harness/release/vendor-081306
Release: vendor@4.0.1-rc.4
2026-08-13 06:10:43 +08:00
imccyu 76be2ef4dc Merge pull request #2446 from deepseek-harness/fix/vendor-release-bump-all
Release: vendor@4.0.1-rc.3
2026-08-13 05:56:57 +08:00
imccyu 069e472e79 Merge pull request #2445 from deepseek-harness/release/vendor-0813
release(vendor): include 1.0.6-rc.2, loader 1.0.2-rc.2
2026-08-13 05:39:59 +08:00
imccyu eb1c67eb6f Merge pull request #2443 from deepseek-harness/fix/session-log-export
Release: dsh@0.0.1-rc.4
2026-08-13 05:29:23 +08:00
imccyu 57abe62a83 Merge pull request #2438 from deepseek-harness/release/dsh-0.0.1-rc.3
Release: dsh@0.0.1-rc.3
2026-08-13 04:18:26 +08:00
imccyu 069c611983 Merge pull request #2047 from deepseek-harness/worktree-cordisweb
feat(cordis-web): model-mounted dynamic dual-half packages for the web client
2026-08-13 04:17:39 +08:00
imccyu 77f9c4fa0a fix: test 2026-08-13 04:02:29 +08:00
imccyu 499d397631 feat: optimze skill and tool 2026-08-13 03:46:20 +08:00
imccyu 35b51dd15c fix: test 2026-08-13 03:24:03 +08:00
imccyu 96d8f9516b feat: optimize prompt 2026-08-13 03:18:04 +08:00
imccyu de25be3647 fix: coverage 2026-08-13 02:58:32 +08:00
imccyu 11a55092e8 fix: rebase 5 2026-08-13 02:51:52 +08:00
imccyu db6b14eb5b fix: rebase 4 2026-08-13 02:38:16 +08:00
imccyu 1ff62760d1 fix: rebase 3 2026-08-13 02:29:17 +08:00
imccyu 45dfff0cdd fix: rebase 2 2026-08-13 02:22:10 +08:00
imccyu 39f55a049f fix: rebase 2026-08-13 01:59:32 +08:00
imccyu 25efb8ff6f fix: snapshot test 2026-08-13 01:37:31 +08:00
imccyu 8bf7b4cc8e fix: vitest 2026-08-13 01:35:47 +08:00
imccyu 4563086a94 fix: ci 2026-08-13 01:35:47 +08:00