Merge remote-tracking branch 'origin/master' into feat/web-message-feedback-ui

Adapt to two contract changes master introduced:

- The generated Remote face now wraps every business result in
  RemoteResult, folding carrier failures into an ok:false branch instead
  of rejecting. The controller reads that envelope at its three call
  sites and maps a carrier failure onto the same settled shape the
  controls already render; three specs cover the new branch.
- Client packages split their tsconfig into host and client halves, and
  the host aggregate now compiles any test not named *.client.spec.*.
  Rename this package's specs to the client convention and drop the
  ../connection project reference, which pointed at a solution file that
  no longer carries the client sources.

Keep master's mount loop with its rollback-on-failure in api-remotes and
add messageFeedbackRemote to it.
This commit is contained in:
Chinesezjc
2026-08-12 10:43:23 +08:00
parent 47f254a252
commit b462d5fd69
507 changed files with 3130 additions and 2238 deletions

View File

@@ -30,6 +30,14 @@
"types": "./lib/types/brand.d.ts",
"default": "./lib/types/brand.js"
},
"./typert": {
"types": "./lib/typert.host.d.ts",
"default": "./lib/typert.host.js"
},
"./remote": {
"types": "./lib/typert.remote-client.d.ts",
"default": "./lib/typert.remote-client.js"
},
"./src/*": "./src/*",
"./package.json": "./package.json"
},
@@ -37,7 +45,11 @@
"lib/index.js",
"lib/invariant.js",
"lib/types/**/*.js",
"lib/types/**/*.d.ts"
"lib/types/**/*.d.ts",
"lib/typert.host.js",
"lib/typert.host.d.ts",
"lib/typert.remote-client.js",
"lib/typert.remote-client.d.ts"
],
"license": "BSD-3-Clause",
"peerDependencies": {
@@ -46,14 +58,19 @@
"@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-scope": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-type-meta": "workspace:^",
"@deepseek-ai/cordis": "workspace:^"
},
"dependencies": {
"zod": "^4.4.3"
},
"devDependencies": {
"@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-brand": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-scope": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-type-meta": "workspace:^",
"@deepseek-ai/cordis": "workspace:^"
}
}

View File

@@ -3,26 +3,27 @@
* @module @deepseek-ai/dsh-commands
*/
import { Context, Service } from '@deepseek-ai/cordis'
import { Context } from '@deepseek-ai/cordis'
import type { Agent } from '@deepseek-ai/dsh-agent'
import { NamedEntries, ScopedLayers } from '@deepseek-ai/dsh-scope'
import type { ScopeKey, ScopeLayer } from '@deepseek-ai/dsh-scope'
import type { Session, SessionEvent, SessionEventMap } from '@deepseek-ai/dsh-session'
import { GatewayService, Remote } from '@deepseek-ai/dsh-type-meta'
import { CommandId } from './brand.ts'
import type {
CommandDescriptor,
CommandExecution,
CommandInputDescriptor,
CommandResult,
} from './types.ts'
export { CommandId } from './brand.ts'
export type { CommandSource, CommandSourceMap } from './types.ts'
export type * from './types.ts'
export const name = 'commands'
const COMMAND_NAME = /^[a-z][a-z0-9_-]*$/u
/** Immutable metadata for a command's optional unstructured input. */
export interface CommandInputDescriptor {
/** Placeholder shown before the user supplies free-form input. */
readonly hint: string
}
/** Invocation passed to one registered command handler. */
export interface CommandInvocation {
/** Pairing id already written to this invocation's `command/run` event. */
@@ -35,29 +36,6 @@ export interface CommandInvocation {
readonly signal: AbortSignal
}
/** Expected command outcome rendered directly by the dispatching UI. */
export type CommandResult =
| {
readonly kind: 'success'
readonly text?: string
/** Earlier authoritative domain event that owns a richer presentation. */
readonly sourceEventSeq?: number
}
| { readonly kind: 'error'; readonly text: string }
/**
* One settled command execution: the handler's normalized result plus the
* lifecycle pairing id minted for its `command/run`/`command/done` records,
* so a dispatching surface can correlate the RPC-level acknowledgment with
* the flow node those events produce.
*/
export interface CommandExecution {
/** Pairing id carried by this execution's lifecycle events. */
readonly commandId: CommandId
/** The handler's normalized outcome. */
readonly result: CommandResult
}
/** Plugin-owned command registration. */
export interface CommandDefinition {
/** Lowercase command name without the leading slash. */
@@ -76,16 +54,6 @@ export interface CommandDefinition {
readonly handler: (invocation: CommandInvocation) => CommandResult | Promise<CommandResult>
}
/** Handler-free immutable command view returned to UI adapters. */
export interface CommandDescriptor {
/** Lowercase command name without the leading slash. */
readonly name: string
/** Human-readable summary used in discovery UI. */
readonly description: string
/** Optional free-form input hint advertised to capable clients. */
readonly input?: CommandInputDescriptor
}
/** Syntactically valid slash command before registry resolution. */
export interface ParsedCommand {
/** Lowercase command name without the leading slash. */
@@ -254,7 +222,7 @@ function normalizeResult(command: string, value: unknown): CommandResult {
* registered through a command-injected child of an agent context shadow
* globals for that agent.
*/
export class CommandService extends Service {
export class CommandService extends GatewayService {
private readonly layers = new ScopedLayers(
scope => new CommandLayer(scope),
() => { this.notifyChange() },
@@ -288,6 +256,7 @@ export class CommandService extends Service {
* @param agent - exact receiving agent and scoped-layer key.
* @returns name-sorted descriptors after scoped shadowing.
*/
@Remote
list(agent: Agent): readonly CommandDescriptor[] {
return Object.freeze([...this.view(agent).values()]
.map(command => command.descriptor)
@@ -324,6 +293,7 @@ export class CommandService extends Service {
* @returns the settled execution (result + lifecycle pairing id), or
* `undefined` when syntax or name does not resolve.
*/
@Remote
async execute(
agent: Agent,
line: string,

View File

@@ -9,6 +9,45 @@
import type { CommandId } from './brand.ts'
/** Immutable metadata for a command's optional unstructured input. */
export interface CommandInputDescriptor {
/** Placeholder shown before the user supplies free-form input. */
readonly hint: string
}
/** Expected command outcome rendered directly by the dispatching UI. */
export type CommandResult =
| {
readonly kind: 'success'
readonly text?: string
/** Earlier authoritative domain event that owns a richer presentation. */
readonly sourceEventSeq?: number
}
| { readonly kind: 'error'; readonly text: string }
/**
* One settled command execution: the handler's normalized result plus the
* lifecycle pairing id minted for its `command/run`/`command/done` records,
* so a dispatching surface can correlate the Remote acknowledgment with the
* flow node those events produce.
*/
export interface CommandExecution {
/** Pairing id carried by this execution's lifecycle events. */
readonly commandId: CommandId
/** The handler's normalized outcome. */
readonly result: CommandResult
}
/** Handler-free immutable command view returned to UI adapters. */
export interface CommandDescriptor {
/** Lowercase command name without the leading slash. */
readonly name: string
/** Human-readable summary used in discovery UI. */
readonly description: string
/** Optional free-form input hint advertised to capable clients. */
readonly input?: CommandInputDescriptor
}
/**
* Producer record for one command invocation (the `command/run` event's
* source slot). Merge-extensible sum type mirroring `MessageSourceMap`'s

View File

@@ -28,6 +28,9 @@
},
{
"path": "../../support/invariants"
},
{
"path": "../../typert/type-meta"
}
]
}