@qilin-agent/client-ui-conversation 0.0.0-stage → 3.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.i18n.yaml +37 -0
- package/README.md +149 -2
- package/README.zh.md +150 -0
- package/lib/client.js +19198 -0
- package/lib/index.js +46 -0
- package/lib/types/client/apply.d.ts +25 -0
- package/lib/types/client/context-occupancy.d.ts +14 -0
- package/lib/types/client/contract/composer-blocks.d.ts +28 -0
- package/lib/types/client/contract/composer-submission.d.ts +8 -0
- package/lib/types/client/contract/context-producer.d.ts +29 -0
- package/lib/types/client/contract/conversation.d.ts +279 -0
- package/lib/types/client/contract/draft-editor.d.ts +102 -0
- package/lib/types/client/contract/groups.d.ts +116 -0
- package/lib/types/client/contract/input.d.ts +361 -0
- package/lib/types/client/contract/records.d.ts +301 -0
- package/lib/types/client/contract/request-inspection.d.ts +131 -0
- package/lib/types/client/contract/slots.d.ts +541 -0
- package/lib/types/client/contract/snapshot.d.ts +20 -0
- package/lib/types/client/contract/system-prompt.d.ts +35 -0
- package/lib/types/client/contract/views.d.ts +36 -0
- package/lib/types/client/conversation/assembler.d.ts +151 -0
- package/lib/types/client/conversation/assembly.d.ts +128 -0
- package/lib/types/client/conversation/definition-registry.d.ts +33 -0
- package/lib/types/client/conversation/event-registry.d.ts +40 -0
- package/lib/types/client/conversation/group-registry.d.ts +30 -0
- package/lib/types/client/conversation/group-store.d.ts +29 -0
- package/lib/types/client/conversation/historical-images.d.ts +49 -0
- package/lib/types/client/conversation/location-index.d.ts +91 -0
- package/lib/types/client/conversation/view-registry.d.ts +12 -0
- package/lib/types/client/image-labels.d.ts +23 -0
- package/lib/types/client/index.d.ts +39 -0
- package/lib/types/client/input/blocks.d.ts +27 -0
- package/lib/types/client/input/decorations.d.ts +32 -0
- package/lib/types/client/input/editor/ComposerContentEditable.d.ts +16 -0
- package/lib/types/client/input/editor/DecoratorPortals.d.ts +14 -0
- package/lib/types/client/input/editor/DraftEditor.d.ts +27 -0
- package/lib/types/client/input/editor/ReferenceChip.d.ts +17 -0
- package/lib/types/client/input/editor/chip-node.d.ts +110 -0
- package/lib/types/client/input/editor/claim-decor.d.ts +23 -0
- package/lib/types/client/input/editor/keymap.d.ts +43 -0
- package/lib/types/client/input/editor/projection.d.ts +93 -0
- package/lib/types/client/input/editor/reference-activation.d.ts +10 -0
- package/lib/types/client/input/editor/runtime.d.ts +123 -0
- package/lib/types/client/input/editor/span-map.d.ts +38 -0
- package/lib/types/client/input/editor/text-ref.d.ts +49 -0
- package/lib/types/client/input/editor/view-binding.d.ts +60 -0
- package/lib/types/client/input/facade.d.ts +303 -0
- package/lib/types/client/input/hub.d.ts +100 -0
- package/lib/types/client/input/machine.d.ts +46 -0
- package/lib/types/client/input/submission-policy.d.ts +52 -0
- package/lib/types/client/layout-policy.d.ts +42 -0
- package/lib/types/client/locales.d.ts +770 -0
- package/lib/types/client/queue/QueueDock.d.ts +27 -0
- package/lib/types/client/service.d.ts +186 -0
- package/lib/types/client/settings/ContentWidthRow.d.ts +26 -0
- package/lib/types/client/settings/EnterBehaviorRow.d.ts +21 -0
- package/lib/types/client/skeleton/ContextMeter.d.ts +14 -0
- package/lib/types/client/skeleton/ConversationContent.d.ts +8 -0
- package/lib/types/client/skeleton/ConversationHeader.d.ts +8 -0
- package/lib/types/client/skeleton/ConversationMainPanel.d.ts +3 -0
- package/lib/types/client/skeleton/ConversationPanel.d.ts +9 -0
- package/lib/types/client/skeleton/ConversationRoot.d.ts +5 -0
- package/lib/types/client/skeleton/ConversationSession.d.ts +21 -0
- package/lib/types/client/skeleton/ConversationWidthControls.d.ts +14 -0
- package/lib/types/client/skeleton/DefaultConversationViews.d.ts +9 -0
- package/lib/types/client/skeleton/EmptyHero.d.ts +49 -0
- package/lib/types/client/skeleton/InputBar.d.ts +18 -0
- package/lib/types/client/skeleton/TodoPanel.d.ts +21 -0
- package/lib/types/client/skeleton/control-row-layout.d.ts +10 -0
- package/lib/types/client/skeleton/safari.d.ts +18 -0
- package/lib/types/client/stop-sequence.d.ts +32 -0
- package/lib/types/client/stop-shortcut.d.ts +17 -0
- package/lib/types/client/stores.d.ts +24 -0
- package/lib/types/client/view-selection.d.ts +11 -0
- package/lib/types/conversation-settings.d.ts +38 -0
- package/lib/types/index.d.ts +9 -0
- package/package.json +106 -3
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { EditorConfig, LexicalEditor, SerializedTextNode } from 'lexical';
|
|
2
|
+
import { TextNode } from 'lexical';
|
|
3
|
+
/** JSON form of one text-ref node. */
|
|
4
|
+
export type SerializedTextRefNode = SerializedTextNode;
|
|
5
|
+
/** One matched plain-text reference as a styled, fully editable text node. */
|
|
6
|
+
export declare class TextRefNode extends TextNode {
|
|
7
|
+
/** Lexical node registry type tag. */
|
|
8
|
+
static getType(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Clone with identity (Lexical writable-copy contract).
|
|
11
|
+
* @param node - node to clone.
|
|
12
|
+
* @returns a copy carrying the same NodeKey.
|
|
13
|
+
*/
|
|
14
|
+
static clone(node: TextRefNode): TextRefNode;
|
|
15
|
+
/**
|
|
16
|
+
* Rebuild one text-ref from its JSON form.
|
|
17
|
+
* @param json - serialized node.
|
|
18
|
+
* @returns a fresh node.
|
|
19
|
+
*/
|
|
20
|
+
static importJSON(json: SerializedTextRefNode): TextRefNode;
|
|
21
|
+
/** Serialize to the JSON node form. */
|
|
22
|
+
exportJSON(): SerializedTextRefNode;
|
|
23
|
+
/** Style the span the base TextNode mounts. */
|
|
24
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
25
|
+
/** Entity nodes never merge with plain siblings (the transform owns their bounds). */
|
|
26
|
+
isTextEntity(): true;
|
|
27
|
+
/** Editing continues inside; the transform re-evaluates match shape per edit. */
|
|
28
|
+
canInsertTextBefore(): boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Register the plain-text reference entity transform. The claim decoration
|
|
32
|
+
* has precedence on the leading-token seat: while a command claim holds, the
|
|
33
|
+
* claimed token must stay a plain TextNode (transforms register per concrete
|
|
34
|
+
* node class, so a TextRefNode would never receive the TextNode claim
|
|
35
|
+
* transform and the warn color would be lost).
|
|
36
|
+
* @param editor - the shell-owned editor.
|
|
37
|
+
* @param lexiconOf - live per-trigger name-roll accessor (the controller's aggregated store).
|
|
38
|
+
* @param activeToken - live claim token accessor; null while unclaimed.
|
|
39
|
+
* @returns the unregister disposer.
|
|
40
|
+
*/
|
|
41
|
+
export declare function registerTextRefDecoration(editor: LexicalEditor, lexiconOf: () => ReadonlyMap<'/' | '@', readonly string[]>, activeToken: () => string | null): () => void;
|
|
42
|
+
/**
|
|
43
|
+
* Force a re-scan of the whole document (transforms only visit dirty nodes;
|
|
44
|
+
* a lexicon roll change dirties nothing on its own). Queued, not discrete —
|
|
45
|
+
* the caller may sit inside an update listener.
|
|
46
|
+
* @param editor - the shell-owned editor.
|
|
47
|
+
*/
|
|
48
|
+
export declare function rescanTextRefs(editor: LexicalEditor): void;
|
|
49
|
+
//# sourceMappingURL=text-ref.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** DOM and keymap bindings installed by the InputBar's existing effects. */
|
|
2
|
+
import type { MouseEvent, MutableRefObject, RefObject } from 'react';
|
|
3
|
+
import type { LexicalEditor } from 'lexical';
|
|
4
|
+
import type { ComposerKeyboard } from '../../contract/draft-editor.ts';
|
|
5
|
+
import type { ComposerBarProps } from '../../contract/slots.ts';
|
|
6
|
+
import type { BusyEnterBehavior } from '../../contract/composer-submission.ts';
|
|
7
|
+
interface DraftViewGate {
|
|
8
|
+
locked: boolean;
|
|
9
|
+
machineBusy: boolean;
|
|
10
|
+
canSteerQueue: boolean;
|
|
11
|
+
running: boolean;
|
|
12
|
+
steeringAvailable: boolean;
|
|
13
|
+
busyEnter: BusyEnterBehavior;
|
|
14
|
+
intakeFiles: (files: readonly File[]) => void;
|
|
15
|
+
uploadsPending: boolean;
|
|
16
|
+
showToast: (text: string) => void;
|
|
17
|
+
t: ComposerBarProps['t'];
|
|
18
|
+
canAcceptDrop: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Reveal the DOM selection within the draft's own scrollport.
|
|
22
|
+
* @param scrollRef - the InputBar-owned scrollport reference.
|
|
23
|
+
*/
|
|
24
|
+
export declare function revealDraftSelection(scrollRef: RefObject<HTMLDivElement>): void;
|
|
25
|
+
/**
|
|
26
|
+
* Focus the borrowed editor and reveal its restored selection.
|
|
27
|
+
* @param editor - the Session-owned editor.
|
|
28
|
+
* @param revealSelection - reveal the selection after Lexical restores it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function focusDraftEditor(editor: LexicalEditor, revealSelection: () => void): void;
|
|
31
|
+
/**
|
|
32
|
+
* Forward wheel movement at the draft's edge to its conversation scrollport.
|
|
33
|
+
* @param scrollRef - the InputBar-owned scrollport reference.
|
|
34
|
+
* @returns the listener cleanup, or undefined when the element is absent.
|
|
35
|
+
*/
|
|
36
|
+
export declare function installDraftWheel(scrollRef: RefObject<HTMLDivElement>): (() => void) | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Bind this view's file dialog through the existing keyboard face.
|
|
39
|
+
* @param keyboard - the Session-owned composer operations.
|
|
40
|
+
* @param gate - live intake availability retained by InputBar.
|
|
41
|
+
* @param fileInputRef - the view's native file input.
|
|
42
|
+
* @returns the picker unbind disposer.
|
|
43
|
+
*/
|
|
44
|
+
export declare function installDraftFilePicker(keyboard: ComposerKeyboard, gate: MutableRefObject<Pick<DraftViewGate, 'canAcceptDrop'>>, fileInputRef: RefObject<HTMLInputElement>): () => void;
|
|
45
|
+
/**
|
|
46
|
+
* Bind editor gestures to the view's live guards and Session operations.
|
|
47
|
+
* @param editor - the borrowed Session-owned editor.
|
|
48
|
+
* @param keyboard - the existing composer keyboard operations.
|
|
49
|
+
* @param gate - live view values read by the installed handlers.
|
|
50
|
+
* @returns the keymap disposer.
|
|
51
|
+
*/
|
|
52
|
+
export declare function installDraftKeymap(editor: LexicalEditor, keyboard: ComposerKeyboard, gate: MutableRefObject<DraftViewGate>): () => void;
|
|
53
|
+
/**
|
|
54
|
+
* Keep a toolbar press from moving focus away from the draft.
|
|
55
|
+
* @param event - the toolbar button's mouse event.
|
|
56
|
+
* @param editor - the borrowed editor, absent in the inert view.
|
|
57
|
+
*/
|
|
58
|
+
export declare function keepDraftFocus(event: MouseEvent<HTMLButtonElement>, editor: LexicalEditor | null): void;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=view-binding.d.ts.map
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionInput shell: owns the per-session Lexical editor (text + chip
|
|
3
|
+
* truth) and the pure SubmitMachine (phase/claim/attempt), and choreographs
|
|
4
|
+
* everything between them — projections and InputState publication, the
|
|
5
|
+
* scoped-event application verbs, the submit transaction plumbing
|
|
6
|
+
* (adjudicate via the session's InputTriggerController; claim.submit; default
|
|
7
|
+
* sink), the notice channel, and the draft persistence mirror.
|
|
8
|
+
* Package-private; the hub alone constructs it and wires the scoped event
|
|
9
|
+
* listeners onto it.
|
|
10
|
+
*/
|
|
11
|
+
import type { Context } from '@qilin-agent/kylin';
|
|
12
|
+
import type { InboxState } from '@qilin-agent/agent/types';
|
|
13
|
+
import { type ObservableSnapshot, type SnapshotStore } from '@qilin-agent/client-store';
|
|
14
|
+
import type { LexicalEditor } from 'lexical';
|
|
15
|
+
import type { CommandClaim, ConsumeTokenRequest, DraftAttachmentId, InputActions, InputNotice, InputState, InputTriggerController, SessionInput, SubmitAttachment, SubmitOutcome } from '../contract/input.ts';
|
|
16
|
+
import type { ArbitrateKey, ArbitrateOutcome, ComposerKeyboard, ReferenceInsert, TokenSpan } from '../contract/draft-editor.ts';
|
|
17
|
+
import type { InputSubmitMode } from '../contract/composer-submission.ts';
|
|
18
|
+
/** Popup face the shell needs (dismissal only; typed structurally to avoid a value import). */
|
|
19
|
+
export interface PopupDismissFace {
|
|
20
|
+
dismiss(): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Construction dependencies of one facade. The slash/popup faces are THUNKS: the
|
|
24
|
+
* shell is created inside the sessions provide materialization (before the
|
|
25
|
+
* scope record is queryable), where `slash.sessionOf`/`command.popupFor`
|
|
26
|
+
* cannot resolve yet — resolution defers to first interactive use.
|
|
27
|
+
*/
|
|
28
|
+
export interface SessionInputDeps {
|
|
29
|
+
/** Session-scope ctx handed to claim.submit transactions. */
|
|
30
|
+
actx: Context;
|
|
31
|
+
/** Enter adjudication face resolver; absent/undefined answer = every '/' line falls to the default sink. */
|
|
32
|
+
inputTriggers?: (() => InputTriggerController | undefined) | undefined;
|
|
33
|
+
/** PopupSelect shell face resolver (dismissal on submit lock / escape). */
|
|
34
|
+
popup?: (() => PopupDismissFace | undefined) | undefined;
|
|
35
|
+
/** Agent Inbox projection; its next-turn list is overlaid onto InputState.queue. */
|
|
36
|
+
inbox?: ObservableSnapshot<InboxState | undefined> | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Steer every still-pending queued message into the running turn, in FIFO
|
|
39
|
+
* order (the empty-draft accelerated-Enter gesture); absent = unsupported.
|
|
40
|
+
*/
|
|
41
|
+
steerQueue?: (() => void) | undefined;
|
|
42
|
+
/** The plain-message sink (send choreography / materialize fork — the hub owns it). */
|
|
43
|
+
defaultSink(text: string, attachmentIds: readonly DraftAttachmentId[], mode: InputSubmitMode, signal: AbortSignal): Promise<SubmitOutcome>;
|
|
44
|
+
/** Command-plane attachment plumbing (the hub owns the conversation face and the copy). */
|
|
45
|
+
commandAttachments: {
|
|
46
|
+
/** Resolve ordered draft ids to wire payloads without sending them; rejects when an id no longer resolves. */
|
|
47
|
+
serialize(ids: readonly DraftAttachmentId[]): Promise<readonly SubmitAttachment[]>;
|
|
48
|
+
/** Free consumed draft attachments after a successful command submit. */
|
|
49
|
+
release(ids: readonly DraftAttachmentId[]): void;
|
|
50
|
+
/** Localized composer notice for a claimed command that does not accept attachments. */
|
|
51
|
+
unsupportedNotice(token: string): string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The per-session input facade: scoped-event application verbs +
|
|
56
|
+
* setDraft/submit + the published InputState store, over a shell-owned
|
|
57
|
+
* Lexical editor.
|
|
58
|
+
*/
|
|
59
|
+
export declare class SessionInputShell implements SessionInput {
|
|
60
|
+
private readonly deps;
|
|
61
|
+
/** Published editor projection + submit-plane state + queue overlay (the InputZone currency source). */
|
|
62
|
+
readonly state: SnapshotStore<InputState>;
|
|
63
|
+
/** Latest surfaced notice (null after clear); the bar renders errors as banners and information inline. */
|
|
64
|
+
readonly notices: SnapshotStore<InputNotice | null>;
|
|
65
|
+
/** The shell-owned editor (text + chip truth); the composer binds its contenteditable to it. */
|
|
66
|
+
get editor(): LexicalEditor;
|
|
67
|
+
/** The public provide-channel action face (one stable identity per session). */
|
|
68
|
+
readonly actions: InputActions;
|
|
69
|
+
private readonly core;
|
|
70
|
+
private readonly draftEditor;
|
|
71
|
+
private get projection();
|
|
72
|
+
private rev;
|
|
73
|
+
private readonly unregister;
|
|
74
|
+
private noticeSeq;
|
|
75
|
+
private lastMirroredDraft;
|
|
76
|
+
private attachmentIds;
|
|
77
|
+
private disposed;
|
|
78
|
+
/** Draft persistence mirror (Conversation store write; receives the clipboard projection). */
|
|
79
|
+
private mirrorFn;
|
|
80
|
+
/** The mounted composer's file-picker opener (scoped pick-files event target). */
|
|
81
|
+
private filePicker;
|
|
82
|
+
/** Default sends retained until admission settles or scope disposal releases their attachments. */
|
|
83
|
+
private readonly detachedDrafts;
|
|
84
|
+
/** Failed default sends waiting to be restored together in submission order. */
|
|
85
|
+
private readonly failedDetached;
|
|
86
|
+
/** Revision of the last automatic failure restoration. */
|
|
87
|
+
private failedRestoreRev;
|
|
88
|
+
private restoringFailures;
|
|
89
|
+
private attachmentFlightSeq;
|
|
90
|
+
/** Attachment-only sends retained until admission settles or scope disposal releases their attachments. */
|
|
91
|
+
private readonly attachmentFlights;
|
|
92
|
+
private readonly unsubscribeInbox;
|
|
93
|
+
constructor(deps: SessionInputDeps);
|
|
94
|
+
/** Re-project, run the claim watch, publish, and feed trigger tracking after every editor commit. */
|
|
95
|
+
private onEditorUpdate;
|
|
96
|
+
/**
|
|
97
|
+
* Replace the whole draft (persisted-draft seed and programmatic writes).
|
|
98
|
+
* Placeholder-sanitized; newlines split paragraphs; the caret lands at the
|
|
99
|
+
* end. Merged into history so a seed is not an undoable step of its own.
|
|
100
|
+
* @param text - the full next draft.
|
|
101
|
+
*/
|
|
102
|
+
setDraft(text: string): void;
|
|
103
|
+
/** Append ordered attachment ids unless an admission transaction is locked. */
|
|
104
|
+
addAttachments(ids: readonly DraftAttachmentId[]): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Remove one attachment id from this draft. Busy admission phases refuse, like
|
|
107
|
+
* {@link addAttachments}: a removal landing while a command submit serializes
|
|
108
|
+
* would otherwise vanish from the rail yet still ride the in-flight send.
|
|
109
|
+
*/
|
|
110
|
+
removeAttachment(id: DraftAttachmentId): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Keep only ids that still resolve in the browser attachment registry.
|
|
113
|
+
* @param available - live registry ids.
|
|
114
|
+
*/
|
|
115
|
+
pruneAttachments(available: readonly DraftAttachmentId[]): void;
|
|
116
|
+
/**
|
|
117
|
+
* Clear the draft as a successful-send commit: the editor empties (no undo
|
|
118
|
+
* unit) and the undo history is cut, so Ctrl/Cmd-Z cannot resurrect sent
|
|
119
|
+
* content (the command path gets the same discipline from submit-settled).
|
|
120
|
+
* @param attachmentIds - admitted attachment ids to remove from this draft.
|
|
121
|
+
*/
|
|
122
|
+
commitSend(attachmentIds: readonly DraftAttachmentId[]): void;
|
|
123
|
+
/**
|
|
124
|
+
* Insert pasted plain text over the current editor selection
|
|
125
|
+
* (placeholder-sanitized). The paste event's own default is suppressed by
|
|
126
|
+
* the caller; PASTE_TAG makes the paste its own history boundary, so one
|
|
127
|
+
* undo never removes both the paste and typing inside the merge window.
|
|
128
|
+
* @param text - pasted plain text.
|
|
129
|
+
*/
|
|
130
|
+
paste(text: string): void;
|
|
131
|
+
/**
|
|
132
|
+
* Enter adjudication + submit transaction + default sink. Effects fan out
|
|
133
|
+
* from the machine; this method only feeds the event. Lock entry
|
|
134
|
+
* (adjudicating/submitting) force-closes the transient layers: the popup
|
|
135
|
+
* dismisses and the menu tracks frozen.
|
|
136
|
+
*/
|
|
137
|
+
submit(mode?: InputSubmitMode): void;
|
|
138
|
+
/**
|
|
139
|
+
* Keyboard arbitration while the menu is open.
|
|
140
|
+
* @param key - the intercepted key.
|
|
141
|
+
* @param composing - IME composition guard state.
|
|
142
|
+
* @returns the menu's verdict; 'pass' when no pipeline is mounted.
|
|
143
|
+
*/
|
|
144
|
+
arbitrate(key: ArbitrateKey, composing: boolean): ArbitrateOutcome;
|
|
145
|
+
/**
|
|
146
|
+
* Steer every still-pending queued message into the running turn (the
|
|
147
|
+
* empty-draft accelerated-Enter gesture). Execution belongs to the hub's
|
|
148
|
+
* queue choreography; absent dep = the gesture falls back to the machine's
|
|
149
|
+
* empty-draft no-op.
|
|
150
|
+
*/
|
|
151
|
+
steerQueue(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Space adjudication over the controller's hot state.
|
|
154
|
+
* @returns true = a claim/insert was applied — the caller preventDefaults.
|
|
155
|
+
*/
|
|
156
|
+
space(): boolean;
|
|
157
|
+
/** Dismiss the popupSelect shell (any interaction outside the box). */
|
|
158
|
+
dismissPopup(): void;
|
|
159
|
+
/**
|
|
160
|
+
* The live selection as a detect-coordinate span (menu-launcher synthetic
|
|
161
|
+
* hits replace it on pick); an absent selection answers a collapsed span at
|
|
162
|
+
* the document end.
|
|
163
|
+
* @returns the ordered [start, end) span in detect coordinates.
|
|
164
|
+
*/
|
|
165
|
+
caretSpan(): {
|
|
166
|
+
start: number;
|
|
167
|
+
end: number;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Hot plain-text reference lexicon source for the decoration scan:
|
|
171
|
+
* delegates to the controller's aggregated store. Stable
|
|
172
|
+
* identity per shell; without a pipeline the snapshot is the empty Map and
|
|
173
|
+
* subscribers never fire.
|
|
174
|
+
*/
|
|
175
|
+
readonly lexicon: ObservableSnapshot<ReadonlyMap<'/' | '@', readonly string[]>>;
|
|
176
|
+
/**
|
|
177
|
+
* Apply one command claim (scoped begin-command event listener body): the
|
|
178
|
+
* editor replaces [0, span.end) with the claim token, then the machine
|
|
179
|
+
* enters claimed.
|
|
180
|
+
* @param claim - the command claim from the pick path.
|
|
181
|
+
* @param span - pick-time span snapshot (detect coordinates).
|
|
182
|
+
* @returns whether the edit applied (phase, span CAS, and leading guard passed).
|
|
183
|
+
*/
|
|
184
|
+
beginCommand(claim: CommandClaim, span: TokenSpan): boolean;
|
|
185
|
+
/**
|
|
186
|
+
* Apply one reference insertion (scoped insert-reference event listener
|
|
187
|
+
* body): the editor replaces the span with one chip node, followed by a
|
|
188
|
+
* separating space unless one is already next.
|
|
189
|
+
* @param ref - the reference insertion from the pick path.
|
|
190
|
+
* @param span - pick-time span snapshot (detect coordinates).
|
|
191
|
+
* @returns whether the edit applied.
|
|
192
|
+
*/
|
|
193
|
+
insertReference(ref: ReferenceInsert, span: TokenSpan): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Consume one command token after business success (scoped consume-token
|
|
196
|
+
* event listener body). Span guard: revision CAS then splice; bare-token
|
|
197
|
+
* guard: trimmed-draft equality then clear.
|
|
198
|
+
* @param guard - exact span or bare-token guard.
|
|
199
|
+
* @returns whether the token was consumed.
|
|
200
|
+
*/
|
|
201
|
+
consumeToken(guard: ConsumeTokenRequest['guard']): boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Insert plain reference text over the pick-time span (scoped insert-text
|
|
204
|
+
* event listener body; the plain-text reference path). The editor gains
|
|
205
|
+
* ordinary characters — no chip node; the chip look is a scan-derived
|
|
206
|
+
* decoration, never state.
|
|
207
|
+
* @param text - the plain reference text to splice in (e.g. `/name `).
|
|
208
|
+
* @param span - pick-time span snapshot (detect coordinates).
|
|
209
|
+
* @param keepCompleting - contract passenger; completion re-opening is
|
|
210
|
+
* automatic here (the update listener re-tracks at the settled caret, so an
|
|
211
|
+
* open token — a directory pick's trailing slash — reopens the menu without
|
|
212
|
+
* an explicit re-track).
|
|
213
|
+
* @returns whether the text was applied.
|
|
214
|
+
*/
|
|
215
|
+
insertText(text: string, span: TokenSpan, keepCompleting?: boolean): boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Surface a notice from outside the machine (detached command results).
|
|
218
|
+
* @param level - severity tier.
|
|
219
|
+
* @param text - notice body.
|
|
220
|
+
*/
|
|
221
|
+
notify(level: 'info' | 'error', text: string): void;
|
|
222
|
+
/**
|
|
223
|
+
* Return the keyboard to the composer with the caret it last held. Lexical's
|
|
224
|
+
* own focus restores its stored selection; a bare DOM focus on the
|
|
225
|
+
* contenteditable would land the caret at the start instead.
|
|
226
|
+
*/
|
|
227
|
+
focus(): void;
|
|
228
|
+
/**
|
|
229
|
+
* Teardown the shell and return every browser-owned attachment still retained by
|
|
230
|
+
* the draft or an unsettled default send.
|
|
231
|
+
* @returns attachment ids the scope disposer must release.
|
|
232
|
+
*/
|
|
233
|
+
dispose(): readonly DraftAttachmentId[];
|
|
234
|
+
/** Read the live input state (guard derivation reads here). */
|
|
235
|
+
get snapshot(): InputState;
|
|
236
|
+
/**
|
|
237
|
+
* Bind the draft persistence mirror (Conversation store write). Adopt-on-bind: the
|
|
238
|
+
* store draft may hold a persisted value from a previous mount; the caller
|
|
239
|
+
* seeds it via setDraft BEFORE binding, and afterwards every editor-adopted
|
|
240
|
+
* draft mirrors out.
|
|
241
|
+
* @param write - store draft write.
|
|
242
|
+
* @returns the unbind disposer.
|
|
243
|
+
*/
|
|
244
|
+
bindMirror(write: (text: string) => void): () => void;
|
|
245
|
+
/**
|
|
246
|
+
* Bind the mounted composer's file action and live intake availability.
|
|
247
|
+
* @param picker - availability query and native file-dialog opener.
|
|
248
|
+
* @returns the unbind disposer.
|
|
249
|
+
*/
|
|
250
|
+
bindFilePicker(picker: Parameters<ComposerKeyboard['bindFilePicker']>[0]): () => void;
|
|
251
|
+
/**
|
|
252
|
+
* Read the mounted composer's live file-intake availability.
|
|
253
|
+
* @returns false when no accepting composer is mounted.
|
|
254
|
+
*/
|
|
255
|
+
canPickFiles(): boolean;
|
|
256
|
+
/**
|
|
257
|
+
* Open the native file dialog when the mounted composer accepts files.
|
|
258
|
+
* @returns whether the opener was called.
|
|
259
|
+
*/
|
|
260
|
+
pickFiles(): boolean;
|
|
261
|
+
/** The claim token the decoration transform styles; null while unclaimed. */
|
|
262
|
+
private activeClaimToken;
|
|
263
|
+
/** Dispatch + execute, refreshing the claim decoration when the styled token flips. */
|
|
264
|
+
private dispatchRun;
|
|
265
|
+
private run;
|
|
266
|
+
private execute;
|
|
267
|
+
/**
|
|
268
|
+
* Execute the commit-draft effect: clear the committed content (retaining
|
|
269
|
+
* a pure typed-during-flight suffix when the snapshot allows) and cut the
|
|
270
|
+
* undo history so sent content cannot resurrect.
|
|
271
|
+
*/
|
|
272
|
+
private commitDraft;
|
|
273
|
+
/**
|
|
274
|
+
* Prompt serialization before the sink: expand each chip occurrence to its
|
|
275
|
+
* owner's model form via the session controller's codec routing. Owner
|
|
276
|
+
* missing or serialization failure rejects the detached send and restores
|
|
277
|
+
* its editor snapshot. Chip-free drafts skip the async detour.
|
|
278
|
+
*/
|
|
279
|
+
private sinkSerialized;
|
|
280
|
+
/** Settle one detached default send independently of other sends. */
|
|
281
|
+
private settleSink;
|
|
282
|
+
/** Restore one failed detached send without overwriting text entered after a restoration. */
|
|
283
|
+
private settleDetachedFailure;
|
|
284
|
+
/** Rebuild all currently failed snapshots in submission order. */
|
|
285
|
+
private restoreFailedDrafts;
|
|
286
|
+
/** Return failed-send attachments to the head of the rail; release happens only after success. */
|
|
287
|
+
private restoreAttachments;
|
|
288
|
+
/** Enter adjudication: poll the session controller; failure = notice + draft retained (never a silent downgrade). */
|
|
289
|
+
private adjudicate;
|
|
290
|
+
/**
|
|
291
|
+
* The submit transaction: claim.submit against the session scope; ok maps
|
|
292
|
+
* from the outcome kind. An accepting claim receives the serialized draft
|
|
293
|
+
* attachments, which are cleared and released only on a success outcome; a
|
|
294
|
+
* failure (serialize, transport, or handler error) keeps draft and attachments
|
|
295
|
+
* for correction.
|
|
296
|
+
*/
|
|
297
|
+
private beginSubmit;
|
|
298
|
+
/** Late-settlement guard: superseded attempts and disposed facades drop silently. */
|
|
299
|
+
private dead;
|
|
300
|
+
private compose;
|
|
301
|
+
private publish;
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=facade.d.ts.map
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InputHub: the SessionInputResolver implementation (`ctx.conversation.input`) — one
|
|
3
|
+
* SessionInputShell per session, created inside the uiSession provide
|
|
4
|
+
* materialization (the 'input' standard-kit entry IS the
|
|
5
|
+
* creation trigger) and torn down by the scope disposer (instance-and-scope
|
|
6
|
+
* share one lifecycle). The hub registers the scoped input-mutation
|
|
7
|
+
* listeners on each Session context and owns the default-sink choreography: every session is a
|
|
8
|
+
* real host entity, so the sink is one unconditional prompt path.
|
|
9
|
+
*/
|
|
10
|
+
import type { Context } from '@qilin-agent/kylin';
|
|
11
|
+
import type { SessionBinding } from '@qilin-agent/api-session-controller/client';
|
|
12
|
+
import type { SessionId } from '@qilin-agent/session/types';
|
|
13
|
+
import type { TranslateNS } from '@qilin-agent/client-locale/client';
|
|
14
|
+
import type { InputTriggerController, SessionInputResolver, SessionInput } from '../contract/input.ts';
|
|
15
|
+
import type { ComposerKeyboard } from '../contract/draft-editor.ts';
|
|
16
|
+
import { SessionInputShell } from './facade.ts';
|
|
17
|
+
/** Session-addressed input facade registry (SessionInputResolver face + composer-layer extras). */
|
|
18
|
+
export declare class InputHub implements SessionInputResolver {
|
|
19
|
+
private readonly rootCtx;
|
|
20
|
+
private readonly t;
|
|
21
|
+
private readonly shells;
|
|
22
|
+
/**
|
|
23
|
+
* @param ctx - client root context (services resolved lazily per call — boot order stays free).
|
|
24
|
+
* @param t - conversation-namespace translate thunk (reads the active locale at call time).
|
|
25
|
+
*/
|
|
26
|
+
constructor(rootCtx: Context, t: TranslateNS<'conversation'>);
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the facade for one session-scope ctx (SessionInputResolver face).
|
|
29
|
+
* @param actx - session-scope context.
|
|
30
|
+
* @returns the resident per-session facade.
|
|
31
|
+
*/
|
|
32
|
+
for(actx: Context): SessionInput;
|
|
33
|
+
/**
|
|
34
|
+
* Resident shell for one session binding — the provide-channel entry
|
|
35
|
+
* (called during scope materialization, BEFORE the scope record is
|
|
36
|
+
* queryable, hence binding-fed and hence the thunked slash/popup deps).
|
|
37
|
+
* Wires the scoped event listeners + teardown into the session scope.
|
|
38
|
+
* @param binding - session assembly handle.
|
|
39
|
+
* @returns the shell.
|
|
40
|
+
*/
|
|
41
|
+
shellFor(binding: SessionBinding): SessionInputShell;
|
|
42
|
+
/**
|
|
43
|
+
* Resident shell by session id (service-face path; the provide channel has
|
|
44
|
+
* normally created it already — this covers direct id-addressed access).
|
|
45
|
+
* @param id - session id.
|
|
46
|
+
* @returns the shell.
|
|
47
|
+
*/
|
|
48
|
+
shell(id: SessionId): SessionInputShell;
|
|
49
|
+
/**
|
|
50
|
+
* The InputBar-exclusive keyboard command face: the shell
|
|
51
|
+
* satisfies it structurally; package-internal — handed through the
|
|
52
|
+
* composer-bar entry's inject, never across a plugin boundary.
|
|
53
|
+
* @param id - session id.
|
|
54
|
+
* @returns the shell as the keyboard face.
|
|
55
|
+
*/
|
|
56
|
+
keyboard(id: SessionId): ComposerKeyboard;
|
|
57
|
+
/**
|
|
58
|
+
* Query file intake without creating a Session input.
|
|
59
|
+
* @param id - target Session.
|
|
60
|
+
* @returns whether its mounted composer currently accepts files.
|
|
61
|
+
*/
|
|
62
|
+
canPickFiles(id: SessionId): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Open the target composer's file dialog under its live intake policy.
|
|
65
|
+
* @param id - target Session.
|
|
66
|
+
*/
|
|
67
|
+
pickFiles(id: SessionId): void;
|
|
68
|
+
/**
|
|
69
|
+
* Resolve the optional slash controller for composer chrome that launches
|
|
70
|
+
* the shared candidate menu without typing a trigger.
|
|
71
|
+
* @param id - session id.
|
|
72
|
+
* @returns the resident controller, or undefined when no trigger provider is installed.
|
|
73
|
+
*/
|
|
74
|
+
inputTriggers(id: SessionId): InputTriggerController | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Default sink: optimistic clear + prompt. The session is always a real
|
|
77
|
+
* host entity (materialized when its workspace was picked), so there is
|
|
78
|
+
* exactly one path; a failed first prompt is an ordinary prompt failure
|
|
79
|
+
* (banner via promptError, draft restored only while untouched).
|
|
80
|
+
*/
|
|
81
|
+
private sink;
|
|
82
|
+
/**
|
|
83
|
+
* Submit every still-pending queued message through QueueDock Steer, in FIFO
|
|
84
|
+
* request order — the same operation as the queue dock's per-row button.
|
|
85
|
+
* An Agent stopping before a command (`session/steer-unavailable`) or a row already
|
|
86
|
+
* claimed by the agent (`session/queue-item-not-found`) converges silently, while a
|
|
87
|
+
* genuine failure surfaces as one composer notice. Repeated triggers
|
|
88
|
+
* (e.g. two rapid empty-draft chords) rely on that `session/queue-item-not-found`
|
|
89
|
+
* convergence: the snapshot may still list a row the host already steered,
|
|
90
|
+
* and the duplicate Steer is a silent no-op.
|
|
91
|
+
* @param session - the addressed host session.
|
|
92
|
+
* @param shell - the resident shell (notice outlet).
|
|
93
|
+
*/
|
|
94
|
+
private steerQueue;
|
|
95
|
+
private controller;
|
|
96
|
+
private popup;
|
|
97
|
+
private sessions;
|
|
98
|
+
private conversation;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=hub.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { InputEffect, InputEvent, InputState } from '../contract/input.ts';
|
|
2
|
+
/** The submit-plane slice of the published InputState. */
|
|
3
|
+
export interface SubmitSnapshot {
|
|
4
|
+
readonly phase: InputState['phase'];
|
|
5
|
+
readonly claim?: InputState['claim'];
|
|
6
|
+
}
|
|
7
|
+
/** Pure phase, claim, and attempt owner for one Session input. */
|
|
8
|
+
export declare class SubmitMachine {
|
|
9
|
+
private phase;
|
|
10
|
+
private claim;
|
|
11
|
+
private seq;
|
|
12
|
+
private inflight;
|
|
13
|
+
/** Ordinary sends detached from the editor, retained for settlement validation and cancellation. */
|
|
14
|
+
private readonly detached;
|
|
15
|
+
/** Read-only snapshot of the submit-plane state. */
|
|
16
|
+
get state(): SubmitSnapshot;
|
|
17
|
+
/**
|
|
18
|
+
* Feed one event through the machine.
|
|
19
|
+
* @param ev - submit-plane event.
|
|
20
|
+
* @returns effects for the SessionInput shell, in execution order.
|
|
21
|
+
*/
|
|
22
|
+
dispatch(ev: InputEvent): readonly InputEffect[];
|
|
23
|
+
/** The complete command name retains its claim with or without the argument separator. */
|
|
24
|
+
private onDraftChanged;
|
|
25
|
+
/** The editor applied a claim-token replacement; busy phases refuse another claim. */
|
|
26
|
+
private onClaim;
|
|
27
|
+
/** Mint an attempt and controller without assigning its lifecycle owner. */
|
|
28
|
+
private mintAttempt;
|
|
29
|
+
/** Mint the frozen command/adjudication attempt. */
|
|
30
|
+
private beginAttempt;
|
|
31
|
+
/** Mint an ordinary send that leaves the phase plain. */
|
|
32
|
+
private beginDetached;
|
|
33
|
+
/** Default-send effects capture the sink input before the editor commit. */
|
|
34
|
+
private detachedEffects;
|
|
35
|
+
private onEnter;
|
|
36
|
+
private onAdjudicated;
|
|
37
|
+
private onAdjudicationFailed;
|
|
38
|
+
/** Claimed command settlement retains the frozen transaction semantics. */
|
|
39
|
+
private onSubmitSettled;
|
|
40
|
+
/** Settle one ordinary send independently of current phase and other detached sends. */
|
|
41
|
+
private onSinkSettled;
|
|
42
|
+
/** Clear after an accepted attachment-only send; it has no text suffix to retain. */
|
|
43
|
+
private onSendCommitted;
|
|
44
|
+
private onRelease;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=machine.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composer submission policy. It owns the live busy-Enter preference and
|
|
3
|
+
* resolves submission gestures into queue/steer delivery modes; Host and
|
|
4
|
+
* Agent keep the actual delivery-window authority.
|
|
5
|
+
*/
|
|
6
|
+
import { type SnapshotStore } from '@qilin-agent/client-store';
|
|
7
|
+
import type { ConfigForm } from '@qilin-agent/client-ui-settings/client';
|
|
8
|
+
import type { BusyEnterBehavior, ComposerSubmitGesture, InputSubmitMode } from '../contract/composer-submission.ts';
|
|
9
|
+
import type { ConversationSettings } from '../../conversation-settings.ts';
|
|
10
|
+
export { DEFAULT_BUSY_ENTER_BEHAVIOR } from '../../conversation-settings.ts';
|
|
11
|
+
/**
|
|
12
|
+
* Resolve one submission gesture against the busy-Enter preference. Plain
|
|
13
|
+
* Enter and the primary Send button share the `enter` gesture, so the button
|
|
14
|
+
* delivers exactly what Enter would. Direct `steer` is intentionally
|
|
15
|
+
* best-effort: AgentLoop turns a closed-window submission into the next waking
|
|
16
|
+
* Queue item.
|
|
17
|
+
* @param preferred - the live busy-Enter preference.
|
|
18
|
+
* @param running - whether the addressed agent currently reports busy.
|
|
19
|
+
* @param gesture - plain Enter (or the Send button) or the Cmd/Ctrl-accelerated chord.
|
|
20
|
+
* @param steeringAvailable - whether this session transport supports steering.
|
|
21
|
+
* @returns Queue outside steer-capable busy state; otherwise the preferred mode or its opposite.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveSubmitMode(preferred: BusyEnterBehavior, running: boolean, gesture: ComposerSubmitGesture, steeringAvailable: boolean): InputSubmitMode;
|
|
24
|
+
/**
|
|
25
|
+
* Busy-Enter preference shared by the composer bar inject face and its
|
|
26
|
+
* Settings row: one live store the bar's submission gestures and Send label
|
|
27
|
+
* read, backed by the Host user-settings document when one is composed.
|
|
28
|
+
*/
|
|
29
|
+
export declare class ComposerSubmissionPolicy {
|
|
30
|
+
/** Reactive preference source for the composer bar and the Settings row. */
|
|
31
|
+
readonly busyEnter: SnapshotStore<BusyEnterBehavior>;
|
|
32
|
+
private readonly host;
|
|
33
|
+
/**
|
|
34
|
+
* @param host - durable preference scope owned by the providing plugin;
|
|
35
|
+
* absent compositions stay process-local. The adoption subscription shares
|
|
36
|
+
* the scope's plugin lifetime — a disposed scope never publishes again, so
|
|
37
|
+
* the policy needs no release hook.
|
|
38
|
+
*/
|
|
39
|
+
constructor(host?: ConfigForm<ConversationSettings>);
|
|
40
|
+
/**
|
|
41
|
+
* Change the busy-state submission behavior; the live value publishes
|
|
42
|
+
* before the durable write starts.
|
|
43
|
+
* @param behavior - Queue or Steer.
|
|
44
|
+
*/
|
|
45
|
+
setBusyEnter(behavior: BusyEnterBehavior): void;
|
|
46
|
+
/**
|
|
47
|
+
* Adopt the scope's accepted durable behavior without writing it back.
|
|
48
|
+
* @param host - the constructor-narrowed scope driving this adoption.
|
|
49
|
+
*/
|
|
50
|
+
private adopt;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=submission-policy.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation layout policy. It owns the live transcript content width and
|
|
3
|
+
* carries the pre-durable browser preference forward, backed by the Host
|
|
4
|
+
* user-settings document so the width the transcript renders at and the width
|
|
5
|
+
* the General section shows are one fact.
|
|
6
|
+
*/
|
|
7
|
+
import { type SnapshotStore } from '@qilin-agent/client-store';
|
|
8
|
+
import type { ConfigForm } from '@qilin-agent/client-ui-settings/client';
|
|
9
|
+
import type { ConversationSettings } from '../conversation-settings.ts';
|
|
10
|
+
/**
|
|
11
|
+
* Content width shared by the resident Conversation shell and its Settings
|
|
12
|
+
* row: one live store both read, backed by the Host user-settings document
|
|
13
|
+
* when one is composed. `0` leaves the transcript to the layout's adaptive
|
|
14
|
+
* clamp; any other value is an explicit width in px.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ConversationLayoutPolicy {
|
|
17
|
+
/** Reactive width source for the shell and the Settings row. */
|
|
18
|
+
readonly contentWidth: SnapshotStore<number>;
|
|
19
|
+
private readonly host;
|
|
20
|
+
/** Width carried from pre-durable storage, awaiting its first Host view. */
|
|
21
|
+
private pendingSeed;
|
|
22
|
+
/**
|
|
23
|
+
* @param host - durable preference scope owned by the same plugin; absent
|
|
24
|
+
* compositions stay process-local. The adoption subscription shares the
|
|
25
|
+
* scope's plugin lifetime, so a disposed scope never publishes again.
|
|
26
|
+
*/
|
|
27
|
+
constructor(host?: ConfigForm<ConversationSettings>);
|
|
28
|
+
/**
|
|
29
|
+
* Change the transcript content width. The live value publishes before the
|
|
30
|
+
* durable write starts. A drag yields a continuous, column-clamped request,
|
|
31
|
+
* so the request is rounded and bounded here rather than rejected.
|
|
32
|
+
* @param px - {@link CONTENT_WIDTH_ADAPTIVE} for the adaptive clamp, or a width in px.
|
|
33
|
+
*/
|
|
34
|
+
setContentWidth(px: number): void;
|
|
35
|
+
/**
|
|
36
|
+
* Adopt the scope's accepted durable width without writing it back, unless
|
|
37
|
+
* the carried pre-durable preference still awaits its first Host view.
|
|
38
|
+
* @param host - the constructor-narrowed scope driving this adoption.
|
|
39
|
+
*/
|
|
40
|
+
private adopt;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=layout-policy.d.ts.map
|