fix(client): consume typed business session events

This commit is contained in:
imccyu
2026-08-09 18:42:25 +08:00
parent 3d70889a8d
commit 10464d155d
47 changed files with 405 additions and 359 deletions

View File

@@ -15,6 +15,10 @@
"types": "./lib/types/invariant.d.ts",
"default": "./lib/invariant.js"
},
"./types": {
"types": "./lib/types/types.d.ts",
"default": "./lib/types/types.js"
},
"./brand": {
"types": "./lib/types/brand.d.ts",
"default": "./lib/types/brand.js"

View File

@@ -11,24 +11,12 @@ import type { Session, SessionEvent, SessionEventMap } from '@deepseek-ai/dsh-se
import { CommandId } from './brand.ts'
export { CommandId } from './brand.ts'
export type { CommandSource, CommandSourceMap } from './types.ts'
export const name = 'commands'
const COMMAND_NAME = /^[a-z][a-z0-9_-]*$/u
/**
* Producer record for one command invocation (the `command/run` event's
* source slot). Merge-extensible sum type mirroring `MessageSourceMap`'s
* shape; minimal today because every executor caller is a human-facing UI
* surface dispatching a human-typed line, so the sole variant is `user`.
*/
export interface CommandSourceMap {
user: { kind: 'user' }
}
/** The union over {@link CommandSourceMap} — who issued a command line. */
export type CommandSource = CommandSourceMap[keyof CommandSourceMap]
/** Immutable metadata for a command's optional unstructured input. */
export interface CommandInputDescriptor {
/** Placeholder shown before the user supplies free-form input. */
@@ -131,34 +119,6 @@ class CommandLayer implements ScopeLayer {
}
}
declare module '@deepseek-ai/dsh-session/types' {
interface SessionEventMap {
/**
* A resolved slash command entered its handler. Log-only (never model
* surface); paired with `command/done` by `commandId`, mirroring the
* `tool/call`↔`tool/result` pairing. The payload is structured — `name`
* and `args` are `parseCommand`'s own split (name and verbatim rawInput,
* separator whitespace included), so a consumer (a projection unit
* folding its own command records, a rich command card) never re-parses
* a line. `args` is absent when the definition sets `recordInput: false`
* because an authoritative domain event owns the input payload.
*/
'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource }
/**
* The paired command settled. `kind`/`text` carry the handler's verbatim
* outcome (a thrown/aborted handler settles as `kind: 'error'` with the
* rendered failure). A successful command may identify the earlier
* authoritative domain event for a richer client-computed presentation.
*/
'command/done': {
commandId: CommandId
kind: 'success' | 'error'
text?: string
sourceEventSeq?: number
}
}
}
declare module 'cordis' {
interface Context {
commands: CommandService

View File

@@ -0,0 +1,48 @@
/**
* Durable command event vocabulary shared with type-only consumers.
*
* @module @deepseek-ai/dsh-commands/types
*/
import type { CommandId } from './brand.ts'
/**
* Producer record for one command invocation (the `command/run` event's
* source slot). Merge-extensible sum type mirroring `MessageSourceMap`'s
* shape; minimal today because every executor caller is a human-facing UI
* surface dispatching a human-typed line, so the sole variant is `user`.
*/
export interface CommandSourceMap {
user: { kind: 'user' }
}
/** The union over {@link CommandSourceMap} — who issued a command line. */
export type CommandSource = CommandSourceMap[keyof CommandSourceMap]
declare module '@deepseek-ai/dsh-session/types' {
interface SessionEventMap {
/**
* A resolved slash command entered its handler. Log-only (never model
* surface); paired with `command/done` by `commandId`, mirroring the
* `tool/call`↔`tool/result` pairing. The payload is structured — `name`
* and `args` are `parseCommand`'s own split (name and verbatim rawInput,
* separator whitespace included), so a consumer (a projection unit
* folding its own command records, a rich command card) never re-parses
* a line. `args` is absent when the definition sets `recordInput: false`
* because an authoritative domain event owns the input payload.
*/
'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource }
/**
* The paired command settled. `kind`/`text` carry the handler's verbatim
* outcome (a thrown/aborted handler settles as `kind: 'error'` with the
* rendered failure). A successful command may identify the earlier
* authoritative domain event for a richer client-computed presentation.
*/
'command/done': {
commandId: CommandId
kind: 'success' | 'error'
text?: string
sourceEventSeq?: number
}
}
}