mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts: # .agents/notes/archived/feature/2026-07-28-dsh-guided-skill-session-commands.i18n.yaml # .agents/notes/archived/manifest.json # .agents/notes/implemented/bug-fix/2026-07-29-human-transcript-append-origin.i18n.yaml # .agents/notes/implemented/feature/2026-07-05-skill-system.i18n.yaml # apps/cli/tests/snapshots/multi-turn-conversation/terminal.expected.txt # apps/cli/tests/snapshots/queued-manual-compact/terminal.expected.txt # apps/cli/tests/tui-keyless-smoke.e2e.ts # apps/cli/tests/tui.snapshot.ts # docs/architecture.i18n.yaml # docs/architecture.md # docs/architecture.zh.md # docs/cookbook/extension-cookbook.i18n.yaml # docs/event-producer-consumer.md # packages/ui/tui/README.i18n.yaml # packages/ui/tui/README.md # packages/ui/tui/README.zh.md # packages/ui/tui/src/index.ts # packages/ui/tui/tests/harness.ts # packages/ui/tui/tests/session-reference.snapshot.ts # packages/ui/tui/tests/snapshots/conversation-streaming.expected.txt # packages/ui/tui/tests/snapshots/details-command.expected.txt # packages/ui/tui/tests/snapshots/details-selector.expected.txt # packages/ui/tui/tests/snapshots/disposed-terminal.expected.txt # packages/ui/tui/tests/snapshots/errors-and-help.expected.txt # packages/ui/tui/tests/snapshots/status-diagnostics-narrow.expected.txt # packages/ui/tui/tests/snapshots/status-diagnostics.expected.txt # packages/ui/tui/tests/snapshots/surface-after-compaction-narrow.expected.txt # packages/ui/tui/tests/snapshots/surface-after-compaction-wide.expected.txt # packages/ui/tui/tests/snapshots/surface-before-compaction.expected.txt # packages/ui/tui/tests/snapshots/surface-replayed-compaction.expected.txt # packages/ui/tui/tests/snapshots/todo-plan-cleared.expected.txt # packages/ui/tui/tests/snapshots/tool-cards-hidden-folded.expected.txt # packages/ui/tui/tests/snapshots/untrusted-controls.expected.txt # packages/ui/tui/tests/tui.snapshot.ts # packages/ui/tui/tests/tui.spec.ts
This commit is contained in:
@@ -254,10 +254,6 @@ class SingleExeBuild {
|
||||
'--config.node-linker=hoisted',
|
||||
'--config.auto-install-peers=false',
|
||||
'--config.link-workspace-packages=true',
|
||||
// The production closure intentionally omits the patched dev-only
|
||||
// @earendil-works/pi-tui package. The root frozen install still validates
|
||||
// every patch; this exception is scoped only to the production deploy.
|
||||
'--config.allow-unused-patches=true',
|
||||
this.staging,
|
||||
])
|
||||
if (this.cli.dryRun) {
|
||||
|
||||
@@ -97,7 +97,6 @@ function workspaceManifests(): WorkspaceManifest[] {
|
||||
|
||||
const packageFileExtras: Readonly<Record<string, readonly string[]>> = {
|
||||
'@deepseek-ai/dsh-helper': ['lib/assets'],
|
||||
'@deepseek-ai/dsh-tui': ['lib/prompt.js'],
|
||||
'@deepseek-ai/dsh-scripts': [
|
||||
'lib/dev/tsdown-config.js',
|
||||
'lib/local-plugin-loader-hooks.js',
|
||||
|
||||
@@ -278,8 +278,6 @@ export const TYPE_LINK_EXEMPTIONS: Readonly<Record<string, string>> = {
|
||||
WebRoute: 'route registration contract is owned by packages/host/webserver/src/index.ts',
|
||||
ThemeTokens: 'service-local token dictionary is owned by packages/client/ui-theme/src/index.ts',
|
||||
Translate: 'service-local bound translator is owned by packages/client/i18n/src/index.ts',
|
||||
TuiOverlayRequest: 'service-local extension contract is owned by packages/ui/tui/README.md',
|
||||
TuiOverlaySession: 'service-local extension contract is owned by packages/ui/tui/README.md',
|
||||
InvariantRegistration: 'service-local lifecycle handle is owned by packages/support/invariants/README.md',
|
||||
PresetOption: 'deployment menu metadata is owned by packages/ui/permission/README.md',
|
||||
PresetSpec: 'deployment preset composition is owned by packages/ui/permission/README.md',
|
||||
|
||||
@@ -218,7 +218,6 @@ const SERVICE_ROLES: ServiceRole[] = [
|
||||
pkg: 'session-reference',
|
||||
title: 'Cross-session snapshot preparation',
|
||||
mode: 'core',
|
||||
consumers: ['tui'],
|
||||
note: 'Projects bounded current-surface conversation snapshots into durable untrusted message context; host adapters own mention syntax.',
|
||||
},
|
||||
{
|
||||
@@ -250,8 +249,7 @@ const SERVICE_ROLES: ServiceRole[] = [
|
||||
pkg: 'user-interaction',
|
||||
title: 'Human question/answer seam',
|
||||
mode: 'seam',
|
||||
implementations: ['tui'],
|
||||
consumers: ['tool-ask-user', 'tui'],
|
||||
consumers: ['tool-ask-user'],
|
||||
note: 'UI front doors provide the active human-answer provider; tool-ask-user pauses a tool call on the provider-neutral ask() promise.',
|
||||
},
|
||||
{
|
||||
@@ -266,8 +264,7 @@ const SERVICE_ROLES: ServiceRole[] = [
|
||||
pkg: 'commands',
|
||||
title: 'Human command registry',
|
||||
mode: 'core',
|
||||
consumers: ['tui'],
|
||||
note: 'Plugins register direct human commands; TUI consumes the effective per-agent catalog without sending invocations to the model.',
|
||||
note: 'Plugins register direct human commands without sending invocations to the model.',
|
||||
},
|
||||
{
|
||||
key: 'sessionProjections',
|
||||
@@ -285,13 +282,6 @@ const SERVICE_ROLES: ServiceRole[] = [
|
||||
consumers: ['host-apiproxy'],
|
||||
note: 'Durably checkpoints projection unit states per session (throttled + turn/end/detach mandatory points) and serves the cold-read ladder: cache row + persistence tail replay, so listings never load full logs.',
|
||||
},
|
||||
{
|
||||
key: 'tui',
|
||||
pkg: 'tui',
|
||||
title: 'Mounted-terminal interaction service',
|
||||
mode: 'bundle',
|
||||
note: 'One TUI front door provides a FIFO overlay host; injected plugins receive caller-fiber ownership without access to pi-tui or terminal lifecycle state.',
|
||||
},
|
||||
{
|
||||
key: 'skills',
|
||||
pkg: 'skill',
|
||||
@@ -306,7 +296,7 @@ const SERVICE_ROLES: ServiceRole[] = [
|
||||
pkg: 'agent',
|
||||
title: 'Agent service',
|
||||
mode: 'core',
|
||||
consumers: ['agent-loop', 'acp', 'cli-demo', 'subagent-inprocess', 'tui-demo'],
|
||||
consumers: ['agent-loop', 'acp', 'cli-demo', 'subagent-inprocess'],
|
||||
note: 'Owns live Agent handles, the create/resume factory seam, and process-local initiator propagation.',
|
||||
},
|
||||
{
|
||||
@@ -626,12 +616,12 @@ function stripYamlScalar(value: string): string {
|
||||
|
||||
const APP_EXAMPLES = [
|
||||
{
|
||||
id: 'tui',
|
||||
id: 'dsh_base',
|
||||
rel: 'apps/cli/composition.md',
|
||||
title: 'TUI Agent App Composition',
|
||||
label: 'apps/cli/config',
|
||||
title: 'DSH Base Composition',
|
||||
label: 'apps/cli/config/base.cordis.yml',
|
||||
config: 'apps/cli/config/base.cordis.yml',
|
||||
summary: 'The TUI surface combines the shared CLI base with its surface overlay and full-screen terminal package.',
|
||||
summary: 'The raw CLI applies one required caller-selected patch list over this shared base; Web and headless apply their own shipped overlays.',
|
||||
},
|
||||
{
|
||||
id: 'headless',
|
||||
@@ -658,9 +648,7 @@ function renderAppExpansion(lines: string[], appNode: string, pluginName: string
|
||||
const jsonl = nodeId('bundle', 'jsonl')
|
||||
lines.push(` ${appNode} --> ${agentCore}["@deepseek-ai/dsh-agent-spine-demo"]`)
|
||||
lines.push(` ${appNode} --> ${jsonl}["@deepseek-ai/dsh-session-persistence-jsonl"]`)
|
||||
if (pluginName === '@deepseek-ai/dsh-tui-demo') {
|
||||
lines.push(` ${appNode} --> ${nodeId('frontdoor', 'tui')}["@deepseek-ai/dsh-tui<br/>pre-created main agent"]`)
|
||||
} else if (pluginName === '@deepseek-ai/dsh-cli-demo') {
|
||||
if (pluginName === '@deepseek-ai/dsh-cli-demo') {
|
||||
lines.push(` ${appNode} --> ${nodeId('frontdoor', 'cli')}["one-shot driver<br/>format-pure stdout<br/>fresh top-level agent"]`)
|
||||
} else if (pluginName === '@deepseek-ai/dsh-acp-demo') {
|
||||
lines.push(` ${appNode} --> ${nodeId('frontdoor', 'acp')}["@deepseek-ai/dsh-acp<br/>automation-only JSON-RPC stdio<br/>fresh sessions created by client"]`)
|
||||
@@ -688,7 +676,7 @@ function renderAppComposition(example: AppExample): string {
|
||||
const pluginNode = nodeId(`plugin_${example.id}`, plugin.id)
|
||||
lines.push(` ${pluginNode}["${escLabel(plugin.id)}<br/>${escLabel(plugin.name)}"]`)
|
||||
lines.push(` cfg --> ${pluginNode}`)
|
||||
if (plugin.name === '@deepseek-ai/dsh-tui-demo' || plugin.name === '@deepseek-ai/dsh-cli-demo' || plugin.name === '@deepseek-ai/dsh-acp-demo') {
|
||||
if (plugin.name === '@deepseek-ai/dsh-cli-demo' || plugin.name === '@deepseek-ai/dsh-acp-demo') {
|
||||
renderAppExpansion(lines, pluginNode, plugin.name)
|
||||
}
|
||||
}
|
||||
@@ -1311,8 +1299,8 @@ function renderDocs(): GraphDoc[] {
|
||||
function renderIndex(docs: GraphDoc[]): string {
|
||||
const labels: Record<string, string> = {
|
||||
'docs/capability-seams.md': 'capability seams and core services',
|
||||
'apps/cli/composition.md': 'dsh shared base composition',
|
||||
'examples/headless-agent/composition.md': 'headless-agent app composition',
|
||||
'examples/tui-agent/composition.md': 'tui-agent app composition',
|
||||
'examples/cordis-agent/composition.md': 'cordis-agent app composition',
|
||||
'examples/acp-agent/composition.md': 'acp-agent app composition',
|
||||
'docs/event-producer-consumer.md': 'event producer/consumer matrix',
|
||||
@@ -1321,8 +1309,8 @@ function renderIndex(docs: GraphDoc[]): string {
|
||||
}
|
||||
const modes: Record<string, string> = {
|
||||
'docs/capability-seams.md': 'hybrid generated',
|
||||
'apps/cli/composition.md': 'hybrid generated',
|
||||
'examples/headless-agent/composition.md': 'hybrid generated',
|
||||
'examples/tui-agent/composition.md': 'hybrid generated',
|
||||
'examples/cordis-agent/composition.md': 'hybrid generated',
|
||||
'examples/acp-agent/composition.md': 'hybrid generated',
|
||||
'docs/event-producer-consumer.md': 'hybrid generated',
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
# `pnpm install`, points the stable `~/.dsh/source/current` symlink
|
||||
# at that staging worktree and symlinks `dsh` onto PATH at `current/bin/dsh`,
|
||||
# records your API credentials in the Harness home (`~/.dsh`) dsh reads at boot,
|
||||
# and lets you launch the Web UI or TUI. The Web choice builds the repository
|
||||
# artifacts first; the TUI runs directly from TypeScript source through the
|
||||
# repo's own tsx. Keeping every checkout under ~/.dsh/source keeps successive
|
||||
# builds the repository artifacts, and launches the Web UI. Keeping every
|
||||
# checkout under ~/.dsh/source keeps successive
|
||||
# upgrades in one place instead of scattered sibling clones, and lets staging
|
||||
# worktrees share the master clone's object store. The PATH symlink resolves through
|
||||
# `current`, so an upgrade repoints one stable symlink instead of relinking PATH:
|
||||
@@ -414,33 +413,15 @@ if [ "${SKIP_CREDS:-0}" != 1 ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- 6. choose and launch an interface -----------------------------------------
|
||||
# --- 6. build and launch the Web interface -------------------------------------
|
||||
step "Done"
|
||||
if [ "$HAS_TTY" = 1 ]; then
|
||||
printf ' 1) Web UI (recommended)\n'
|
||||
printf ' 2) TUI\n'
|
||||
while :; do
|
||||
LAUNCH_INTERFACE=$(ask "Choose an interface [1/2]:" 1)
|
||||
case "$LAUNCH_INTERFACE" in
|
||||
1|web|Web|WEB)
|
||||
step "Building DeepSeek Harness for Web UI"
|
||||
( cd "$DSH_STAGING" && pnpm run build )
|
||||
info "launching Web UI — run 'dsh web' anytime to start again"
|
||||
exec "$DSH_BIN_DIR/dsh" web </dev/tty
|
||||
;;
|
||||
2|tui|Tui|TUI)
|
||||
info "launching TUI — run 'dsh' anytime to start again"
|
||||
exec "$DSH_BIN_DIR/dsh" </dev/tty
|
||||
;;
|
||||
*)
|
||||
warn "choose 1 for Web UI or 2 for TUI"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
step "Building DeepSeek Harness for Web UI"
|
||||
( cd "$DSH_STAGING" && pnpm run build )
|
||||
info "launching Web UI — run 'dsh web' anytime to start again"
|
||||
exec "$DSH_BIN_DIR/dsh" web </dev/tty
|
||||
else
|
||||
info "install complete. Build and start the Web UI with:"
|
||||
printf ' (cd %s && pnpm run build)\n' "$DSH_STAGING"
|
||||
printf ' %s web\n' "$DSH_BIN_DIR/dsh"
|
||||
info "or start the TUI with:"
|
||||
printf ' %s\n' "$DSH_BIN_DIR/dsh"
|
||||
fi
|
||||
|
||||
@@ -594,7 +594,7 @@ function builtBinSmokeGate(needs: string[] = ['build']): Gate {
|
||||
'--config',
|
||||
'vitest.e2e.config.ts',
|
||||
'examples/headless-agent/tests/keyless-smoke.e2e.ts',
|
||||
'apps/cli/tests/tui-keyless-smoke.e2e.ts',
|
||||
'apps/cli/tests/built-bin.e2e.ts',
|
||||
'packages/examples/cli-demo/tests/built-bin.e2e.ts',
|
||||
'packages/examples/acp-demo/tests/built-bin.e2e.ts',
|
||||
'packages/ui/jsonrpc/tests/built-scope-carrier.e2e.ts',
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user