@qilin-agent/client-ui-input-trigger 3.1.5 → 3.1.6
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/README.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/lib/client.js +18 -0
- package/lib/types/client/controller.d.ts +11 -1
- package/lib/types/types.d.ts +9 -1
- package/package.json +15 -15
package/README.i18n.yaml
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
en: 331a1247c318b1e3
|
|
19
19
|
zh: 6689a92ce0c82942
|
|
20
20
|
/qilin-agent-client-ui-input-trigger/use-this-package/keyboard-and-mouse:
|
|
21
|
-
en:
|
|
22
|
-
zh:
|
|
21
|
+
en: c206c2a507ba00c3
|
|
22
|
+
zh: ac6457cfb135a6bb
|
|
23
23
|
/qilin-agent-client-ui-input-trigger/understand-the-implementation:
|
|
24
24
|
en: 81ac247b6e84a670
|
|
25
25
|
zh: a81221be009a1f47
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ Mount this plugin alongside `ui-conversation`; the menu then appears in the inpu
|
|
|
29
29
|
|
|
30
30
|
### Keyboard and mouse
|
|
31
31
|
|
|
32
|
-
The composer surface keeps focus while the menu is open: rows pick on mousedown, the highlight rides `aria-activedescendant`, and a pointer press outside both the menu and the composer card dismisses it. Opening it from the launcher button puts the keyboard back in the editor before the menu opens, so the arrows drive it there too. Space and Enter adjudication polls the optional `matchSpace`/`matchEnter` hooks in registration order; the first non-undefined answer wins, and a source can refuse a submission it cannot consume whole. Tab acts on the highlighted completion: a candidate declaring `drill: true` routes through `onPick` with `action: 'drill'`, while an ordinary candidate settles through `action: 'pick'`; without a highlight Tab passes untouched so native focus traversal survives. Escape and Shift+Tab leave the menu instead, never settling: the exit gesture cannot consume or rewrite the draft. A dismissed menu stays dismissed: the same token re-tracked with the same query keeps its menu closed, so restoring the caret after a pointer dismissal — or after a settled command closes the surface it opened — cannot bring the menu back; typing a new query or moving to another token re-arms it. A drillable row's trailing chevron exposes the same second verb to pointer users. A source implementing the optional `header` hook additionally publishes crumbs above its group: the pipeline re-polls it on every hit with the live query and whether a drill, rather than typing, produced it, and a crumb pick routes back through `onPick` with `action: 'drill'`.
|
|
32
|
+
The composer surface keeps focus while the menu is open: rows pick on mousedown, the highlight rides `aria-activedescendant`, and a pointer press outside both the menu and the composer card dismisses it. Opening it from the launcher button puts the keyboard back in the editor before the menu opens, so the arrows drive it there too. Space and Enter adjudication polls the optional `matchSpace`/`matchEnter` hooks in registration order; the first non-undefined answer wins, and a source can refuse a submission it cannot consume whole. Restore-time claim resolution polls its own optional `matchClaim` hook over the same registration order: it awaits the source's catalog and returns the claim a token names, never opening a popup, running an action, or executing the command. Tab acts on the highlighted completion: a candidate declaring `drill: true` routes through `onPick` with `action: 'drill'`, while an ordinary candidate settles through `action: 'pick'`; without a highlight Tab passes untouched so native focus traversal survives. Escape and Shift+Tab leave the menu instead, never settling: the exit gesture cannot consume or rewrite the draft. A dismissed menu stays dismissed: the same token re-tracked with the same query keeps its menu closed, so restoring the caret after a pointer dismissal — or after a settled command closes the surface it opened — cannot bring the menu back; typing a new query or moving to another token re-arms it. A drillable row's trailing chevron exposes the same second verb to pointer users. A source implementing the optional `header` hook additionally publishes crumbs above its group: the pipeline re-polls it on every hit with the live query and whether a drill, rather than typing, produced it, and a crumb pick routes back through `onPick` with `action: 'drill'`.
|
|
33
33
|
|
|
34
34
|
A source may implement `openReference(session, reference)` to open a draft reference without submitting it. Acceptance may precede asynchronous catalog loading. Chips route by source name; editable tokens route through the current source lexicon. Returning `false`, a missing source, or a disposed controller leaves the editor gesture unchanged.
|
|
35
35
|
|
package/README.zh.md
CHANGED
|
@@ -29,7 +29,7 @@ kind: "package-reference"
|
|
|
29
29
|
|
|
30
30
|
### 键盘与鼠标
|
|
31
31
|
|
|
32
|
-
菜单打开期间 composer 表面保持焦点:行在 mousedown 时完成 pick,高亮由 `aria-activedescendant` 承载,指针落在菜单与所在 composer 卡片之外即关闭菜单。从 launcher 按钮打开菜单时会先把键盘还给编辑器再开菜单,因此方向键在那里同样可用。空格与回车裁决按注册序轮询可选的 `matchSpace`/`matchEnter` 钩子;第一个非 undefined 的应答胜出,source
|
|
32
|
+
菜单打开期间 composer 表面保持焦点:行在 mousedown 时完成 pick,高亮由 `aria-activedescendant` 承载,指针落在菜单与所在 composer 卡片之外即关闭菜单。从 launcher 按钮打开菜单时会先把键盘还给编辑器再开菜单,因此方向键在那里同样可用。空格与回车裁决按注册序轮询可选的 `matchSpace`/`matchEnter` 钩子;第一个非 undefined 的应答胜出,source 也可以拒绝它无法整体消费的提交。恢复期的认领解析按同一注册序轮询各自的 `matchClaim` 钩子:它等待该 source 的目录就绪,只返回 token 所指的认领,不打开弹窗、不运行 action、也不执行命令。Tab 会作用于高亮补全项:声明 `drill: true` 的候选项以 `action: 'drill'` 进入 `onPick`,普通候选项则以 `action: 'pick'` 完成选定;没有高亮项时 Tab 原样放行,原生焦点遍历不受影响。Escape 与 Shift+Tab 则是离开菜单——它们从不选定,因此退出动作不会消耗或改写草稿。被关闭的菜单保持关闭:同一个 token 以同一查询重新 track 时菜单不会重开——因此指针关闭之后恢复光标、或已选定的命令关闭它自己打开的界面,都不会把菜单召回来;输入新的查询或移到另一个 token 才会重新武装。可下钻行尾的 chevron 向指针用户提供同一个动词。实现可选 `header` 钩子的 source 还会在其分组上方发布面包屑:流水线在每次命中时用实时查询、以及该查询由下钻还是由键入产生这一事实重新询问它,点击面包屑经 `onPick` 以 `action: 'drill'` 回到该 source。
|
|
33
33
|
|
|
34
34
|
来源可以实现 `openReference(session, reference)`,打开草稿引用而不提交。来源可以先接受预览请求,再异步加载目录。标签按来源名称路由;可编辑文本按来源当前的词表路由。返回 `false`、来源缺失或控制器已释放时,保留编辑器原有的手势处理。
|
|
35
35
|
|
package/lib/client.js
CHANGED
|
@@ -1287,6 +1287,24 @@ window.__ModuleLoader__.load({
|
|
|
1287
1287
|
}
|
|
1288
1288
|
}
|
|
1289
1289
|
/**
|
|
1290
|
+
* Resolve the claim a persisted command chip names, polling sources'
|
|
1291
|
+
* matchClaim in registration order; the first claim wins. Never acts on the
|
|
1292
|
+
* token (see {@link InputTriggerSource.matchClaim}).
|
|
1293
|
+
* @param token - command spelling without its argument separator, e.g. '/goal'.
|
|
1294
|
+
* @param signal - abort for the caller's restore attempt.
|
|
1295
|
+
* @returns the claim, or undefined when no source claims the token. Rejects
|
|
1296
|
+
* when a polled source's warmup fails or `signal` aborts.
|
|
1297
|
+
*/
|
|
1298
|
+
async resolveClaim(token, signal) {
|
|
1299
|
+
const projection = this.project();
|
|
1300
|
+
for (const src of this.deps.roster.all()) {
|
|
1301
|
+
if (signal.aborted) throw signal.reason instanceof Error ? signal.reason : /* @__PURE__ */ new Error("command restore aborted");
|
|
1302
|
+
if (src.matchClaim === void 0 || !token.startsWith(src.trigger)) continue;
|
|
1303
|
+
const claim = await src.matchClaim(projection, token, signal);
|
|
1304
|
+
if (claim !== void 0) return claim;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1290
1308
|
* Drop the menu group of a disposed source (root registry change notification).
|
|
1291
1309
|
* @param source - the source whose registration was disposed.
|
|
1292
1310
|
*/
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { Context as ClientContext } from '@qilin-agent/kylin';
|
|
11
11
|
import { type SnapshotStore } from '@qilin-agent/client-store';
|
|
12
|
-
import type { ArbitrateKey, ArbitrateOutcome, PickOutcome, ReferenceInsert } from '@qilin-agent/client-ui-conversation/client';
|
|
12
|
+
import type { ArbitrateKey, ArbitrateOutcome, CommandClaim, PickOutcome, ReferenceInsert } from '@qilin-agent/client-ui-conversation/client';
|
|
13
13
|
import type { SessionId } from '@qilin-agent/session/types';
|
|
14
14
|
import type { MenuState, TriggerHit } from '../core/contract.ts';
|
|
15
15
|
import type { InputTriggerCrumb, InputTriggerSource, PickAction, SubmitEnvelope, TriggerChar, TriggerGuard } from '../types.ts';
|
|
@@ -166,6 +166,16 @@ export declare class InputTriggerController {
|
|
|
166
166
|
* the caller must not silently downgrade.
|
|
167
167
|
*/
|
|
168
168
|
adjudicate(line: string, signal: AbortSignal, envelope: SubmitEnvelope): Promise<PickOutcome>;
|
|
169
|
+
/**
|
|
170
|
+
* Resolve the claim a persisted command chip names, polling sources'
|
|
171
|
+
* matchClaim in registration order; the first claim wins. Never acts on the
|
|
172
|
+
* token (see {@link InputTriggerSource.matchClaim}).
|
|
173
|
+
* @param token - command spelling without its argument separator, e.g. '/goal'.
|
|
174
|
+
* @param signal - abort for the caller's restore attempt.
|
|
175
|
+
* @returns the claim, or undefined when no source claims the token. Rejects
|
|
176
|
+
* when a polled source's warmup fails or `signal` aborts.
|
|
177
|
+
*/
|
|
178
|
+
resolveClaim(token: string, signal: AbortSignal): Promise<CommandClaim | undefined>;
|
|
169
179
|
/**
|
|
170
180
|
* Drop the menu group of a disposed source (root registry change notification).
|
|
171
181
|
* @param source - the source whose registration was disposed.
|
package/lib/types/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* through the provider plugin's own root context captured at registration.
|
|
9
9
|
*/
|
|
10
10
|
import type { ComponentType } from 'react';
|
|
11
|
-
import type { PickOutcome, ReferenceInsert, TokenSpan } from '@qilin-agent/client-ui-conversation/client';
|
|
11
|
+
import type { CommandClaim, PickOutcome, ReferenceInsert, TokenSpan } from '@qilin-agent/client-ui-conversation/client';
|
|
12
12
|
import type { IconProps } from '@qilin-agent/client-ui-primitives';
|
|
13
13
|
import type { SessionId } from '@qilin-agent/session/types';
|
|
14
14
|
export type { ArbitrateKey, ArbitrateOutcome, BeginCommandRequest, CommandClaim, ConsumeTokenRequest, InsertReferenceRequest, InsertTextRequest, PickOutcome, ReferenceInsert, SubmitAttachment, SubmitOutcome, TokenSpan, } from '@qilin-agent/client-ui-conversation/client';
|
|
@@ -172,6 +172,14 @@ export interface InputTriggerSource {
|
|
|
172
172
|
* submission intact.
|
|
173
173
|
*/
|
|
174
174
|
matchEnter?(session: ClientSessionContext, line: string, signal: AbortSignal, envelope: SubmitEnvelope): Promise<PickOutcome>;
|
|
175
|
+
/**
|
|
176
|
+
* Restore-time claim resolution for a persisted command chip. Answers the
|
|
177
|
+
* claim `matchSpace` would make for `token` (e.g. '/goal') after awaiting
|
|
178
|
+
* the source's own warmup, and never acts: a token that would open a
|
|
179
|
+
* popup, run an action, or execute detached answers undefined. Rejects when
|
|
180
|
+
* the warmup fails or `signal` aborts.
|
|
181
|
+
*/
|
|
182
|
+
matchClaim?(session: ClientSessionContext, token: string, signal: AbortSignal): Promise<CommandClaim | undefined>;
|
|
175
183
|
/**
|
|
176
184
|
* Scope-birth prewarm hook (fire-and-forget): the per-session controller
|
|
177
185
|
* calls it once when the session scope comes alive so sources can fetch
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qilin-agent/client-ui-input-trigger",
|
|
3
3
|
"description": "Input trigger pipeline: '/' and '@' detection, candidate menu, pick routing to registered sources",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.6",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -41,25 +41,25 @@
|
|
|
41
41
|
},
|
|
42
42
|
"license": "MIT",
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@qilin-agent/kylin": "~4.0.
|
|
44
|
+
"@qilin-agent/kylin": "~4.0.5"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/react": "~18.3.1",
|
|
48
48
|
"react": "^18.2.0",
|
|
49
49
|
"clsx": "^2.0.0",
|
|
50
|
-
"@qilin-agent/client-locale": "3.1.
|
|
51
|
-
"@qilin-agent/client-ui-conversation": "3.1.
|
|
52
|
-
"@qilin-agent/client-ui-renderer": "3.1.
|
|
53
|
-
"@qilin-agent/client-ui-slots": "3.1.
|
|
54
|
-
"@qilin-agent/client-test-runtime": "3.1.
|
|
55
|
-
"@qilin-agent/client-ui-primitives": "3.1.
|
|
56
|
-
"@qilin-agent/
|
|
57
|
-
"@qilin-agent/api-session-controller": "3.1.
|
|
58
|
-
"@qilin-agent/
|
|
59
|
-
"@qilin-agent/client-store": "3.1.
|
|
60
|
-
"@qilin-agent/
|
|
61
|
-
"@qilin-agent/
|
|
62
|
-
"@qilin-agent/
|
|
50
|
+
"@qilin-agent/client-locale": "3.1.6",
|
|
51
|
+
"@qilin-agent/client-ui-conversation": "3.1.6",
|
|
52
|
+
"@qilin-agent/client-ui-renderer": "3.1.6",
|
|
53
|
+
"@qilin-agent/client-ui-slots": "3.1.6",
|
|
54
|
+
"@qilin-agent/client-test-runtime": "3.1.6",
|
|
55
|
+
"@qilin-agent/client-ui-primitives": "3.1.6",
|
|
56
|
+
"@qilin-agent/kylin": "~4.0.5",
|
|
57
|
+
"@qilin-agent/api-session-controller": "3.1.6",
|
|
58
|
+
"@qilin-agent/file-reference": "3.1.6",
|
|
59
|
+
"@qilin-agent/client-store": "3.1.6",
|
|
60
|
+
"@qilin-agent/session": "3.1.6",
|
|
61
|
+
"@qilin-agent/util-values": "3.1.6",
|
|
62
|
+
"@qilin-agent/client-ui-session": "3.1.6"
|
|
63
63
|
},
|
|
64
64
|
"files": [
|
|
65
65
|
"lib/index.js",
|