@zhin.js/command 1.0.12 → 1.0.14

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.md CHANGED
@@ -11,7 +11,7 @@ Zhin Plugin Runtime 的约定式 Command Feature。它发现 `commands/**/*.ts(x
11
11
  ```ts
12
12
  // commands/gh/issue/list.ts -> gh issue list
13
13
  // commands/赞我.ts -> 赞我
14
- import { defineCommand } from '@zhin.js/command';
14
+ import { defineCommand } from 'zhin.js/command';
15
15
 
16
16
  export default defineCommand({
17
17
  description: 'List GitHub issues',
@@ -31,7 +31,7 @@ export declare class CommandIndex {
31
31
  list(): readonly CommandDescriptor[];
32
32
  has(name: string): boolean;
33
33
  execute(name: string, args?: readonly string[]): Promise<unknown>;
34
- dispatch(input: CommandMatchInput, source?: unknown, promptFactory?: CommandPromptFactory): Promise<CommandDispatchResult>;
34
+ dispatch(input: CommandMatchInput, source?: unknown, promptFactory?: CommandPromptFactory, commandPrefix?: string): Promise<CommandDispatchResult>;
35
35
  }
36
36
  export declare function isCommandIndex(value: unknown): value is CommandIndex;
37
37
  export declare class CommandParameterValueError extends TypeError {
@@ -119,9 +119,9 @@ export class CommandIndex {
119
119
  // Host / 无 session:跳过 permit;无 source 时函数默认值得到空 session。
120
120
  return match.command.slot.definition.execute(createCommandContext(this.snapshot, match.command.slot.owner, args, resolveDynamicParams(match.params, undefined)));
121
121
  }
122
- async dispatch(input, source = undefined, promptFactory) {
122
+ async dispatch(input, source = undefined, promptFactory, commandPrefix = '') {
123
123
  if (this.#menu) {
124
- const menuValue = this.#dispatchMenu(input);
124
+ const menuValue = this.#dispatchMenu(input, commandPrefix);
125
125
  if (menuValue !== undefined) {
126
126
  return Object.freeze({
127
127
  matched: true,
@@ -249,22 +249,22 @@ export class CommandIndex {
249
249
  // ==========================================================================
250
250
  // 内置菜单命令
251
251
  // ==========================================================================
252
- #dispatchMenu(input) {
252
+ #dispatchMenu(input, commandPrefix = '') {
253
253
  const text = typeof input === 'string' ? input.trim() : exactMessageText(input);
254
254
  if (text === undefined)
255
255
  return undefined;
256
256
  const keyword = this.#menu.keyword;
257
257
  if (text === keyword)
258
- return this.#buildMenu();
258
+ return this.#buildMenu(undefined, commandPrefix);
259
259
  if (text.startsWith(keyword + ' ')) {
260
260
  const key = text.slice(keyword.length + 1).trim();
261
261
  if (key)
262
- return this.#buildMenu(key);
263
- return this.#buildMenu();
262
+ return this.#buildMenu(key, commandPrefix);
263
+ return this.#buildMenu(undefined, commandPrefix);
264
264
  }
265
265
  return undefined;
266
266
  }
267
- #buildMenu(pluginKey) {
267
+ #buildMenu(pluginKey, commandPrefix = '') {
268
268
  const root = this.snapshot.root;
269
269
  const targetId = pluginKey
270
270
  ? `${root}/${pluginKey.split('.').join('/')}`
@@ -283,7 +283,7 @@ export class CommandIndex {
283
283
  lines.push('');
284
284
  for (const cmd of directCommands) {
285
285
  const desc = cmd.description ? ` - ${cmd.description}` : '';
286
- lines.push(` ${cmd.name}${desc}`);
286
+ lines.push(` ${commandPrefix}${cmd.name}${desc}`);
287
287
  }
288
288
  }
289
289
  if (children.length > 0) {
@@ -301,7 +301,7 @@ export class CommandIndex {
301
301
  }
302
302
  if (children.length > 0) {
303
303
  lines.push('');
304
- lines.push(`提示:使用「${keyword} <插件名>」查看子插件的指令`);
304
+ lines.push(`提示:使用「${commandPrefix}${keyword} <插件名>」查看子插件的指令`);
305
305
  }
306
306
  return lines.join('\n');
307
307
  }
@@ -146,6 +146,8 @@ export interface CommandSession {
146
146
  export interface CommandPromptOptions {
147
147
  readonly timeout?: number;
148
148
  readonly timeoutText?: string;
149
+ /** Cancel the pending claim when the owning turn aborts. */
150
+ readonly signal?: AbortSignal;
149
151
  }
150
152
  export interface CommandPromptListOptions extends CommandPromptOptions {
151
153
  readonly type?: 'text' | 'number' | 'boolean';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/command",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Convention-based Command Feature for Zhin Plugin Runtime",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -18,9 +18,9 @@
18
18
  ],
19
19
  "dependencies": {
20
20
  "segment-matcher": "^1.0.5",
21
+ "@zhin.js/feature-kit": "1.0.11",
21
22
  "@zhin.js/permission": "1.0.2",
22
- "@zhin.js/plugin-runtime": "1.1.6",
23
- "@zhin.js/feature-kit": "1.0.9"
23
+ "@zhin.js/plugin-runtime": "1.1.6"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/node": "^26.1.2",
@@ -222,9 +222,10 @@ export class CommandIndex {
222
222
  input: CommandMatchInput,
223
223
  source: unknown = undefined,
224
224
  promptFactory?: CommandPromptFactory,
225
+ commandPrefix = '',
225
226
  ): Promise<CommandDispatchResult> {
226
227
  if (this.#menu) {
227
- const menuValue = this.#dispatchMenu(input);
228
+ const menuValue = this.#dispatchMenu(input, commandPrefix);
228
229
  if (menuValue !== undefined) {
229
230
  return Object.freeze({
230
231
  matched: true,
@@ -369,20 +370,20 @@ export class CommandIndex {
369
370
  // 内置菜单命令
370
371
  // ==========================================================================
371
372
 
372
- #dispatchMenu(input: CommandMatchInput): string | undefined {
373
+ #dispatchMenu(input: CommandMatchInput, commandPrefix = ''): string | undefined {
373
374
  const text = typeof input === 'string' ? input.trim() : exactMessageText(input);
374
375
  if (text === undefined) return undefined;
375
376
  const keyword = this.#menu!.keyword;
376
- if (text === keyword) return this.#buildMenu();
377
+ if (text === keyword) return this.#buildMenu(undefined, commandPrefix);
377
378
  if (text.startsWith(keyword + ' ')) {
378
379
  const key = text.slice(keyword.length + 1).trim();
379
- if (key) return this.#buildMenu(key);
380
- return this.#buildMenu();
380
+ if (key) return this.#buildMenu(key, commandPrefix);
381
+ return this.#buildMenu(undefined, commandPrefix);
381
382
  }
382
383
  return undefined;
383
384
  }
384
385
 
385
- #buildMenu(pluginKey?: string): string {
386
+ #buildMenu(pluginKey?: string, commandPrefix = ''): string {
386
387
  const root = this.snapshot.root;
387
388
  const targetId = pluginKey
388
389
  ? `${root}/${pluginKey.split('.').join('/')}` as PluginId
@@ -404,7 +405,7 @@ export class CommandIndex {
404
405
  lines.push('');
405
406
  for (const cmd of directCommands) {
406
407
  const desc = cmd.description ? ` - ${cmd.description}` : '';
407
- lines.push(` ${cmd.name}${desc}`);
408
+ lines.push(` ${commandPrefix}${cmd.name}${desc}`);
408
409
  }
409
410
  }
410
411
 
@@ -425,7 +426,7 @@ export class CommandIndex {
425
426
 
426
427
  if (children.length > 0) {
427
428
  lines.push('');
428
- lines.push(`提示:使用「${keyword} <插件名>」查看子插件的指令`);
429
+ lines.push(`提示:使用「${commandPrefix}${keyword} <插件名>」查看子插件的指令`);
429
430
  }
430
431
 
431
432
  return lines.join('\n');
package/src/definition.ts CHANGED
@@ -196,6 +196,8 @@ export interface CommandSession {
196
196
  export interface CommandPromptOptions {
197
197
  readonly timeout?: number;
198
198
  readonly timeoutText?: string;
199
+ /** Cancel the pending claim when the owning turn aborts. */
200
+ readonly signal?: AbortSignal;
199
201
  }
200
202
 
201
203
  export interface CommandPromptListOptions extends CommandPromptOptions {