Commit Graph
338 Commits
Author SHA1 Message Date
Ruilin Geng dd06371929 feat(gates): 禁止插件入口新增值导出 (#7860)
* feat(gates): reject value exports on function plugin entries

A function plugin entry may export only the Loader fields (name, inject,
Config, apply), types, and classes whose instances extend Cordis Service or
Error, as docs/defensive-patterns/package-surface.md requires. The new
verify-plugin-entry-exports gate reads every packages/*/*/src/index.ts that
exports a value apply through the Host and then the Client compiler face,
and rejects any other value export, including a default export beside
apply, values that arrive through export *, and exports that do not resolve.

Exports that predate the gate are listed per package in
scripts/plugin-entry-existing-exports.ts. A listed export passes; a line
fails when its package has no function plugin entry, its list is empty or
repeats a name, or it names an export the entry no longer reports.

* docs(gates): mark new existing-export lines as rule exceptions

A line added to scripts/plugin-entry-existing-exports.ts after the gate's
introduction is an exception under the plugin entry rule in
docs/defensive-patterns/package-surface.md, which requires the domain
owner's confirmation.

* fix(gates): report a default export beside apply even when it is a class

The class allowance also covered the default export, so a function plugin
entry that default-exported a class extending Cordis Service or Error beside
apply passed the gate. The Loader then loads that default export instead of
the module namespace, which is the mixed plugin form the rule forbids. A
default export beside apply is now reported whatever it holds.

* fix(gates): judge plugin entry exports by their run-time export paths

The gate read TypeScript's export table, which differs from what the entry
exports at run time in two forms. An `export type { x }` hid a value that
`export *` brings in under the same name, although the type-only export is
erased and the value stays. A name that a nested `export type *` reaches was
reported as a value, although nothing reaches the entry at run time.

The gate now walks the emitted export forms: type-only exports and declare
declarations emit nothing, a re-export emits only a run-time export of its
target, and `export *` brings in every run-time name of its target except
default and the names the module exports itself. An `export *` whose module
does not resolve is reported as `*`.

* feat(gates): check service plugin entries for value exports

The plugin entry rule in docs/defensive-patterns/package-surface.md covers
both entry forms: a function plugin exports the Loader fields, a service
plugin default-exports its plugin class, and beyond those a Host entry may
export only Service Definition classes and error types. The gate checked
only function plugins, so a value on a service plugin entry, which another
package imports past the Loader row just the same, went unreported, and an
entry could escape the gate by default-exporting a class.

An entry without apply whose default export is a class the Loader can
construct is now a service plugin. Its default class passes under any name,
as do types and classes extending Cordis Service or Error; name, inject,
Config, and every other value are reported. Libraries, a default export
that is not a class, and an abstract default class, which defines a
capability seam, stay unchecked. The corpus guard now requires both forms.

The existing-export list is regenerated to cover the service plugin
entries' current value exports.

* fix(gates): admit the plugin entry export list as a plugin record name

The plugin entry export list now records the session service entry's
existing value exports, appendPluginRecord among them. Like the published
dependency policy, the list names the function without calling it, so the
plugin record caller gate admits it.

* chore(gates): list the plugin entry exports that landed on master

Master gained value exports on the plugin-manager, llm, and subagent
service entries and renamed office-to-pdf to office-kit before the gate
lands. They predate the gate, so the existing-export list records them.
2026-11-05 11:11:05 +00:00
Turtle 38c7a9fbf4 feat(release): publish package source, declaration maps, and documentation (#5884)
* feat(release): publish package source, declaration maps, and documentation

Every release member publishes its TypeScript source and the declaration
maps that resolve into it, and @deepseek-ai/dsh publishes the repository
Markdown documentation staged from docs/ at prepack time.

The ./src/* export most members already declared now resolves for an
installed consumer, and a consumer editor follows a declaration to the
implementation. Bundled JavaScript maps stay unpublished; the vendored
family and the Desktop runtime file policy are unchanged.

Rationale: .agents/notes/implemented/process/2026-10-08-published-source-and-docs.md

* feat(release): publish JavaScript maps and compress bundles

Every emitted JavaScript map ships beside the bundle it describes, and the
workspace build and the client preset compress bundles without mangling
identifiers.

The documentation payload now mirrors the website publication manifest and
is removed again by `postpack`; Desktop and the Python executable exclude
the published source, documentation, and maps; `clean` removes a staged
copy. Typert's publication contract gains the Remote declaration map.

* fix(release): keep node bundles readable for the worker image

The browser worker image lowers `yield*` only as a whole statement and
rewrites `for await` loops by their source layout, so compressed node-side
entries either fail that lowering or lower to unparseable code. Only the
browser bundles keep compression, which removes about a third of their text.

The bundle-purity assertion now matches the module-loader call regardless of
the quote style compression picks, and the release-pack fixture exercises
the installed package's new documentation requirement.

* feat(release): publish the whole documentation tree

`@deepseek-ai/dsh` copies `docs/` in full instead of the website's page
set: the maintainer documents, the generated migration records, the
translation guidelines, and the `*.i18n.yaml` consistency records ship
with the installed package, so the documentation's own links resolve
without a checkout.

* feat(release): publish the upgrade guides with the documentation

The staged documentation keeps the website's page set and adds every
`docs/upgrade-guide/` document, which is what an installed reader consults
when a released change breaks something. The rest of the maintainer tree
stays out.

* test(release): expect source and maps in master's new payload cases

* feat(release): keep installed docs and source readable in Desktop

Desktop keeps the published src/ and docs/ trees inside app.asar, and
every model shell call receives DSH_INSTALL_DIR and DSH_NODE_EXECUTABLE
so an agent can read them through Electron's Node mode. Staging also
generates docs/upgrade-guide/README.md, an index of the upgrade guides
grouped by the release they upgrade from.

Minified client bundles print string literals with backticks: the
worker image packer now recognizes those chunk requests, client license
banners are prepended after minification so their text survives, and
the affected artifact tests accept either quote.

* test(desktop): read archived docs through the Windows PowerShell form

Regenerate the config catalog for the shifted shell-env source line.

* test(desktop): wait for the GUI-subsystem Electron process from PowerShell

* build(release): publish source and maps from the message-quotes package

* build(release): publish source and maps from packages new on master

* build(release): publish source and maps from the tool-office package
2026-11-05 00:22:36 +08:00
Dudu-0223 43c4919f86 merge: refresh ID-only Team UI from core master updates 2026-10-30 15:13:05 +08:00
Dudu-0223 0eb1bb52e2 refactor(team): keep session UI and task tools keyed by IDs 2026-10-30 14:25:27 +08:00
liukx0205 c0b48f8961 fix(ci): bound CLI help children inside aggregate gates 2026-10-30 13:47:01 +08:00
imccyu b9266aefd6 Merge pull request #7094 from deepseek-harness/worktree/ci-schedule
ci: cut PR check latency across the slow lanes
2026-10-24 14:58:40 +08:00
gengruilin bc0069450f Merge remote-tracking branch 'origin/master' into docs/long-table-filter 2026-10-23 16:05:14 +08:00
07akioni 1552f524f7 fix(i18n): address translation, installer and coverage review findings 2026-10-22 22:14:47 +08:00
07akioni 84edeadc2b feat(i18n): add Spanish French German Russian and Portuguese 2026-10-22 19:53:52 +08:00
07akioni 11295990b5 fix(i18n): cover nested metadata and repair locale CI regressions 2026-10-21 17:00:42 +08:00
07akioni 9ce74cda96 feat(desktop): localize Windows installer with per-language JSON resources 2026-10-21 16:43:19 +08:00
07akioni 87c4de2e43 chore(i18n): limit added locale checks to JSON metadata 2026-10-21 16:22:53 +08:00
07akioni ed783066e6 fix(i18n): complete Japanese plugin metadata and guard locale coverage 2026-10-21 16:14:12 +08:00
Tianyi Cui cfb65d3bb2 fix: validate the Node 24.9 runtime floor 2026-10-15 23:33:49 +08:00
Tianyi Cui c6a59a1ae9 build: require Node.js 24 or newer 2026-10-15 22:51:03 +08:00
imccyu b77cc1c0f2 feat(gates): reject module-scope await in package sources
Package modules that other code imports must not suspend evaluation at module scope. A syntax-aware gate scans packages/*/*/src and excludes only executables (a shebang or a package bin target). The SenseVoice worker, the SSH helper entry, and the Inspector worker entry now run an explicit main().
2026-10-15 03:56:25 +08:00
Magolor 7110b615eb fix(llm): 生成提供方元数据并显示凭据检测状态 (#6106)
* fix(llm): generate provider metadata and clarify credential hints

* fix(settings): shorten credential hints and mark detected sources in green

* fix(llm): verify staged provider metadata and document regeneration

* fix(provider-metadata): reconcile authentication hints and key controls

* test(user-text): calibrate ratio headroom across unmatched workloads

* test(gates): include provider metadata in hygiene expectations

* fix(models): hide authentication hints for entered keys
2026-10-14 12:29:31 +08:00
gengruilin 568f12ea42 wip(docs): 保存长表筛选与固定表头实现 2026-10-13 01:53:50 +08:00
imccyu ad43b1f7da docs: state that the documentation aggregate cap applies in CI
doc-sync, test:docs, hygiene, and check:all run at most 8 gates in CI as
well; the constant, the development guide, and the Agent Note now say so.
The Note also states that the source-only Typert guard rejects unresolved
workspace imports, so a missing alias fails before or after host-src.

Refs #5852
2026-10-12 11:06:56 +08:00
imccyu ed7bf8cc42 perf(gates): cap local default worker counts
os.availableParallelism() reports host CPUs rather than a container's
CPU quota (256 against a 64-CPU quota here), so local defaults spawned
255 Vitest forks (55 GiB peak RSS) and oversubscribed every scheduler.
scripts/parallelism.ts keeps the CPU count in CI and caps other runs at
12, or 48 for Vitest forks and the local coverage budget; documentation
and hygiene aggregates run up to 8 gates instead of 4. Explicit
DSH_GATE_CONCURRENCY, DSH_OXLINT_THREADS, DSH_COVERAGE_MAX_WORKERS, and
--maxWorkers still win.

Refs #5852
2026-10-12 11:06:50 +08:00
imccyu 04af9a1df7 perf(build): generate Typert contracts without bundling for typecheck and lint
Type checks only need Host declarations and Typert-generated
declarations, but typecheck, lint, lint:fix, doc-typecheck, and the CI
typert-contracts gate rebuilt the whole Host tsdown pass, Desktop bundle
included, to obtain them. A source-only scripts/generate-typert.ts now
runs the same generator and artifact writer as the tsdown plugin, beside
Host package compilation: Typert reads only sources once the missing
@deepseek-ai/dsh-client-file-upload/types path alias exists, and
rejectBuildOutputs fails the pass when a workspace lib/ declaration
enters its program. typecheck runs as a build.ts scope that checks both
aggregates in build mode after their own face compiles.

Refs #5852
2026-10-12 11:06:49 +08:00
imccyu f6b0c5af59 build: rename build:src and build:test to build:artifacts and build:check
build:artifacts produces every artifact, including the tsdown bundles,
the Desktop bundle, and Web, so naming it after sources undersold it;
build:check checks scripts, benchmarks, and website code besides tests.
The build.ts scopes, aggregate step ids, the Python builder flag
(--build-artifacts), workflows, callers, docs, and the build-split Agent
Note follow the new names. The note also records the naming
alternatives.

Refs #5852
2026-10-11 22:16:47 +08:00
imccyu 129c915498 build: split build:src and build:test, and schedule build in parallel
pnpm run build ran every step in one serial chain, including the two
noEmit aggregate programs (tests, scripts, benchmarks, website) that no
artifact step consumes, so the Host aggregate check alone delayed tsdown by
about 66 s.

- build:src (scripts/build.ts --scope src) builds every artifact in the
  existing order and writes the client build record; it replaces the
  removed --artifacts-only flag and the libraries CLI mode.
- build:test (--scope test) type-checks only the Host and Client aggregate
  programs with tsc -p, concurrently, without compiling references or
  checking prerequisites.
- build runs both as one dependency graph through run-gates' new
  runAggregate: each aggregate check starts once its face's packages are
  compiled, and Client compilation stays after the Host bundle that writes
  the Typert /remote declarations. DSH_GATE_CONCURRENCY=1 serializes it;
  DSH_GATE_FAIL_FAST=1 stops the remaining steps at the first failure.
  Passing steps print one PASS line (DSH_GATE_VERBOSE=1 shows their output).
- PR artifact builds (e2e, release, preview, Node 22 compatibility) and the
  Python builder (--build-src) use build:src; dev:web and dev:desktop use
  build:src. test:*, bench, typecheck and the required consumer/Windows
  lanes keep the complete build.
- lint, lint:fix, doc-typecheck and the Typert contracts gate prepare with
  host-libraries (Host package compilation + Host bundle) instead of
  build:lib:host; their own checks never read the aggregate root or the
  Desktop bundle.

Parallel and serial build produce byte-identical lib/, Web dist and client
build record; a test-only type error fails build and build:test while
build:src passes.

Refs #5852
2026-10-11 18:19:23 +08:00
Tianyi Cui 8ed0b530ed feat(plugins): offer official bundles through on-demand installation 2026-10-07 01:26:00 +08:00
Tianyi Cui b48384223a refactor(experimental)!: classify optional packages and move prototypes 2026-10-06 16:41:04 +08:00
Tianyi Cui 8f3959a196 Merge branch 'master' into worktree/client-control/cli-help-reference 2026-10-06 10:59:23 +08:00
Tianyi Cui 8a7d5014bf Merge pull request #5716 from deepseek-harness/worktree/pr-ci-speed-independent-20261005
perf(ci): reduce repeated compilation without raising concurrency
2026-10-05 19:35:09 +08:00
Tianyi Cui 75935af1d0 feat(cli): generate the CLI help reference and add dsh plugin help
`scripts/gen-cli-help.ts` runs the source `dsh` launcher with temporary
Harness and Agents homes and captures the launcher, `dsh plugin`, and every
shipped profile's text help (profile names come from `PROFILE_TEMPLATES`).
It recursively discovers subcommands from each page's `Commands:` section,
shows identical alias help once with every invocation, and writes
`docs/cli-help.md`, its Chinese page, and their pairing record. The record
resolves links between the two pages as written, so a first run already
matches `verify-translation-pairing`. `verify-cli-help` checks all three
files and runs as the `cli-help` doc-sync leaf, which the static CI lane
also runs on an unbuilt tree.

`dsh plugin` now owns `-h`/`--help` and reads its own options only before
the forwarded pnpm arguments: `dsh plugin --help` prints its help instead of
failing on the missing `--profile`, while everything after the pnpm command
(including `-h`, `--help`, and `--profile`) reaches pnpm verbatim. A
`--profile` placed after the pnpm command is no longer accepted; the
v0.2.1-alpha.1 upgrade guide covers the migration.

Refs #4114
2026-10-05 17:45:17 +08:00
Tianyi Cui be28d4c15c perf(ci): consolidate compatibility startup within one worker 2026-10-05 14:15:56 +08:00
Tianyi Cui 536aaef0b3 fix(ci): preserve workflow concurrency and portable artifact checks 2026-10-05 12:53:52 +08:00
Tianyi Cui 853ad0bb9f perf(ci): remove repeated aggregate compilation and gate work 2026-10-05 12:07:57 +08:00
Tianyi Cui 75542dd10a feat(session): let experimental packages append plugin records
Add appendPluginRecord(), which appends one ignorable event whose type is
`plugin:` followed by lowercase slash-separated segments, and
pluginRecordOf(), which reads such an event back. Records are not
SessionEventMap members, so the persistence catalog is unchanged; a build
that does not recognize one retains and skips it, and records never enter
the model-visible surface. Resume and fork carry them with the log, and a
format migration keeps them on a best-effort basis.

Only production source under packages/experimental/ may call the writer.
The verify-plugin-record-callers hygiene gate checks every reference in
repository sources, and the persistence catalog generator rejects a
SessionEventMap member in the plugin: namespace.

Session.append() and the record writer share one commit path, so a record
follows the same reentrancy, detach, and observer-containment rules. The
ignorable-events decision, the session README, the format-version
cookbook, and the plugin-author practices describe the records.
2026-10-05 08:57:58 +08:00
Turtle 819eb8078e Merge origin/master into turtle/remove-invariants-ccf1396aaf61 2026-10-01 16:33:09 +08:00
Tianyi Cui c7f66d13a6 docs(notes): prune redundant active decision records 2026-09-30 23:20:22 +08:00
turtle1999 fe56439edc refine(ci): keep Electron preparation independent of build 2026-09-30 17:57:24 +08:00
turtle1999 40133c707f fix(ci): provision Electron before Windows coverage 2026-09-30 17:57:24 +08:00
Turtle f028f25667 refactor: remove runtime invariant plugins
Delete @deepseek-ai/dsh-invariants, every package's ./invariant companion
and its tests, the invariant gates and Vitest setup, the scoped-event
resolver generator, and the INVARIANT-coded listener rethrow paths.
Update docs, READMEs, Agent Notes, and add an upgrade guide.
2026-09-30 12:52:18 +08:00
turtle1999 41a869e33a Merge commit 'c413bb92ee765460eeeb2644234180459e561f65' into fix/master-ci-windows-acl 2026-09-29 13:32:00 +08:00
Turtle 17da46e4f3 Merge pull request #5389 from deepseek-harness/docs/upgrade-guide-structure
docs: add upgrade guide structure, skill, and gate
2026-09-29 13:10:23 +08:00
turtle1999 ffab80f0cc merge: integrate master CI reliability fixes 2026-09-29 12:39:34 +08:00
turtle1999 9cd1264115 Merge branch 'master' into docs/upgrade-guide-structure 2026-09-29 10:19:14 +08:00
turtle1999 374f7df31b chore(ci): align proxy opt-in and clarify test contracts 2026-09-29 01:07:38 +08:00
Tianyi Cui f4d8115b4a merge: master into lane-budget-inline-projects
Resolves the semantic conflict with #5331: its ci-unit gate spread
coverageTestTimeoutArgs, which this branch retires; the gate is now a
plain vitest run and the darwin lane budget reaches vitest.config.ts
through the inherited DSH_COVERAGE_TEST_TIMEOUT_MS. The ci-unit spec
cases pin that shape under both budget values.
2026-09-28 23:25:21 +08:00
turtle1999 6790ad428d Merge commit '50daf9d60e356dfe02e1ea302c3fb45f971e1eba' into fix/master-ci-windows-acl 2026-09-28 23:23:00 +08:00
Tianyi Cui 7b30c81614 Merge pull request #5331 from deepseek-harness/ci/unit-darwin-lane-budget-20260928
ci(sandbox): grant the darwin unit parity job the coverage lanes' test budget
2026-09-28 23:10:50 +08:00
turtle1999 3545e9a2a6 fix(ci): provision Electron before Windows smoke tests 2026-09-28 21:13:12 +08:00
turtle1999 23d3807ae1 docs: add upgrade guide structure, skill, and gate
Introduce docs/upgrade-guide/v<version>/<item>/guide.md for externally
perceptible breaking changes. The dsh-create-upgrade-guide skill owns scope,
placement, maintenance, and format; verify-upgrade-guides enforces layout,
frontmatter, sections, and the 500-word ceiling. Guides are English-only and
registered as the upgrade-guide document kind.
2026-09-28 19:12:16 +08:00
Tianyi Cui 3e38e2118c test(vitest): make the lane-budget regression load-independent and own its resources
The fixture's poll case counts attempts instead of reading a clock, so a host
stall cannot turn a budget-ended poll into a pass; the control case reads the
poll's reported duration, which the 1000 ms default bounds from below. The
spawning spec acquires its temporary config in beforeAll, bounds the child
with a timeout and asserts no signal ended it, and counts the polled values it
inspects. CoverageTestTimeoutOptions is Vitest's own TestUserConfig members;
the rule's reach has one home in its JSDoc, which the config, gate, spec, and
note comments reference.
2026-09-28 14:18:03 +08:00
Tianyi Cui 333d7e75d2 test(vitest): apply the lane test budget inside every inline project
DSH_COVERAGE_TEST_TIMEOUT_MS expanded to --testTimeout, --hookTimeout, and
--expect.poll.timeout on the coverage and serial lanes, but Vitest forwards
only a fixed list of CLI overrides into inline projects and neither
hookTimeout nor expect is on it, so under the root config's two projects the
hook and expect.poll budgets stayed at Vitest's defaults on every lane.

vitest.config.ts now reads the variable through coverageTestTimeoutOptions and
spreads the three budgets into both projects; run-gates and the partition
coordinator pass no timeout flags, leaving one owner for the rule. A new spec
spawns vitest on the root config with a 200 ms budget and proves all three
waits end inside both projects, that unset keeps the defaults, and that a
malformed value fails at config load.

Fixes #5335
Related to #5325
2026-09-28 13:37:20 +08:00
Tianyi Cui 0976d15122 test(run-gates): own the coverage-gate environment in the spec and pin ci-unit to the test script
run-gates.spec.ts clears DSH_COVERAGE_PARTITIONS and DSH_COVERAGE_MAX_WORKERS
before each case, so the coverage gates it builds take their shape from the
case, not from a partitioned lane that exports the variables to every child.
The ci-unit case derives its two gates from the `test` package script's
segments. The serial-reference note keeps only the lane fact; the mechanism
fact about inline-project inheritance is owned by the fix that changes it.
2026-09-28 13:28:31 +08:00