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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user