@x-otto/plugin 0.1.0-alpha.0 → 0.1.0-alpha.10

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/dist/index.d.ts CHANGED
@@ -1,11 +1,9 @@
1
- /// <reference types="node" />
2
1
  import { z } from "zod";
3
- import { URL, URLSearchParams as URLSearchParams$1 } from "node:url";
4
- import { Duplex, Readable, Writable } from "node:stream";
5
- import { EventEmitter } from "node:events";
6
- import { Blob, File } from "node:buffer";
7
- import { ConnectionOptions, TLSSocket } from "node:tls";
8
- import { IpcNetConnectOpts, Socket, TcpNetConnectOpts } from "node:net";
2
+ import { TypedEventEmitter } from "@x-otto/shared";
3
+ import * as _$_x_otto_interchange0 from "@x-otto/interchange";
4
+ import { PluginInputRegistry, PluginInputRegistry as PluginInputRegistry$1, SigilEntry, SigilEntry as SigilEntry$1, SigilKind, SigilPrefix, SigilProvider, SigilProvider as SigilProvider$1, SigilSource, sigilOf } from "@x-otto/interchange";
5
+ import * as _$_x_otto_provider0 from "@x-otto/provider";
6
+ import { HookAbortSignal, HookPayloadMap, WaterfallTiming } from "@x-otto/hook-contracts";
9
7
 
10
8
  //#region src/capabilities.d.ts
11
9
  /**
@@ -24,7 +22,7 @@ import { IpcNetConnectOpts, Socket, TcpNetConnectOpts } from "node:net";
24
22
  * - 非高危 = 纯数据 / 用户显式触发 / 写面物理隔离 / 单向推送不进入模型上下文。
25
23
  */
26
24
  /** 能力声明词表(RFC-105 D8)。详见各能力注释。 */
27
- declare const PLUGIN_CAPABILITIES: readonly ["provider", "tools", "hooks", "tui.renderer", "network", "context", "monitor", "wire-protocol", "a2ui.component", "panel.backend", "mcp.server", "feedback", "input.resolver", "a2ui.renderer", "theme", "agent.dispatch", "service", "storage", "session.read", "llm.complete", "user.notify", "user.ask"];
25
+ declare const PLUGIN_CAPABILITIES: readonly ["provider", "tools", "hooks", "tui.renderer", "network", "context", "monitor", "wire-protocol", "a2ui.component", "panel.backend", "mcp.server", "feedback", "input.resolver", "a2ui.renderer", "theme", "agent.dispatch", "service", "storage", "session.read", "llm.complete", "user.notify", "user.ask", "config", "credentials", "cli.command", "tui.command", "events", "settings.read", "schedule"];
28
26
  type PluginCapability = (typeof PLUGIN_CAPABILITIES)[number];
29
27
  /**
30
28
  * 高危能力轴(RFC-105 D8):既有布尔信任**不**自动授予这些轴——已信任插件升级后首次
@@ -117,7 +115,7 @@ type PluginFileViewerEntry = z.infer<typeof fileViewerEntrySchema>;
117
115
  /**
118
116
  * a2ui 组件贡献(RFC-105 D1/D6 "a2uiComponents 轴",RFC-155 M155-2 补齐实现):插件声明
119
117
  * 一个新的 a2ui 组件类型名 + 提供渲染实现,扩展宿主受信 catalog(Text/Card/List/Progress/
120
- * Chip/Button 六个内置类型,见 `@otto/tui a2ui-renderer.ts`)。`entry` 同 renderers/panels
118
+ * Chip/Button 六个内置类型,见 `@x-otto/tui a2ui-renderer.ts`)。`entry` 同 renderers/panels
121
119
  * 是**已编译产物**路径。内置类型名为保留字(不可在此声明覆盖,装载层拒绝,见 R4)——
122
120
  * schema 层只做基础字段校验,保留字/跨插件同名冲突检查在装载层完成(装载层才知道运行时
123
121
  * 已注册了哪些类型,schema 层是纯静态声明校验,职责分离)。
@@ -243,6 +241,10 @@ declare const modelEntrySchema: z.ZodObject<{
243
241
  "long-context": "long-context";
244
242
  }>>>>;
245
243
  reasoning: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
244
+ input: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodEnum<{
245
+ text: "text";
246
+ image: "image";
247
+ }>>>>;
246
248
  thinkingLevels: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodEnum<{
247
249
  low: "low";
248
250
  medium: "medium";
@@ -322,7 +324,7 @@ type PluginI18nContribution = z.infer<typeof i18nContributionSchema>;
322
324
  /**
323
325
  * RFC-277 M5:插件贡献主题预设的完整颜色表——镜像 `packages/tui/src/theme/colors.ts` 的
324
326
  * `ThemeColors` interface 全部 27 个字段(`text` 允许省略,对应"终端默认前景"语义)。
325
- * 与 `@otto/setting` 的 `themeColorRoleSchema`(settings 层用户 override,只放行角色名)
327
+ * 与 `@x-otto/setting` 的 `themeColorRoleSchema`(settings 层用户 override,只放行角色名)
326
328
  * 是两个正交的枚举:这里是插件声明**完整调色板**(必须是真实颜色值),那里是用户**引用
327
329
  * 已有角色**做轻量 override(RFC-277 D3 受限覆盖面)。两者不得混淆合并。
328
330
  */
@@ -403,11 +405,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
403
405
  success: "success";
404
406
  error: "error";
405
407
  accent: "accent";
408
+ text: "text";
406
409
  brand: "brand";
407
410
  brandShimmer: "brandShimmer";
408
411
  accentDim: "accentDim";
409
412
  accentBright: "accentBright";
410
- text: "text";
411
413
  inactive: "inactive";
412
414
  secondary: "secondary";
413
415
  subtle: "subtle";
@@ -432,11 +434,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
432
434
  success: "success";
433
435
  error: "error";
434
436
  accent: "accent";
437
+ text: "text";
435
438
  brand: "brand";
436
439
  brandShimmer: "brandShimmer";
437
440
  accentDim: "accentDim";
438
441
  accentBright: "accentBright";
439
- text: "text";
440
442
  inactive: "inactive";
441
443
  secondary: "secondary";
442
444
  subtle: "subtle";
@@ -461,11 +463,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
461
463
  success: "success";
462
464
  error: "error";
463
465
  accent: "accent";
466
+ text: "text";
464
467
  brand: "brand";
465
468
  brandShimmer: "brandShimmer";
466
469
  accentDim: "accentDim";
467
470
  accentBright: "accentBright";
468
- text: "text";
469
471
  inactive: "inactive";
470
472
  secondary: "secondary";
471
473
  subtle: "subtle";
@@ -490,11 +492,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
490
492
  success: "success";
491
493
  error: "error";
492
494
  accent: "accent";
495
+ text: "text";
493
496
  brand: "brand";
494
497
  brandShimmer: "brandShimmer";
495
498
  accentDim: "accentDim";
496
499
  accentBright: "accentBright";
497
- text: "text";
498
500
  inactive: "inactive";
499
501
  secondary: "secondary";
500
502
  subtle: "subtle";
@@ -519,11 +521,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
519
521
  success: "success";
520
522
  error: "error";
521
523
  accent: "accent";
524
+ text: "text";
522
525
  brand: "brand";
523
526
  brandShimmer: "brandShimmer";
524
527
  accentDim: "accentDim";
525
528
  accentBright: "accentBright";
526
- text: "text";
527
529
  inactive: "inactive";
528
530
  secondary: "secondary";
529
531
  subtle: "subtle";
@@ -548,11 +550,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
548
550
  success: "success";
549
551
  error: "error";
550
552
  accent: "accent";
553
+ text: "text";
551
554
  brand: "brand";
552
555
  brandShimmer: "brandShimmer";
553
556
  accentDim: "accentDim";
554
557
  accentBright: "accentBright";
555
- text: "text";
556
558
  inactive: "inactive";
557
559
  secondary: "secondary";
558
560
  subtle: "subtle";
@@ -577,11 +579,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
577
579
  success: "success";
578
580
  error: "error";
579
581
  accent: "accent";
582
+ text: "text";
580
583
  brand: "brand";
581
584
  brandShimmer: "brandShimmer";
582
585
  accentDim: "accentDim";
583
586
  accentBright: "accentBright";
584
- text: "text";
585
587
  inactive: "inactive";
586
588
  secondary: "secondary";
587
589
  subtle: "subtle";
@@ -606,11 +608,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
606
608
  success: "success";
607
609
  error: "error";
608
610
  accent: "accent";
611
+ text: "text";
609
612
  brand: "brand";
610
613
  brandShimmer: "brandShimmer";
611
614
  accentDim: "accentDim";
612
615
  accentBright: "accentBright";
613
- text: "text";
614
616
  inactive: "inactive";
615
617
  secondary: "secondary";
616
618
  subtle: "subtle";
@@ -635,11 +637,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
635
637
  success: "success";
636
638
  error: "error";
637
639
  accent: "accent";
640
+ text: "text";
638
641
  brand: "brand";
639
642
  brandShimmer: "brandShimmer";
640
643
  accentDim: "accentDim";
641
644
  accentBright: "accentBright";
642
- text: "text";
643
645
  inactive: "inactive";
644
646
  secondary: "secondary";
645
647
  subtle: "subtle";
@@ -664,11 +666,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
664
666
  success: "success";
665
667
  error: "error";
666
668
  accent: "accent";
669
+ text: "text";
667
670
  brand: "brand";
668
671
  brandShimmer: "brandShimmer";
669
672
  accentDim: "accentDim";
670
673
  accentBright: "accentBright";
671
- text: "text";
672
674
  inactive: "inactive";
673
675
  secondary: "secondary";
674
676
  subtle: "subtle";
@@ -693,11 +695,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
693
695
  success: "success";
694
696
  error: "error";
695
697
  accent: "accent";
698
+ text: "text";
696
699
  brand: "brand";
697
700
  brandShimmer: "brandShimmer";
698
701
  accentDim: "accentDim";
699
702
  accentBright: "accentBright";
700
- text: "text";
701
703
  inactive: "inactive";
702
704
  secondary: "secondary";
703
705
  subtle: "subtle";
@@ -722,11 +724,11 @@ declare const themePresetContributionSchema: z.ZodObject<{
722
724
  success: "success";
723
725
  error: "error";
724
726
  accent: "accent";
727
+ text: "text";
725
728
  brand: "brand";
726
729
  brandShimmer: "brandShimmer";
727
730
  accentDim: "accentDim";
728
731
  accentBright: "accentBright";
729
- text: "text";
730
732
  inactive: "inactive";
731
733
  secondary: "secondary";
732
734
  subtle: "subtle";
@@ -771,6 +773,14 @@ declare const MAX_I18N_TRANSLATION_BYTES: number;
771
773
  declare const MAX_I18N_LOCALE_FILES_PER_PLUGIN = 20;
772
774
  /** 单个 locale 文件的字节上限(RFC-141 D4,对齐 `context-sources.ts` 的 `MAX_CONTENT_BYTES` 纪律,超限整个文件跳过)。 */
773
775
  declare const MAX_I18N_FILE_BYTES: number;
776
+ /** 单插件可声明的配置字段数上限(RFC-401 D4,防海量字段内存膨胀 DoS)。 */
777
+ declare const MAX_CONFIG_FIELDS_PER_PLUGIN = 32;
778
+ /** 配置 schema 最大嵌套深度(RFC-401 D4,防深嵌套解析 DoS)。 */
779
+ declare const MAX_CONFIG_SCHEMA_DEPTH = 4;
780
+ /** 配置 schema 片段总字节数上限(RFC-401 D4,对齐 i18n 文件上限纪律)。 */
781
+ declare const MAX_CONFIG_SCHEMA_BYTES: number;
782
+ /** 单字段 description 最大字符数(RFC-401 D4,防 UI 渲染膨胀)。 */
783
+ declare const MAX_CONFIG_FIELD_DESCRIPTION_CHARS = 256;
774
784
  /**
775
785
  * 性能采集器贡献(RFC-116 §8:插件可执行的指标采集器,非静态文本)。
776
786
  * `toolRef` 引用同插件 `contributes.tools` 已声明的某个工具名——该工具的返回值即本
@@ -812,6 +822,7 @@ declare const providerEntrySchema: z.ZodObject<{
812
822
  } | undefined;
813
823
  strengths?: ("planning" | "knowledge" | "coding" | "reasoning" | "vision" | "speed" | "long-context")[] | undefined;
814
824
  reasoning?: boolean | undefined;
825
+ input?: ("text" | "image")[] | undefined;
815
826
  thinkingLevels?: ("low" | "medium" | "high" | "xhigh" | "max")[] | undefined;
816
827
  thinkingMode?: "enabled" | "adaptive" | undefined;
817
828
  }[] | undefined, unknown, z.core.$ZodTypeInternals<{
@@ -826,6 +837,7 @@ declare const providerEntrySchema: z.ZodObject<{
826
837
  } | undefined;
827
838
  strengths?: ("planning" | "knowledge" | "coding" | "reasoning" | "vision" | "speed" | "long-context")[] | undefined;
828
839
  reasoning?: boolean | undefined;
840
+ input?: ("text" | "image")[] | undefined;
829
841
  thinkingLevels?: ("low" | "medium" | "high" | "xhigh" | "max")[] | undefined;
830
842
  thinkingMode?: "enabled" | "adaptive" | undefined;
831
843
  }[] | undefined, unknown>>>>;
@@ -863,6 +875,7 @@ declare const providerEntrySchema: z.ZodObject<{
863
875
  }, z.core.$strip>>>;
864
876
  allowAuthHeaderOverride: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
865
877
  preserveProviderId: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
878
+ requiresIntranet: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
866
879
  imageConstraints: z.ZodCatch<z.ZodOptional<z.ZodObject<{
867
880
  maxImagesPerRequest: z.ZodNumber;
868
881
  maxDimensionPxIfOverLimit: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
@@ -881,6 +894,36 @@ declare const cliContributionSchema: z.ZodObject<{
881
894
  bin: z.ZodCatch<z.ZodOptional<z.ZodString>>;
882
895
  }, z.core.$strip>;
883
896
  type PluginCliContribution = z.infer<typeof cliContributionSchema>;
897
+ /**
898
+ * RFC-410 M2:进程内 CLI 命令贡献(`otto <name> [args...]` 在宿主进程内执行插件
899
+ * definePlugin 导出的 handler,与 RFC-112 的 `contributes.cli`(bin 透传子进程)并列)。
900
+ * `name` 命名约束与 `cliContributionSchema` 完全一致(lowercase kebab-case,同一命名空间——
901
+ * 装载层把 cli 与 cliCommands 的 name 放入同一冲突判定漏斗做 fail-closed)。
902
+ * `summary` 是 `otto --help` 命令段与命令列表的帮助行;`i18nKey` 可选指向本插件
903
+ * contributes.i18n 条目做本地化。带 `.max()` + noControlChars 做终端注入防护。
904
+ * 需 `capabilities:["cli.command"]`(高危,宿主进程内执行代码)。
905
+ */
906
+ declare const cliCommandContributionSchema: z.ZodObject<{
907
+ name: z.ZodString;
908
+ summary: z.ZodString;
909
+ i18nKey: z.ZodCatch<z.ZodOptional<z.ZodString>>;
910
+ }, z.core.$strip>;
911
+ type PluginCliCommandContribution = z.infer<typeof cliCommandContributionSchema>;
912
+ /**
913
+ * RFC-440:TUI 斜杠命令贡献元数据(`contributes.slashCommands[].name`)。
914
+ * `name` 命名约束:lowercase kebab-case(对齐 cliCommands;斜杠命令消费方在命令前加 `/`)。
915
+ * `description` 是 `/help` 与命令列表的帮助行;`group` 可选对齐内置 SLASH_COMMANDS 的
916
+ * 分组('session'/'model'/'agent'/'debug'/'ui'/'other',未知值归 'other');`i18nKey` 可选指向
917
+ * 本插件 contributes.i18n 条目做本地化。带 `.max()` + noControlChars 做终端注入防护。
918
+ * 需 `capabilities:["tui.command"]`(高危,宿主进程内执行代码 + TUI 交互面)。
919
+ */
920
+ declare const slashCommandContributionSchema: z.ZodObject<{
921
+ name: z.ZodString;
922
+ description: z.ZodString;
923
+ group: z.ZodCatch<z.ZodOptional<z.ZodString>>;
924
+ i18nKey: z.ZodCatch<z.ZodOptional<z.ZodString>>;
925
+ }, z.core.$strip>;
926
+ type PluginSlashCommandContribution = z.infer<typeof slashCommandContributionSchema>;
884
927
  /**
885
928
  * 声明式 OAuth 贡献(RFC-122 D1):插件声明一个 OAuth 流程(PKCE 或 device-flow),
886
929
  * 装载器据此注册 `OAuthProvider` 实例到 `OAuthRegistry`,`/login` 命令自动发现。
@@ -921,6 +964,52 @@ declare const oauthContributionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
921
964
  }, z.core.$strip>], "kind">;
922
965
  type OAuthContribution = z.infer<typeof oauthContributionSchema>;
923
966
  /** 插件声明贡献了哪些能力面(信息性 + 未来 gating;缺省全部按目录探测)。 */
967
+ /**
968
+ * config schema 格式 = JSON Schema Draft 07 子集(RFC-401 D6)。
969
+ * 支持的 type: string/number/integer/boolean/array/object。
970
+ * 支持的关键字: type/title/description/default/enum/minimum/maximum/pattern/items/properties。
971
+ * 不支持: $ref/oneOf/anyOf/allOf/$defs(DoS 防护 + YAGNI)。
972
+ * DoS 上限: 字段数 ≤32 / 嵌套深度 ≤4 / 总字节 ≤8192 / description ≤256 字符。
973
+ */
974
+ declare const configSchemaEntrySchema: z.ZodObject<{
975
+ type: z.ZodEnum<{
976
+ string: "string";
977
+ number: "number";
978
+ boolean: "boolean";
979
+ object: "object";
980
+ array: "array";
981
+ integer: "integer";
982
+ }>;
983
+ title: z.ZodCatch<z.ZodOptional<z.ZodString>>;
984
+ description: z.ZodCatch<z.ZodOptional<z.ZodString>>;
985
+ default: z.ZodOptional<z.ZodUnknown>;
986
+ enum: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodUnknown>>>;
987
+ minimum: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
988
+ maximum: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
989
+ pattern: z.ZodCatch<z.ZodOptional<z.ZodString>>;
990
+ items: z.ZodOptional<z.ZodUnknown>;
991
+ properties: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
992
+ }, z.core.$strip>;
993
+ /** RFC-401: 配置 schema 片段类型(JSON Schema Draft 07 子集,z.infer 单一真源)。 */
994
+ type PluginConfigSchemaEntry = z.infer<typeof configSchemaEntrySchema>;
995
+ /**
996
+ * RFC-427 D1:插件事件贡献条目。插件声明可发布的自定义事件类型 + payload schema。
997
+ *
998
+ * - `type`:事件类型,强制 `<pluginId>.<event>` 命名空间格式(zod refine 校验),
999
+ * 防跨插件撞名。如 `skill-inductor.candidate-detected`。
1000
+ * - `description`:供事件订阅方理解事件语义(文档性 + 审计面)。
1001
+ * - `payloadSchema`:JSON Schema Draft 07 子集(同 `configField` 约束,RFC-401),
1002
+ * 装载时解析为校验器;emit 时 safeParse,失败 → 丢弃 + warn(fail-closed)。
1003
+ *
1004
+ * 不需要 capability(纯数据声明);但 emit/subscribe 运行时需 `events` capability(D3)。
1005
+ * 卸载走 unregisterBySource 漏斗(R4 可逆 effect)。
1006
+ */
1007
+ declare const eventContributionSchema: z.ZodObject<{
1008
+ type: z.ZodString;
1009
+ description: z.ZodCatch<z.ZodOptional<z.ZodString>>;
1010
+ payloadSchema: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
1011
+ }, z.core.$strip>;
1012
+ type PluginEventContribution = z.infer<typeof eventContributionSchema>;
924
1013
  declare const contributesSchema: z.ZodObject<{
925
1014
  skills: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
926
1015
  agents: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
@@ -930,6 +1019,26 @@ declare const contributesSchema: z.ZodObject<{
930
1019
  name: z.ZodString;
931
1020
  bin: z.ZodCatch<z.ZodOptional<z.ZodString>>;
932
1021
  }, z.core.$strip>>>;
1022
+ cliCommands: z.ZodCatch<z.ZodOptional<z.ZodType<{
1023
+ name: string;
1024
+ summary: string;
1025
+ i18nKey?: string | undefined;
1026
+ }[] | undefined, unknown, z.core.$ZodTypeInternals<{
1027
+ name: string;
1028
+ summary: string;
1029
+ i18nKey?: string | undefined;
1030
+ }[] | undefined, unknown>>>>;
1031
+ slashCommands: z.ZodCatch<z.ZodOptional<z.ZodType<{
1032
+ name: string;
1033
+ description: string;
1034
+ group?: string | undefined;
1035
+ i18nKey?: string | undefined;
1036
+ }[] | undefined, unknown, z.core.$ZodTypeInternals<{
1037
+ name: string;
1038
+ description: string;
1039
+ group?: string | undefined;
1040
+ i18nKey?: string | undefined;
1041
+ }[] | undefined, unknown>>>>;
933
1042
  panels: z.ZodCatch<z.ZodOptional<z.ZodType<{
934
1043
  id: string;
935
1044
  title: string;
@@ -1037,6 +1146,7 @@ declare const contributesSchema: z.ZodObject<{
1037
1146
  } | undefined;
1038
1147
  strengths?: ("planning" | "knowledge" | "coding" | "reasoning" | "vision" | "speed" | "long-context")[] | undefined;
1039
1148
  reasoning?: boolean | undefined;
1149
+ input?: ("text" | "image")[] | undefined;
1040
1150
  thinkingLevels?: ("low" | "medium" | "high" | "xhigh" | "max")[] | undefined;
1041
1151
  thinkingMode?: "enabled" | "adaptive" | undefined;
1042
1152
  }[] | undefined;
@@ -1062,6 +1172,7 @@ declare const contributesSchema: z.ZodObject<{
1062
1172
  } | undefined;
1063
1173
  allowAuthHeaderOverride?: boolean | undefined;
1064
1174
  preserveProviderId?: boolean | undefined;
1175
+ requiresIntranet?: boolean | undefined;
1065
1176
  imageConstraints?: {
1066
1177
  maxImagesPerRequest: number;
1067
1178
  maxDimensionPxIfOverLimit?: number | undefined;
@@ -1088,6 +1199,7 @@ declare const contributesSchema: z.ZodObject<{
1088
1199
  } | undefined;
1089
1200
  strengths?: ("planning" | "knowledge" | "coding" | "reasoning" | "vision" | "speed" | "long-context")[] | undefined;
1090
1201
  reasoning?: boolean | undefined;
1202
+ input?: ("text" | "image")[] | undefined;
1091
1203
  thinkingLevels?: ("low" | "medium" | "high" | "xhigh" | "max")[] | undefined;
1092
1204
  thinkingMode?: "enabled" | "adaptive" | undefined;
1093
1205
  }[] | undefined;
@@ -1113,6 +1225,7 @@ declare const contributesSchema: z.ZodObject<{
1113
1225
  } | undefined;
1114
1226
  allowAuthHeaderOverride?: boolean | undefined;
1115
1227
  preserveProviderId?: boolean | undefined;
1228
+ requiresIntranet?: boolean | undefined;
1116
1229
  imageConstraints?: {
1117
1230
  maxImagesPerRequest: number;
1118
1231
  maxDimensionPxIfOverLimit?: number | undefined;
@@ -1316,18 +1429,18 @@ declare const contributesSchema: z.ZodObject<{
1316
1429
  text?: string | undefined;
1317
1430
  };
1318
1431
  markdown?: {
1319
- heading1?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1320
- heading2?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1321
- headingWeak?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1322
- listMarker?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1323
- listMarkerMuted?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1324
- quoteBar?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1325
- quoteText?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1326
- link?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1327
- inlineCode?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1328
- codeFence?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1329
- tableHeader?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1330
- tableDivider?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1432
+ heading1?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1433
+ heading2?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1434
+ headingWeak?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1435
+ listMarker?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1436
+ listMarkerMuted?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1437
+ quoteBar?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1438
+ quoteText?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1439
+ link?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1440
+ inlineCode?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1441
+ codeFence?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1442
+ tableHeader?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1443
+ tableDivider?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1331
1444
  listIndent?: 2 | 3 | undefined;
1332
1445
  listMarkers?: [string, string, string, string] | undefined;
1333
1446
  codeBlockDivider?: "none" | "hr" | undefined;
@@ -1371,18 +1484,18 @@ declare const contributesSchema: z.ZodObject<{
1371
1484
  text?: string | undefined;
1372
1485
  };
1373
1486
  markdown?: {
1374
- heading1?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1375
- heading2?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1376
- headingWeak?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1377
- listMarker?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1378
- listMarkerMuted?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1379
- quoteBar?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1380
- quoteText?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1381
- link?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1382
- inlineCode?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1383
- codeFence?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1384
- tableHeader?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1385
- tableDivider?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1487
+ heading1?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1488
+ heading2?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1489
+ headingWeak?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1490
+ listMarker?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1491
+ listMarkerMuted?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1492
+ quoteBar?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1493
+ quoteText?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1494
+ link?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1495
+ inlineCode?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1496
+ codeFence?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1497
+ tableHeader?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1498
+ tableDivider?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1386
1499
  listIndent?: 2 | 3 | undefined;
1387
1500
  listMarkers?: [string, string, string, string] | undefined;
1388
1501
  codeBlockDivider?: "none" | "hr" | undefined;
@@ -1427,6 +1540,48 @@ declare const contributesSchema: z.ZodObject<{
1427
1540
  entry: string;
1428
1541
  export?: string | undefined;
1429
1542
  }[] | undefined, unknown>>>>;
1543
+ config: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodUnknown, z.ZodTransform<{
1544
+ type: "string" | "number" | "boolean" | "object" | "array" | "integer";
1545
+ title?: string | undefined;
1546
+ description?: string | undefined;
1547
+ default?: unknown;
1548
+ enum?: unknown[] | undefined;
1549
+ minimum?: number | undefined;
1550
+ maximum?: number | undefined;
1551
+ pattern?: string | undefined;
1552
+ items?: unknown;
1553
+ properties?: Record<string, unknown> | undefined;
1554
+ } | undefined, unknown>>>>;
1555
+ credentialBackends: z.ZodCatch<z.ZodOptional<z.ZodType<{
1556
+ id: string;
1557
+ entry: string;
1558
+ label?: string | undefined;
1559
+ capabilities?: {
1560
+ atomic?: boolean | undefined;
1561
+ permSecure?: boolean | undefined;
1562
+ crossProcessLock?: boolean | undefined;
1563
+ watchable?: boolean | undefined;
1564
+ } | undefined;
1565
+ }[] | undefined, unknown, z.core.$ZodTypeInternals<{
1566
+ id: string;
1567
+ entry: string;
1568
+ label?: string | undefined;
1569
+ capabilities?: {
1570
+ atomic?: boolean | undefined;
1571
+ permSecure?: boolean | undefined;
1572
+ crossProcessLock?: boolean | undefined;
1573
+ watchable?: boolean | undefined;
1574
+ } | undefined;
1575
+ }[] | undefined, unknown>>>>;
1576
+ events: z.ZodCatch<z.ZodOptional<z.ZodType<{
1577
+ type: string;
1578
+ description?: string | undefined;
1579
+ payloadSchema?: Record<string, unknown> | undefined;
1580
+ }[] | undefined, unknown, z.core.$ZodTypeInternals<{
1581
+ type: string;
1582
+ description?: string | undefined;
1583
+ payloadSchema?: Record<string, unknown> | undefined;
1584
+ }[] | undefined, unknown>>>>;
1430
1585
  }, z.core.$strip>;
1431
1586
  type PluginContributes = z.infer<typeof contributesSchema>;
1432
1587
  /**
@@ -1439,6 +1594,10 @@ declare const scriptsSchema: z.ZodObject<{
1439
1594
  }, z.core.$catchall<z.ZodString>>;
1440
1595
  type PluginScripts = z.infer<typeof scriptsSchema>;
1441
1596
  declare const manifestSchema: z.ZodObject<{
1597
+ plane: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
1598
+ host: "host";
1599
+ preset: "preset";
1600
+ }>>>;
1442
1601
  id: z.ZodString;
1443
1602
  name: z.ZodCatch<z.ZodOptional<z.ZodString>>;
1444
1603
  version: z.ZodCatch<z.ZodOptional<z.ZodString>>;
@@ -1455,6 +1614,26 @@ declare const manifestSchema: z.ZodObject<{
1455
1614
  name: z.ZodString;
1456
1615
  bin: z.ZodCatch<z.ZodOptional<z.ZodString>>;
1457
1616
  }, z.core.$strip>>>;
1617
+ cliCommands: z.ZodCatch<z.ZodOptional<z.ZodType<{
1618
+ name: string;
1619
+ summary: string;
1620
+ i18nKey?: string | undefined;
1621
+ }[] | undefined, unknown, z.core.$ZodTypeInternals<{
1622
+ name: string;
1623
+ summary: string;
1624
+ i18nKey?: string | undefined;
1625
+ }[] | undefined, unknown>>>>;
1626
+ slashCommands: z.ZodCatch<z.ZodOptional<z.ZodType<{
1627
+ name: string;
1628
+ description: string;
1629
+ group?: string | undefined;
1630
+ i18nKey?: string | undefined;
1631
+ }[] | undefined, unknown, z.core.$ZodTypeInternals<{
1632
+ name: string;
1633
+ description: string;
1634
+ group?: string | undefined;
1635
+ i18nKey?: string | undefined;
1636
+ }[] | undefined, unknown>>>>;
1458
1637
  panels: z.ZodCatch<z.ZodOptional<z.ZodType<{
1459
1638
  id: string;
1460
1639
  title: string;
@@ -1562,6 +1741,7 @@ declare const manifestSchema: z.ZodObject<{
1562
1741
  } | undefined;
1563
1742
  strengths?: ("planning" | "knowledge" | "coding" | "reasoning" | "vision" | "speed" | "long-context")[] | undefined;
1564
1743
  reasoning?: boolean | undefined;
1744
+ input?: ("text" | "image")[] | undefined;
1565
1745
  thinkingLevels?: ("low" | "medium" | "high" | "xhigh" | "max")[] | undefined;
1566
1746
  thinkingMode?: "enabled" | "adaptive" | undefined;
1567
1747
  }[] | undefined;
@@ -1587,6 +1767,7 @@ declare const manifestSchema: z.ZodObject<{
1587
1767
  } | undefined;
1588
1768
  allowAuthHeaderOverride?: boolean | undefined;
1589
1769
  preserveProviderId?: boolean | undefined;
1770
+ requiresIntranet?: boolean | undefined;
1590
1771
  imageConstraints?: {
1591
1772
  maxImagesPerRequest: number;
1592
1773
  maxDimensionPxIfOverLimit?: number | undefined;
@@ -1613,6 +1794,7 @@ declare const manifestSchema: z.ZodObject<{
1613
1794
  } | undefined;
1614
1795
  strengths?: ("planning" | "knowledge" | "coding" | "reasoning" | "vision" | "speed" | "long-context")[] | undefined;
1615
1796
  reasoning?: boolean | undefined;
1797
+ input?: ("text" | "image")[] | undefined;
1616
1798
  thinkingLevels?: ("low" | "medium" | "high" | "xhigh" | "max")[] | undefined;
1617
1799
  thinkingMode?: "enabled" | "adaptive" | undefined;
1618
1800
  }[] | undefined;
@@ -1638,6 +1820,7 @@ declare const manifestSchema: z.ZodObject<{
1638
1820
  } | undefined;
1639
1821
  allowAuthHeaderOverride?: boolean | undefined;
1640
1822
  preserveProviderId?: boolean | undefined;
1823
+ requiresIntranet?: boolean | undefined;
1641
1824
  imageConstraints?: {
1642
1825
  maxImagesPerRequest: number;
1643
1826
  maxDimensionPxIfOverLimit?: number | undefined;
@@ -1841,18 +2024,18 @@ declare const manifestSchema: z.ZodObject<{
1841
2024
  text?: string | undefined;
1842
2025
  };
1843
2026
  markdown?: {
1844
- heading1?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1845
- heading2?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1846
- headingWeak?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1847
- listMarker?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1848
- listMarkerMuted?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1849
- quoteBar?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1850
- quoteText?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1851
- link?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1852
- inlineCode?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1853
- codeFence?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1854
- tableHeader?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1855
- tableDivider?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2027
+ heading1?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2028
+ heading2?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2029
+ headingWeak?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2030
+ listMarker?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2031
+ listMarkerMuted?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2032
+ quoteBar?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2033
+ quoteText?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2034
+ link?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2035
+ inlineCode?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2036
+ codeFence?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2037
+ tableHeader?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2038
+ tableDivider?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1856
2039
  listIndent?: 2 | 3 | undefined;
1857
2040
  listMarkers?: [string, string, string, string] | undefined;
1858
2041
  codeBlockDivider?: "none" | "hr" | undefined;
@@ -1896,18 +2079,18 @@ declare const manifestSchema: z.ZodObject<{
1896
2079
  text?: string | undefined;
1897
2080
  };
1898
2081
  markdown?: {
1899
- heading1?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1900
- heading2?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1901
- headingWeak?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1902
- listMarker?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1903
- listMarkerMuted?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1904
- quoteBar?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1905
- quoteText?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1906
- link?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1907
- inlineCode?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1908
- codeFence?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1909
- tableHeader?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1910
- tableDivider?: "success" | "error" | "accent" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "text" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2082
+ heading1?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2083
+ heading2?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2084
+ headingWeak?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2085
+ listMarker?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2086
+ listMarkerMuted?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2087
+ quoteBar?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2088
+ quoteText?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2089
+ link?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2090
+ inlineCode?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2091
+ codeFence?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2092
+ tableHeader?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
2093
+ tableDivider?: "success" | "error" | "accent" | "text" | "brand" | "brandShimmer" | "accentDim" | "accentBright" | "inactive" | "secondary" | "subtle" | "replyPrefix" | "warning" | "special" | "suggestion" | "permission" | "codeText" | "diffAdd" | "diffRemove" | "diffAddBg" | "diffRemoveBg" | "panelBorder" | "overlayBg" | "tagBg" | "toolText" | "focusBorder" | "selection" | undefined;
1911
2094
  listIndent?: 2 | 3 | undefined;
1912
2095
  listMarkers?: [string, string, string, string] | undefined;
1913
2096
  codeBlockDivider?: "none" | "hr" | undefined;
@@ -1952,12 +2135,54 @@ declare const manifestSchema: z.ZodObject<{
1952
2135
  entry: string;
1953
2136
  export?: string | undefined;
1954
2137
  }[] | undefined, unknown>>>>;
2138
+ config: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodUnknown, z.ZodTransform<{
2139
+ type: "string" | "number" | "boolean" | "object" | "array" | "integer";
2140
+ title?: string | undefined;
2141
+ description?: string | undefined;
2142
+ default?: unknown;
2143
+ enum?: unknown[] | undefined;
2144
+ minimum?: number | undefined;
2145
+ maximum?: number | undefined;
2146
+ pattern?: string | undefined;
2147
+ items?: unknown;
2148
+ properties?: Record<string, unknown> | undefined;
2149
+ } | undefined, unknown>>>>;
2150
+ credentialBackends: z.ZodCatch<z.ZodOptional<z.ZodType<{
2151
+ id: string;
2152
+ entry: string;
2153
+ label?: string | undefined;
2154
+ capabilities?: {
2155
+ atomic?: boolean | undefined;
2156
+ permSecure?: boolean | undefined;
2157
+ crossProcessLock?: boolean | undefined;
2158
+ watchable?: boolean | undefined;
2159
+ } | undefined;
2160
+ }[] | undefined, unknown, z.core.$ZodTypeInternals<{
2161
+ id: string;
2162
+ entry: string;
2163
+ label?: string | undefined;
2164
+ capabilities?: {
2165
+ atomic?: boolean | undefined;
2166
+ permSecure?: boolean | undefined;
2167
+ crossProcessLock?: boolean | undefined;
2168
+ watchable?: boolean | undefined;
2169
+ } | undefined;
2170
+ }[] | undefined, unknown>>>>;
2171
+ events: z.ZodCatch<z.ZodOptional<z.ZodType<{
2172
+ type: string;
2173
+ description?: string | undefined;
2174
+ payloadSchema?: Record<string, unknown> | undefined;
2175
+ }[] | undefined, unknown, z.core.$ZodTypeInternals<{
2176
+ type: string;
2177
+ description?: string | undefined;
2178
+ payloadSchema?: Record<string, unknown> | undefined;
2179
+ }[] | undefined, unknown>>>>;
1955
2180
  }, z.core.$strip>>>;
1956
2181
  scripts: z.ZodCatch<z.ZodOptional<z.ZodObject<{
1957
2182
  postinstall: z.ZodCatch<z.ZodOptional<z.ZodString>>;
1958
2183
  setup: z.ZodCatch<z.ZodOptional<z.ZodString>>;
1959
2184
  }, z.core.$catchall<z.ZodString>>>>;
1960
- capabilities: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodTransform<("provider" | "tools" | "hooks" | "tui.renderer" | "network" | "context" | "monitor" | "wire-protocol" | "a2ui.component" | "panel.backend" | "mcp.server" | "feedback" | "input.resolver" | "a2ui.renderer" | "theme" | "agent.dispatch" | "service" | "storage" | "session.read" | "llm.complete" | "user.notify" | "user.ask")[] | undefined, unknown[]>>>>;
2185
+ capabilities: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodTransform<("config" | "events" | "provider" | "tools" | "hooks" | "tui.renderer" | "network" | "context" | "monitor" | "wire-protocol" | "a2ui.component" | "panel.backend" | "mcp.server" | "feedback" | "input.resolver" | "a2ui.renderer" | "theme" | "agent.dispatch" | "service" | "storage" | "session.read" | "llm.complete" | "user.notify" | "user.ask" | "credentials" | "cli.command" | "tui.command" | "settings.read" | "schedule")[] | undefined, unknown[]>>>>;
1961
2186
  activationEvents: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodTransform<string[] | undefined, unknown[]>>>>;
1962
2187
  dependsOn: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodTransform<string[] | undefined, unknown[]>>>>;
1963
2188
  codeProviderIds: z.ZodCatch<z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodTransform<string[] | undefined, unknown[]>>>>;
@@ -1983,6 +2208,7 @@ declare const manifestSchema: z.ZodObject<{
1983
2208
  } | undefined;
1984
2209
  strengths?: ("planning" | "knowledge" | "coding" | "reasoning" | "vision" | "speed" | "long-context")[] | undefined;
1985
2210
  reasoning?: boolean | undefined;
2211
+ input?: ("text" | "image")[] | undefined;
1986
2212
  thinkingLevels?: ("low" | "medium" | "high" | "xhigh" | "max")[] | undefined;
1987
2213
  thinkingMode?: "enabled" | "adaptive" | undefined;
1988
2214
  }[] | undefined;
@@ -1998,6 +2224,13 @@ declare const manifestSchema: z.ZodObject<{
1998
2224
  }> | undefined, Record<string, unknown>>>>>;
1999
2225
  }, z.core.$strip>;
2000
2226
  type PluginManifest = z.infer<typeof manifestSchema>;
2227
+ /** RFC-327 修订 D2(M2):manifest 显式 plane 声明('host' | 'preset')。 */
2228
+ type PluginManifestPlane = 'host' | 'preset';
2229
+ /**
2230
+ * RFC-327 修订 D2(M2):解析 manifest 的 plane 声明。缺省 = `'preset'`
2231
+ * (存量插件零行为变化——绝大多数插件贡献是会话/workspace 级,host 是刻意声明)。
2232
+ */
2233
+ declare function resolveManifestPlane(manifest: PluginManifest): PluginManifestPlane;
2001
2234
  /** 有效激活事件:字段缺失或空 → `['onStartup']`(存量插件零行为变化,RFC-105 D7)。 */
2002
2235
  declare function resolveActivationEvents(manifest: PluginManifest): string[];
2003
2236
  /**
@@ -2095,7 +2328,7 @@ declare const PLUGIN_API_VERSION = 1;
2095
2328
  *
2096
2329
  * 单一真源(RFC-082 R7):两条作者路径必须 round-trip 到**同一个** `PluginContributions`——
2097
2330
  * 1. Tier 0 文件约定(`skills/`*.md、`commands/`、`.mcp.json`、`panels/` …)解析 → 本形状
2098
- * 2. Tier 1 `definePlugin()`(`@otto/plugin-sdk`,M082-04)直接返回 → 本形状
2331
+ * 2. Tier 1 `definePlugin()`(`@x-otto/plugin-sdk`,M082-04)直接返回 → 本形状
2099
2332
  * 禁止文件 schema 与代码 schema 两套并行漂移。
2100
2333
  *
2101
2334
  * 装载(RFC-082 D1/D4,Shape B 保形):合并后的 `PluginContributions` 在装载时被**拆解**,
@@ -2116,7 +2349,7 @@ interface CommandContribution {
2116
2349
  body: string;
2117
2350
  }
2118
2351
  /**
2119
- * Agent 贡献(→ 装载为 `@otto/prompt AgentProfile`)。
2352
+ * Agent 贡献(→ 装载为 `@x-otto/prompt AgentProfile`)。
2120
2353
  * 作者可声明子集;运行时解析/补默认在 agent loader。
2121
2354
  */
2122
2355
  interface AgentContribution {
@@ -2132,7 +2365,7 @@ interface AgentContribution {
2132
2365
  allowSubagents?: boolean;
2133
2366
  }
2134
2367
  /**
2135
- * Skill 贡献(→ 装载为 `@otto/skill SkillDefinition`)。
2368
+ * Skill 贡献(→ 装载为 `@x-otto/skill SkillDefinition`)。
2136
2369
  * 作者声明元数据 + 正文;目录/附属文件路径由 loader 在发现时解析。
2137
2370
  */
2138
2371
  interface SkillContribution {
@@ -2141,11 +2374,11 @@ interface SkillContribution {
2141
2374
  /** SKILL.md 去 frontmatter 后正文。 */
2142
2375
  body: string;
2143
2376
  }
2144
- /** MCP transport(镜像 `@otto/mcp McpTransportType`,作者侧字面量避免运行时依赖)。 */
2377
+ /** MCP transport(镜像 `@x-otto/mcp McpTransportType`,作者侧字面量避免运行时依赖)。 */
2145
2378
  type McpTransport = 'stdio' | 'http' | 'sse';
2146
2379
  /**
2147
2380
  * MCP server 贡献(→ 装载为 `EffectiveMcpServer`,loader 注入 source/pluginId)。
2148
- * 镜像 `@otto/mcp McpServerConfig` 的作者可声明子集。插件层 MCP 默认 `managed`(RFC-081 归属保护)
2381
+ * 镜像 `@x-otto/mcp McpServerConfig` 的作者可声明子集。插件层 MCP 默认 `managed`(RFC-081 归属保护)
2149
2382
  * 由 loader 标记,作者无需声明。
2150
2383
  */
2151
2384
  interface McpContribution {
@@ -2208,6 +2441,13 @@ interface PluginContributions {
2208
2441
  * 贡献——凡是"需要先加载 plugin.ts 代码才能算出"的注入内容,视为独立后续项(YAGNI)。
2209
2442
  */
2210
2443
  contextSources?: ContextSourceContribution[];
2444
+ /**
2445
+ * RFC-427 D1:插件事件贡献面(纯数据声明,逐条 fail-soft)。插件声明可发布的自定义
2446
+ * 事件类型 + payload schema,其他插件经 `subscribeEvent` 订阅。需 `capabilities` 含
2447
+ * `events`(非高危——observer-only,不改写引擎状态、不进 prompt)。事件经宿主 event-dispatcher
2448
+ * 中转(身份/权限/payload/频率单点执法),不持久化、不回放(R7)。卸载走 unregisterBySource。
2449
+ */
2450
+ events?: PluginEventContribution[];
2211
2451
  }
2212
2452
  /**
2213
2453
  * 合并多源贡献为单一 `PluginContributions`(RFC-082 §4.2 装载流,R7;RFC-157 M1 轴表化)。
@@ -2295,888 +2535,219 @@ interface DispatchCaps {
2295
2535
  /** 按 type 路由 CommandRef 到注入的 capability。未注入对应 cap → 抛 MissingCapabilityError。 */
2296
2536
  declare function dispatch(cmd: CommandRef, caps: DispatchCaps): Promise<void>;
2297
2537
  //#endregion
2298
- //#region ../provider/dist/index.d.ts
2299
- //#region ../interchange/dist/index.d.ts
2300
- //#region src/message.d.ts
2301
- /** Message: AgentMessage/UserMessage/SystemMessage interchange types. */
2302
- type Timestamp = number;
2303
- type KnownApi = 'openai-completions' | 'openai-responses' | 'azure-openai-responses' | 'openai-codex-responses' | 'anthropic-messages' | 'bedrock-converse-stream' | 'google-generative-ai' | 'google-gemini-cli' | 'google-vertex';
2304
- type Api = KnownApi | (string & {});
2305
- type KnownProvider = 'anthropic' | 'openai' | 'google' | 'amazon-bedrock' | 'github-copilot' | 'xai' | 'groq' | 'openrouter' | 'deepseek' | 'ollama' | 'moonshot' | 'custom';
2306
- type Provider = KnownProvider | (string & {});
2307
- type StopReason = 'end_turn' | 'max_tokens' | 'tool_use' | 'stop_sequence' | 'refusal';
2308
- interface Usage {
2309
- inputTokens: number;
2310
- outputTokens: number;
2311
- cacheReadTokens: number;
2312
- cacheWriteTokens: number;
2313
- }
2538
+ //#region src/sdk.d.ts
2314
2539
  /**
2315
- * 结构化的 zod 兼容垫片——协议层不直接依赖 zod,靠结构类型让 provider/工具定义喂入真 zod schema。
2540
+ * @x-otto/plugin-sdk —— 插件作者 SDK(RFC-082 M082-04,代码逻辑入口)。
2541
+ *
2542
+ * 作者写一份 `plugin.ts`,`export default definePlugin(ctx => ({...}))`。这是 Vite `defineConfig`
2543
+ * 的对等物:`definePlugin` 仅做**类型锚 + identity**(原样返回工厂),不含任何运行时编排——
2544
+ * 产物由 otto 装载器(`loadPluginModule`,M082-04-02)**拆解**喂现有各轴 loader(D1/R1,无中央执行器)。
2545
+ *
2546
+ * 职责边界(RFC-082 R9,F1 修订):`definePlugin` 只承载**代码才需要的东西**——
2547
+ * ① hooks(拦截器/观察器)② computed 贡献(装载时按环境算出的声明式贡献)③ 生命周期。
2548
+ * **静态命令/agent/skill/mcp 仍走文件**(Tier 0),不在此声明——杜绝「两种做法做一件事」。
2549
+ *
2550
+ * 安全(RFC-082 R10):`plugin.ts` 在 otto 主进程内、装载时执行(非沙箱,全 Node 权限),
2551
+ * 由信任门门控*是否*执行;hooks(尤其可 deny/block 工具的 preToolUse)默认关 + 显式启用。
2316
2552
  */
2317
- interface ZodType<T = unknown> {
2318
- parse(data: unknown): T;
2319
- safeParse(data: unknown): {
2320
- success: boolean;
2321
- data?: T;
2322
- error?: unknown;
2323
- };
2324
- toJSONSchema?: () => unknown;
2325
- }
2326
- interface TextContent {
2327
- type: 'text';
2328
- text: string;
2329
- signature?: string;
2330
- }
2331
- interface ImageContent {
2332
- type: 'image';
2333
- mime: string;
2334
- source: string;
2335
- }
2336
- interface ThinkingContent {
2337
- type: 'thinking';
2338
- text: string;
2339
- signature?: string;
2340
- }
2341
- interface ToolCall {
2342
- type: 'tool_call';
2343
- id: string;
2344
- name: string;
2345
- arguments: Record<string, unknown>;
2346
- /**
2347
- * 流式参数 JSON 解析失败标记(RFC-142 D4)——`stopReason: max_tokens` 截断半截
2348
- * JSON 时 `parseToolArguments` 置位,runtime 责任链据此把该调用转为明确错误
2349
- * tool_result 而非带空参数进入 zod 校验(与污染类错误分离错误通道)。
2350
- *
2351
- * **进程内标记,不进 wire**:各 provider 序列化发给模型时均为显式字段拾取
2352
- * (`{type, id, name, input: arguments}`,无 spread),本字段天然剥除——有测试钉住
2353
- * (RFC-142 重要事项规则4)。
2354
- */
2355
- argumentsParseFailed?: boolean;
2356
- }
2357
2553
  /**
2358
- * A2UI content block(RFC-105 D6/M105-5b):agent 生成的声明式 UI payload。
2359
- * 对齐 a2ui-project/a2ui(v0.9)的核心哲学——扁平组件列表 + ID 引用 + 受信组件 catalog、
2360
- * 纯数据非代码、未知组件类型文本降级。
2554
+ * 工具调用上下文(hooks 观测/拦截用)。
2361
2555
  *
2362
- * 组件类型(TUI 终端安全子集,首阶段只读 display):
2363
- * - Text:纯文本(text 字段)。
2364
- * - Card:带标题容器(title + children ID 引用)。
2365
- * - List:条目列表(items ID 引用 + ordered 标志)。
2366
- * - Progress:ASCII 进度条(value 0-100,label 可选)。
2367
- * - Chip:内联彩色标签(text + color)。
2368
- * - Button:交互按钮(RFC-105 D6 F5/M105-5c,数字键触发 a2ui action;只读 display 通过
2369
- * renderA2uiBlock 提取为 A2uiButtonInfo 元数据)。
2370
- * - Form:交互式表单(RFC-211 M1:字段定义 + TUI 弹窗填写 + web-ui 原生表单)。
2371
- * 字段类型 text/select/toggle,payload 原样回流,不可执行代码。
2372
- * 未知 type → 文本摘要表示(不崩,fail-soft,R7)。
2556
+ * `paths`/`readonly`/`sessionId` 是只读上下文(从 `ToolExecuteBeforeInput` 透传),
2557
+ * 让插件做路径级权限策略(如 browser-use 的站点级规则)。三字段可选——
2558
+ * 旧宿主不注入时 undefined,插件容错(`?? fallback`)。只读透传不破坏 R10
2559
+ * (插件只能 deny/ask 不能 allow)。
2373
2560
  */
2374
- interface A2uiComponent {
2375
- id: string;
2376
- type: 'Text' | 'Card' | 'List' | 'Progress' | 'Chip' | 'Button' | 'Form' | (string & {});
2377
- text?: string;
2378
- title?: string;
2379
- children?: string[];
2380
- items?: string[];
2381
- ordered?: boolean;
2382
- value?: number;
2383
- max?: number;
2384
- label?: string;
2385
- color?: 'accent' | 'green' | 'amber' | 'red' | 'gray';
2386
- action?: string;
2387
- shortcut?: string;
2388
- /** 表单标题(弹窗标题 + 对话流摘要标题)。 */
2389
- formTitle?: string;
2390
- /** 表单字段定义。 */
2391
- fields?: A2uiFormField[];
2392
- }
2393
- /** 单个表单字段(`A2uiComponent.type === 'Form'` 时使用)。 */
2394
- interface A2uiFormField {
2395
- /** 字段 id(Form 内唯一,submit payload 的 key)。 */
2396
- id: string;
2397
- /** 字段类型。 */
2398
- type: 'text' | 'select' | 'toggle';
2399
- /** 显示标签。 */
2400
- label: string;
2401
- /** 默认值(text=字符串, select=option id, toggle=boolean)。 */
2402
- defaultValue?: string | boolean;
2403
- /** 占位符(text 类型)。 */
2404
- placeholder?: string;
2405
- /** 选项列表(select 类型必填)。 */
2406
- options?: Array<{
2407
- id: string;
2408
- label: string;
2409
- }>;
2410
- /** 是否必填(渲染提示,不做前端校验——非目标)。 */
2411
- required?: boolean;
2412
- }
2413
- interface A2uiContent {
2414
- type: 'a2ui';
2415
- /** A2UI 协议版本(v0.9 snapshot),供未来版本迁移用。 */
2416
- version: string;
2417
- /** 扁平组件列表,ID 引用构建组件树,增量子集可追加/替换。 */
2418
- components: A2uiComponent[];
2419
- }
2420
- type ContentPart = TextContent | ImageContent | ThinkingContent | ToolCall | A2uiContent;
2421
- interface UserMessage {
2422
- role: 'user';
2423
- content: string | ContentPart[];
2424
- timestamp: Timestamp;
2425
- uuid?: string;
2426
- /**
2427
- * RFC-050 REV-1:引擎注入的内部消息(如预算收尾 steering、截断续写提示),模型需要看到、
2428
- * 但**不应渲染给用户**(否则 resume 时显示成用户从未输入的发言)。provider 序列化忽略此字段。
2429
- */
2430
- internal?: boolean;
2431
- }
2432
- interface AssistantMessage {
2433
- role: 'assistant';
2434
- /**
2435
- * 消息内容。A2uiContent 是前向兼容新增(RFC-155 M2 结案后的协议层收口):
2436
- * provider 序列化层仅消费 text/tool_call/thinking,a2ui 块被静默跳过不出进 LLM 请求体;
2437
- * 渲染层(message-lines.ts)经 `renderA2uiBlock` 渲染。
2438
- */
2439
- content: (TextContent | ThinkingContent | ToolCall | A2uiContent)[];
2440
- api: Api;
2441
- provider: Provider;
2442
- model: string;
2443
- usage: Usage;
2444
- stopReason: StopReason;
2445
- uuid?: string;
2446
- }
2447
- interface ToolResultMessage<T extends unknown = unknown> {
2448
- role: 'tool_result';
2449
- toolCallId: string;
2561
+ interface ToolUseContext {
2450
2562
  toolName: string;
2451
- /**
2452
- * 工具结果内容。A2uiContent 是前向兼容新增(RFC-155 M2 结案后的协议层收口):
2453
- * provider 序列化仅消费 text,a2ui 块被静默跳过;渲染层(message-lines.ts)经
2454
- * `renderA2uiBlock` 渲染为终端卡片。
2455
- */
2456
- content: (TextContent | ImageContent | A2uiContent)[];
2457
- details: T;
2458
- isError: boolean;
2459
- timestamp: Timestamp;
2460
- uuid?: string;
2461
- /** RFC-050 REV-1:引擎合成的内部 tool_result(如预算耗尽未执行的占位),不渲染给用户。 */
2462
- internal?: boolean;
2563
+ input: unknown;
2564
+ /** 工具声明的 AgentTool.pathParams args 解析出的文件系统路径(只读)。 */
2565
+ paths?: readonly string[];
2566
+ /** 工具是否为只读(AgentTool.readonly,只读)。 */
2567
+ readonly?: boolean;
2568
+ /** 会话 ID(只读)。 */
2569
+ sessionId?: string;
2463
2570
  }
2464
2571
  /**
2465
- * RFC-144 M1:mid-conversation system 通知消息——**真正进 provider 请求**的协议消息类型
2466
- * (区别于 `@otto/hook-contracts` 的 `SystemAgentMessage`,后者是 hooks/UI 域、
2467
- * convertToLLM 类型边界显式过滤、绝不进 provider 请求)。
2468
- *
2469
- * 用途:lifecycleAsync 工具(RFC-144)真正完成时,追加一条独立消息告知 LLM"运营方观察到
2470
- * 的状态变化"(Anthropic mid-conversation system message 官方场景之一),不修改/替换任何
2471
- * 历史消息(纯追加语义),LLM 在下一轮推理中作为权威事实处理。
2572
+ * PreToolUse 决策(拦截器返回)。`deny` 拒绝;`ask` 转人工确认。
2472
2573
  *
2473
- * provider 序列化:
2474
- * - Anthropic(原生支持,Claude Opus 4.8+)→ `{role: 'system', content}` 追加进 messages 数组,
2475
- * 放置规则见 RFC-144 重要事项规则 5(必须紧跟携带 tool_result 的 user turn 之后)。
2476
- * - 不支持该特性的模型/provider(如 OpenAI,或 Anthropic 旧模型)→ 降级为等价的
2477
- * `role: 'user'` 消息 + 显式文本前缀(牺牲"运营方权威"语义,保留基本可用性),
2478
- * 降级逻辑归属 provider adapter 层(本类型定义不关心降级细节)。
2479
- *
2480
- * 不可变性(RFC-144 禁区):一旦追加,绝不编辑或删除已发送的 system 通知——结果更新一律
2481
- * 追加新消息,不改写旧消息(Anthropic 官方限制:编辑会使该点之后的 prompt cache 失效)。
2482
- */
2483
- interface SystemNotificationMessage {
2484
- role: 'system_notification';
2485
- /** 通知正文(如 "[Tool completion] pnpm build finished: exit 0")。 */
2486
- content: string;
2487
- /**
2488
- * 该通知对应的工具执行是否失败——显式字段,供消费方(渲染层/审计)直接读取,不必解析
2489
- * `content` 文案判断状态(RFC-144 M2:文案格式可能演进,靠字符串匹配脆弱且易误判)。
2490
- */
2491
- isError?: boolean;
2492
- /** 关联的 lifecycleAsync 工具调用 id,供消费方(渲染层/审计)溯源。 */
2493
- relatedToolCallId?: string;
2494
- timestamp: Timestamp;
2495
- uuid?: string;
2496
- }
2497
- type Message = UserMessage | AssistantMessage | ToolResultMessage | SystemNotificationMessage;
2498
- /**
2499
- * 历史压缩摘要消息的标记前缀——单一真相源(跨包协议常量)。
2500
- * 生产者 @otto/memory 注入摘要消息时用、压缩去重(isSummaryMessage)时识别;消费者
2501
- * @otto/agent 的 ContextPipeline 从会话树恢复摘要时用同一前缀重建摘要消息。放在协议叶子,
2502
- * 避免双份字面量漂移导致 isSummaryMessage 失配。
2574
+ * `void` = 无意见/放行到既有 hook 链判定(等价于 `allow`——不干预,交由既有权限链判定)。
2575
+ * 插件不能授权,只能限制(R10:allow no-op,故不设 allow 变体——
2576
+ * 返回 void 即放行,deny/ask 之外无需第三个值)。
2503
2577
  */
2504
- //#endregion
2505
- //#region src/stream.d.ts
2578
+ type PreToolUseDecision = {
2579
+ decision: 'deny';
2580
+ reason?: string;
2581
+ } | {
2582
+ decision: 'ask';
2583
+ reason?: string;
2584
+ };
2506
2585
  /**
2507
- * 供应商 usage 快照(状态栏「周/小时额度」展示,RFC 无编号临时功能——状态栏 provider usage)。
2586
+ * 插件代码 hooks(RFC-082 R9,映射 RFC-032 hook 事件;RFC-129 D1 扩展 9 个 observer 字段)。
2587
+ * `preToolUse` = 拦截器(可改变控制流);其余全部 = 观察器(fire-and-forget,无法改写引擎状态)。
2588
+ * 全部可选;返回 Promise 则 await。R10:默认关 + 信任门,由装载器把关。
2508
2589
  *
2509
- * Anthropic OAuth 订阅计划(Claude Pro/Max)请求会带 anthropic-ratelimit-unified-* 响应头族;
2510
- * API key 走标准 RPM/TPM 限流不带此头族,故 provider/ai 层解析不到时返回 null,调用方天然
2511
- * 实现"API key 不显示"(见 packages/ai/src/provider-usage.ts extractProviderUsageFromHeaders
2512
- * 与 packages/ai/src/auth-store.ts getAuthSource)。
2590
+ * RFC-129 D1 边界纪律:新增的 9 个字段全部是 observer-only——不开放任何可变换消息/参数的
2591
+ * interceptor timing(`messages.transform`/`chat.params`/`system.prompt.transform`/
2592
+ * `chat.message.after` 均不对插件开放,见 RFC-129 §1.2 非目标 + 放弃方案)。
2513
2593
  *
2514
- * usedPercent 未经 Anthropic 官方文档确认(仅有 status/representative-claim/reset 三个字段有
2515
- * SDK 源码级证据),探测不到时为 undefined——UI 侧绝不显示猜测/编造的百分比数字。
2594
+ * RFC-327 修订 D1(M1)显式修订:上述边界纪律对 `waterfall` 贡献面**不再成立**——
2595
+ * waterfall 是**新的贡献面**(不是 observer 改 interceptor),经受控白名单 timing
2596
+ * (`WaterfallTiming`)开放三个受控中间产物的改写点,见下方 `waterfall` 字段说明。
2516
2597
  */
2517
- interface ProviderUsageSnapshot {
2518
- /**
2519
- * 订阅配额状态。'allowed'/'allowed_warning'/'rejected' 来自 Anthropic unified 头族的
2520
- * 真实语义;**'unknown' = 无订阅配额数据**(RFC-118 小修 S11:OpenAI 只有标准
2521
- * x-ratelimit-* 头无配额语义,此前重载 'allowed' 造成同字段双语义——UI 按
2522
- * status!=='rejected' 判「额度 OK」会让 OpenAI 用户永远看不到预警)。
2523
- * 消费端对 'unknown' 应展示中性态(不判额度充足也不报警)。
2524
- */
2525
- status: 'allowed' | 'allowed_warning' | 'rejected' | 'unknown';
2526
- limitType?: 'five_hour' | 'seven_day' | 'seven_day_opus' | 'seven_day_sonnet' | 'seven_day_overage_included';
2527
- /** Unix 时间戳(秒)——配额重置时刻。 */
2528
- resetsAt?: number;
2529
- /** 已用百分比(0-100)。未探测到时 undefined。 */
2530
- usedPercent?: number;
2598
+ interface PluginHooks {
2599
+ preToolUse?: (ctx: ToolUseContext) => PreToolUseDecision | void | Promise<PreToolUseDecision | void>;
2600
+ postToolUse?: (ctx: ToolUseContext & {
2601
+ result: unknown;
2602
+ }) => void | Promise<void>;
2603
+ userPromptSubmit?: (ctx: {
2604
+ prompt: string;
2605
+ }) => void | Promise<void>;
2606
+ sessionStart?: () => void | Promise<void>;
2607
+ stop?: () => void | Promise<void>;
2608
+ /** 会话从持久化存储恢复时触发(`session.restored`)。 */
2609
+ sessionRestored?: (ctx: {
2610
+ sessionId: string;
2611
+ }) => void | Promise<void>;
2612
+ /** 会话被删除时触发(`session.deleted`)。 */
2613
+ sessionDeleted?: (ctx: {
2614
+ sessionId: string;
2615
+ }) => void | Promise<void>;
2616
+ /** 会话进入空闲态时触发(`session.idle`)。 */
2617
+ sessionIdle?: (ctx: {
2618
+ sessionId: string;
2619
+ }) => void | Promise<void>;
2531
2620
  /**
2532
- * Overage(额外用量池)状态。
2533
- * 仅当标准额度已耗尽(status='rejected')且 overage 可用(overageStatus='allowed'/'allowed_warning')
2534
- * 时有意义——此时 isUsingOverage = true,状态栏应展示 overage 标识而非 rejected 错误态。
2535
- * 无 overage 头族的请求(API key / 未开通 overage)此字段为 undefined。
2621
+ * 会话发生错误时触发(`session.error`)。`error` 为字符串(非 `Error` 对象)——
2622
+ * 装载器负责把 `Error.message` 序列化后传入,避免栈追踪等敏感信息泄漏给插件代码。
2536
2623
  */
2537
- overageStatus?: 'allowed' | 'allowed_warning' | 'rejected';
2538
- /** Overage 池重置时刻(Unix 秒)。 */
2539
- overageResetsAt?: number;
2540
- /** Overage 不可用原因(仅在 overageStatus='rejected' 时可能有值)。 */
2541
- overageDisabledReason?: string;
2624
+ sessionError?: (ctx: {
2625
+ sessionId: string;
2626
+ error: string;
2627
+ }) => void | Promise<void>;
2628
+ /** 流式响应开始时触发(`stream.start`)。 */
2629
+ streamStart?: (ctx: {
2630
+ sessionId: string;
2631
+ model: string;
2632
+ }) => void | Promise<void>;
2542
2633
  /**
2543
- * 标准 API 限流快照(x-ratelimit-* 头族,有官方文档)。与 Anthropic unified 订阅配额
2544
- * 不同——这里表示的是分钟级请求/Token 的 token bucket 限流,任何认证方式的请求都返回
2545
- * (Anthropic API key + OpenAI API key + OAuth 订阅)。undefined = 没有标准限流头。
2546
- *
2547
- * 格式来自 OpenAI Rate Limits 文档(x-ratelimit-limit-requests/remaining-requests/
2548
- * reset-requests/-limit-tokens/-remaining-tokens/-reset-tokens),Anthropic 也用
2549
- * 同名头族但加上 `anthropic-` 前缀。
2634
+ * 即将触发压缩裁剪前触发(`compaction.before`)。`messageCount` 是即将参与裁剪判定的消息量——
2635
+ * `compactionOccurred`(`retainedCount`=裁剪后保留量)是不同信息维度,可用于预判裁剪规模。
2636
+ * observer 语义(无法否决压缩),不要与 memory 内部专用的 `memory.prune.before` 拦截器混淆。
2550
2637
  */
2551
- standardLimits?: {
2552
- remainingRequests?: number;
2553
- remainingTokens?: number;
2554
- limitRequests?: number;
2555
- limitTokens?: number;
2556
- resetRequestsMs?: number;
2557
- resetTokensMs?: number;
2558
- };
2559
- }
2560
- /**
2561
- * 流式增量事件——provider converse() 的统一产物面。RFC-067 M111(A5):所有 provider 都必须
2562
- * 发齐 text/thinking/tool_call 的 start/delta/end 包络(end 带累积 content),否则下游
2563
- * 「完成通知」会丢内容。单一真相源避免 anthropic 全发 12 变体而 OpenAI 系发不全的漂移。
2564
- */
2565
- type StreamEvent = {
2566
- type: 'start';
2567
- partial: AssistantMessage;
2568
- } | {
2569
- type: 'text_start';
2570
- index: number;
2571
- partial: AssistantMessage;
2572
- } | {
2573
- type: 'text_delta';
2574
- index: number;
2575
- delta: string;
2576
- partial: AssistantMessage;
2577
- } | {
2578
- type: 'text_end';
2579
- index: number;
2580
- content: string;
2581
- partial: AssistantMessage;
2582
- } | {
2583
- type: 'thinking_start';
2584
- index: number;
2585
- partial: AssistantMessage;
2586
- } | {
2587
- type: 'thinking_delta';
2588
- index: number;
2589
- delta: string;
2590
- partial: AssistantMessage;
2591
- } | {
2592
- type: 'thinking_end';
2593
- index: number;
2594
- content: string;
2595
- partial: AssistantMessage;
2596
- } | {
2597
- type: 'tool_call_start';
2598
- index: number;
2599
- partial: AssistantMessage;
2600
- } | {
2601
- type: 'tool_call_delta';
2602
- index: number;
2603
- delta: string;
2604
- partial: AssistantMessage;
2605
- } | {
2606
- type: 'tool_call_end';
2607
- index: number;
2608
- toolCall: ToolCall;
2609
- partial: AssistantMessage;
2610
- } | {
2611
- type: 'done';
2612
- reason: StopReason;
2613
- message: AssistantMessage; /** 本轮成功响应解析出的供应商 usage 快照(仅 Anthropic OAuth 订阅计划非 null)。 */
2614
- providerUsage?: ProviderUsageSnapshot | null;
2615
- } | {
2616
- type: 'error';
2617
- error: Error;
2618
- }; //#endregion
2619
- //#region src/model.d.ts
2620
- /**
2621
- * 推理投入档(reasoning effort)——RFC-235 对齐 Claude Code 词表:`low/medium/high/xhigh/max`。
2622
- * 去除历史遗留的 `minimal`(无对应厂商语义,存量配置载入时迁移为 `low`),新增 `max`(Claude
2623
- * Code 最高档 + DeepSeek `reasoning_effort:'max'` 顶档)。各模型真实支持的子集由 manifest 的
2624
- * `Model.thinkingLevels` 声明,provider 组装请求体时按"≤该档最高支持档"降级(见 RFC-235 §3.3)。
2625
- */
2626
- type ThinkingLevel = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
2627
- /**
2628
- * 模型能力优势标签(供大模型为 subagent 选型)。非 /models API 返回——由
2629
- * model-capabilities 据「精选家族图 + 启发式」推导。
2630
- * planning=方案/架构 · knowledge=知识/通识 · coding=编码 · reasoning=深度推理
2631
- * · vision=视觉 · speed=低延迟 · long-context=长上下文
2632
- */
2633
- type ModelStrength = 'planning' | 'knowledge' | 'coding' | 'reasoning' | 'vision' | 'speed' | 'long-context';
2634
- interface Cost {
2635
- input: number;
2636
- output: number;
2637
- cacheRead: number;
2638
- cacheWrite: number;
2639
- }
2640
- interface Model<T = Api> {
2641
- id: string;
2642
- name: string;
2643
- api: T;
2644
- provider: Provider;
2645
- baseUrl: string;
2646
- reasoning: boolean;
2647
- input: ('text' | 'image')[];
2638
+ compactionPending?: (ctx: {
2639
+ sessionId: string;
2640
+ messageCount: number;
2641
+ }) => void | Promise<void>;
2642
+ /** 压缩裁剪完成后触发(`compaction.after`)。 */
2643
+ compactionOccurred?: (ctx: {
2644
+ sessionId: string;
2645
+ retainedCount: number;
2646
+ }) => void | Promise<void>;
2648
2647
  /**
2649
- * 美元 / 百万 token 定价(终局修复:改为可选,不再强制归零)。三家主流供应商
2650
- * (Anthropic/OpenAI/GitHub Copilot,逐一核实过官方文档+SDK 源码)的 `/models` 列表接口
2651
- * 均不返回定价——这不是接口设计缺陷,是行业普遍现状:`/models` 回答"能用哪些模型",
2652
- * 定价只写在面向人类阅读的文档页(会随时间调整),没有供应商把它做成程序化查询接口。
2653
- * 缺省(`undefined`)= 该模型没有已知定价来源(如运行时从供应商接口动态发现的新型号),
2654
- * UI 层应据此不显示开销估算,而非显示误导性的 $0(用户可能误以为模型免费,实际正常计费)。
2655
- * 有值 = 人工核实过的真实历史定价(当前来自各插件 manifest 声明)。
2648
+ * 任务(子 agent task)完成时触发(`task.completed`)。`durationMs`/`tokenUsage` 为可选字段,
2649
+ * 从底层 `TaskHookOutput` 透传,可能因任务类型或早期版本缺失。
2656
2650
  */
2657
- cost?: Cost;
2658
- contextWindow: number;
2659
- maxOutputTokens: number;
2660
- thinkingLevels?: ThinkingLevel[];
2651
+ taskCompleted?: (ctx: {
2652
+ taskId: string;
2653
+ status: string;
2654
+ durationMs?: number;
2655
+ tokenUsage?: {
2656
+ input: number;
2657
+ output: number;
2658
+ cacheRead: number;
2659
+ };
2660
+ }) => void | Promise<void>;
2661
+ /** 任务失败时触发(`task.failed`)。 */
2662
+ taskFailed?: (ctx: {
2663
+ taskId: string;
2664
+ error: string;
2665
+ }) => void | Promise<void>;
2661
2666
  /**
2662
- * thinking 配置格式声明:
2663
- * - 'enabled'(缺省):标准 Anthropic `{ type: 'enabled', budget_tokens: N }`
2664
- * - 'adaptive':`{ type: 'adaptive' }` + 顶层 `output_config.effort`(部分网关要求此格式)
2667
+ * 任务被取消时触发(`task.cancelled`,08-13 终局 review 观察项:纯 observer,
2668
+ * 对自迭代感知"子任务被取消"有真实价值——被取消的任务不该重复派发)。
2665
2669
  */
2666
- thinkingMode?: 'enabled' | 'adaptive';
2667
- /** 能力优势标签(供 subagent 选型);由 model-capabilities 推导,非内置硬编码真源。 */
2668
- strengths?: ModelStrength[];
2670
+ taskCancelled?: (ctx: {
2671
+ taskId: string;
2672
+ }) => void | Promise<void>;
2669
2673
  /**
2670
- * 图片约束声明(RFC-148 M5):单请求最大图片数 + 超阈值后的单图最大边长约束。
2671
- * 由插件 manifest 的模型条目声明(供应商专属约束,如 Anthropic 官方规则"单请求
2672
- * >maxImagesPerRequest 张图时单图任一边 > maxDimensionPxIfOverLimit 即 400",
2673
- * 见 `packages/agent/src/image-degradation.ts` 消费方)。缺省 = 无已知约束
2674
- * (引擎侧不主动截断,行为等价于约束不存在——不臆造保守默认值)。
2674
+ * 任务(子 agent task)建档时触发(`task.created`),先于 `task.started` 触发。
2675
+ * 此时 agent 归属尚未确定(`TaskHookInfo` subagent 字段),仅 taskId 可用。
2675
2676
  */
2676
- imageConstraints?: {
2677
- maxImagesPerRequest: number;
2678
- maxDimensionPxIfOverLimit?: number;
2679
- };
2680
- /**
2681
- * 工具调用支持声明(RFC-130 M131-2,同 `imageConstraints` 声明化模式):该模型/provider
2682
- * 是否支持客户端工具委托。缺省 `undefined` = 支持(向后兼容——绝大多数 provider 支持工具,
2683
- * 不臆造保守默认值破坏存量行为)。仅当 provider 协议层明确不支持工具委托时(如 Cursor
2684
- * agent API 只服务端自跑内置工具,M131-3-00b 已证伪双向映射可行性)声明 `false`,宿主
2685
- * (`session-config-resolver.ts`)据此剥离工具集,避免 provider 抛协议错误——引擎侧
2686
- * 只读布尔声明,不识别具体厂商字符串(终局判据,同 RFC-148 系列的 zero-vendor-knowledge
2687
- * 原则)。
2688
- */
2689
- supportsTools?: boolean;
2690
- /**
2691
- * Responses API 请求体策略声明(RFC-213):供 `openai-responses` 协议实现按声明覆盖
2692
- * 标准请求体字段,替代此前失效的 `model.api === 'openai-codex-responses'` 字符串判断
2693
- * (RFC-122 provider 插件化迁移后该字面量已物理不可达,是死代码——见 RFC-213 背景的
2694
- * 逐层源码追溯)。缺省 = 标准行为(不设置 `store`、按
2695
- * `context.maxTokens ?? model.maxOutputTokens` 发送 `max_output_tokens`)。
2696
- */
2697
- responseBodyPolicy?: {
2698
- /** 显式设置 body.store(如 ZDR 合规场景需要 false)。缺省不设置该字段(沿用 API 默认)。 */store?: boolean;
2699
- /**
2700
- * false = 不发送 max_output_tokens 字段。官方 `openai/codex` CLI 源码(`ResponsesApiRequest`
2701
- * 结构体)从不发送该字段(用 `reasoning`/`text` 控制输出),且社区证据(reasoning 模型
2702
- * 系列经 Responses API 收到该字段会被 400 拒绝)表明这不是可选的风格差异。缺省 true(发送)。
2703
- */
2704
- sendMaxOutputTokens?: boolean;
2705
- };
2706
- } //#endregion
2707
- //#region src/types.d.ts
2708
- interface ToolDefinition<TArgs = unknown> {
2709
- name: string;
2710
- description: string;
2711
- parameters: ZodType<TArgs>;
2712
- }
2713
- /**
2714
- * system prompt 的缓存稳定性分层段。仅用于 Anthropic 动态断点定位——
2715
- * provider 在「最后一个 stable 段」之后挂 cache_control,volatile 段照发但不进缓存前缀。
2716
- * content 的真相源仍是 StreamContext.systemPrompt(完整扁平串,供其它 provider 消费)。
2717
- */
2718
- interface SystemPromptSegment {
2719
- text: string;
2720
- /** 'stable'(默认)=会话内冻结、进缓存前缀;'volatile'=每轮可变、落在断点之后。 */
2721
- cache?: 'stable' | 'volatile';
2722
- }
2723
- /**
2724
- * prompt cache 保留档(决定 Anthropic ephemeral 断点的 TTL):
2725
- * - 'none':不放任何缓存断点(一次性/eval 请求,省去缓存写开销);
2726
- * - 'short'(缺省语义):5 分钟 TTL;
2727
- * - 'long':1 小时 TTL(长会话——思考久/工具轮多/有交互空档时命中率更高)。
2728
- */
2729
- type CacheRetention = 'none' | 'short' | 'long';
2730
- interface StreamContext {
2731
- model: Model;
2732
- /** 完整 system 文本(stable + volatile 已拼接)。所有 provider 的 content 真相源。 */
2733
- systemPrompt: string;
2677
+ taskCreated?: (ctx: {
2678
+ taskId: string;
2679
+ }) => void | Promise<void>;
2680
+ /** 任务开始执行时触发(`task.started`),已通过并发准入、进入 running 态,agent 归属已确定。 */
2681
+ taskStarted?: (ctx: {
2682
+ taskId: string;
2683
+ agent: string;
2684
+ }) => void | Promise<void>;
2734
2685
  /**
2735
- * 可选的缓存分层视图。仅 Anthropic 据此动态放断点;省略时退化为单块尾部断点(旧行为)。
2736
- * 各段 text 拼接应等价于 systemPrompt。
2686
+ * 通知发生时触发(`notification`,终局 review 2026-08-14 插件化方案 A)。
2687
+ * 来自 @x-otto/notification 脊柱的出站交付——会话事件经归一
2688
+ * (turn_complete/error/approval_required/input_required)后由 hook 桥 emit。
2689
+ * `notification_type` 是归一类别而非原始 AgentSessionEvent 形状(跨包边界纪律)。
2737
2690
  */
2738
- systemPromptSegments?: SystemPromptSegment[];
2739
- messages: Message[];
2740
- tools?: ToolDefinition[];
2741
- thinkingLevel?: ThinkingLevel;
2742
- maxTokens?: number;
2743
- temperature?: number;
2744
- cacheRetention?: CacheRetention;
2745
- }
2746
- interface StreamOptions {
2747
- signal?: AbortSignal;
2748
- timeout?: number;
2691
+ onNotification?: (ctx: {
2692
+ sessionId: string;
2693
+ message: string;
2694
+ title?: string;
2695
+ notification_type: string;
2696
+ }) => void | Promise<void>;
2749
2697
  /**
2750
- * SSE 流的**空闲**超时(毫秒,仅 stream()):每收到一个 chunk 重置;连续此 ms 内无任何
2751
- * 字节到达即 abort。与 `timeout`(整请求墙钟上限)不同——专治「连接活着但 provider
2752
- * 静默不再吐字节」的挂死。缺省 120s。
2698
+ * RFC-327 修订 D1(M1):waterfall 贡献面——插件经受控白名单 timing 改写主循环中间产物。
2753
2699
  *
2754
- * RFC-XX reasoning-thinking:reasoning 模型(kimi-k3/GLM-5.2 等)的 thinking 阶段可
2755
- * 长达分钟级零 visible token——中间无任何 SSE chunk,默认 120s idle 会无差别单边坑
2756
- * 所有 reasoning 模型(实测 turn 3 触发:thinking_start 零输出 → stream.retry×2 →
2757
- * 崩)。调用方应据此在转产 conversational function 具调用(work-loop 等里)显式加大。
2758
- */
2759
- idleTimeout?: number;
2760
- }
2761
- interface ProviderStream {
2762
- readonly id: string;
2763
- readonly displayName: string;
2764
- /**
2765
- * 统一鉴权解析(RFC-140 D5):此前 4 个 provider 实现(当时在本包,RFC-148 M2 后
2766
- * anthropic-messages/openai-responses/openai-completions 已迁至
2767
- * extensions/plugin-otto-wire-protocols/src/,github-copilot 在
2768
- * extensions/plugin-github-copilot/src/provider.ts)各自的凭据解析签名各不相同——
2769
- * anthropic 是 `resolveAuthCredential(): Promise<ResolvedAuth>`(唯一带 mode/beta 的
2770
- * 完整版,未走接口声明的 `resolveKey`),其余三个各自实现
2771
- * `resolveKey(): Promise<string>` 但入参/来源不统一。新 provider 作者(含第三方代码式
2772
- * 插件)不知道该实现哪一个。统一为单一签名:`ResolvedAuth` 已含 token/mode/beta,语义
2773
- * 完整,解析失败时 reject(不返回 null——沿用各实现既有的 PROVIDER_AUTH_MISSING
2774
- * 错误纹理)。
2700
+ * 语义对齐 HookRegistry 既有 interceptor(priority → 共享可变 output → 后续可见前者
2701
+ * 改写),**外加** serial-with-early-bail:任一 handler 返回 `{ abort: true }` →
2702
+ * 终止该 timing 的整条 hook 链,output 保留已累积值(后续引擎 hook 不执行)。
2775
2703
  *
2776
- * 可选(`?`)保留是因为 `ProviderRegistry`/`AuthStore` 侧的调用路径本就允许 provider
2777
- * 不声明鉴权解析(极少数场景,如未来的零凭据本地 provider);四个内置 wire 实现全部
2778
- * 实现该方法。
2779
- */
2780
- resolveAuth?(model: Model): Promise<ResolvedAuth>;
2781
- converse(model: Model<Api>, context: StreamContext, options: StreamOptions, signal: AbortSignal): AsyncIterable<StreamEvent>;
2782
- /**
2783
- * 可选清理钩子(RFC-105 D2/评审 F8):卸载时释放 HTTP 连接池/流等资源。
2784
- * 内置 provider 目前均无持久资源,可不实现;插件 provider 卸载时
2785
- * `ProviderRegistry.unregisterBySource` 会调用(存在则调用)。
2786
- */
2787
- dispose?(): void | Promise<void>;
2788
- }
2789
- /**
2790
- * JWT claim 派生 header 配置(RFC-122 D3)。结构对齐 openai-responses/openai-completions
2791
- * 各自的同名本地定义——本类型仅供 `WireProtocolFactoryInput` 使用(RFC-148 新增的协议中立层
2792
- * 入口);两个协议实现随 RFC-148 M2 物理迁移至 extensions/plugin-otto-wire-protocols/src/。
2793
- */
2794
- interface TokenDerivedHeader {
2795
- header: string;
2796
- source: {
2797
- kind: 'jwt-claim';
2798
- claim: string;
2799
- namespace?: string;
2800
- tokenSources?: Array<'id_token' | 'access_token'>;
2801
- };
2802
- }
2803
- /**
2804
- * Wire 协议实现的注册契约(RFC-148 D1)——`@otto/ai` 的 `WireProtocolRegistry` 与
2805
- * `@otto/plugin` 的 `PluginModule.wireProtocols` 轴共用同一份类型定义,避免跨包重复。
2806
- * 定义在协议中立层(`@otto/provider`)而非 `@otto/ai`:两个消费方(宿主注册表 + 插件 SDK)
2807
- * 都已 type-only 依赖本包,符合既有 `AnthropicRequestCustomizeInput` 的分层先例。
2808
- */
2809
- interface WireRequestCustomizeInput {
2810
- auth: {
2811
- mode: 'api_key' | 'oauth';
2812
- beta?: string;
2813
- };
2814
- sessionId: string;
2815
- }
2816
- /** 通用 system 文本块最小结构(`Anthropic.TextBlockParam` 的子集,SDK 无关,见 WireRequestCustomization.transformSystemBlocks)。 */
2817
- interface WireSystemTextBlock {
2818
- type: 'text';
2819
- text: string;
2820
- cache_control?: unknown;
2821
- }
2822
- interface WireRequestCustomization {
2823
- defaultHeaders?: Record<string, string>;
2824
- /** system 数组变换(如插入身份前缀块);非全部协议都支持——不支持的协议实现忽略该字段。 */
2825
- transformSystemBlocks?: (blocks: WireSystemTextBlock[] | undefined) => WireSystemTextBlock[] | undefined;
2826
- metadata?: Record<string, unknown>;
2827
- }
2828
- /**
2829
- * 插件侧协议实现的日志端口(RFC-185 D3)。宿主注入(走宿主进程的单一 pino 单例 →
2830
- * 日志总线/文件),插件源码**禁止**自建 `createLogger`——esbuild bundle 会把
2831
- * `@otto/shared` logger 整体复制成第二份单例,宿主的级别/通道控制够不着它,直写
2832
- * stderr 破坏 TUI(findings-backlog「2026-07-13 TUI 残影回归」根因环 2)。
2833
- * `debug` 档是宿主↔协议实现的内部约定(`PluginContext.logger` 对外仍是
2834
- * info/warn/error 三档 + 可选 debug)。
2835
- */
2836
- interface WireProtocolLogger {
2837
- /** 首参兼容 pino 两种惯用形态:结构化对象(mergingObject)或格式化字符串。 */
2838
- debug: (objOrMsg: string | Record<string, unknown>, ...args: unknown[]) => void;
2839
- info: (objOrMsg: string | Record<string, unknown>, ...args: unknown[]) => void;
2840
- warn: (objOrMsg: string | Record<string, unknown>, ...args: unknown[]) => void;
2841
- error: (objOrMsg: string | Record<string, unknown>, ...args: unknown[]) => void;
2842
- }
2843
- interface WireProtocolFactoryInput {
2844
- resolveAuth: () => Promise<{
2845
- token: string;
2846
- mode: 'api_key' | 'oauth';
2847
- beta?: string;
2848
- } | undefined>;
2849
- resolveBaseUrl: () => Promise<string | undefined>;
2850
- headers?: Record<string, string>;
2851
- tokenDerivedHeaders?: TokenDerivedHeader[];
2852
- /** 请求定制点——厂商个性注入唯一通道(如 plugin-anthropic 的 Claude Code 伪装)。 */
2853
- customizeRequest?: (input: WireRequestCustomizeInput) => WireRequestCustomization;
2854
- /**
2855
- * RFC-270 D3:允许 manifest 静态头/JWT 派生头/拦截器覆盖鉴权头(`authorization`/`x-api-key`)。
2856
- * 缺省 `undefined` = 不允许(默认丢弃 + warn)——otto 的 manifest 可由第三方插件分发,
2857
- * 静默替换 Authorization 等于把用户凭据路由到任意端点。企业网关确需换鉴权时由 provider
2858
- * 在 manifest 显式声明 `allowAuthHeaderOverride: true`,装载期 warn 一条保证可审计。
2859
- */
2860
- allowAuthHeaderOverride?: boolean;
2861
- sessionId?: string;
2862
- /**
2863
- * RFC-185 D3:宿主注入的日志端口。可选字段(向后兼容,不 bump PLUGIN_API_VERSION);
2864
- * 缺省时协议实现必须 fallback 到 no-op——绝不 fallback 到 createLogger(复活第二单例)。
2865
- */
2866
- logger?: WireProtocolLogger;
2867
- }
2868
- /** 协议注册携带的能力元数据(RFC-147 B-1:替代 `CACHE_REPORTING_APIS` 硬编码白名单)。 */
2869
- interface WireProtocolMeta {
2870
- /** 该协议的 usage 是否携带 cache token 字段。缺省 = false(不上报)。 */
2871
- reportsCacheTokens?: boolean;
2872
- }
2873
- interface WireProtocolRegistration {
2874
- create: (input: WireProtocolFactoryInput) => ProviderStream;
2875
- meta?: WireProtocolMeta;
2876
- }
2877
- type OAuthCredentials = {
2878
- refresh: string;
2879
- access: string;
2880
- expires: number; /** GitHub Enterprise host(如 company.ghe.com);持久化以便后续刷新仍打到企业域而非默认 github.com。 */
2881
- domain?: string;
2882
- [key: string]: unknown;
2883
- };
2884
- type OAuthProviderId = string;
2885
- interface OAuthInfo {
2886
- url: string;
2887
- code?: string;
2888
- instructions?: string;
2889
- }
2890
- interface OAuthPrompt {
2891
- message: string;
2892
- placeholder?: string;
2893
- allowEmpty?: boolean;
2894
- }
2895
- interface OAuthLoginOptions {
2896
- onAuth: (info: OAuthInfo) => void;
2897
- onPrompt: (prompt: OAuthPrompt) => Promise<string>;
2898
- onProgress?: (message: string) => void;
2899
- /**
2900
- * 手动粘贴授权码兜底通道。`signal` 由 provider 在自动通道(loopback 回调)
2901
- * 先完成时触发——实现方应据此关闭粘贴输入框并 resolve 空串。
2902
- */
2903
- onManualCode?: (signal?: AbortSignal) => Promise<string>;
2904
- signal?: AbortSignal;
2905
- }
2906
- interface OAuthRefreshTokenOptions extends OAuthCredentials {
2907
- domain?: string;
2908
- }
2909
- interface OAuthProvider {
2910
- readonly id: OAuthProviderId;
2911
- readonly name: string;
2912
- usesCallbackServer?: boolean;
2913
- /**
2914
- * 以 OAuth token 调用对应 API 时必带的 beta 头(如 Anthropic 的 `oauth-2025-04-20`)。
2915
- * provider 据此在 oauth 模式下附加 `anthropic-beta`(M8-04/05)。
2916
- */
2917
- readonly oauthBeta?: string;
2918
- /**
2919
- * 此 OAuth 令牌是否绑定到某个**产品订阅**(如 Anthropic 的 Claude Code 订阅 token
2920
- * `sk-ant-oat`)。这类令牌在用于该产品自身 system prompt 之外的请求时会被服务端限流
2921
- * (HTTP 429),因此**不适合**用作 subagent 委派的可用模型来源(RFC-061 §3 D2)。
2922
- * 由 usability gate(`@otto/ai/model-usability`)消费;供 api_key 凭证不受此影响——
2923
- * provider 一旦持有真 API key,`getAuthSource` 返回 `api_key`,此标志即不被查询。
2704
+ * 安全边界(R1'/R10):
2705
+ * - 只作用于白名单 timing 的**受控中间产物**(`system.prompt.transform` /
2706
+ * `chat.params` / `messages.transform`)——不开放原始会话存储与工具执行参数
2707
+ * (messages.transform 会看到待发送消息列表,含历史派生内容——白名单设计内的
2708
+ * 能力,全程审计);
2709
+ * - 白名单编译期强制(`WaterfallTiming` `HookPayloadMap` Pick),装载器运行时校验兜底,
2710
+ * 白名单外 timing 一律拒绝注册(fail-closed);
2711
+ * - `system.prompt.transform` 默认只开放 `systemTail`(volatile,cache 断点后,逐轮可变)
2712
+ * + 预算闸(4KB 顶)——`systemPrompt`(stable,进 prompt cache)**第一版不开放**,
2713
+ * 尝试写入被装载器拒绝(fail-closed,写入会永久污染后续所有轮次的 prompt cache 前缀);
2714
+ * - 全程审计(pluginId + timing + 变更摘要),走既有 capability/trust/隔离 RPC 三重门,
2715
+ * 不另建旁路。
2716
+ *
2717
+ * 能力面跃迁声明:从「插件只能 deny/ask 升级限制」到「插件能改写受控中间产物」是质变,
2718
+ * 本字段是新贡献面(非 observer interceptor),配套 D1a 分权与安全门见 RFC-327 修订 §3。
2924
2719
  */
2925
- readonly subscriptionScoped?: boolean;
2926
- login(options: OAuthLoginOptions): Promise<OAuthCredentials>;
2927
- refreshToken(options: OAuthRefreshTokenOptions): Promise<OAuthCredentials>;
2928
- getAccessKey(credentials: OAuthCredentials): string;
2929
- }
2930
- type AuthMode = 'api_key' | 'oauth';
2931
- interface ResolvedAuth {
2932
- /** 实际用于鉴权的令牌(API key 或 OAuth access token)。 */
2933
- token: string;
2934
- /** 鉴权模式。 */
2935
- mode: AuthMode;
2936
- /** OAuth 模式下需附带的 beta 头(来源于 OAuthProvider.oauthBeta)。 */
2937
- beta?: string;
2938
- } //#endregion
2939
- //#region src/provider/chat-completions.d.ts
2940
- //#endregion
2941
- //#region ../interchange/dist/index.d.ts
2942
- interface GrillOption {
2943
- label: string;
2944
- rationale: string;
2945
- recommended?: boolean;
2946
- preview?: string;
2947
- }
2948
- interface GrillAnswer {
2949
- answer: string;
2950
- selectedOptionLabels?: string[];
2951
- acceptedRecommendation: boolean;
2720
+ waterfall?: PluginWaterfallHooks;
2952
2721
  /**
2953
- * 回答的来源(终局语义):
2954
- * - 'human':真实用户(TUI/交互端)作答。
2955
- * - 'auto_recommendation':调用方/LLM 侧在无交互需求下按推荐直接沉降(推荐被采纳,且这不是环境限制导致)。
2956
- * - 'environment_headless':运行环境本身不支持问询(headless/无 UI),自动把推荐沉降。
2957
- * 插件状态机不应把这种回答当作"用户明确接受"来推进候选。
2722
+ * RFC-401 D5:配置变更通知(observer-only,不走整插件重载)。
2723
+ * 宿主在 PluginConfigStore 写入后调用此 hook 传入新配置对象——插件可选择实现
2724
+ * (不实现则下次 reload 时自然更新)。与 onActivate/onDeactivate 的区别:
2725
+ * onActivate/onDeactivate 是"装载/卸载"生命周期,onConfigChange 是"运行时配置热更"。
2726
+ * observer 纹理:不改变引擎状态,异常被吞 + 记录日志(同其他 observer hook,R5)。
2958
2727
  */
2959
- resolvedBy: 'human' | 'auto_recommendation' | 'environment_headless';
2960
- /** grill_me allowFreeform:用户在选项之外输入的补充文字。 */
2961
- freeformText?: string;
2728
+ onConfigChange?: (newConfig: Record<string, unknown>) => void | Promise<void>;
2962
2729
  }
2963
- //#endregion
2964
- //#region src/input.d.ts
2965
- /** Input: mentions, sigils, content providers — user input enrichment types. */
2966
- /** sigil 子类型:`hashtag` 属 `#`,其余属 `@`。`resource` = 插件自定义资源(RFC-210 D2);
2967
- * `shortcut` = 用户在本仓库自定义的文本快捷方式(RFC-233)。 */
2968
- type SigilKind = 'hashtag' | 'file' | 'person' | 'agent' | 'skill' | 'mcp' | 'plugin' | 'model' | 'resource' | 'shortcut';
2969
- /** 触发前缀。 */
2970
- type SigilPrefix = '#' | '@';
2971
- /** 条目来源标识(unregisterBySource 据此批量注销,防僵尸条目)。 */
2972
- type SigilSource = 'builtin' | 'plugin' | 'skill' | 'mcp' | (string & {});
2973
2730
  /**
2974
- * 动态供给函数(pull 模型):按 query 懒查候选,服务 @file 等大候选集——
2975
- * 不全量 register()。可同步或异步(文件系统遍历走异步)。
2731
+ * RFC-327 修订 D1(M1):waterfall handler timing 签名——input/output 与引擎
2732
+ * `HookPayloadMap` 对齐(编译期逐 timing 精确类型,无双重断言),返回值支持 abort 哨兵。
2976
2733
  */
2977
- type SigilProvider = (query: string, sigil: SigilPrefix) => SigilEntry[] | Promise<SigilEntry[]>;
2978
- /** sigil 面板条目:label(展示)与 value(替换内容)严格分离(R2)。 */
2979
- interface SigilEntry {
2980
- /** 面板中展示的名称(简短、人类可读)。绝不进入 prompt 文本。 */
2981
- label: string;
2982
- /** 选中后替换 #trigger/@trigger 的实质内容。绝不在面板中完整展示。 */
2983
- value: string;
2984
- /** 面板中展示的描述(可选,列表副标题)。 */
2985
- description?: string;
2986
- /** 条目类型(影响面板分组/着色,并决定属于 # 还是 @)。 */
2987
- kind: SigilKind;
2988
- /** 来源标识(builtin | plugin | skill | mcp | 自定义 pluginId)。 */
2989
- source?: SigilSource;
2990
- /**
2991
- * RFC-210 D2:resolve 引用。非空 = "提交时展开"型资源——展开管线(app.expandSigilChips)
2992
- * 用此 id 查 SigilResolverRegistry 拿 resolve 函数,把该条目的 chip 替换为其返回值。
2993
- * 空 = 透传型(chip 原样给 LLM)或纯文本型(value 即内容),行为与现状完全一致。
2994
- */
2995
- resolverId?: string;
2996
- }
2734
+ type PluginWaterfallHandler<T extends WaterfallTiming> = (input: HookPayloadMap[T]['input'], output: HookPayloadMap[T]['output']) => void | HookAbortSignal | Promise<void | HookAbortSignal>;
2735
+ /** RFC-327 修订 D1(M1):waterfall 贡献面的逐 timing 映射(mapped type 保持 per-key 类型精确)。 */
2736
+ type PluginWaterfallHooks = { [T in WaterfallTiming]?: PluginWaterfallHandler<T> };
2997
2737
  /**
2998
- * RFC-210 D2:@ 资源提交时展开函数(代码契约——不可序列化,归 coding 层
2999
- * SigilResolverRegistry,与纯数据的 PluginInputRegistry 平行;D9 两类契约纪律)。
2738
+ * 终局 review(2026-08-14):PluginHooks 按域分组类型别名。
2739
+ * 运行时契约不变——PluginHooks 仍是一层扁平可选字段;这些别名在类型层补域结构,
2740
+ * 供 IDE/文档/插件作者理解 hook 的分类。新增 timing 必须在此登记到对应域,
2741
+ * 且在 module-wiring 的 ScalarPluginHookField 排除/登记(编译期门)。
3000
2742
  */
3001
- interface SigilResolver {
3002
- /** resolver id,命名空间 `<pluginId>:<name>`(内置无前缀)。 */
3003
- id: string;
3004
- /** 提交时展开:输入 chip 参数(`[@kind:param]` param 段),返回发给 LLM 的内容。 */
3005
- resolve: (param: string, ctx: SigilResolveContext) => string | Promise<string>;
3006
- /** 超时(ms,缺省 10_000,对齐既有 CONTEXT_CHIPS 约束)。 */
3007
- timeoutMs?: number;
3008
- /**
3009
- * uiHostOnly(RFC-210 评审 B11):true = 读取"UI 所在机器"的本地资源(非 workspaceDir
3010
- * 内容),只应在与用户同机的宿主进程(TUI/cli)执行;service expand 端点跳过执行。
3011
- * @clipboard = true(读桌面剪贴板);@changes/@git = false(读 workspaceDir git 状态,
3012
- * service 为远程 workspace 服务时服务器上的状态正是用户要的内容)。
3013
- */
3014
- uiHostOnly?: boolean;
3015
- }
3016
- /** SigilResolver.resolve 的执行上下文。 */
3017
- interface SigilResolveContext {
3018
- workspaceDir: string;
3019
- /** 输出上限(字符,缺省 20_000,超限截断——对齐既有 MAX_OUTPUT)。 */
3020
- maxOutput: number;
3021
- }
3022
- /**
3023
- * 插件输入注册表(UI 无关,由 createApp() 创建单例,实现留 @otto/coding)。
3024
- *
3025
- * 静态 push 供给(register)+ 动态 pull 供给(registerProvider,服务 @file
3026
- * 大候选集懒查,RFC §1.3.1 F-domain / RFC-044 M044-07)。
3027
- */
3028
- interface PluginInputRegistry {
3029
- /** 注册一批条目(last-write-wins,按 (label, kind) 复合键去重)。 */
3030
- register(entries: SigilEntry[]): void;
3031
- /**
3032
- * 注册某 sigil 的动态供给器(pull 模型,按 query 懒查,如 @file)。
3033
- * 返回注销函数。其结果在 searchAsync 中与静态条目合并。
3034
- */
3035
- registerProvider(sigil: SigilPrefix, provider: SigilProvider): () => void;
3036
- /**
3037
- * 按 query + sigil 过滤匹配条目。过滤在此完成(R4),UI 只渲染结果。
3038
- * 命中数达 maxResults 立即返回,不全量遍历(F-domain 性能)。
3039
- * 仅静态条目;动态 provider 结果见 searchAsync。
3040
- */
3041
- search(query: string, sigil?: SigilPrefix, maxResults?: number): SigilEntry[];
3042
- /**
3043
- * 异步搜索:静态条目(即时)+ 动态 provider 结果(await)合并去重。
3044
- * UI 应优先用此方法以纳入 @file 等懒查候选;无 provider 时等价 search。
3045
- */
3046
- searchAsync(query: string, sigil?: SigilPrefix, maxResults?: number): Promise<SigilEntry[]>;
3047
- /** 返回某 sigil(或全部)的全量条目(只读快照)。 */
3048
- getAll(sigil?: SigilPrefix): readonly SigilEntry[];
3049
- /** 按 label 查首个匹配条目。 */
3050
- findByLabel(label: string): SigilEntry | undefined;
3051
- /** 注销某 label 的所有条目,返回是否删除过。 */
3052
- unregister(label: string): boolean;
3053
- /** 注销某 source 的所有条目(插件 unload 必调,防僵尸——R5)。 */
3054
- unregisterBySource(source: string): void;
3055
- }
3056
- /** 根据 kind 推断其归属的 sigil 前缀。 */
3057
- declare function sigilOf(kind: SigilKind): SigilPrefix;
3058
- /** sigil 触发信息:检测到的 sigil 字符 + 查询串 + 锚点位置。 */
3059
- //#endregion
3060
- //#region src/sdk.d.ts
3061
- /**
3062
- * @otto/plugin-sdk —— 插件作者 SDK(RFC-082 M082-04,代码逻辑入口)。
3063
- *
3064
- * 作者写一份 `plugin.ts`,`export default definePlugin(ctx => ({...}))`。这是 Vite `defineConfig`
3065
- * 的对等物:`definePlugin` 仅做**类型锚 + identity**(原样返回工厂),不含任何运行时编排——
3066
- * 产物由 otto 装载器(`loadPluginModule`,M082-04-02)**拆解**喂现有各轴 loader(D1/R1,无中央执行器)。
3067
- *
3068
- * 职责边界(RFC-082 R9,F1 修订):`definePlugin` 只承载**代码才需要的东西**——
3069
- * ① hooks(拦截器/观察器)② computed 贡献(装载时按环境算出的声明式贡献)③ 生命周期。
3070
- * **静态命令/agent/skill/mcp 仍走文件**(Tier 0),不在此声明——杜绝「两种做法做一件事」。
3071
- *
3072
- * 安全(RFC-082 R10):`plugin.ts` 在 otto 主进程内、装载时执行(非沙箱,全 Node 权限),
3073
- * 由信任门门控*是否*执行;hooks(尤其可 deny/block 工具的 preToolUse)默认关 + 显式启用。
3074
- */
3075
- /** 工具调用上下文(hooks 观测/拦截用)。 */
3076
- interface ToolUseContext {
3077
- toolName: string;
3078
- input: unknown;
3079
- }
3080
- /** PreToolUse 决策(拦截器返回)。`allow` 放行;`deny` 拒绝;`ask` 转人工确认。 */
3081
- type PreToolUseDecision = {
3082
- decision: 'allow';
3083
- } | {
3084
- decision: 'deny';
3085
- reason?: string;
3086
- } | {
3087
- decision: 'ask';
3088
- reason?: string;
3089
- };
3090
- /**
3091
- * 插件代码 hooks(RFC-082 R9,映射 RFC-032 hook 事件;RFC-129 D1 扩展 9 个 observer 字段)。
3092
- * `preToolUse` = 拦截器(可改变控制流);其余全部 = 观察器(fire-and-forget,无法改写引擎状态)。
3093
- * 全部可选;返回 Promise 则 await。R10:默认关 + 信任门,由装载器把关。
3094
- *
3095
- * RFC-129 D1 边界纪律:新增的 9 个字段全部是 observer-only——不开放任何可变换消息/参数的
3096
- * interceptor timing(`messages.transform`/`chat.params`/`system.prompt.transform`/
3097
- * `chat.message.after` 均不对插件开放,见 RFC-129 §1.2 非目标 + 放弃方案)。
3098
- */
3099
- interface PluginHooks {
3100
- preToolUse?: (ctx: ToolUseContext) => PreToolUseDecision | void | Promise<PreToolUseDecision | void>;
3101
- postToolUse?: (ctx: ToolUseContext & {
3102
- result: unknown;
3103
- }) => void | Promise<void>;
3104
- userPromptSubmit?: (ctx: {
3105
- prompt: string;
3106
- }) => void | Promise<void>;
3107
- sessionStart?: () => void | Promise<void>;
3108
- stop?: () => void | Promise<void>;
3109
- /** 会话从持久化存储恢复时触发(`session.restored`)。 */
3110
- sessionRestored?: (ctx: {
3111
- sessionId: string;
3112
- }) => void | Promise<void>;
3113
- /** 会话被删除时触发(`session.deleted`)。 */
3114
- sessionDeleted?: (ctx: {
3115
- sessionId: string;
3116
- }) => void | Promise<void>;
3117
- /** 会话进入空闲态时触发(`session.idle`)。 */
3118
- sessionIdle?: (ctx: {
3119
- sessionId: string;
3120
- }) => void | Promise<void>;
3121
- /**
3122
- * 会话发生错误时触发(`session.error`)。`error` 为字符串(非 `Error` 对象)——
3123
- * 装载器负责把 `Error.message` 序列化后传入,避免栈追踪等敏感信息泄漏给插件代码。
3124
- */
3125
- sessionError?: (ctx: {
3126
- sessionId: string;
3127
- error: string;
3128
- }) => void | Promise<void>;
3129
- /** 流式响应开始时触发(`stream.start`)。 */
3130
- streamStart?: (ctx: {
3131
- sessionId: string;
3132
- model: string;
3133
- }) => void | Promise<void>;
3134
- /**
3135
- * 即将触发压缩裁剪前触发(`compaction.before`)。`messageCount` 是即将参与裁剪判定的消息量——
3136
- * 与 `compactionOccurred`(`retainedCount`=裁剪后保留量)是不同信息维度,可用于预判裁剪规模。
3137
- * observer 语义(无法否决压缩),不要与 memory 内部专用的 `memory.prune.before` 拦截器混淆。
3138
- */
3139
- compactionPending?: (ctx: {
3140
- sessionId: string;
3141
- messageCount: number;
3142
- }) => void | Promise<void>;
3143
- /** 压缩裁剪完成后触发(`compaction.after`)。 */
3144
- compactionOccurred?: (ctx: {
3145
- sessionId: string;
3146
- retainedCount: number;
3147
- }) => void | Promise<void>;
3148
- /**
3149
- * 任务(子 agent task)完成时触发(`task.completed`)。`durationMs`/`tokenUsage` 为可选字段,
3150
- * 从底层 `TaskHookOutput` 透传,可能因任务类型或早期版本缺失。
3151
- */
3152
- taskCompleted?: (ctx: {
3153
- taskId: string;
3154
- status: string;
3155
- durationMs?: number;
3156
- tokenUsage?: {
3157
- input: number;
3158
- output: number;
3159
- cacheRead: number;
3160
- };
3161
- }) => void | Promise<void>;
3162
- /** 任务失败时触发(`task.failed`)。 */
3163
- taskFailed?: (ctx: {
3164
- taskId: string;
3165
- error: string;
3166
- }) => void | Promise<void>;
3167
- /**
3168
- * 任务(子 agent task)建档时触发(`task.created`),先于 `task.started` 触发。
3169
- * 此时 agent 归属尚未确定(`TaskHookInfo` 无 subagent 字段),仅 taskId 可用。
3170
- */
3171
- taskCreated?: (ctx: {
3172
- taskId: string;
3173
- }) => void | Promise<void>;
3174
- /** 任务开始执行时触发(`task.started`),已通过并发准入、进入 running 态,agent 归属已确定。 */
3175
- taskStarted?: (ctx: {
3176
- taskId: string;
3177
- agent: string;
3178
- }) => void | Promise<void>;
3179
- }
2743
+ /** 工具域 hooks(pre/post tool use)。 */
2744
+ type PluginToolHooks = Pick<PluginHooks, 'preToolUse' | 'postToolUse'>;
2745
+ /** 会话域 hooks(session lifecycle + stream + compaction)。 */
2746
+ type PluginSessionHooks = Pick<PluginHooks, 'sessionStart' | 'sessionRestored' | 'sessionDeleted' | 'sessionIdle' | 'sessionError' | 'stop' | 'streamStart' | 'compactionPending' | 'compactionOccurred'>;
2747
+ /** 任务域 hooks(task lifecycle)。 */
2748
+ type PluginTaskHooks = Pick<PluginHooks, 'taskCreated' | 'taskStarted' | 'taskCompleted' | 'taskFailed' | 'taskCancelled'>;
2749
+ /** 消息域 hooks(prompt submit + config change)。 */
2750
+ type PluginMessageHooks = Pick<PluginHooks, 'userPromptSubmit' | 'onConfigChange'>;
3180
2751
  /** 装载时注入工厂的上下文。 */
3181
2752
  interface PluginContext {
3182
2753
  /** 插件 id(= manifest.id = source 标签)。 */
@@ -3214,16 +2785,25 @@ interface PluginContext {
3214
2785
  * RFC-132 既定架构边界)——`WireProtocolRegistry.get()` 就是插件间协议复用的公开通道。
3215
2786
  * 未注入 `wireProtocolRegistry` 时(如轻量测试装配)恒返回 `undefined`。
3216
2787
  */
3217
- getWireProtocol: (wireApi: string) => WireProtocolRegistration | undefined;
2788
+ getWireProtocol: (wireApi: string) => _$_x_otto_provider0.WireProtocolRegistration | undefined;
2789
+ /**
2790
+ * 解析该插件自身 provider 的裸凭据 key(RFC-148 M3,`resolveProviderAuth` 的姊妹方法):
2791
+ * 多数代码式 provider 工厂(如 GitHub Copilot 自定义头场景)只需要裸 key,不需要
2792
+ * `mode`/`beta` 等完整凭据上下文。跨插件隔离:仅放行该插件 manifest 声明的
2793
+ * `codeProviderIds` 白名单或自身 `<pluginId>:` 前缀命名空间,其余一律返回 `null`
2794
+ * (不触达 AuthStore,见 `plugin-module-manager.ts` 装载器实现)。
2795
+ * 未注入 `providerRegistry` 或 api 不属于本插件时恒返回 `null`。
2796
+ */
2797
+ resolveProviderCredential: (api: string) => Promise<string | null>;
3218
2798
  /**
3219
2799
  * 解析该插件自身 provider 的完整凭据(RFC-148 M3,`resolveProviderCredential` 的姊妹方法):
3220
- * 后者只给裸 key(多数代码式 provider 够用,如 GitHub Copilot),本方法额外给 `mode`/`beta`
2800
+ * 前者只给裸 key(多数代码式 provider 够用,如 GitHub Copilot),本方法额外给 `mode`/`beta`
3221
2801
  * ——`anthropic-messages` 协议实现需要区分 api_key 与 oauth 模式(决定是否启用 Claude Code
3222
2802
  * 客户端伪装)。跨插件隔离规则与 `resolveProviderCredential` 一致(同一 owned-namespace
3223
2803
  * 白名单校验,装载器实现层面共享同一份判定逻辑,见 `plugin-module-manager.ts`)。
3224
2804
  * 未注入 `providerRegistry` 或 api 不属于本插件时恒返回 `null`。
3225
2805
  */
3226
- resolveProviderAuth: (api: string) => Promise<ResolvedAuth | null>;
2806
+ resolveProviderAuth: (api: string) => Promise<_$_x_otto_provider0.ResolvedAuth | null>;
3227
2807
  /**
3228
2808
  * RFC-287 D2:受控宿主能力面——每个字段对应一个独立声明+独立授权的高危能力,
3229
2809
  * 未声明/未授予即为 `undefined`(fail-closed)。详见 `PluginHostCapabilities`。
@@ -3237,37 +2817,75 @@ interface PluginContext {
3237
2817
  * 可选(additive)——旧宿主不注入时插件侧应容忍 undefined。
3238
2818
  */
3239
2819
  listActivePlugins?: () => readonly ActivePluginSnapshot[];
2820
+ /**
2821
+ * RFC-401 D2:插件配置值(解析后的对象,additive——旧宿主不注入时为 undefined)。
2822
+ * 宿主在装载时合并 manifest config schema 默认值 + PluginConfigStore 持久化值 → 注入。
2823
+ * 配置变更时经 onConfigChange hook 通知插件(不走整插件重载)。
2824
+ */
2825
+ config?: Record<string, unknown>;
2826
+ /**
2827
+ * RFC-427 D2:发布一个插件事件。事件类型必须在本插件 manifest 的 `contributes.events`
2828
+ * 中声明(未声明 → fail-closed 丢弃 + warn)。payload 经声明式 schema 校验,
2829
+ * 校验失败 → fail-closed 丢弃 + warn。宿主中转给所有已声明订阅的插件。
2830
+ * observer-only:不影响引擎状态、不写 prompt、不进 session log(R2/R7)。
2831
+ *
2832
+ * 跨进程(service worker 插件):经反向 RPC 桥接到宿主 event-dispatcher
2833
+ * (复用 RFC-287 D2 host 能力面桥接模式),不是 postMessage 函数传递。
2834
+ *
2835
+ * 可选(additive)——旧宿主/轻量测试装配不注入时插件侧应容忍 undefined。
2836
+ */
2837
+ emitEvent?: (type: string, payload: Readonly<Record<string, unknown>>) => void;
2838
+ /**
2839
+ * RFC-427 D2:订阅一个插件事件。type 可以是完整事件类型
2840
+ * (`skill-inductor.candidate-detected`)或通配符(`skill-inductor.*`)。
2841
+ * 订阅是 effect:插件卸载时自动反注册(unregisterBySource,R4 可逆 effect)。
2842
+ * handler 收到的 payload 已过 schema 校验 + 深冻结(Object.freeze 递归,R2 observer-only),
2843
+ * handler 不可 mutate。
2844
+ *
2845
+ * 通配符 `*`(订阅全部)在 M2 阶段不实现(R5 闸门)——API 签名保留但运行时 reject + warn,
2846
+ * 防止实现时顺手支持绕过闸门。
2847
+ *
2848
+ * handler 异常 = 吞掉 + warn,不传播、不阻断其他订阅方(R2a,对齐 PluginMonitor.onEvent
2849
+ * 既有纪律 sdk.ts:524-530)。
2850
+ *
2851
+ * 可选(additive)——旧宿主不注入时为 undefined。
2852
+ *
2853
+ * @returns disposer,手动取消订阅(对齐 dsh 可逆 effect 语义)
2854
+ */
2855
+ subscribeEvent?: (type: string, handler: (payload: Readonly<Record<string, unknown>>, source: {
2856
+ pluginId: string;
2857
+ }) => void) => () => void;
3240
2858
  }
3241
2859
  /**
3242
2860
  * provider 工厂(RFC-105 D3,代码式 provider 轴)。
3243
2861
  *
3244
2862
  * **分层纪律例外(RFC-140 D6,评审 R2,显式承认)**:此前签名故意保持轻量、不 import
3245
- * `@otto/ai` 的 `ProviderStream`——`@otto/plugin` 是前端与领域无关的契约层(同
3246
- * session-contract 分层纪律),不该下沉到具体能力包的类型。这里对 `@otto/provider` 的
3247
- * type-only 依赖是对该纪律的**有意识放松**,非"不违反":`@otto/provider` 是可发布的
2863
+ * `@x-otto/ai` 的 `ProviderStream`——`@x-otto/plugin` 是前端与领域无关的契约层(同
2864
+ * session-contract 分层纪律),不该下沉到具体能力包的类型。这里对 `@x-otto/provider` 的
2865
+ * type-only 依赖是对该纪律的**有意识放松**,非"不违反":`@x-otto/provider` 是可发布的
3248
2866
  * provider 插入点公开契约包(不是任意能力包),此依赖消除了每个代码式 provider 插件
3249
2867
  * 之前被迫写的 `as unknown as Record<string, unknown>` 双重类型断言。
3250
2868
  *
3251
- * 守卫条款:`@otto/provider` **不得**反向依赖 `@otto/plugin`(已核实零依赖,见
2869
+ * 守卫条款:`@x-otto/provider` **不得**反向依赖 `@x-otto/plugin`(已核实零依赖,见
3252
2870
  * `packages/provider/package.json`)——若未来该依赖产生实际问题,可回退为宽松形状。
3253
2871
  */
3254
- type PluginProviderFactory = () => ProviderStream;
2872
+ type PluginProviderFactory = () => _$_x_otto_provider0.ProviderStream;
3255
2873
  /**
3256
2874
  * Wire 协议实现注册(RFC-148 D1/D2):注册具名 wire 格式(如 `anthropic-messages`)的流式
3257
2875
  * 协议实现,供任意声明式/代码式 provider 插件经 `wireApi` 字符串引用。与 `PluginProviderFactory`
3258
- * 同一分层纪律——type-only 依赖 `@otto/provider`(可发布的公开契约包),不下沉到具体能力包。
3259
- * 直接复用 `@otto/provider` 的 `WireProtocolRegistration`(宿主 `WireProtocolRegistry` 与本
2876
+ * 同一分层纪律——type-only 依赖 `@x-otto/provider`(可发布的公开契约包),不下沉到具体能力包。
2877
+ * 直接复用 `@x-otto/provider` 的 `WireProtocolRegistration`(宿主 `WireProtocolRegistry` 与本
3260
2878
  * SDK 类型共用同一份定义,见 `packages/provider/src/types.ts`),不重复声明字段。
3261
2879
  */
3262
- type PluginWireProtocolRegistration = WireProtocolRegistration;
2880
+ type PluginWireProtocolRegistration = _$_x_otto_provider0.WireProtocolRegistration;
3263
2881
  /**
3264
2882
  * 代码式 OAuth 工厂(RFC-122 D1 逃生口,RFC-130 M131-1 首用)。
3265
- * 分层纪律同 `PluginProviderFactory`(终局 review 修复:直接 import `@otto/provider` 的
3266
- * `OAuthProvider` 官方类型而非宽松 `Record<string, unknown>`——`@otto/provider` 是零反向
2883
+ * 分层纪律同 `PluginProviderFactory`(终局 review 修复:直接 import `@x-otto/provider` 的
2884
+ * `OAuthProvider` 官方类型而非宽松 `Record<string, unknown>`——`@x-otto/provider` 是零反向
3267
2885
  * 依赖的公开契约包,插件作者可获得编译期类型检查,`class XxxOAuthProvider implements
3268
2886
  * OAuthProvider` 能直接赋值,不再需要类型收窄绕行)。
3269
2887
  */
3270
- type PluginOAuthProviderFactory = () => OAuthProvider;
2888
+ type PluginOAuthProviderFactory = () => _$_x_otto_provider0.OAuthProvider;
3271
2889
  /**
3272
2890
  * RFC-303 M4:代码式工具执行上下文(execute 的可选第二参数,additive——存量单参工具
3273
2891
  * `execute(args)` 零改动继续工作,R7 不 bump PLUGIN_API_VERSION)。
@@ -3304,7 +2922,7 @@ interface PluginToolContext {
3304
2922
  }
3305
2923
  /**
3306
2924
  * 代码式工具(RFC-105 D4,tools 轴)。同 `PluginProviderFactory` 的分层纪律——不 import
3307
- * `@otto/interchange` 的 `AgentTool`,避免契约层下沉到具体能力包类型。作者写的工具对象在
2925
+ * `@x-otto/interchange` 的 `AgentTool`,避免契约层下沉到具体能力包类型。作者写的工具对象在
3308
2926
  * 装载时由 `coding/src/plugin/` 收窄校验为真实 `AgentTool`(结构不符时 fail-soft 丢弃该条)。
3309
2927
  */
3310
2928
  interface PluginTool {
@@ -3319,12 +2937,60 @@ interface PluginTool {
3319
2937
  data?: unknown;
3320
2938
  error?: unknown;
3321
2939
  };
2940
+ /**
2941
+ * 模型侧序列化契约(与 @x-otto/interchange 的 AgentTool.parameters 对齐):
2942
+ * provider 序列化时无此方法则模型收到空 {} schema、参数完全不可见。
2943
+ * 手写 schema 必须与 safeParse 成对提供(2026-08-13 终局复核回归教训)。
2944
+ */
2945
+ toJSONSchema?: () => unknown;
3322
2946
  };
3323
2947
  /**
3324
2948
  * 执行体。第二参数 `ctx` 为 RFC-303 M4 可选上下文(pluginId/workspaceDir/logger/
3325
2949
  * host/signal);存量单参工具不传第二参数即忽略,天然兼容。
3326
2950
  */
3327
2951
  execute: (args: unknown, ctx?: PluginToolContext) => Promise<unknown>;
2952
+ /**
2953
+ * RFC-397 D1:工具所属预设层级。缺省 'full'(= 当前硬编码行为)。
2954
+ * 内联联合而非 import ToolPreset——packages/plugin 不依赖 @x-otto/setting,
2955
+ * 保持分层纪律(同 PluginTool 不 import AgentTool)。
2956
+ */
2957
+ preset?: 'minimal' | 'standard' | 'full';
2958
+ /** RFC-397 D4:工具分类(如 'fs'/'search'/'analysis')。缺省 = 不分组。 */
2959
+ category?: string;
2960
+ /**
2961
+ * RFC-397 D4:行为指南文本(注入 system prompt 的 Tool Reference 段,按 category 分组渲染)。
2962
+ * 与内置工具的 ToolNode.guidance 同等待遇。缺省 = 无指南。
2963
+ */
2964
+ guideline?: string;
2965
+ /**
2966
+ * RFC-397 D2:工具对模型的暴露策略。缺省 'direct'(= 当前行为,直接进模型工具表)。
2967
+ * 'deferred' = 经 tool_search 按需发现(MCP 工具默认态);'hidden' = 仅可派发,不进表。
2968
+ */
2969
+ exposure?: 'direct' | 'deferred' | 'hidden';
2970
+ /**
2971
+ * RFC-397 D3:声明哪些参数承载文件系统路径(如 ['path'] / ['filePath'])。
2972
+ * PEP(permission/file guard)据此解析受管路径。
2973
+ * **必须与 resolvePath 成对声明**——无 resolvePath 时 PEP 拿到原始相对串,
2974
+ * file-guard 锚定模式(如 `^/etc/`)对相对穿越(`../../etc/x`)失配 = 路径权限绕过。
2975
+ */
2976
+ pathParams?: readonly string[];
2977
+ /**
2978
+ * RFC-397 D3:把 pathParams 的原始值解析成工具实际操作的绝对路径。
2979
+ * **pathParams 的安全伴侣**——声明了 pathParams 就必须声明 resolvePath。
2980
+ *
2981
+ * 二参函数(与 AgentTool.resolvePath 的单参形态不同):第二参数 projectRoot 由
2982
+ * toAgentTool 在透传时从 PluginToolCtxSource.workspaceDir 注入,适配为单参闭包
2983
+ * `(raw) => tool.resolvePath!(raw, projectRoot)`(RFC-397 D6)。
2984
+ */
2985
+ resolvePath?: (rawPath: string, projectRoot: string) => string;
2986
+ /** RFC-397 D3:标记为只读工具,可与其他只读工具并发执行(work-loop 并发桶)。 */
2987
+ readonly?: boolean;
2988
+ /**
2989
+ * RFC-437 D1:声明本工具输出可再生可剪(无副作用查询类)。memory prune 经装配侧
2990
+ * ToolRegistry 收集(listRegenerableNames)——插件工具声明即生效,长会话可剪。
2991
+ * 缺省 undefined = 不声明 = 不可再生(fail-closed)。写类工具不得声明。
2992
+ */
2993
+ regenerableOutput?: boolean;
3328
2994
  }
3329
2995
  /**
3330
2996
  * Monitor 投影事件(RFC-129 D6):与 `PluginHooks` 平行的独立概念——"被动订阅事件流做旁路统计"
@@ -3345,14 +3011,25 @@ interface PluginTool {
3345
3011
  type MonitorEvent = {
3346
3012
  type: 'turn.completed';
3347
3013
  sessionId: string;
3348
- tokens: {
3014
+ tokenUsage: {
3349
3015
  input: number;
3350
3016
  output: number;
3351
3017
  };
3352
- } | {
3018
+ }
3019
+ /**
3020
+ * 压缩发生。`tokensSaved` **可选**——引擎侧 `compaction.after` 当前只携带
3021
+ * `retainedCount`(裁剪后保留的消息数),没有"裁剪前后 token 差值"这个量纲
3022
+ * (见 `@x-otto/hook-contracts` 的 `HookPayloadMap['compaction.after']`)。
3023
+ *
3024
+ * 为什么是可选而不是填 0:`0` 是一个**合法取值**("确实没省下 token"),用它冒充
3025
+ * "未知"会让任何基于该字段的统计静默得到错误结果,且插件作者无从分辨。`undefined`
3026
+ * 在类型层就强制消费方处理"拿不到这个量"的情况,这是诚实降级的正确形态。
3027
+ * 若未来 `compaction.after` 补充 token 维度数据,此处透传真实值即可,契约无需再改。
3028
+ */
3029
+ | {
3353
3030
  type: 'compaction.occurred';
3354
3031
  sessionId: string;
3355
- tokensSaved: number;
3032
+ tokensSaved?: number;
3356
3033
  } | {
3357
3034
  type: 'error';
3358
3035
  sessionId: string;
@@ -3380,7 +3057,32 @@ type MonitorEvent = {
3380
3057
  type: 'tool.unregistered';
3381
3058
  toolName: string;
3382
3059
  source?: string;
3060
+ }
3061
+ /**
3062
+ * 插件装载失败(自迭代闭环负反馈面,08-13 终局 review B1):模型生成/用户安装的
3063
+ * 插件在装载链路任一环节失败时派发。与 `pluginHealthTracker`(人看面板)不同,
3064
+ * 本事件进 monitor 事件面——运行中的插件(如 skill-inductor)与模型可感知
3065
+ * "我生成的插件坏了",是自迭代"失败可学习"的结构化通道。observer-only。
3066
+ */
3067
+ | {
3068
+ type: 'plugin.load-failed';
3069
+ pluginId: string;
3070
+ reason: PluginLoadFailureReason;
3071
+ message: string;
3072
+ }
3073
+ /**
3074
+ * 能力缺口上报(自迭代闭环认知输入面,08-13 终局 review B2):capability_gap 工具
3075
+ * 每次上报经宿主桥接派发。缺口记录本身是跨会话聚合 store(CapabilityGapReportStore),
3076
+ * 本事件是同一事实的事件面投影——运行中的 service 插件无需轮询即可感知"本工作区
3077
+ * 出现了新能力缺口"并主动响应。observer-only。
3078
+ */
3079
+ | {
3080
+ type: 'capability_gap.reported';
3081
+ dedupKey: string;
3082
+ searchTerms: string[];
3383
3083
  };
3084
+ /** 插件装载失败原因分类(`plugin.load-failed` 事件 reason 字段)。 */
3085
+ type PluginLoadFailureReason = /** 依赖缺失/环(topology 层剔除,RFC-132 D5)。 */'dependency-missing' /** 依赖环(topology 层剔除,RFC-132 D5)。 */ | 'dependency-cycle' /** 引擎版本门不兼容(RFC-148 M0)。 */ | 'version-incompatible' /** plugin.ts 编译/加载/工厂执行失败(module-loader 层)。 */ | 'module-error' /** project/repository 插件未通过布尔信任门(RFC-124 C1,08-13 终局复核 B1 扩展)。 */ | 'not-trusted' /** manifest 声明高危能力但未显式授予(pendingCapabilities 门,RFC-140 D3,08-13 终局复核 B1 扩展)。 */ | 'capability-not-granted' /** 声明式 provider/oauth 轴装载拒绝(能力未声明/id 冲突/保留 id 等,08-13 终局复核 B1 扩展)。 */ | 'provider-rejected';
3384
3086
  /**
3385
3087
  * 插件后台观察者(RFC-129 D6,capability: `monitor`)。`onEvent` 抛错被装载器 100% 隔离
3386
3088
  * (try/catch 吞掉 + 记录日志,绝不 rethrow、绝不阻塞引擎主流程或影响其他插件/hook,R5)——
@@ -3430,6 +3132,46 @@ type FeedbackIssueResult = {
3430
3132
  kind: string;
3431
3133
  detail: string;
3432
3134
  };
3135
+ /**
3136
+ * issue 反馈来源平台(RFC-430 §2.1 双平台)。`'github'` = 公网 GitHub;`'coding'` =
3137
+ * 企业内网代码托管平台——内网地址一律经 settings(`feedback_coding_base_url`)/
3138
+ * env(token)运行时注入,公网源码(含注释)零内网域名硬编码。
3139
+ */
3140
+ type FeedbackSource = 'github' | 'coding';
3141
+ /** 面板列表展示的归一化 issue 条目(RFC-430 §2.4,github/coding 双源归一到同一形状)。 */
3142
+ interface FeedbackIssueItem {
3143
+ source: FeedbackSource;
3144
+ /** 平台侧 issue 标识(GitHub number / Coding issue id 字符串化)。 */
3145
+ platformIssueId: string;
3146
+ title: string;
3147
+ state: 'open' | 'closed';
3148
+ url: string;
3149
+ author?: string;
3150
+ createdAt?: string;
3151
+ updatedAt?: string;
3152
+ /** GitHub REST `/issues` 端点会把 PR 一并返回——`kind` 区分 issue 与讨论类条目。 */
3153
+ kind: 'issue' | 'discussion';
3154
+ /** 列表行预览摘要(正文截断片段,可选)。 */
3155
+ excerpt?: string;
3156
+ labels?: string[];
3157
+ }
3158
+ /**
3159
+ * 双源聚合列表结果(RFC-430 §2.4):任一源失败/无凭据/超时时不抛错——该源
3160
+ * `items` 为空且 `unavailable[source]` 携带面向用户的原因文案(**只含 HTTP 状态码/
3161
+ * 失败类别,绝不携带 token 或内网地址以外的敏感信息**)。
3162
+ */
3163
+ interface FeedbackIssueListResult {
3164
+ items: FeedbackIssueItem[];
3165
+ unavailable?: Partial<Record<FeedbackSource, string>>;
3166
+ }
3167
+ /** 一条「本地标记已解决」记录(RFC-430 §2.4,插件侧 JSONL 落地)。 */
3168
+ interface FeedbackResolvedMark {
3169
+ ts: number;
3170
+ source: FeedbackSource;
3171
+ platformIssueId: string;
3172
+ url: string;
3173
+ title: string;
3174
+ }
3433
3175
  /**
3434
3176
  * Feedback 能力契约(RFC-209 §2.1,capability: `feedback`)——业务逻辑/数据契约层,
3435
3177
  * 不含任何 TUI/web-ui 渲染代码。核心包(coding/cli/tui/service)只通过 `FeedbackRegistry`
@@ -3453,6 +3195,32 @@ interface FeedbackProvider {
3453
3195
  * 提供 `feedbackProviders` 的插件必须实现本方法,即使不实现 `submitIssueViaGh`)。
3454
3196
  */
3455
3197
  buildIssueUrl: (input: FeedbackIssueInput) => string;
3198
+ /**
3199
+ * 双源 issue 列表聚合(RFC-430 §2.4,反馈面板数据面)。**必填**(M1 契约扩展,
3200
+ * 与 `buildIssueUrl` 同为面板/路由的最低兜底方法)。必须 fail-soft:任一源失败/
3201
+ * 无凭据/超时时该源 items 为空且 `unavailable[source]` 携带原因,绝不抛出。
3202
+ */
3203
+ listIssues: (opts?: {
3204
+ state?: 'open' | 'closed' | 'all';
3205
+ limitPerSource?: number;
3206
+ }) => Promise<FeedbackIssueListResult>;
3207
+ /** RFC-430 §2.1 平台判定链:settings 显式值优先,`auto` 时按内网可达性探测。 */
3208
+ resolveFeedbackPlatform?: () => Promise<FeedbackSource>;
3209
+ /**
3210
+ * 本地标记「已解决」(RFC-430 §2.4)——仅本地标记(JSONL 落地),真实关闭请在
3211
+ * 平台侧操作。返回是否实际写入(shadow 模式零写盘返回 false)。
3212
+ */
3213
+ markIssueResolved?: (mark: Omit<FeedbackResolvedMark, 'ts'>) => Promise<boolean>;
3214
+ /** 取消本地「已解决」标记(原子重写剔除匹配行);无匹配/影子态返回 false。 */
3215
+ unmarkIssueResolved?: (source: FeedbackSource, platformIssueId: string) => Promise<boolean>;
3216
+ /** 读取全部本地「已解决」标记;读取失败/影子态返回空数组(fail-soft,不抛)。 */
3217
+ listResolvedMarks?: () => Promise<FeedbackResolvedMark[]>;
3218
+ /**
3219
+ * 构造 Coding 平台新建 issue 预填 URL(RFC-430 §2.6)——纯函数式字符串构造,
3220
+ * 不执行任何子进程/网络调用(同 `buildIssueUrl` 的物理分离纪律);未配置
3221
+ * `feedback_coding_base_url`/`feedback_coding_repo` 时返回 null。
3222
+ */
3223
+ buildCodingIssueUrl?: (input: FeedbackIssueInput) => string | null;
3456
3224
  }
3457
3225
  /**
3458
3226
  * 工厂返回的插件模块(装载器拆解的对象)。
@@ -3507,11 +3275,11 @@ interface PluginModule {
3507
3275
  * key = resolver 名(装载器强制 `<pluginId>:<name>` 命名空间前缀防碰撞,同 providerFactories
3508
3276
  * 纪律)。声明式条目(`contributes.sigilEntries`)经 `resolverId` 引用这里的 resolver——
3509
3277
  * 装载器校验引用完整性(entry.resolverId 无对应 resolver → warn + 该条目仍注册但提交时
3510
- * 透传,fail-soft)。resolve 契约见 `@otto/interchange` SigilResolver(本 SDK 不重复类型,
3278
+ * 透传,fail-soft)。resolve 契约见 `@x-otto/interchange` SigilResolver(本 SDK 不重复类型,
3511
3279
  * 分层纪律同 PluginProviderFactory 的 type-only 依赖豁免——interchange 是可发布契约包)。
3512
3280
  */
3513
- sigilResolvers?: Record<string, SigilResolver['resolve'] | {
3514
- resolve: SigilResolver['resolve'];
3281
+ sigilResolvers?: Record<string, _$_x_otto_interchange0.SigilResolver['resolve'] | {
3282
+ resolve: _$_x_otto_interchange0.SigilResolver['resolve'];
3515
3283
  timeoutMs?: number;
3516
3284
  uiHostOnly?: boolean;
3517
3285
  }>;
@@ -3521,7 +3289,7 @@ interface PluginModule {
3521
3289
  * `SigilProvider` 先例)。装载器注册进 PluginInputRegistry.registerProvider('@', …),
3522
3290
  * 返回条目的 source 由装载器强制打为 pluginId(R2)。
3523
3291
  */
3524
- sigilProviders?: SigilProvider[];
3292
+ sigilProviders?: _$_x_otto_interchange0.SigilProvider[];
3525
3293
  /**
3526
3294
  * RFC-287 D-M3-1:常驻服务(代码轴)。需 manifest 声明 `capabilities: ["service"]`
3527
3295
  * (fail-closed,高危)。宿主在独立的 `PluginServicePool`(长生命周期 worker,启用
@@ -3533,11 +3301,135 @@ interface PluginModule {
3533
3301
  * `onActivate` 里起 setInterval——那会被既有池的超时/回收语义打断。
3534
3302
  */
3535
3303
  services?: PluginService[];
3304
+ /**
3305
+ * RFC-410 M2:进程内 CLI 命令 handler(代码轴,挂 `PluginModule`——不是 `contributes.*`
3306
+ * 声明式轴,元数据在 `contributes.cliCommands` 声明、handler 实现在此)。key = 命令名
3307
+ * (必须与 `contributes.cliCommands[].name` 对应;装载器只注册两侧都齐全的命令)。
3308
+ *
3309
+ * 需 manifest 声明 `capabilities: ["cli.command"]`(高危,fail-closed——宿主进程内自主
3310
+ * 执行代码,同 tui.renderer 风险等级)。handler 收窄 ctx(`PluginCliCommandContext`),
3311
+ * **不含** CliContext——只有 args/options/stdout/stderr + 有限 host 能力。
3312
+ *
3313
+ * 无状态一次性边界(RFC-112 D5 继承):handler 只做查询/配置读写类一次性子命令,
3314
+ * **不得**做生命周期管理/后台常驻/detached 进程/daemonize——宿主以一次性调用 + 超时
3315
+ * 包装执行(对齐透传档 60s 语义)。返回退出码(0=成功)。
3316
+ */
3317
+ cliCommands?: Record<string, PluginCliCommandHandler>;
3318
+ /**
3319
+ * RFC-440:TUI 斜杠命令 handler(代码轴,挂 `PluginModule`——元数据在
3320
+ * `contributes.slashCommands` 声明、handler 实现在此)。key = 命令名(必须与
3321
+ * `contributes.slashCommands[].name` 对应;装载器只注册两侧都齐全的命令)。
3322
+ *
3323
+ * 需 manifest 声明 `capabilities: ["tui.command"]`(高危,fail-closed——宿主进程内
3324
+ * 自主执行代码 + TUI 交互面,同 cli.command/tui.renderer 风险等级)。handler 收窄 ctx
3325
+ * (`PluginSlashCommandContext`),**不含** CliContext——TUI 桥(openInput/confirm/
3326
+ * openPluginPanel/showToast)与 app 窄面(workspaceDir/modelId/settings.get/pluginPanels)
3327
+ * 由宿主在命令执行时注入(装载时不持有 TUI 会话状态)。
3328
+ *
3329
+ * 一次性边界(继承 RFC-410 D5 纪律):handler 只做查询/交互式一次性命令,**不得**做
3330
+ * 生命周期管理/后台常驻/detached 进程。
3331
+ *
3332
+ * **超时语义(RFC-440 §M2 D8)**:宿主以 60s 超时包装执行。超时后宿主**停止等待**并向用户
3333
+ * 提示,但**无法强杀** handler(进程内无独立线程)——挂起的 handler 会作为孤儿继续运行。
3334
+ * 因此"不常驻、按时返回"是插件作者必须自觉遵守的契约,而非宿主能强制的边界。
3335
+ */
3336
+ slashCommands?: Record<string, PluginSlashCommandHandler>;
3536
3337
  /** 激活钩子:装载完成、贡献注册后调用。 */
3537
3338
  onActivate?: () => void | Promise<void>;
3538
3339
  /** 卸载/禁用钩子。 */
3539
3340
  onDeactivate?: () => void | Promise<void>;
3540
3341
  }
3342
+ /**
3343
+ * RFC-410 M2:进程内 CLI 命令 handler 的执行上下文(**窄接口**,独立于 `@x-otto/cli`——
3344
+ * plugin 包禁止反向依赖 cli 包,故不复用 `SubCommandContext`/`CLIOptions`,只声明命令
3345
+ * handler 真正需要的字段)。
3346
+ */
3347
+ interface PluginCliCommandContext {
3348
+ /** 命令名之后的位置参数(已 tokenize,不含命令名本身)。 */
3349
+ args: string[];
3350
+ /**
3351
+ * 与命令相关的运行选项子集(宿主从 CLI 解析结果投影而来的**纯数据**快照,只读)。
3352
+ * 有意只暴露命令 handler 常用的少数字段,不透传完整 CLIOptions(避免耦合与越权)。
3353
+ */
3354
+ options: PluginCliCommandOptions;
3355
+ /** 写 stdout(宿主注入,默认 process.stdout.write)。 */
3356
+ stdout: (s: string) => void;
3357
+ /** 写 stderr(宿主注入,默认 process.stderr.write)。 */
3358
+ stderr: (s: string) => void;
3359
+ /** JSON 输出模式(`otto --json <cmd>`)——handler 据此决定输出形状(RFC-410 M3 语义)。 */
3360
+ json: boolean;
3361
+ }
3362
+ /** RFC-410 M2:投影给插件 CLI handler 的只读运行选项(纯数据,不含引擎/会话句柄)。 */
3363
+ interface PluginCliCommandOptions {
3364
+ /** 工作区目录(绝对路径)。 */
3365
+ workspaceDir: string;
3366
+ /** 显式模型 id(`-m/--model`),未指定为 undefined。 */
3367
+ model?: string;
3368
+ /** 配置文件路径(`-c/--config`),未指定为 undefined。 */
3369
+ configPath?: string;
3370
+ }
3371
+ /**
3372
+ * RFC-410 M2:进程内 CLI 命令 handler 签名。返回退出码(0=成功,非 0=失败)。
3373
+ * 宿主以超时包装调用(handler 挂起 → 超时报错,不阻塞 CLI 无限期)。
3374
+ */
3375
+ type PluginCliCommandHandler = (ctx: PluginCliCommandContext) => Promise<number> | number;
3376
+ /**
3377
+ * RFC-440:TUI 斜杠命令 handler 的 TUI 窄桥(宿主执行命令时注入)。
3378
+ * 窄接口自声明(本包不依赖 cli/tui 包,同 PluginCliCommandContext 纪律)——只暴露
3379
+ * 命令 handler 真正需要的 TUI 原语,不透传 CliContext(53 成员教训,RFC-410 评审必须调整项 #3)。
3380
+ */
3381
+ interface PluginSlashCommandTuiBridge {
3382
+ /** 打开输入弹层,返回用户输入(取消/关闭返回 null)。 */
3383
+ openInput(opts: {
3384
+ title: string;
3385
+ description?: string[];
3386
+ placeholder?: string;
3387
+ }): Promise<string | null>;
3388
+ /** 打开确认弹层,返回用户选择。 */
3389
+ confirm(title: string, message: string | string[]): Promise<boolean>;
3390
+ /** 打开插件面板(contributes.panels 注册的 Ink 面板,对齐 /schedule 的 pluginPanel 打开模式)。 */
3391
+ openPluginPanel(info: {
3392
+ title: string;
3393
+ modulePath: string;
3394
+ exportName: string;
3395
+ pluginId: string;
3396
+ }): Promise<void>;
3397
+ /** 状态栏 toast。 */
3398
+ showToast(title: string, message: string): void;
3399
+ }
3400
+ /** RFC-440:投影给插件斜杠命令 handler 的只读 app 窄面(纯数据 + 窄读取,无引擎/会话句柄)。 */
3401
+ interface PluginSlashCommandAppBridge {
3402
+ /** 工作区目录(绝对路径)。 */
3403
+ workspaceDir: string;
3404
+ /** 当前会话模型 id(可能未配置)。 */
3405
+ modelId: string | undefined;
3406
+ /** settings 窄读取(对齐 RFC-430 的 host.getSettings 语义:只读单键值,返回 unknown)。 */
3407
+ settings: {
3408
+ get(key: string): unknown;
3409
+ };
3410
+ /** 已注册的插件面板列表(供 handler 定位自己的面板打开)。 */
3411
+ pluginPanels: Array<{
3412
+ pluginId: string;
3413
+ title: string;
3414
+ modulePath: string;
3415
+ exportName: string;
3416
+ }>;
3417
+ }
3418
+ /** RFC-440:TUI 斜杠命令 handler 上下文(窄接口,宿主执行命令时注入 TUI 桥与 app 窄面)。 */
3419
+ interface PluginSlashCommandContext {
3420
+ /** 命令名之后的参数(不含 '/' 前缀与命令名本身)。 */
3421
+ args: string[];
3422
+ tui: PluginSlashCommandTuiBridge;
3423
+ app: PluginSlashCommandAppBridge;
3424
+ }
3425
+ /**
3426
+ * RFC-440:TUI 斜杠命令 handler 签名。返回 void(TUI 内以 toast/面板呈现结果,
3427
+ * 无进程退出码概念)。
3428
+ *
3429
+ * 宿主以 60s 超时包装调用:handler 挂起时宿主停止等待并 toast 提示,TUI 不被无限期阻塞;
3430
+ * 但进程内**无法强杀** handler,超时后它仍可能在后台运行(RFC-440 §M2 D8/R3)。
3431
+ */
3432
+ type PluginSlashCommandHandler = (ctx: PluginSlashCommandContext) => Promise<void> | void;
3541
3433
  /**
3542
3434
  * RFC-287 D2:宿主注入给插件的**受控能力面**(capability-gated host capabilities)。
3543
3435
  *
@@ -3587,6 +3479,57 @@ interface PluginHostCapabilities {
3587
3479
  }) => Promise<{
3588
3480
  jobId: string;
3589
3481
  }>;
3482
+ /**
3483
+ * RFC-441 M2:操作宿主调度器(**扁平端口**——隔离路径 stub 是扁平方法名→函数 Proxy,
3484
+ * 嵌套 `schedule:{...}` 必然 TypeError,评审 P0-2)。需 manifest 声明
3485
+ * `capabilities: ["schedule"]`(高危,fail-closed);未授予时均为 `undefined`。
3486
+ *
3487
+ * **安全契约(宿主侧强制)**:
3488
+ * - origin 固定 `'model'`(工具场景——插件是工具载体,发起者仍是模型,评审 P1);
3489
+ * 插件不可自选 origin,不可伪装 user/main/plugin。
3490
+ * - cron/锁/持久化/terminate 咽喉点全在宿主侧(RFC-443 内核留主线程)。
3491
+ * - 数据形状完全对齐 ScheduleCapability(create 含 name/target echo,list 含
3492
+ * enabled/recurring/last*——工具结果文案依赖,不缩减,评审 P1)。
3493
+ */
3494
+ scheduleCreate?: (input: {
3495
+ cron: string;
3496
+ prompt: string;
3497
+ recurring: boolean;
3498
+ name?: string;
3499
+ maxDurationMs?: number;
3500
+ target?: 'job' | 'session';
3501
+ modelId?: string;
3502
+ thinkingLevel?: 'low' | 'medium' | 'high' | 'xhigh' | 'max';
3503
+ eventTrigger?: {
3504
+ source: string;
3505
+ event: string;
3506
+ filter?: {
3507
+ sessionId?: string;
3508
+ };
3509
+ };
3510
+ }) => Promise<{
3511
+ taskId: string;
3512
+ nextFireAt: number;
3513
+ name: string;
3514
+ target?: 'job' | 'session';
3515
+ }>;
3516
+ scheduleList?: () => Promise<Array<{
3517
+ id: string;
3518
+ name: string;
3519
+ cronExpression: string;
3520
+ enabled: boolean;
3521
+ recurring: boolean;
3522
+ nextFireAt: number;
3523
+ lastFiredAt?: number;
3524
+ lastFireFailed?: boolean;
3525
+ lastFireError?: string;
3526
+ }>>;
3527
+ scheduleDelete?: (taskId: string) => Promise<boolean>;
3528
+ scheduleRun?: (taskId: string) => Promise<void>;
3529
+ scheduleCancel?: (taskId: string) => Promise<{
3530
+ ok: boolean;
3531
+ reason?: string;
3532
+ }>;
3590
3533
  /**
3591
3534
  * RFC-318 D2(M1):读取一段会话轨迹(**只读**)。需 manifest 声明
3592
3535
  * `capabilities: ["session.read"]`(高危,fail-closed);未授予时本字段为 `undefined`。
@@ -3650,10 +3593,22 @@ interface PluginHostCapabilities {
3650
3593
  * 入参没有 `id` / `askedBy` / `sessionId`;`askedBy` 由宿主按连接侧插件身份强制填
3651
3594
  * `plugin:<pluginId>`,插件不能伪装成 agent/user/其他插件。
3652
3595
  */
3653
- ask?: (input: HostAskInput) => Promise<GrillAnswer>;
3596
+ ask?: (input: HostAskInput) => Promise<_$_x_otto_interchange0.GrillAnswer>;
3597
+ /**
3598
+ * RFC-430 M1:读取宿主 settings 的**单个键值**。需 manifest 声明并授权
3599
+ * `capabilities: ["settings.read"]`(fail-closed);未授予或宿主未提供取值源时
3600
+ * 本字段为 `undefined`。
3601
+ *
3602
+ * **契约**:
3603
+ * - 只读单键、返回 `unknown`——插件侧自行运行时收窄(非法值落默认),宿主不做类型保证;
3604
+ * - 不做键白名单:settings 值面与凭据物理隔离(token 走 env / AuthStore,不进 settings);
3605
+ * - 惰性:`settings.load()` 完成前调用返回 `undefined`,插件应 fail-soft 落默认值
3606
+ * (与 RFC-230 D5「延迟冻结」纹理一致)。
3607
+ */
3608
+ getSettings?: (key: string) => unknown;
3654
3609
  }
3655
3610
  /**
3656
- * RFC-318 D2(M1):`readTranscript` 的投影消息——**不是** `@otto/ai` 的 `Message`。
3611
+ * RFC-318 D2(M1):`readTranscript` 的投影消息——**不是** `@x-otto/ai` 的 `Message`。
3657
3612
  *
3658
3613
  * 契约层刻意定义独立结构:既隔离内部消息模型的演进(插件不耦合 `Message` 内部形状),
3659
3614
  * 又在类型层面就物理排除敏感字段(没有 `tool_calls`/`arguments` 字段可填)。
@@ -3663,7 +3618,7 @@ interface HostAskInput {
3663
3618
  question: string;
3664
3619
  background: string;
3665
3620
  recommendation: string;
3666
- options?: GrillOption[];
3621
+ options?: _$_x_otto_interchange0.GrillOption[];
3667
3622
  allowFreeform?: boolean;
3668
3623
  multiSelect?: boolean;
3669
3624
  evidence?: string[];
@@ -3762,10 +3717,23 @@ interface PluginServiceContext {
3762
3717
  * (走既有退避重启),**不静默吞掉**。未注册 handler 时通知被丢弃。
3763
3718
  */
3764
3719
  onNotify?: (handler: (n: PluginServiceNotification) => void | Promise<void>) => void;
3720
+ /**
3721
+ * RFC-427 D2:插件事件发布函数(可选——同 PluginContext.emitEvent)。
3722
+ * 在 service worker 中经反向 RPC 桥接到宿主 event-dispatcher。
3723
+ * 需 manifest 声明 `capabilities: ["events"]`(fail-closed:未声明不注入)。
3724
+ */
3725
+ emitEvent?: (type: string, payload: Readonly<Record<string, unknown>>) => void;
3726
+ /**
3727
+ * RFC-427 D2:插件事件订阅函数(可选——同 PluginContext.subscribeEvent)。
3728
+ * 返回 disposer(R4 可逆 effect)。
3729
+ */
3730
+ subscribeEvent?: (type: string, handler: (payload: Readonly<Record<string, unknown>>, source: {
3731
+ pluginId: string;
3732
+ }) => void) => () => void;
3765
3733
  }
3766
3734
  /**
3767
- * RFC-303 M5:插件 scoped persistence 的契约 shape(`@otto/plugin` 契约层不下沉实现——
3768
- * 只声明插件侧可见的接口;`PluginScopedStorage` 实现类在 `@otto/coding`,结构适配)。
3735
+ * RFC-303 M5:插件 scoped persistence 的契约 shape(`@x-otto/plugin` 契约层不下沉实现——
3736
+ * 只声明插件侧可见的接口;`PluginScopedStorage` 实现类在 `@x-otto/coding`,结构适配)。
3769
3737
  */
3770
3738
  interface PluginScopedStorageShape {
3771
3739
  /** 当前插件的 scoped 根目录(realpath 已断言在 plugin-state 根下)。 */
@@ -3846,10 +3814,10 @@ type PluginFactory = (ctx: PluginContext) => PluginModule | Promise<PluginModule
3846
3814
  declare function definePlugin(factory: PluginFactory): PluginFactory;
3847
3815
  //#endregion
3848
3816
  //#region src/input/registry.d.ts
3849
- declare function createPluginInputRegistry(): PluginInputRegistry;
3817
+ declare function createPluginInputRegistry(): PluginInputRegistry$1;
3850
3818
  //#endregion
3851
3819
  //#region src/input/builtin.d.ts
3852
- declare function createBuiltinHashtags(): SigilEntry[];
3820
+ declare function createBuiltinHashtags(): SigilEntry$1[];
3853
3821
  //#endregion
3854
3822
  //#region src/input/file-provider.d.ts
3855
3823
  interface FileProviderOptions {
@@ -3867,15 +3835,37 @@ interface FileProviderOptions {
3867
3835
  * 创建 @file 供给器。walk 结果按 TTL 缓存,query 在缓存上过滤——
3868
3836
  * 每次按键 O(n) 过滤而非重 walk 文件系统。
3869
3837
  */
3870
- declare function createFileProvider(opts: FileProviderOptions): SigilProvider;
3838
+ declare function createFileProvider(opts: FileProviderOptions): SigilProvider$1;
3871
3839
  //#endregion
3872
3840
  //#region src/trust-store.d.ts
3873
3841
  /** key(绝对路径)是否在白名单中。 */
3874
3842
  declare function isPathTrusted(storePath: string, key: string): boolean;
3875
3843
  /** 加入白名单(幂等)。返回是否发生变更(供调用方决定是否记日志)。 */
3876
3844
  declare function trustPath(storePath: string, key: string, label: string): boolean;
3877
- /** 移出白名单。返回是否发生变更。同时清除该 key 的已授予能力集(撤信任=能力清零,无残留特权)。 */
3845
+ /**
3846
+ * 移出白名单。返回是否发生变更。同时清除该 key 的已授予能力集
3847
+ * (撤信任=能力清零,无残留特权)。
3848
+ *
3849
+ * **RFC-354 P1-1**:本函数是唯一走 `requireLock` 的路径——撤销丢失是 fail-open
3850
+ * (用户以为收回权限、实际没有),故锁拿不到时**抛错而非无锁硬写**。
3851
+ * 同理 `writeStore` 落盘失败也会抛出(P5-2):撤销必须失败可见,不允许虚假确认。
3852
+ * 调用方(`extension-plugin.ts` / `misc.ts` 的撤销入口)应捕获并如实告知用户。
3853
+ */
3878
3854
  declare function untrustPath(storePath: string, key: string, label: string): boolean;
3855
+ /**
3856
+ * RFC-327 修订 R6'(M2):版本感知的授予——授予高危能力的同时记录授权时刻的插件
3857
+ * manifest 版本快照。语义同 `grantCapabilities`,额外写 `versions[key] = version`。
3858
+ *
3859
+ * 幂等语义:同 key 同版本重复调用 → 能力已含 + 版本已一致 → 返回 false(无变更)。
3860
+ * 版本变更后再次授予 → 覆盖版本快照并合并能力(重新评估的落点)。
3861
+ */
3862
+ declare function grantCapabilitiesWithVersion(storePath: string, key: string, caps: readonly string[], version: string, label: string): boolean;
3863
+ /**
3864
+ * RFC-327 修订 R6'(M2):版本匹配的能力读取——仅当记录的授权版本 === 当前版本时
3865
+ * 返回已授予能力;版本不符(或旧文件无版本快照)返回 `[]`(fail-closed)——
3866
+ * 插件更新后需重新评估白名单 timing,trust 不跨版本自动存续。
3867
+ */
3868
+ declare function grantedCapabilitiesForVersion(storePath: string, key: string, currentVersion: string): string[];
3879
3869
  //#endregion
3880
3870
  //#region src/plugin-trust.d.ts
3881
3871
  /** 信任白名单落盘路径(用户级)。`OTTO_PLUGIN_TRUST_PATH` 可覆盖(测试隔离)。调用时求值。 */
@@ -3893,19 +3883,33 @@ declare function grantedPluginCapabilities(pluginDir: string, storePath?: string
3893
3883
  * `sourceDir` 是包/本地目录本身;读不到/解析失败时返回空数组
3894
3884
  * (fail-soft——不阻塞安装流程本身,只是不弹确认)。
3895
3885
  *
3896
- * 单一真相源:此前 `@otto/cli` 的 CLI 安装路径(`plugin.ts`)与 TUI 安装路径
3886
+ * 单一真相源:此前 `@x-otto/cli` 的 CLI 安装路径(`plugin.ts`)与 TUI 安装路径
3897
3887
  * (`extension-plugin.ts`)各自内联实现了同一段"读 manifest → 过滤高危能力"逻辑,
3898
3888
  * 下沉到此处消除双写(终局架构 review 2026-07-20)。
3899
3889
  */
3900
3890
  declare function readHighRiskCapabilities(sourceDir: string): string[];
3901
3891
  /** 显式授予插件一组高危能力(幂等,持久化;用户逐项/整体确认后调用)。 */
3902
3892
  declare function grantPluginCapabilities(pluginDir: string, caps: readonly string[], storePath?: string): void;
3893
+ /**
3894
+ * RFC-327 修订 R6'(M2):版本感知的授予——同 grantPluginCapabilities,额外记录
3895
+ * 授权时刻的 manifest 版本快照。插件更新后调用
3896
+ * `grantedPluginCapabilitiesForVersion` 读取时版本不匹配 → 空集(fail-closed,
3897
+ * trust 不跨版本自动存续,需重新评估白名单)。
3898
+ */
3899
+ declare function grantPluginCapabilitiesWithVersion(pluginDir: string, caps: readonly string[], version: string, storePath?: string): void;
3900
+ /**
3901
+ * RFC-327 修订 R6'(M2):版本匹配的能力读取——仅当授权版本 === 当前 manifest 版本时
3902
+ * 返回已授予能力;版本变更(或旧文件无版本快照)→ `[]`(需重新评估)。
3903
+ */
3904
+ declare function grantedPluginCapabilitiesForVersion(pluginDir: string, version: string, storePath?: string): string[];
3903
3905
  /** 插件目录受信任门面探测结果(可执行面 ① + 内容面 ② + 高危能力声明 ③)。 */
3904
3906
  interface PluginExecutableSurface {
3905
3907
  mcpJson: boolean;
3906
3908
  commands: boolean;
3907
3909
  scripts: boolean;
3908
3910
  panels: boolean;
3911
+ /** 插件代码入口存在(`plugin.ts`/`plugin.tsx`,与 module-loader 的 PLUGIN_ENTRY_CANDIDATES 同源)。 */
3912
+ pluginEntry: boolean;
3909
3913
  skills: boolean;
3910
3914
  agents: boolean;
3911
3915
  cli: boolean;
@@ -3969,835 +3973,46 @@ interface PluginTrustVerdict {
3969
3973
  */
3970
3974
  declare function evaluatePluginTrust(plugin: DiscoveredPlugin, storePath?: string): PluginTrustVerdict;
3971
3975
  //#endregion
3972
- //#region ../shared/dist/event-bus-inioRzYz.d.ts
3973
- //#region src/event-emitter.d.ts
3974
- type EventListener = (...args: never[]) => void;
3975
- declare class TypedEventEmitter<T extends Record<keyof T, EventListener>> {
3976
- private readonly listeners;
3977
- on<K extends keyof T>(event: K, listener: T[K]): () => void;
3978
- off<K extends keyof T>(event: K, listener: T[K]): void;
3979
- emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void;
3980
- once<K extends keyof T>(event: K, listener: T[K]): () => void;
3981
- removeAllListeners<K extends keyof T>(event?: K): void;
3982
- listenerCount<K extends keyof T>(event: K): number;
3983
- } //#endregion
3984
- //#region src/event-bus.d.ts
3985
- //#endregion
3986
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/utility.d.ts
3987
- type AutocompletePrimitiveBaseType<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : never;
3988
- type Autocomplete<T> = T | (AutocompletePrimitiveBaseType<T> & Record<never, never>);
3989
- //#endregion
3990
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/header.d.ts
3976
+ //#region src/config-sensitive.d.ts
3991
3977
  /**
3992
- * The header type declaration of `undici`.
3978
+ * config-sensitive.ts —— RFC-401 重要事项规则 9:配置敏感字段脱敏。
3979
+ *
3980
+ * config 能力本身非高危(纯数据声明),但配置值可能含 apiKey/secret/token 等敏感字段。
3981
+ * 宿主在日志/错误信息中输出配置值时,须自动 redact 敏感字段——不依赖插件自觉。
3982
+ *
3983
+ * 判据:字段名(不区分大小写)匹配 `apiKey`/`secret`/`token`/`password`/`credential`
3984
+ * 任一子串 → 值替换为 `'[REDACTED]'`。非敏感字段原样输出。
3993
3985
  */
3994
- type IncomingHttpHeaders = Record<string, string | string[] | undefined>;
3986
+ /** 判断字段名是否敏感(子串匹配,不区分大小写)。 */
3987
+ declare function isSensitiveField(fieldName: string): boolean;
3995
3988
  /**
3996
- * The header type declaration of `undici` for outgoing requests.
3989
+ * 脱敏配置对象:深遍历,敏感字段的值替换为 `'[REDACTED]'`。
3990
+ * 返回新对象,不修改原对象。
3997
3991
  */
3998
- type OutgoingHttpHeaders = Record<string, number | string | string[] | undefined>;
3999
- type HeaderNames = Autocomplete<'Accept' | 'Accept-CH' | 'Accept-Charset' | 'Accept-Encoding' | 'Accept-Language' | 'Accept-Patch' | 'Accept-Post' | 'Accept-Ranges' | 'Access-Control-Allow-Credentials' | 'Access-Control-Allow-Headers' | 'Access-Control-Allow-Methods' | 'Access-Control-Allow-Origin' | 'Access-Control-Expose-Headers' | 'Access-Control-Max-Age' | 'Access-Control-Request-Headers' | 'Access-Control-Request-Method' | 'Age' | 'Allow' | 'Alt-Svc' | 'Alt-Used' | 'Authorization' | 'Cache-Control' | 'Clear-Site-Data' | 'Connection' | 'Content-Disposition' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Range' | 'Content-Security-Policy' | 'Content-Security-Policy-Report-Only' | 'Content-Type' | 'Cookie' | 'Cross-Origin-Embedder-Policy' | 'Cross-Origin-Opener-Policy' | 'Cross-Origin-Resource-Policy' | 'Date' | 'Device-Memory' | 'ETag' | 'Expect' | 'Expect-CT' | 'Expires' | 'Forwarded' | 'From' | 'Host' | 'If-Match' | 'If-Modified-Since' | 'If-None-Match' | 'If-Range' | 'If-Unmodified-Since' | 'Keep-Alive' | 'Last-Modified' | 'Link' | 'Location' | 'Max-Forwards' | 'Origin' | 'Permissions-Policy' | 'Priority' | 'Proxy-Authenticate' | 'Proxy-Authorization' | 'Range' | 'Referer' | 'Referrer-Policy' | 'Retry-After' | 'Sec-Fetch-Dest' | 'Sec-Fetch-Mode' | 'Sec-Fetch-Site' | 'Sec-Fetch-User' | 'Sec-Purpose' | 'Sec-WebSocket-Accept' | 'Server' | 'Server-Timing' | 'Service-Worker-Navigation-Preload' | 'Set-Cookie' | 'SourceMap' | 'Strict-Transport-Security' | 'TE' | 'Timing-Allow-Origin' | 'Trailer' | 'Transfer-Encoding' | 'Upgrade' | 'Upgrade-Insecure-Requests' | 'User-Agent' | 'Vary' | 'Via' | 'WWW-Authenticate' | 'X-Content-Type-Options' | 'X-Frame-Options'>;
4000
- type IANARegisteredMimeType = Autocomplete<'audio/aac' | 'video/x-msvideo' | 'image/avif' | 'video/av1' | 'application/octet-stream' | 'image/bmp' | 'text/css' | 'text/csv' | 'application/vnd.ms-fontobject' | 'application/epub+zip' | 'image/gif' | 'application/gzip' | 'text/html' | 'image/x-icon' | 'text/calendar' | 'image/jpeg' | 'text/javascript' | 'application/json' | 'application/ld+json' | 'audio/x-midi' | 'audio/mpeg' | 'video/mp4' | 'video/mpeg' | 'audio/ogg' | 'video/ogg' | 'application/ogg' | 'audio/opus' | 'font/otf' | 'application/pdf' | 'image/png' | 'application/rtf' | 'image/svg+xml' | 'image/tiff' | 'video/mp2t' | 'font/ttf' | 'text/plain' | 'application/wasm' | 'video/webm' | 'audio/webm' | 'image/webp' | 'font/woff' | 'font/woff2' | 'application/xhtml+xml' | 'application/xml' | 'application/zip' | 'video/3gpp' | 'video/3gpp2' | 'model/gltf+json' | 'model/gltf-binary'>;
4001
- type KnownHeaderValues = {
4002
- 'content-type': IANARegisteredMimeType;
4003
- };
4004
- type HeaderRecord = { [K in HeaderNames | Lowercase<HeaderNames>]?: Lowercase<K> extends keyof KnownHeaderValues ? KnownHeaderValues[Lowercase<K>] : string };
3992
+ declare function redactSensitiveFields(config: Record<string, unknown>): Record<string, unknown>;
4005
3993
  //#endregion
4006
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/readable.d.ts
4007
- declare class BodyReadable extends Readable {
4008
- constructor(opts: {
4009
- resume: (this: Readable, size: number) => void | null;
4010
- abort: () => void | null;
4011
- contentType?: string;
4012
- contentLength?: number;
4013
- highWaterMark?: number;
4014
- });
4015
- /** Consumes and returns the body as a string
4016
- * https://fetch.spec.whatwg.org/#dom-body-text
4017
- */
4018
- text(): Promise<string>;
4019
- /** Consumes and returns the body as a JavaScript Object
4020
- * https://fetch.spec.whatwg.org/#dom-body-json
4021
- */
4022
- json(): Promise<unknown>;
4023
- /** Consumes and returns the body as a Blob
4024
- * https://fetch.spec.whatwg.org/#dom-body-blob
4025
- */
4026
- blob(): Promise<Blob>;
4027
- /** Consumes and returns the body as an Uint8Array
4028
- * https://fetch.spec.whatwg.org/#dom-body-bytes
4029
- */
4030
- bytes(): Promise<Uint8Array>;
4031
- /** Consumes and returns the body as an ArrayBuffer
4032
- * https://fetch.spec.whatwg.org/#dom-body-arraybuffer
4033
- */
4034
- arrayBuffer(): Promise<ArrayBuffer>;
4035
- /** Not implemented
4036
- *
4037
- * https://fetch.spec.whatwg.org/#dom-body-formdata
4038
- */
4039
- formData(): Promise<never>;
4040
- /** Returns true if the body is not null and the body has been consumed
4041
- *
4042
- * Otherwise, returns false
4043
- *
4044
- * https://fetch.spec.whatwg.org/#dom-body-bodyused
4045
- */
4046
- readonly bodyUsed: boolean;
4047
- /**
4048
- * If body is null, it should return null as the body
4049
- *
4050
- * If body is not null, should return the body as a ReadableStream
4051
- *
4052
- * https://fetch.spec.whatwg.org/#dom-body-body
4053
- */
4054
- readonly body: never | undefined;
4055
- /** Dumps the response body by reading `limit` number of bytes.
4056
- * @param opts.limit Number of bytes to read (optional) - Default: 131072
4057
- * @param opts.signal AbortSignal to cancel the operation (optional)
4058
- */
4059
- dump(opts?: {
4060
- limit: number;
4061
- signal?: AbortSignal;
4062
- }): Promise<void>;
4063
- }
4064
- //#endregion
4065
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/fetch.d.ts
4066
- type BodyInit = ArrayBuffer | AsyncIterable<Uint8Array> | Blob | FormData | Iterable<Uint8Array> | NodeJS.ArrayBufferView | URLSearchParams$1 | null | string;
4067
- interface SpecIterator<T, TReturn = any, TNext = undefined> {
4068
- next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
4069
- }
4070
- interface SpecIteratorObject<T, TReturn = undefined, TNext = unknown> extends SpecIterator<T, TReturn, TNext> {
4071
- [Symbol.iterator](): SpecIteratorObject<T, TReturn, TNext>;
4072
- map<U>(callbackfn: (value: T, index: number) => U): SpecIteratorObject<U>;
4073
- filter<S extends T>(predicate: (value: T, index: number) => value is S): SpecIteratorObject<S>;
4074
- filter(predicate: (value: T, index: number) => unknown): SpecIteratorObject<T>;
4075
- take(limit: number): SpecIteratorObject<T>;
4076
- drop(count: number): SpecIteratorObject<T>;
4077
- flatMap<U>(callbackfn: (value: T, index: number) => Iterator<U> | Iterable<U>): SpecIteratorObject<U>;
4078
- reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number) => T): T;
4079
- reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number) => T, initialValue: T): T;
4080
- reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U;
4081
- toArray(): T[];
4082
- forEach(callbackfn: (value: T, index: number) => void): void;
4083
- some(predicate: (value: T, index: number) => unknown): boolean;
4084
- every(predicate: (value: T, index: number) => unknown): boolean;
4085
- find<S extends T>(predicate: (value: T, index: number) => value is S): S | undefined;
4086
- find(predicate: (value: T, index: number) => unknown): T | undefined;
4087
- readonly [Symbol.toStringTag]: string;
4088
- }
4089
- interface SpecIterableIterator<T> extends SpecIteratorObject<T> {
4090
- [Symbol.iterator](): SpecIterableIterator<T>;
4091
- }
4092
- interface SpecIterable<T> {
4093
- [Symbol.iterator](): SpecIterableIterator<T>;
4094
- }
4095
- type HeadersInit = [string, string][] | HeaderRecord | Headers$1;
4096
- declare class Headers$1 implements SpecIterable<[string, string]> {
4097
- constructor(init?: HeadersInit);
4098
- readonly append: (name: string, value: string) => void;
4099
- readonly delete: (name: string) => void;
4100
- readonly get: (name: string) => string | null;
4101
- readonly has: (name: string) => boolean;
4102
- readonly set: (name: string, value: string) => void;
4103
- readonly getSetCookie: () => string[];
4104
- readonly forEach: (callbackfn: (value: string, key: string, iterable: Headers$1) => void, thisArg?: unknown) => void;
4105
- readonly keys: () => SpecIterableIterator<string>;
4106
- readonly values: () => SpecIterableIterator<string>;
4107
- readonly entries: () => SpecIterableIterator<[string, string]>;
4108
- readonly [Symbol.iterator]: () => SpecIterableIterator<[string, string]>;
4109
- }
4110
- //#endregion
4111
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/formdata.d.ts
3994
+ //#region src/config-merge.d.ts
4112
3995
  /**
4113
- * A `string` or `File` that represents a single value from a set of `FormData` key-value pairs.
4114
- */
4115
- declare type FormDataEntryValue = string | File;
4116
- /**
4117
- * Provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using fetch().
3996
+ * config-merge.ts —— RFC-401 D2:配置合并纯函数。
3997
+ *
3998
+ * manifest config schema 的默认值与 PluginConfigStore 持久化值合并
3999
+ * (store 值 overlay manifest 默认值)。纯函数、零副作用、零依赖。
4000
+ *
4001
+ * 供 @x-otto/coding 的 module-loader 在装载时调用,也供测试验证。
4118
4002
  */
4119
- declare class FormData {
4003
+ interface ConfigSchemaLike {
4120
4004
  /**
4121
- * Appends a new value onto an existing key inside a FormData object,
4122
- * or adds the key if it does not already exist.
4123
- *
4124
- * The difference between `set()` and `append()` is that if the specified key already exists, `set()` will overwrite all existing values with the new one, whereas `append()` will append the new value onto the end of the existing set of values.
4125
- *
4126
- * @param name The name of the field whose data is contained in `value`.
4127
- * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
4128
- or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.
4129
- * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is "blob". The default filename for File objects is the file's filename.
4005
+ * 属性表:值类型为 unknown(与 manifest zod schema 对齐——z.record(z.string(), z.unknown()),
4006
+ * 递归 JSON schema entry 的值在 zod 推导时为 unknown)。合并实现做运行时窄化
4007
+ * (`typeof def === 'object' && 'default' in def`),只读 default 字段,不关心其余形状。
4130
4008
  */
4131
- append(name: string, value: unknown, fileName?: string): void;
4132
- /**
4133
- * Set a new value for an existing key inside FormData,
4134
- * or add the new field if it does not already exist.
4135
- *
4136
- * @param name The name of the field whose data is contained in `value`.
4137
- * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
4138
- or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.
4139
- * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is "blob". The default filename for File objects is the file's filename.
4140
- *
4141
- */
4142
- set(name: string, value: unknown, fileName?: string): void;
4143
- /**
4144
- * Returns the first value associated with a given key from within a `FormData` object.
4145
- * If you expect multiple values and want all of them, use the `getAll()` method instead.
4146
- *
4147
- * @param {string} name A name of the value you want to retrieve.
4148
- *
4149
- * @returns A `FormDataEntryValue` containing the value. If the key doesn't exist, the method returns null.
4150
- */
4151
- get(name: string): FormDataEntryValue | null;
4152
- /**
4153
- * Returns all the values associated with a given key from within a `FormData` object.
4154
- *
4155
- * @param {string} name A name of the value you want to retrieve.
4156
- *
4157
- * @returns An array of `FormDataEntryValue` whose key matches the value passed in the `name` parameter. If the key doesn't exist, the method returns an empty list.
4158
- */
4159
- getAll(name: string): FormDataEntryValue[];
4160
- /**
4161
- * Returns a boolean stating whether a `FormData` object contains a certain key.
4162
- *
4163
- * @param name A string representing the name of the key you want to test for.
4164
- *
4165
- * @return A boolean value.
4166
- */
4167
- has(name: string): boolean;
4168
- /**
4169
- * Deletes a key and its value(s) from a `FormData` object.
4170
- *
4171
- * @param name The name of the key you want to delete.
4172
- */
4173
- delete(name: string): void;
4174
- /**
4175
- * Executes given callback function for each field of the FormData instance
4176
- */
4177
- forEach: (callbackfn: (value: FormDataEntryValue, key: string, iterable: FormData) => void, thisArg?: unknown) => void;
4178
- /**
4179
- * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.
4180
- * Each key is a `string`.
4181
- */
4182
- keys: () => SpecIterableIterator<string>;
4183
- /**
4184
- * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all values contained in this object `FormData` object.
4185
- * Each value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).
4186
- */
4187
- values: () => SpecIterableIterator<FormDataEntryValue>;
4188
- /**
4189
- * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through the `FormData` key/value pairs.
4190
- * The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).
4191
- */
4192
- entries: () => SpecIterableIterator<[string, FormDataEntryValue]>;
4193
- /**
4194
- * An alias for FormData#entries()
4195
- */
4196
- [Symbol.iterator]: () => SpecIterableIterator<[string, FormDataEntryValue]>;
4197
- readonly [Symbol.toStringTag]: string;
4198
- }
4199
- //#endregion
4200
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/connector.d.ts
4201
- declare function buildConnector(options?: buildConnector.BuildOptions): buildConnector.connector;
4202
- declare namespace buildConnector {
4203
- export type BuildOptions = (ConnectionOptions | TcpNetConnectOpts | IpcNetConnectOpts) & {
4204
- allowH2?: boolean;
4205
- preferH2?: boolean;
4206
- maxCachedSessions?: number | null;
4207
- socketPath?: string | null;
4208
- timeout?: number | null;
4209
- port?: number;
4210
- keepAlive?: boolean | null;
4211
- keepAliveInitialDelay?: number | null;
4212
- typeOfService?: number | null;
4213
- };
4214
- export interface Options {
4215
- hostname: string;
4216
- host?: string;
4217
- protocol: string;
4218
- port: string;
4219
- servername?: string;
4220
- localAddress?: string | null;
4221
- socketPath?: string | null;
4222
- httpSocket?: Socket;
4223
- }
4224
- export type Callback = (...args: CallbackArgs) => void;
4225
- type CallbackArgs = [null, Socket | TLSSocket] | [Error, null];
4226
- export interface connector {
4227
- (options: buildConnector.Options, callback: buildConnector.Callback): void;
4228
- }
4009
+ properties?: Record<string, unknown>;
4229
4010
  }
4230
- //#endregion
4231
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/client-stats.d.ts
4232
- declare class ClientStats {
4233
- constructor(pool: Client);
4234
- /** If socket has open connection. */
4235
- connected: boolean;
4236
- /** Number of open socket connections in this client that do not have an active request. */
4237
- pending: number;
4238
- /** Number of currently active requests of this client. */
4239
- running: number;
4240
- /** Number of active, pending, or queued requests of this client. */
4241
- size: number;
4242
- }
4243
- //#endregion
4244
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/client.d.ts
4245
- type ClientConnectOptions<TOpaque = null> = Omit<Dispatcher.ConnectOptions<TOpaque>, 'origin'>;
4246
4011
  /**
4247
- * A basic HTTP/1.1 client, mapped on top a single TCP/TLS connection. Pipelining is disabled by default.
4012
+ * 合并 manifest config schema 默认值与 PluginConfigStore 持久化值。
4013
+ * store 值 overlay manifest 默认值——store 里不在 schema 里的字段保留(前向兼容)。
4248
4014
  */
4249
- declare class Client extends Dispatcher {
4250
- constructor(url: string | URL, options?: Client.Options);
4251
- /** Property to get and set the pipelining factor. */
4252
- pipelining: number;
4253
- /** `true` after `client.close()` has been called. */
4254
- closed: boolean;
4255
- /** `true` after `client.destroyed()` has been called or `client.close()` has been called and the client shutdown has completed. */
4256
- destroyed: boolean;
4257
- /** Aggregate stats for a Client. */
4258
- readonly stats: ClientStats; // Override dispatcher APIs.
4259
- override connect<TOpaque = null>(options: ClientConnectOptions<TOpaque>): Promise<Dispatcher.ConnectData<TOpaque>>;
4260
- override connect<TOpaque = null>(options: ClientConnectOptions<TOpaque>, callback: (err: Error | null, data: Dispatcher.ConnectData<TOpaque>) => void): void;
4261
- }
4262
- declare namespace Client {
4263
- export interface Options {
4264
- /** The maximum length of request headers in bytes. Default: Node.js' `--max-http-header-size` or `16384` (16KiB). */
4265
- maxHeaderSize?: number;
4266
- /** The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers (Node 14 and above only). Default: `300e3` milliseconds (300s). */
4267
- headersTimeout?: number;
4268
- /** @deprecated unsupported socketTimeout, use headersTimeout & bodyTimeout instead */
4269
- socketTimeout?: never;
4270
- /** @deprecated unsupported requestTimeout, use headersTimeout & bodyTimeout instead */
4271
- requestTimeout?: never;
4272
- /** The timeout for establishing a socket connection, in milliseconds. Use `0` to disable it entirely. Default: `10e3` milliseconds (10s). */
4273
- connectTimeout?: number;
4274
- /** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Default: `300e3` milliseconds (300s). */
4275
- bodyTimeout?: number;
4276
- /** @deprecated unsupported idleTimeout, use keepAliveTimeout instead */
4277
- idleTimeout?: never;
4278
- /** @deprecated unsupported keepAlive, use pipelining=0 instead */
4279
- keepAlive?: never;
4280
- /** the timeout, in milliseconds, after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. Default: `4e3` milliseconds (4s). */
4281
- keepAliveTimeout?: number;
4282
- /** @deprecated unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead */
4283
- maxKeepAliveTimeout?: never;
4284
- /** the maximum allowed `idleTimeout`, in milliseconds, when overridden by *keep-alive* hints from the server. Default: `600e3` milliseconds (10min). */
4285
- keepAliveMaxTimeout?: number;
4286
- /** A number of milliseconds subtracted from server *keep-alive* hints when overriding `idleTimeout` to account for timing inaccuracies caused by e.g. transport latency. Default: `1e3` milliseconds (1s). */
4287
- keepAliveTimeoutThreshold?: number;
4288
- /** An IPC endpoint, either a Unix domain socket or Windows named pipe. Default: `null`. */
4289
- socketPath?: string;
4290
- /** The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Only enable values greater than `1` when the remote server is trusted. Default: `1`. */
4291
- pipelining?: number;
4292
- /** @deprecated use the connect option instead */
4293
- tls?: never;
4294
- /** If `true`, an error is thrown when the request content-length header doesn't match the length of the request body. Default: `true`. */
4295
- strictContentLength?: boolean;
4296
- /** Maximum number of TLS cached sessions used by the built-in connector. Use `0` to disable TLS session caching. Default: `100`. */
4297
- maxCachedSessions?: number;
4298
- /** Connector options passed to `buildConnector`, or a custom connector function. Default: `null`. */
4299
- connect?: Partial<buildConnector.BuildOptions> | buildConnector.connector;
4300
- /** The maximum number of requests to send over a single connection before it is reset. Use `0` to disable this limit. Default: `null`. */
4301
- maxRequestsPerClient?: number;
4302
- /** Local IP address the socket should connect from. */
4303
- localAddress?: string;
4304
- /** Max response body size in bytes, -1 is disabled */
4305
- maxResponseSize?: number;
4306
- /** WebSocket-specific options */
4307
- webSocket?: Client.WebSocketOptions;
4308
- /** Enables a family autodetection algorithm that loosely implements section 5 of RFC 8305. */
4309
- autoSelectFamily?: boolean;
4310
- /** The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. */
4311
- autoSelectFamilyAttemptTimeout?: number;
4312
- /**
4313
- * @description Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation.
4314
- * @default true
4315
- */
4316
- allowH2?: boolean;
4317
- /**
4318
- * @description Dictates the maximum number of concurrent streams for a single H2 session. It can be overridden by a SETTINGS remote frame.
4319
- * @default 100
4320
- */
4321
- maxConcurrentStreams?: number;
4322
- /**
4323
- * @description Sets the HTTP/2 stream-level flow-control window size (SETTINGS_INITIAL_WINDOW_SIZE).
4324
- * @default 262144
4325
- */
4326
- initialWindowSize?: number;
4327
- /**
4328
- * @description Sets the HTTP/2 connection-level flow-control window size (ClientHttp2Session.setLocalWindowSize).
4329
- * @default 524288
4330
- */
4331
- connectionWindowSize?: number;
4332
- /**
4333
- * @description Time interval between PING frames dispatch
4334
- * @default 60000
4335
- */
4336
- pingInterval?: number;
4337
- }
4338
- export interface SocketInfo {
4339
- localAddress?: string;
4340
- localPort?: number;
4341
- remoteAddress?: string;
4342
- remotePort?: number;
4343
- remoteFamily?: string;
4344
- timeout?: number;
4345
- bytesWritten?: number;
4346
- bytesRead?: number;
4347
- }
4348
- export interface WebSocketOptions {
4349
- /**
4350
- * Maximum number of fragments in a message. Set to 0 to disable the limit.
4351
- * @default 131072
4352
- */
4353
- maxFragments?: number;
4354
- /**
4355
- * Maximum allowed payload size in bytes for WebSocket messages.
4356
- * Applied to uncompressed messages, compressed frame payloads, and decompressed (permessage-deflate) messages.
4357
- * Set to 0 to disable the limit.
4358
- * @default 134217728 (128 MB)
4359
- */
4360
- maxPayloadSize?: number;
4361
- }
4362
- }
4363
- //#endregion
4364
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/errors.d.ts
4365
- declare namespace Errors {
4366
- export class UndiciError extends Error {
4367
- name: string;
4368
- code: string;
4369
- }
4370
- /** Connect timeout error. */
4371
- export class ConnectTimeoutError extends UndiciError {
4372
- name: 'ConnectTimeoutError';
4373
- code: 'UND_ERR_CONNECT_TIMEOUT';
4374
- }
4375
- /** A header exceeds the `headersTimeout` option. */
4376
- export class HeadersTimeoutError extends UndiciError {
4377
- name: 'HeadersTimeoutError';
4378
- code: 'UND_ERR_HEADERS_TIMEOUT';
4379
- }
4380
- /** Headers overflow error. */
4381
- export class HeadersOverflowError extends UndiciError {
4382
- name: 'HeadersOverflowError';
4383
- code: 'UND_ERR_HEADERS_OVERFLOW';
4384
- }
4385
- /** A body exceeds the `bodyTimeout` option. */
4386
- export class BodyTimeoutError extends UndiciError {
4387
- name: 'BodyTimeoutError';
4388
- code: 'UND_ERR_BODY_TIMEOUT';
4389
- }
4390
- export class ResponseError extends UndiciError {
4391
- constructor(message: string, code: number, options: {
4392
- headers?: IncomingHttpHeaders | string[] | null;
4393
- body?: null | Record<string, any> | string;
4394
- });
4395
- name: 'ResponseError';
4396
- code: 'UND_ERR_RESPONSE';
4397
- statusCode: number;
4398
- body: null | Record<string, any> | string;
4399
- headers: IncomingHttpHeaders | string[] | null;
4400
- }
4401
- /** Passed an invalid argument. */
4402
- export class InvalidArgumentError extends UndiciError {
4403
- name: 'InvalidArgumentError';
4404
- code: 'UND_ERR_INVALID_ARG';
4405
- }
4406
- /** Returned an invalid value. */
4407
- export class InvalidReturnValueError extends UndiciError {
4408
- name: 'InvalidReturnValueError';
4409
- code: 'UND_ERR_INVALID_RETURN_VALUE';
4410
- }
4411
- /** The request has been aborted by the user. */
4412
- export class RequestAbortedError extends UndiciError {
4413
- name: 'AbortError';
4414
- code: 'UND_ERR_ABORTED';
4415
- }
4416
- /** Expected error with reason. */
4417
- export class InformationalError extends UndiciError {
4418
- name: 'InformationalError';
4419
- code: 'UND_ERR_INFO';
4420
- }
4421
- /** Request body length does not match content-length header. */
4422
- export class RequestContentLengthMismatchError extends UndiciError {
4423
- name: 'RequestContentLengthMismatchError';
4424
- code: 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH';
4425
- }
4426
- /** Response body length does not match content-length header. */
4427
- export class ResponseContentLengthMismatchError extends UndiciError {
4428
- name: 'ResponseContentLengthMismatchError';
4429
- code: 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH';
4430
- }
4431
- /** Trying to use a destroyed client. */
4432
- export class ClientDestroyedError extends UndiciError {
4433
- name: 'ClientDestroyedError';
4434
- code: 'UND_ERR_DESTROYED';
4435
- }
4436
- /** Trying to use a closed client. */
4437
- export class ClientClosedError extends UndiciError {
4438
- name: 'ClientClosedError';
4439
- code: 'UND_ERR_CLOSED';
4440
- }
4441
- /** There is an error with the socket. */
4442
- export class SocketError extends UndiciError {
4443
- name: 'SocketError';
4444
- code: 'UND_ERR_SOCKET';
4445
- socket: Client.SocketInfo | null;
4446
- }
4447
- /** Encountered unsupported functionality. */
4448
- export class NotSupportedError extends UndiciError {
4449
- name: 'NotSupportedError';
4450
- code: 'UND_ERR_NOT_SUPPORTED';
4451
- }
4452
- /** No upstream has been added to the BalancedPool. */
4453
- export class BalancedPoolMissingUpstreamError extends UndiciError {
4454
- name: 'MissingUpstreamError';
4455
- code: 'UND_ERR_BPL_MISSING_UPSTREAM';
4456
- }
4457
- export class HTTPParserError extends UndiciError {
4458
- name: 'HTTPParserError';
4459
- code: string;
4460
- }
4461
- /** The response exceed the length allowed. */
4462
- export class ResponseExceededMaxSizeError extends UndiciError {
4463
- name: 'ResponseExceededMaxSizeError';
4464
- code: 'UND_ERR_RES_EXCEEDED_MAX_SIZE';
4465
- }
4466
- export class RequestRetryError extends UndiciError {
4467
- constructor(message: string, statusCode: number, headers?: IncomingHttpHeaders | string[] | null, body?: null | Record<string, any> | string);
4468
- name: 'RequestRetryError';
4469
- code: 'UND_ERR_REQ_RETRY';
4470
- statusCode: number;
4471
- data: {
4472
- count: number;
4473
- };
4474
- headers: Record<string, string | string[]>;
4475
- }
4476
- export class SecureProxyConnectionError extends UndiciError {
4477
- constructor(cause?: Error, message?: string, options?: Record<any, any>);
4478
- name: 'SecureProxyConnectionError';
4479
- code: 'UND_ERR_PRX_TLS';
4480
- }
4481
- export class ProxyConnectionError extends UndiciError {
4482
- constructor(cause?: Error, message?: string, options?: Record<any, any>);
4483
- name: 'ProxyConnectionError';
4484
- code: 'UND_ERR_PRX_CONN';
4485
- }
4486
- export class MaxOriginsReachedError extends UndiciError {
4487
- name: 'MaxOriginsReachedError';
4488
- code: 'UND_ERR_MAX_ORIGINS_REACHED';
4489
- }
4490
- /** SOCKS5 proxy related error. */
4491
- export class Socks5ProxyError extends UndiciError {
4492
- constructor(message?: string, code?: string);
4493
- name: 'Socks5ProxyError';
4494
- code: string;
4495
- }
4496
- /** WebSocket decompressed message exceeded maximum size. */
4497
- export class MessageSizeExceededError extends UndiciError {
4498
- name: 'MessageSizeExceededError';
4499
- code: 'UND_ERR_WS_MESSAGE_SIZE_EXCEEDED';
4500
- }
4501
- }
4502
- //#endregion
4503
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/dispatcher.d.ts
4504
- type UndiciHeaders = OutgoingHttpHeaders | string[] | Iterable<[string, string | string[] | undefined]> | null;
4505
- /** Dispatcher is the core API used to dispatch requests. */
4506
- declare class Dispatcher extends EventEmitter {
4507
- /** Dispatches a request. This API is expected to evolve through semver-major versions and is less stable than the preceding higher level APIs. It is primarily intended for library developers who implement higher level APIs on top of this. */
4508
- dispatch(options: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandler): boolean;
4509
- /** Starts two-way communications with the requested resource. */
4510
- connect<TOpaque = null>(options: Dispatcher.ConnectOptions<TOpaque>, callback: (err: Error | null, data: Dispatcher.ConnectData<TOpaque>) => void): void;
4511
- connect<TOpaque = null>(options: Dispatcher.ConnectOptions<TOpaque>): Promise<Dispatcher.ConnectData<TOpaque>>;
4512
- /** Compose a chain of dispatchers */
4513
- compose(dispatchers: Dispatcher.DispatcherComposeInterceptor[]): Dispatcher.ComposedDispatcher;
4514
- compose(...dispatchers: Dispatcher.DispatcherComposeInterceptor[]): Dispatcher.ComposedDispatcher;
4515
- /** Performs an HTTP request. */
4516
- request<TOpaque = null>(options: Dispatcher.RequestOptions<TOpaque>, callback: (err: Error | null, data: Dispatcher.ResponseData<TOpaque>) => void): void;
4517
- request<TOpaque = null>(options: Dispatcher.RequestOptions<TOpaque>): Promise<Dispatcher.ResponseData<TOpaque>>;
4518
- /** For easy use with `stream.pipeline`. */
4519
- pipeline<TOpaque = null>(options: Dispatcher.PipelineOptions<TOpaque>, handler: Dispatcher.PipelineHandler<TOpaque>): Duplex;
4520
- /** A faster version of `Dispatcher.request`. */
4521
- stream<TOpaque = null>(options: Dispatcher.RequestOptions<TOpaque>, factory: Dispatcher.StreamFactory<TOpaque>, callback: (err: Error | null, data: Dispatcher.StreamData<TOpaque>) => void): void;
4522
- stream<TOpaque = null>(options: Dispatcher.RequestOptions<TOpaque>, factory: Dispatcher.StreamFactory<TOpaque>): Promise<Dispatcher.StreamData<TOpaque>>;
4523
- /** Upgrade to a different protocol. */
4524
- upgrade(options: Dispatcher.UpgradeOptions, callback: (err: Error | null, data: Dispatcher.UpgradeData) => void): void;
4525
- upgrade(options: Dispatcher.UpgradeOptions): Promise<Dispatcher.UpgradeData>;
4526
- /** Closes the client and gracefully waits for enqueued requests to complete before invoking the callback (or returning a promise if no callback is provided). */
4527
- close(callback: () => void): void;
4528
- close(): Promise<void>;
4529
- /** Destroy the client abruptly with the given err. All the pending and running requests will be asynchronously aborted and error. Waits until socket is closed before invoking the callback (or returning a promise if no callback is provided). Since this operation is asynchronously dispatched there might still be some progress on dispatched requests. */
4530
- destroy(err: Error | null, callback: () => void): void;
4531
- destroy(callback: () => void): void;
4532
- destroy(err: Error | null): Promise<void>;
4533
- destroy(): Promise<void>;
4534
- on(eventName: 'connect', callback: (origin: URL, targets: readonly Dispatcher[]) => void): this;
4535
- on(eventName: 'disconnect', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4536
- on(eventName: 'connectionError', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4537
- on(eventName: 'drain', callback: (origin: URL) => void): this;
4538
- once(eventName: 'connect', callback: (origin: URL, targets: readonly Dispatcher[]) => void): this;
4539
- once(eventName: 'disconnect', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4540
- once(eventName: 'connectionError', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4541
- once(eventName: 'drain', callback: (origin: URL) => void): this;
4542
- off(eventName: 'connect', callback: (origin: URL, targets: readonly Dispatcher[]) => void): this;
4543
- off(eventName: 'disconnect', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4544
- off(eventName: 'connectionError', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4545
- off(eventName: 'drain', callback: (origin: URL) => void): this;
4546
- addListener(eventName: 'connect', callback: (origin: URL, targets: readonly Dispatcher[]) => void): this;
4547
- addListener(eventName: 'disconnect', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4548
- addListener(eventName: 'connectionError', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4549
- addListener(eventName: 'drain', callback: (origin: URL) => void): this;
4550
- removeListener(eventName: 'connect', callback: (origin: URL, targets: readonly Dispatcher[]) => void): this;
4551
- removeListener(eventName: 'disconnect', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4552
- removeListener(eventName: 'connectionError', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4553
- removeListener(eventName: 'drain', callback: (origin: URL) => void): this;
4554
- prependListener(eventName: 'connect', callback: (origin: URL, targets: readonly Dispatcher[]) => void): this;
4555
- prependListener(eventName: 'disconnect', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4556
- prependListener(eventName: 'connectionError', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4557
- prependListener(eventName: 'drain', callback: (origin: URL) => void): this;
4558
- prependOnceListener(eventName: 'connect', callback: (origin: URL, targets: readonly Dispatcher[]) => void): this;
4559
- prependOnceListener(eventName: 'disconnect', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4560
- prependOnceListener(eventName: 'connectionError', callback: (origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void): this;
4561
- prependOnceListener(eventName: 'drain', callback: (origin: URL) => void): this;
4562
- listeners(eventName: 'connect'): ((origin: URL, targets: readonly Dispatcher[]) => void)[];
4563
- listeners(eventName: 'disconnect'): ((origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void)[];
4564
- listeners(eventName: 'connectionError'): ((origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void)[];
4565
- listeners(eventName: 'drain'): ((origin: URL) => void)[];
4566
- rawListeners(eventName: 'connect'): ((origin: URL, targets: readonly Dispatcher[]) => void)[];
4567
- rawListeners(eventName: 'disconnect'): ((origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void)[];
4568
- rawListeners(eventName: 'connectionError'): ((origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError) => void)[];
4569
- rawListeners(eventName: 'drain'): ((origin: URL) => void)[];
4570
- emit(eventName: 'connect', origin: URL, targets: readonly Dispatcher[]): boolean;
4571
- emit(eventName: 'disconnect', origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError): boolean;
4572
- emit(eventName: 'connectionError', origin: URL, targets: readonly Dispatcher[], error: Errors.UndiciError): boolean;
4573
- emit(eventName: 'drain', origin: URL): boolean;
4574
- }
4575
- declare namespace Dispatcher {
4576
- export interface ComposedDispatcher extends Dispatcher {}
4577
- export type Dispatch = Dispatcher['dispatch'];
4578
- export type DispatcherComposeInterceptor = (dispatch: Dispatch) => Dispatch;
4579
- export interface DispatchOptions {
4580
- origin?: string | URL;
4581
- path: string;
4582
- method: HttpMethod;
4583
- /** Default: `null` */
4584
- body?: string | Buffer | Uint8Array | Readable | null | FormData;
4585
- /** Default: `null` */
4586
- headers?: UndiciHeaders;
4587
- /** Query string params to be embedded in the request URL. Default: `null` */
4588
- query?: Record<string, any>;
4589
- /** Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline have completed. Default: `true` if `method` is `HEAD` or `GET`. */
4590
- idempotent?: boolean;
4591
- /** Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received. Defaults to `method !== 'HEAD'`. */
4592
- blocking?: boolean;
4593
- /** The IP Type of Service (ToS) value for the request socket. Must be an integer between 0 and 255. Default: `0` */
4594
- typeOfService?: number | null;
4595
- /** Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. Default: `method === 'CONNECT' || null`. */
4596
- upgrade?: boolean | string | null;
4597
- /** The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers. Defaults to 300 seconds. */
4598
- headersTimeout?: number | null;
4599
- /** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use 0 to disable it entirely. Defaults to 300 seconds. */
4600
- bodyTimeout?: number | null;
4601
- /** Whether the request should stablish a keep-alive or not. Default `false` */
4602
- reset?: boolean;
4603
- /** For H2, it appends the expect: 100-continue header, and halts the request body until a 100-continue is received from the remote server */
4604
- expectContinue?: boolean;
4605
- }
4606
- export interface ConnectOptions<TOpaque = null> {
4607
- origin: string | URL;
4608
- path: string;
4609
- /** Default: `null` */
4610
- headers?: UndiciHeaders;
4611
- /** Default: `null` */
4612
- signal?: AbortSignal | EventEmitter | null;
4613
- /** This argument parameter is passed through to `ConnectData` */
4614
- opaque?: TOpaque;
4615
- /** Default: `null` */
4616
- responseHeaders?: 'raw' | null;
4617
- }
4618
- export interface RequestOptions<TOpaque = null> extends DispatchOptions {
4619
- /** Default: `null` */
4620
- opaque?: TOpaque;
4621
- /** Default: `null` */
4622
- signal?: AbortSignal | EventEmitter | null;
4623
- /** Default: `null` */
4624
- onInfo?: (info: {
4625
- statusCode: number;
4626
- headers: Record<string, string | string[]>;
4627
- }) => void;
4628
- /** Default: `null` */
4629
- responseHeaders?: 'raw' | null;
4630
- /** Default: `64 KiB` */
4631
- highWaterMark?: number;
4632
- }
4633
- export interface PipelineOptions<TOpaque = null> extends RequestOptions<TOpaque> {
4634
- /** `true` if the `handler` will return an object stream. Default: `false` */
4635
- objectMode?: boolean;
4636
- }
4637
- export interface UpgradeOptions {
4638
- path: string;
4639
- /** Default: `'GET'` */
4640
- method?: string;
4641
- /** Default: `null` */
4642
- headers?: UndiciHeaders;
4643
- /** A string of comma separated protocols, in descending preference order. Default: `'Websocket'` */
4644
- protocol?: string;
4645
- /** Default: `null` */
4646
- signal?: AbortSignal | EventEmitter | null;
4647
- /** Default: `null` */
4648
- responseHeaders?: 'raw' | null;
4649
- }
4650
- export interface ConnectData<TOpaque = null> {
4651
- statusCode: number;
4652
- headers: IncomingHttpHeaders;
4653
- socket: Duplex;
4654
- opaque: TOpaque;
4655
- }
4656
- export interface ResponseData<TOpaque = null> {
4657
- statusCode: number;
4658
- statusText: string;
4659
- headers: IncomingHttpHeaders;
4660
- body: BodyReadable & BodyMixin;
4661
- trailers: Record<string, string>;
4662
- opaque: TOpaque;
4663
- context: object;
4664
- }
4665
- export interface PipelineHandlerData<TOpaque = null> {
4666
- statusCode: number;
4667
- headers: IncomingHttpHeaders;
4668
- opaque: TOpaque;
4669
- body: BodyReadable;
4670
- context: object;
4671
- }
4672
- export interface StreamData<TOpaque = null> {
4673
- opaque: TOpaque;
4674
- trailers: Record<string, string>;
4675
- }
4676
- export interface UpgradeData<TOpaque = null> {
4677
- headers: IncomingHttpHeaders;
4678
- socket: Duplex;
4679
- opaque: TOpaque;
4680
- }
4681
- export interface StreamFactoryData<TOpaque = null> {
4682
- statusCode: number;
4683
- headers: IncomingHttpHeaders;
4684
- opaque: TOpaque;
4685
- context: object;
4686
- }
4687
- export type StreamFactory<TOpaque = null> = (data: StreamFactoryData<TOpaque>) => Writable;
4688
- export interface DispatchController {
4689
- get aborted(): boolean;
4690
- get paused(): boolean;
4691
- get reason(): Error | null;
4692
- rawHeaders?: Buffer[] | string[] | IncomingHttpHeaders | null;
4693
- rawTrailers?: Buffer[] | string[] | IncomingHttpHeaders | null;
4694
- abort(reason: Error): void;
4695
- pause(): void;
4696
- resume(): void;
4697
- }
4698
- export interface DispatchHandler {
4699
- onRequestStart?(controller: DispatchController, context: any): void;
4700
- onRequestUpgrade?(controller: DispatchController, statusCode: number, headers: IncomingHttpHeaders, socket: Duplex): void;
4701
- onResponseStart?(controller: DispatchController, statusCode: number, headers: IncomingHttpHeaders, statusMessage?: string): void;
4702
- onResponseData?(controller: DispatchController, chunk: Buffer): void;
4703
- onResponseEnd?(controller: DispatchController, trailers: IncomingHttpHeaders): void;
4704
- onResponseError?(controller: DispatchController, error: Error): void;
4705
- /** Invoked when response is received, before headers have been read. **/
4706
- onResponseStarted?(): void;
4707
- /** Invoked when a body chunk is sent to the server. May be invoked multiple times for chunked requests */
4708
- onBodySent?(chunk: Buffer): void;
4709
- /** Invoked after the request body is fully sent. */
4710
- onRequestSent?(): void;
4711
- }
4712
- export type PipelineHandler<TOpaque = null> = (data: PipelineHandlerData<TOpaque>) => Readable;
4713
- export type HttpMethod = Autocomplete<'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH'>;
4714
- /**
4715
- * @link https://fetch.spec.whatwg.org/#body-mixin
4716
- */
4717
- interface BodyMixin {
4718
- readonly body?: never;
4719
- readonly bodyUsed: boolean;
4720
- arrayBuffer(): Promise<ArrayBuffer>;
4721
- blob(): Promise<Blob>;
4722
- bytes(): Promise<Uint8Array>;
4723
- formData(): Promise<never>;
4724
- json(): Promise<unknown>;
4725
- text(): Promise<string>;
4726
- }
4727
- export interface DispatchInterceptor {
4728
- (dispatch: Dispatch): Dispatch;
4729
- }
4730
- }
4731
- //#endregion
4732
- //#region ../../node_modules/.pnpm/undici@8.7.0/node_modules/undici/types/mock-interceptor.d.ts
4733
- /** The scope associated with a mock dispatch. */
4734
- declare class MockScope<TData extends object = object> {
4735
- constructor(mockDispatch: MockInterceptor.MockDispatch<TData>);
4736
- /** Delay a reply by a set amount of time in ms. */
4737
- delay(waitInMs: number): MockScope<TData>;
4738
- /** Persist the defined mock data for the associated reply. It will return the defined mock data indefinitely. */
4739
- persist(): MockScope<TData>;
4740
- /** Define a reply for a set amount of matching requests. */
4741
- times(repeatTimes: number): MockScope<TData>;
4742
- }
4743
- /** The interceptor for a Mock. */
4744
- declare class MockInterceptor {
4745
- constructor(options: MockInterceptor.Options, mockDispatches: MockInterceptor.MockDispatch[]);
4746
- /** Mock an undici request with the defined reply. */
4747
- reply<TData extends object = object>(replyOptionsCallback: MockInterceptor.MockReplyOptionsCallback<TData>): MockScope<TData>;
4748
- reply<TData extends object = object>(statusCode: number, data?: TData | Buffer | string | MockInterceptor.MockResponseDataHandler<TData>, responseOptions?: MockInterceptor.MockResponseOptions): MockScope<TData>;
4749
- /** Mock an undici request by throwing the defined reply error. */
4750
- replyWithError<TError extends Error = Error>(error: TError): MockScope;
4751
- /** Set default reply headers on the interceptor for subsequent mocked replies. */
4752
- defaultReplyHeaders(headers: IncomingHttpHeaders): MockInterceptor;
4753
- /** Set default reply trailers on the interceptor for subsequent mocked replies. */
4754
- defaultReplyTrailers(trailers: Record<string, string>): MockInterceptor;
4755
- /** Set automatically calculated content-length header on subsequent mocked replies. */
4756
- replyContentLength(): MockInterceptor;
4757
- }
4758
- declare namespace MockInterceptor {
4759
- /** MockInterceptor options. */
4760
- export interface Options {
4761
- /** Path to intercept on. */
4762
- path: string | RegExp | ((path: string) => boolean);
4763
- /** Method to intercept on. Defaults to GET. */
4764
- method?: string | RegExp | ((method: string) => boolean);
4765
- /** Body to intercept on. */
4766
- body?: string | RegExp | ((body: string) => boolean);
4767
- /** Headers to intercept on. */
4768
- headers?: Record<string, string | RegExp | ((body: string) => boolean)> | ((headers: Record<string, string>) => boolean);
4769
- /** Query params to intercept on */
4770
- query?: Record<string, any>;
4771
- }
4772
- export interface MockDispatch<TData extends object = object, TError extends Error = Error> extends Options {
4773
- times: number | null;
4774
- persist: boolean;
4775
- consumed: boolean;
4776
- data: MockDispatchData<TData, TError>;
4777
- }
4778
- export interface MockDispatchData<TData extends object = object, TError extends Error = Error> extends MockResponseOptions {
4779
- error: TError | null;
4780
- statusCode?: number;
4781
- data?: TData | string;
4782
- }
4783
- export interface MockResponseOptions {
4784
- headers?: IncomingHttpHeaders;
4785
- trailers?: Record<string, string>;
4786
- }
4787
- export interface MockResponseCallbackOptions {
4788
- path: string;
4789
- method: string;
4790
- headers?: Headers$1 | Record<string, string>;
4791
- origin?: string;
4792
- body?: BodyInit | Dispatcher.DispatchOptions['body'] | null;
4793
- }
4794
- export type MockResponseDataHandler<TData extends object = object> = (opts: MockResponseCallbackOptions) => TData | Buffer | string;
4795
- export type MockReplyOptionsCallback<TData extends object = object> = (opts: MockResponseCallbackOptions) => {
4796
- statusCode: number;
4797
- data?: TData | Buffer | string;
4798
- responseOptions?: MockResponseOptions;
4799
- };
4800
- }
4015
+ declare function mergeConfigWithDefaults(schema: ConfigSchemaLike | undefined, stored: Record<string, unknown>): Record<string, unknown>;
4801
4016
  //#endregion
4802
4017
  //#region src/i18n-registry.d.ts
4803
4018
  /** 单条 i18n 贡献条目(loader 产出,供 `register()` 消费)。 */
@@ -4848,5 +4063,5 @@ declare class PluginI18nRegistry extends TypedEventEmitter<PluginI18nRegistryEve
4848
4063
  t(fullKey: string, locale?: string): string;
4849
4064
  }
4850
4065
  //#endregion
4851
- export { type ActionContribution, type AgentContribution, type CommandContribution, type CommandRef, type ContextKeyProvider, type ContextMap, type ContextSourceContribution, type ContributionPoint, type DiscoverPluginsOptions, type DiscoveredPlugin, type DispatchCaps, EXTENSION_POINTS, type EngineCompatResult, type FeedbackIssueInput, type FeedbackIssueResult, type FeedbackProvider, type FileProviderOptions, HIGH_RISK_CAPABILITIES, type HostAskInput, ID_RE, MAX_I18N_ENTRIES_PER_PLUGIN, MAX_I18N_FILE_BYTES, MAX_I18N_LOCALE_FILES_PER_PLUGIN, MAX_I18N_TRANSLATION_BYTES, MAX_THEME_PRESETS_PER_PLUGIN, type McpContribution, type McpTransport, type MenuContribution, type MonitorEvent, type OAuthContribution, PLUGIN_API_VERSION, PLUGIN_CAPABILITIES, PLUGIN_MANIFEST_FILENAME, POINT, type PerfMetricContribution, type PluginA2uiComponentEntry, type PluginA2uiRendererEntry, type PluginCapability, type PluginCliContribution, type PluginContext, type PluginContributes, type PluginContributions, type PluginExecutableSurface, type PluginFactory, type PluginFileViewerEntry, type PluginHooks, type PluginHostCapabilities, type PluginI18nContribution, type PluginI18nEntry, PluginI18nRegistry, type PluginInputRegistry, type PluginManifest, type PluginModelEntry, type PluginModule, type PluginMonitor, type PluginPanelEntry, type PluginProviderEntry, type PluginProviderFactory, type PluginRendererEntry, type PluginScheduleSubscription, type PluginScopedStorageShape, type PluginScripts, type PluginService, type PluginServiceContext, type PluginServiceNotification, type PluginThemePresetColors, type PluginThemePresetContribution, type PluginTool, type PluginToolContext, type PluginTrustVerdict, type PluginWireProtocolRegistration, type PreToolUseDecision, type PulseSurveyEntry, type PulseSurveyRating, type PulseSurveyResolvedConfig, type ResolvedAction, SHELL_POINTS, type ScheduleTickNotification, type SessionIdleNotification, type SigilEntry, type SigilEntryContribution, type SigilKind, type SigilPrefix, type SigilProvider, type SigilSource, type SkillContribution, type StatusItemContribution, type StatusWidgetContribution, type ToolUseContext, type TopoSortResult, type TranscriptMessage, createBuiltinHashtags, createFileProvider, createPluginInputRegistry, definePlugin, detectPluginExecutableSurface, discoverPlugins, dispatch, evaluateContextKey, evaluateContextKeys, evaluatePluginTrust, evaluateWhen, expandPath, filterEngineCompatible, grantPluginCapabilities, grantedPluginCapabilities, isEngineCompatible, isPathTrusted, isPluginTrusted, mergeContributions, parsePluginManifest, pluginTrustStorePath, readHighRiskCapabilities, resolveActions, resolveActivationEvents, sigilOf, topoSortPlugins, trustPath, trustPlugin, untrustPath, untrustPlugin };
4066
+ export { type ActionContribution, type AgentContribution, type CommandContribution, type CommandRef, type ConfigSchemaLike, type ContextKeyProvider, type ContextMap, type ContextSourceContribution, type ContributionPoint, type DiscoverPluginsOptions, type DiscoveredPlugin, type DispatchCaps, EXTENSION_POINTS, type EngineCompatResult, type FeedbackIssueInput, type FeedbackIssueItem, type FeedbackIssueListResult, type FeedbackIssueResult, type FeedbackProvider, type FeedbackResolvedMark, type FeedbackSource, type FileProviderOptions, HIGH_RISK_CAPABILITIES, type HostAskInput, ID_RE, MAX_CONFIG_FIELDS_PER_PLUGIN, MAX_CONFIG_FIELD_DESCRIPTION_CHARS, MAX_CONFIG_SCHEMA_BYTES, MAX_CONFIG_SCHEMA_DEPTH, MAX_I18N_ENTRIES_PER_PLUGIN, MAX_I18N_FILE_BYTES, MAX_I18N_LOCALE_FILES_PER_PLUGIN, MAX_I18N_TRANSLATION_BYTES, MAX_THEME_PRESETS_PER_PLUGIN, type McpContribution, type McpTransport, type MenuContribution, type MonitorEvent, type OAuthContribution, PLUGIN_API_VERSION, PLUGIN_CAPABILITIES, PLUGIN_MANIFEST_FILENAME, POINT, type PerfMetricContribution, type PluginA2uiComponentEntry, type PluginA2uiRendererEntry, type PluginCapability, type PluginCliCommandContext, type PluginCliCommandContribution, type PluginCliCommandHandler, type PluginCliCommandOptions, type PluginCliContribution, type PluginConfigSchemaEntry, type PluginContext, type PluginContributes, type PluginContributions, type PluginEventContribution, type PluginExecutableSurface, type PluginFactory, type PluginFileViewerEntry, type PluginHooks, type PluginHostCapabilities, type PluginI18nContribution, type PluginI18nEntry, PluginI18nRegistry, type PluginInputRegistry, type PluginLoadFailureReason, type PluginManifest, type PluginManifestPlane, type PluginMessageHooks, type PluginModelEntry, type PluginModule, type PluginMonitor, type PluginPanelEntry, type PluginProviderEntry, type PluginProviderFactory, type PluginRendererEntry, type PluginScheduleSubscription, type PluginScopedStorageShape, type PluginScripts, type PluginService, type PluginServiceContext, type PluginServiceNotification, type PluginSessionHooks, type PluginSlashCommandAppBridge, type PluginSlashCommandContext, type PluginSlashCommandContribution, type PluginSlashCommandHandler, type PluginSlashCommandTuiBridge, type PluginTaskHooks, type PluginThemePresetColors, type PluginThemePresetContribution, type PluginTool, type PluginToolContext, type PluginToolHooks, type PluginTrustVerdict, type PluginWaterfallHandler, type PluginWaterfallHooks, type PluginWireProtocolRegistration, type PreToolUseDecision, type PulseSurveyEntry, type PulseSurveyRating, type PulseSurveyResolvedConfig, type ResolvedAction, SHELL_POINTS, type ScheduleTickNotification, type SessionIdleNotification, type SigilEntry, type SigilEntryContribution, type SigilKind, type SigilPrefix, type SigilProvider, type SigilSource, type SkillContribution, type StatusItemContribution, type StatusWidgetContribution, type ToolUseContext, type TopoSortResult, type TranscriptMessage, createBuiltinHashtags, createFileProvider, createPluginInputRegistry, definePlugin, detectPluginExecutableSurface, discoverPlugins, dispatch, evaluateContextKey, evaluateContextKeys, evaluatePluginTrust, evaluateWhen, expandPath, filterEngineCompatible, grantCapabilitiesWithVersion, grantPluginCapabilities, grantPluginCapabilitiesWithVersion, grantedCapabilitiesForVersion, grantedPluginCapabilities, grantedPluginCapabilitiesForVersion, isEngineCompatible, isPathTrusted, isPluginTrusted, isSensitiveField, mergeConfigWithDefaults, mergeContributions, parsePluginManifest, pluginTrustStorePath, readHighRiskCapabilities, redactSensitiveFields, resolveActions, resolveActivationEvents, resolveManifestPlane, sigilOf, topoSortPlugins, trustPath, trustPlugin, untrustPath, untrustPlugin };
4852
4067
  //# sourceMappingURL=index.d.ts.map