refactor: relocate demo app bundles to packages/examples/*-demo

Move the agent-spine bundle and the stdio/ACP/JSON-RPC app packages out of
core/ and ui/ into a new packages/examples/ group, renamed with a -demo
suffix so the npm name marks them as non-product surface:

  core/agent-core   -> examples/agent-spine-demo  (dsh-agent-spine-demo)
  ui/stdio-agent    -> examples/stdio-demo        (dsh-stdio-demo)
  ui/acp-agent      -> examples/acp-demo          (dsh-acp-demo)
  ui/jsonrpc-agent  -> examples/jsonrpc-demo      (dsh-jsonrpc-demo)

Update every code/config/test reference and reference-only doc mentions, and
regenerate module-graph, config-catalog, and doc-graphs. The jsonrpc bin
(dsh-jsonrpc-agent) and single-file exe (dsh-jsonrpc-agent-pkg) keep their
names; the SDK runtime-startup surface is reconciled separately.
This commit is contained in:
imccyu
2026-07-15 15:57:57 +08:00
parent c2a0ca1927
commit 6f77da4c8c
118 changed files with 492 additions and 490 deletions
+27
View File
@@ -0,0 +1,27 @@
# @deepseek-ai/dsh-jsonrpc-demo
Bin-only app that boots an external `cordis.yml`; its [`jsonrpc`](../jsonrpc/README.md) entry serves SDK clients over newline-delimited stdio. The config composes the spine, backends, and serving plugin. `lib/bin.js` is also the [single-executable runtime](../../../docs/rfc/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md) entry.
## Config discovery
The first non-empty channel wins: `$DSH_CORDIS_CONFIG`, then positional `argv[2]`. If neither names an existing file, the bin prints one-line usage to stderr and exits 1; there is no working-directory or built-in fallback. [`dsh-app-boot`](../app-boot/README.md) makes plugin load failures fatal. This protocol does not use `DSH_SNAPSHOT`.
A config without `dsh-jsonrpc` is valid and serves nothing; the bin does not designate a server plugin.
## Exit lifecycle
stdin EOF and `SIGTERM` dispose the root to quiescence and exit 0; `SIGINT` exits 130 after the same disposal. EOF may cut off an in-flight turn as documented in the [distribution RFC](../../../docs/rfc/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md). The `jsonrpc` plugin owns response-before-exit protocol shutdown; both paths are idempotent and safe to race.
## stdout is the protocol
stdout carries only JSON-RPC frames. The bin and boot guards diagnose on stderr, and the config must omit stdout loggers.
## Model Experience
Indirectly, through the plugins loaded from the external `cordis.yml`, which own every model-bound prompt, schema, message, and result; this bin adds none of its own.
## Known Limitations and Deferred Work
- **The bin cannot prove that the config serves JSON-RPC** — a valid config with no `dsh-jsonrpc` entry boots successfully and serves nothing.
- **No built-in or default config exists** — every launch must provide `DSH_CORDIS_CONFIG` or a positional path, and deployment owns the complete plugin tree and stdout discipline.
- **stdin EOF cuts off in-flight work** — client disappearance disposes the root immediately; callers that need orderly completion use the protocol-level `shutdown` request.
@@ -0,0 +1,41 @@
{
"name": "@deepseek-ai/dsh-jsonrpc-demo",
"description": "Bin that boots an external Cordis config for the stdio JSON-RPC SDK runtime",
"version": "0.0.1",
"private": true,
"type": "module",
"main": "lib/index.js",
"types": "lib/types/index.d.ts",
"bin": {
"dsh-jsonrpc-agent": "lib/bin.js"
},
"exports": {
".": {
"types": "./lib/types/index.d.ts",
"default": "./lib/index.js"
},
"./bin": {
"types": "./lib/types/bin.d.ts",
"default": "./lib/bin.js"
},
"./src/*": "./src/*",
"./package.json": "./package.json"
},
"files": [
"lib/index.js",
"lib/bin.js",
"lib/types/**/*.d.ts",
"lib/types/**/*.d.ts.map",
"src"
],
"license": "BSD-3-Clause",
"dependencies": {
"@deepseek-ai/dsh-app-boot": "workspace:^"
},
"peerDependencies": {
"cordis": "^4.0.0-rc.7"
},
"devDependencies": {
"cordis": "^4.0.0-rc.7"
}
}
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env node
/**
* Boots an external `cordis.yml`; its `@deepseek-ai/dsh-jsonrpc` entry serves
* newline-delimited JSON-RPC on stdio. `$DSH_CORDIS_CONFIG` wins over `argv[2]`;
* empty or missing paths exit 1, with no default config or `DSH_SNAPSHOT` mode.
* App-boot owns env loading, Loader guards, and settled-tree startup.
* stdin EOF and SIGTERM dispose the root context and exit 0; SIGINT exits 130.
* Protocol `shutdown` belongs to the server plugin. Stdout is reserved for frames.
*
* @module @deepseek-ai/dsh-jsonrpc-demo/bin
*/
import { existsSync } from 'node:fs'
import { boot, installFailLoud, loadEnv, resolveConfigPath } from '@deepseek-ai/dsh-app-boot'
const NAME = 'dsh-jsonrpc-agent'
/* v8 ignore start -- composition over tested app-boot/jsonrpc and executable acceptance paths */
installFailLoud(NAME)
loadEnv(NAME)
// Env wins over argv; empty values are absent. External config defines the deployment.
const fromEnv = process.env['DSH_CORDIS_CONFIG']
const fromArgv = process.argv[2]
const requested = fromEnv !== undefined && fromEnv !== ''
? fromEnv
: fromArgv !== undefined && fromArgv !== '' ? fromArgv : undefined
const configPath = requested === undefined ? undefined : resolveConfigPath(requested, undefined)
if (configPath === undefined || !existsSync(configPath)) {
process.stderr.write(
`usage: ${NAME} <path/to/cordis.yml> (or set DSH_CORDIS_CONFIG=<path>, which wins); the config is required — there is no built-in fallback\n`,
)
process.exit(1)
}
const ctx = await boot(NAME, configPath)
let exiting = false
async function disposeAndExit(code: number): Promise<void> {
if (exiting) return
exiting = true
try {
await ctx.fiber.dispose()
} finally {
process.exit(code)
}
}
process.stdin.on('end', () => { void disposeAndExit(0) })
process.on('SIGTERM', () => { void disposeAndExit(0) })
process.on('SIGINT', () => { void disposeAndExit(130) })
/* v8 ignore stop */
@@ -0,0 +1,9 @@
/**
* Bin-only app package: `bin.ts` discovers an external `cordis.yml` and owns
* process exit. This module exports no composition plugin; the config chooses
* whether to load the {@link @deepseek-ai/dsh-jsonrpc} serving plugin.
*
* @module @deepseek-ai/dsh-jsonrpc-demo
*/
export {}
@@ -0,0 +1,21 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "lib/types"
},
"include": [
"src"
],
"references": [
{
"path": "../../../vendor/cordis"
},
{
"path": "../../../vendor/loader"
},
{
"path": "../../ui/app-boot"
}
]
}
@@ -0,0 +1,15 @@
import { defineConfig } from 'tsdown'
/**
* Build the doc-only module and CLI entry; `tsc -b` supplies declarations.
*/
export default defineConfig({
entry: ['lib/types/index.js', 'lib/types/bin.js'],
outDir: 'lib',
format: ['esm'],
platform: 'node',
target: 'es2024',
fixedExtension: false,
dts: false,
clean: false,
})