@sendevia/pi-ask-author 1.0.5 → 1.1.0

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/model.d.ts CHANGED
@@ -7,17 +7,47 @@
7
7
  * - 两层清洗:`sanitize.ts` 边界归一化 + 本层对文本字段幂等兜底(绕过 sanitize 直接构造模型时同样安全)
8
8
  * - 封套防止击穿:插值文本经由 `sanitizeEnvelopeText` 归一化,定界符不可被作者文本击穿
9
9
  * - 封套语言单一:自动生成的占位题目/标签在封套编译期替换为英文占位(`Question N` / `Option N`),作者界面保留中文占位
10
- * - 答卷完整性:显式跳过与仅批注提交均产出条目,多选题目恒产出条目,问题不在结果中静默消失
10
+ * - 答卷完整性:显示中的题目即使显式跳过或仅批注提交也产出条目,多选题目恒产出条目,不存在静默消失的作答
11
+ * - 自适应显隐:题目与选项可声明 `showIf` 条件且仅允许引用更早题目;显隐快照按 `revision` 缓存,隐藏项的选择不计入作答与答卷
11
12
  *
12
13
  * 依赖方向:model.ts → format.ts / schema.ts / texts.ts(纯函数工具、Schema 单一类型源与文案字典,无回边);不引用 `Theme` 与 TUI 组件,渲染细节全部上移组件层
13
14
  */
14
15
  import type { QuestionOption, RawParams } from "./schema.js";
16
+ /**
17
+ * 显示条件的归一化形态:引用的题目索引与选项索引均已解析
18
+ * - `option`:指定题目中某个选项当前处于选中状态
19
+ * - `answered`:指定题目存在(或不存在)任何作答痕迹
20
+ */
21
+ export type VisibilityCondition = {
22
+ readonly kind: "option";
23
+ readonly questionIndex: number;
24
+ readonly optionIndex: number;
25
+ } | {
26
+ readonly kind: "answered";
27
+ readonly questionIndex: number;
28
+ readonly answered: boolean;
29
+ };
30
+ /** 归一化后的候选选项(在 Schema 选项字段之外附带显示条件) */
31
+ export interface NormalizedOption {
32
+ /** 选项标签 */
33
+ label: string;
34
+ /** 情节推演 / 设定阐述(可选) */
35
+ description?: string;
36
+ /** 正文草稿或分镜头预览(可选) */
37
+ preview?: string;
38
+ /** 选项补充说明占位词(可选) */
39
+ customPlaceholder?: string;
40
+ /** 该选项的显示条件(空数组表示恒显示) */
41
+ showIf: VisibilityCondition[];
42
+ }
15
43
  /** 归一化后的问题对象(字段已兜底,区间已收敛) */
16
44
  export interface NormalizedQuestion {
17
45
  /** 题目唯一标识符 */
18
46
  id: string;
19
47
  /** 题目标题 */
20
48
  title: string;
49
+ /** Tab 栏短标签(可选;缺省时 Tab 栏显示题号) */
50
+ tabLabel?: string;
21
51
  /** 题目背景描述(可选) */
22
52
  description?: string;
23
53
  /** 是否多选(默认 false,即单选) */
@@ -31,11 +61,21 @@ export interface NormalizedQuestion {
31
61
  /** 是否允许 0 勾选提交(默认 false;单选与多选均生效) */
32
62
  allowEmpty: boolean;
33
63
  /** 归一化后的候选选项列表(至少一项) */
34
- options: QuestionOption[];
64
+ options: NormalizedOption[];
35
65
  /** 是否允许自由补充说明(默认 true) */
36
66
  allowCustom: boolean;
37
67
  /** 补充说明输入框占位提示词 */
38
68
  customPlaceholder: string;
69
+ /** 该题目的显示条件(空数组表示恒显示) */
70
+ showIf: VisibilityCondition[];
71
+ }
72
+ /** 自适应条件非法(引用未知题目、后置题目或不存在的选项):携带面向 LLM 的英文诊断消息,由入口层映射为结构化错误结果 */
73
+ export declare class AdaptiveConditionError extends Error {
74
+ /**
75
+ * 构造自适应条件异常
76
+ * @param message - 英文诊断消息(取自 `TEXTS.markdown.adaptiveErrors`)
77
+ */
78
+ constructor(message: string);
39
79
  }
40
80
  /** 单题作答状态(内部数据结构,选项索引 0-based) */
41
81
  export interface QuestionAnswerState {
@@ -122,7 +162,7 @@ type NoteSaveResult = "saved" | "cleared" | "savedUnselected" | "savedAtLimit";
122
162
  export declare function hasQuestionNote(st: QuestionAnswerState): boolean;
123
163
  /**
124
164
  * 问卷数据模型:题目归一化、作答状态流转与答卷编译;全部状态突变经本类 mutation 方法完成并自动推进 `revision`,组件层只读
125
- * 只读访问面:`revision` / `questionCount` / `getQuestion` / `getState` / `getSelectedIndices`(0-based 升序,排序不变量唯一实现)/ `getMenuItems` / `isQuestionAnswered` / `areAllQuestionsAnswered` / `compileAnswers` / `formatAnswers`
165
+ * 只读访问面:`revision` / `questionCount` / `getQuestion` / `getState` / `getSelectedIndices`(0-based 升序,排序不变量唯一实现)/ `getSelectedIndex` / `isQuestionVisible` / `isOptionVisible` / `getVisibleQuestionIndices` / `hasAnyResponse` / `getMenuItems` / `isQuestionAnswered` / `areAllQuestionsAnswered` / `compileAnswers` / `formatAnswers`
126
166
  */
127
167
  export declare class AskAuthorFormModel {
128
168
  /** 问卷总标题 */
@@ -135,6 +175,8 @@ export declare class AskAuthorFormModel {
135
175
  private revisionValue;
136
176
  /** 各题作答状态映射(题目索引 0-based) */
137
177
  private readonly states;
178
+ /** 显隐快照缓存(按 `revision` 失效;包含题目可见性、选项可见性与可见选中项) */
179
+ private visibilityCache?;
138
180
  /**
139
181
  * 构造问卷数据模型实例(单题平铺与批量问卷两模式归一化)
140
182
  * @param rawParams - 经 prepareArguments 规整的入参;`questions` 缺省或为空数组时回退单题平铺模式,`options` 亦为空则题目列表为空
@@ -158,31 +200,82 @@ export declare class AskAuthorFormModel {
158
200
  */
159
201
  getState(index: number): QuestionAnswerState;
160
202
  /**
161
- * 获取已勾选选项索引(0-based 升序,未作答为空数组;排序不变量唯一实现在此)
203
+ * 获取当前显隐快照(按 `revision` 缓存,题目顺序一次正向计算)
204
+ * 条件只允许引用更早题目,故单次正向遍历即可得出全部可见性;被引用题目自身不可见时,引用它的条件恒不成立
205
+ * @returns 题目可见性、各题选项可见性与各题可见选中项索引(升序)
206
+ */
207
+ private snapshot;
208
+ /**
209
+ * 判定单个显示条件是否成立
210
+ * @param condition - 已解析的条件
211
+ * @param questions - 已完成计算的题目可见性(下标小于当前题)
212
+ * @param selected - 已完成计算的可见选中项(下标小于当前题)
213
+ * @returns 被引用题目不可见时为 false;否则按选项选中态或作答存在性判定
214
+ */
215
+ private conditionHolds;
216
+ /**
217
+ * 判定指定题目是否留下过任何作答痕迹(已选选项或非空批注,不区分选项当前是否可见)
218
+ * @param qIndex - 题目顺序索引(0-based)
219
+ * @returns 存在任意痕迹时为 true;状态未创建时为 false
220
+ */
221
+ hasAnyResponse(qIndex: number): boolean;
222
+ /**
223
+ * 判定指定题目是否可见
224
+ * @param index - 题目顺序索引(0-based)
225
+ * @returns 无显示条件或全部条件成立时为 true;索引越界为 false
226
+ */
227
+ isQuestionVisible(index: number): boolean;
228
+ /**
229
+ * 判定指定选项是否可见
230
+ * @param qIndex - 题目顺序索引(0-based)
231
+ * @param optionIndex - 选项索引(0-based)
232
+ * @returns 无显示条件或全部条件成立时为 true;索引越界为 false
233
+ */
234
+ isOptionVisible(qIndex: number, optionIndex: number): boolean;
235
+ /**
236
+ * 获取当前可见题目索引
237
+ * @returns 升序索引数组;第一题无前置题目可引用,因此结果恒非空(题目列表非空时)
238
+ */
239
+ getVisibleQuestionIndices(): number[];
240
+ /**
241
+ * 获取已勾选且当前可见的选项索引(0-based 升序,未作答为空数组;排序不变量唯一实现在此)
242
+ * 选项因条件失效而隐藏时,其既有勾选不计入作答与答卷;条件恢复后重新生效
162
243
  * @param qIndex - 题目顺序索引(0-based)
163
244
  * @returns 全新数组(调用方可安全持有而不影响内部状态);题目越界或状态未创建时为空数组
164
245
  */
165
246
  getSelectedIndices(qIndex: number): number[];
247
+ /**
248
+ * 获取单选选中项索引(可见选中项为空时 undefined)
249
+ * @param qIndex - 题目顺序索引(0-based)
250
+ * @returns 首个可见选中项索引;未选中、选中项已隐藏或索引越界时为 undefined
251
+ */
252
+ getSelectedIndex(qIndex: number): number | undefined;
166
253
  /** 推进作答状态版本号(全部 mutation 方法的统一出口) */
167
254
  private bumpRevision;
168
255
  /**
169
256
  * 派生指定题目的左侧菜单项列表(预设选项 + 自由补充入口 + 确认推进按钮)
170
257
  * 菜单项标签与确认按钮明细随当前作答状态派生:多选展示已选数/下限,单选展示已选项标签、自定义方案名或「未选」
171
258
  * @param qIndex - 题目顺序索引(0-based)
172
- * @returns 顺序固定的菜单项数组(选项按声明顺序在前、补充入口居中、确认按钮殿后);题目越界为空数组;`allowCustom` 为 false 时省略补充入口
259
+ * @returns 顺序固定的菜单项数组(选项按声明顺序在前、补充入口居中、确认按钮殿后);题目越界为空数组;`allowCustom` 为 false 时省略补充入口;不可见选项不产出条目
173
260
  */
174
261
  getMenuItems(qIndex: number): MenuItem[];
262
+ /**
263
+ * 判定指定题目是否存在会被提交的批注(题目级批注或可见选项上的批注)
264
+ * @param qIndex - 题目顺序索引(0-based)
265
+ * @returns 存在非空批注时为 true;状态未创建时为 false
266
+ */
267
+ private hasSubmittableNote;
175
268
  /**
176
269
  * 判定指定题目是否满足作答下限提交要求
177
270
  * 单选:已选一项、`allowEmpty`,或 `allowCustom` 开启且存在任意非空批注;多选:勾选数达 `minSelect`、`allowEmpty` 下 0 选,
178
271
  * 或缺省下限未勾选(`minSelect` 未显式给出时收敛为 `min(1, 选项数)`,故此时 `count < minSelect` 等价于 `count === 0`)且 `allowCustom` 开启并存在任意非空批注
179
272
  * @param qIndex - 题目顺序索引(0-based)
180
- * @returns 题目越界恒为 false;作答状态尚未懒加载时按只读空状态({@link EMPTY_STATE})判定,不写入任何状态
273
+ * @returns 题目越界或该题当前不可见时恒为 false;作答状态尚未懒加载时按空作答判定,不写入任何状态
181
274
  */
182
275
  isQuestionAnswered(qIndex: number): boolean;
183
276
  /**
184
- * 判定问卷中的全部题目是否均已作答完毕
185
- * @returns 每题均满足 {@link isQuestionAnswered} 时为 true;题目列表为空时恒为 true(`every` 的空集语义)
277
+ * 判定问卷中当前可见的题目是否均已作答完毕(隐藏题目不参与判定)
278
+ * @returns 所有可见题目均满足 {@link isQuestionAnswered} 时为 true;无可见题目时恒为 true(`every` 的空集语义)
186
279
  */
187
280
  areAllQuestionsAnswered(): boolean;
188
281
  /**
@@ -234,17 +327,18 @@ export declare class AskAuthorFormModel {
234
327
  */
235
328
  clearQuestionNote(qIndex: number): boolean;
236
329
  /**
237
- * 收集全部非空选项批注(含未选中选项上的孤立批注),键转换为 1-based;与总览页展示保持一致
330
+ * 收集全部非空选项批注(含未选中选项上的孤立批注,跳过当前不可见的选项),键转换为 1-based;与总览页展示保持一致
331
+ * @param qIndex - 题目顺序索引(0-based)
238
332
  * @param q - 归一化题目对象
239
333
  * @param st - 题目作答状态(可选)
240
334
  * @returns 1-based 选项索引 → 批注内容的映射表
241
335
  */
242
336
  private collectOptionNotes;
243
337
  /**
244
- * 编译全部作答状态为结果答案条目列表
338
+ * 编译当前可见题目的作答状态为结果答案条目列表(隐藏题目不产出条目)
245
339
  * 产出规则:多选题目恒产出条目(未作答时 `selectedOptions` / `selectedIndices` 为空);单选题目仅在已作答时才产出条目(已选一项、`allowEmpty` 主动跳过或仅批注提交)
246
- * 两种模式均杜绝问题在结果封套中静默消失;0-based 内部索引统一转换为 1-based
247
- * @returns 与题目顺序一致的答卷条目列表(未产出的单选题目不占位);题干无任何作答且非多选时为空数组
340
+ * 两种模式均杜绝可见题目在结果封套中静默消失;0-based 内部索引统一转换为 1-based
341
+ * @returns 与题目顺序一致的答卷条目列表(未产出的单选题目不占位);无已作答题目时为空数组
248
342
  */
249
343
  compileAnswers(): AuthorAnswerItem[];
250
344
  /**
@@ -3,7 +3,7 @@
3
3
  * @description 小说语法高亮引擎:把语义定界符(`「」` / `()`)标注为携带哨兵的原生行内代码,折行与配色交还 Pi 原生 Markdown 引擎
4
4
  *
5
5
  * 核心架构特性:
6
- * - 声明式语法模板表(`NOVEL_TEMPLATE_*` 派生索引)驱动「定界符 → 语义哨兵 → 行内代码载体 → 主题样式」映射
6
+ * - 声明式语法模板表(定义于 `novel-syntax.ts` 的 `NOVEL_TEMPLATES` 与派生索引)驱动「定界符 → 语义哨兵 → 行内代码载体 → 主题样式」映射
7
7
  * - 对话台词「...」与旁白心理(...)由 `MarkdownOptions.transform` 在 marked 解析前完成标注
8
8
  * - `theme.code` 回调兼作哨兵分类器,未命中哨兵即完整交还原生行内代码样式
9
9
  * - 折行、嵌套与配色全部由原生 Markdown 引擎回填,插件不触碰任何 ANSI 转义流
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * 索引约定:全文「扁平索引 / 行内列索引」一律指 UTF-16 码元下标,含义与 `String.prototype.length` / `charAt` / `slice` 一致
13
13
  *
14
- * 依赖方向:novel-markdown.ts → format.ts / texts.ts / theme.ts(另行引入 model.ts 的 `MenuItem` 类型,无回环依赖);外部依赖 `@earendil-works/pi-tui` 的 `Markdown` / `MarkdownTheme` 与 `@earendil-works/pi-coding-agent` 的 `getMarkdownTheme`
14
+ * 依赖方向:novel-markdown.ts → format.ts / novel-syntax.ts / texts.ts / theme.ts(另行引入 model.ts 的 `MenuItem` 类型,无回环依赖);外部依赖 `@earendil-works/pi-tui` 的 `Markdown` / `MarkdownTheme` 与 `@earendil-works/pi-coding-agent` 的 `getMarkdownTheme`
15
15
  * 宿主主题耦合:围栏代码块由 `getMarkdownTheme()` 的 `highlightCode` 着色,提取颜色读取宿主全局活动主题(须宿主已 `initTheme`,本模块不自行持有主题);行内代码仅在未命中哨兵时走同一全局 `code` 提取颜色
16
16
  */
17
17
  import type { MenuItem } from "./model.js";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @file novel-syntax.ts
3
+ * @description 小说语法资产:定界符 → 语义哨兵 → 原生 Markdown 载体 → 主题样式的声明式模板表
4
+ *
5
+ * 核心架构特性:
6
+ * - 新增小说语法只需在 `NOVEL_TEMPLATES` 表尾追加一项,两个派生索引自动生成
7
+ * - 仅依赖 `theme.ts` 的类型别名,不装载语言资源与任何视图模块
8
+ *
9
+ * 依赖方向:novel-syntax.ts → theme.ts(仅类型);被 novel-markdown.ts 消费
10
+ */
11
+ import type { Theme } from "./theme.js";
12
+ /**
13
+ * 语义哨兵前缀:不可见 NUL 控制字符,仅存在于 transform 产出与 `theme.code` 消费之间的中间态
14
+ * 约定:输入侧已在 `format.ts` 边界剥离,分类时立即剥离,绝不进入终端输出
15
+ */
16
+ export declare const NOVEL_MARKER_PREFIX = "\0";
17
+ /** 小说语法模板的字段规范(定界符 → 语义哨兵 → 原生 Markdown 载体 → 主题样式) */
18
+ export interface NovelSyntaxTemplate {
19
+ /** 开始定界符 */
20
+ readonly opener: string;
21
+ /** 结束定界符 */
22
+ readonly closer: string;
23
+ /** 语义哨兵字符(紧随 {@link NOVEL_MARKER_PREFIX} 之后,`theme.code` 分类依据;`d` = dialogue、`m` = monologue) */
24
+ readonly marker: string;
25
+ /** 单个语义跨距最大字符数(含定界符;超出视为残缺定界符并放弃高亮) */
26
+ readonly maxSpanLength: number;
27
+ /**
28
+ * 依据当前主题绘制语义文本
29
+ * @param theme - 当前 TUI 主题实例(类型定义于叶层 `theme.ts`)
30
+ * @param text - 已剥离哨兵的语义原文(含定界符)
31
+ * @returns 应用语义样式后的富文本
32
+ */
33
+ readonly paint: (theme: Theme, text: string) => string;
34
+ }
35
+ /** 开定界符 → 语法模板 的 `O(1)` 索引(同开定界符按声明顺序后者覆盖前者) */
36
+ export declare const NOVEL_TEMPLATE_BY_OPENER: ReadonlyMap<string, NovelSyntaxTemplate>;
37
+ /** 语义哨兵字符 → 语法模板 的 `O(1)` 索引(`theme.code` 分类依据) */
38
+ export declare const NOVEL_TEMPLATE_BY_MARKER: ReadonlyMap<string, NovelSyntaxTemplate>;
package/dist/schema.d.ts CHANGED
@@ -10,8 +10,17 @@
10
10
  * 依赖方向:schema.ts → typebox / texts.ts(上限常量与字段描述);被 sanitize / model / index 消费
11
11
  */
12
12
  import { Type, type Static } from "typebox";
13
+ /** 显示条件参数 Schema:引用更早题目的作答状态,决定本题或本选项是否出现 */
14
+ export declare const ShowIfConditionSchema: Type.TObject<{
15
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
16
+ questionId: Type.TString;
17
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
18
+ option: Type.TOptional<Type.TString>;
19
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
20
+ answered: Type.TOptional<Type.TBoolean>;
21
+ }>;
13
22
  /** 单个候选选项的参数 Schema */
14
- declare const OptionSchema: Type.TObject<{
23
+ export declare const OptionSchema: Type.TObject<{
15
24
  /** 选项简短标题/行动标签(必须填写;缺失时经 `sanitize.ts` → `model.ts` 两级兜底为自动占位标签) */
16
25
  label: Type.TString;
17
26
  /** 情节推演后果或设定阐述(可选) */
@@ -20,13 +29,31 @@ declare const OptionSchema: Type.TObject<{
20
29
  preview: Type.TOptional<Type.TString>;
21
30
  /** 该选项专属补充说明的占位引导文案(可选) */
22
31
  customPlaceholder: Type.TOptional<Type.TString>;
32
+ /** 该选项的显示条件(可选;不成立时不展示,选中态同样不计入答卷) */
33
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
34
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
35
+ questionId: Type.TString;
36
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
37
+ option: Type.TOptional<Type.TString>;
38
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
39
+ answered: Type.TOptional<Type.TBoolean>;
40
+ }>, Type.TArray<Type.TObject<{
41
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
42
+ questionId: Type.TString;
43
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
44
+ option: Type.TOptional<Type.TString>;
45
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
46
+ answered: Type.TOptional<Type.TBoolean>;
47
+ }>>]>>;
23
48
  }>;
24
49
  /** 单个问题的参数 Schema(批量问卷与平铺模式共用) */
25
- declare const QuestionSchema: Type.TObject<{
50
+ export declare const QuestionSchema: Type.TObject<{
26
51
  /** 题目唯一标识符(可选;缺省由模型层按顺序生成,跨题重复由模型层去重) */
27
52
  id: Type.TOptional<Type.TString>;
28
53
  /** 题目标题(必须填写;缺失时两级兜底为自动占位标题) */
29
54
  title: Type.TString;
55
+ /** Tab 栏短标签(可选;缺省时 Tab 栏显示题号) */
56
+ tabLabel: Type.TOptional<Type.TString>;
30
57
  /** 题目背景与语境(可选) */
31
58
  description: Type.TOptional<Type.TString>;
32
59
  /** 是否允许多选(可选;默认 false,即单选) */
@@ -47,11 +74,43 @@ declare const QuestionSchema: Type.TObject<{
47
74
  preview: Type.TOptional<Type.TString>;
48
75
  /** 该选项专属补充说明的占位引导文案(可选) */
49
76
  customPlaceholder: Type.TOptional<Type.TString>;
77
+ /** 该选项的显示条件(可选;不成立时不展示,选中态同样不计入答卷) */
78
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
79
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
80
+ questionId: Type.TString;
81
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
82
+ option: Type.TOptional<Type.TString>;
83
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
84
+ answered: Type.TOptional<Type.TBoolean>;
85
+ }>, Type.TArray<Type.TObject<{
86
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
87
+ questionId: Type.TString;
88
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
89
+ option: Type.TOptional<Type.TString>;
90
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
91
+ answered: Type.TOptional<Type.TBoolean>;
92
+ }>>]>>;
50
93
  }>>;
51
94
  /** 是否允许自由补充说明(可选;默认 true) */
52
95
  allowCustom: Type.TOptional<Type.TBoolean>;
53
96
  /** 题目整体补充说明的占位引导词(可选) */
54
97
  customPlaceholder: Type.TOptional<Type.TString>;
98
+ /** 该题目的显示条件(可选;不成立时不展示,也不计入答卷) */
99
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
100
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
101
+ questionId: Type.TString;
102
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
103
+ option: Type.TOptional<Type.TString>;
104
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
105
+ answered: Type.TOptional<Type.TBoolean>;
106
+ }>, Type.TArray<Type.TObject<{
107
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
108
+ questionId: Type.TString;
109
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
110
+ option: Type.TOptional<Type.TString>;
111
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
112
+ answered: Type.TOptional<Type.TBoolean>;
113
+ }>>]>>;
55
114
  }>;
56
115
  /** `ask_author` 工具完整参数 Schema(必须填写 `formTitle`;批量问卷传递 `questions`,单题平铺传递顶层 `question` + `options`) */
57
116
  export declare const AskAuthorParams: Type.TObject<{
@@ -65,6 +124,8 @@ export declare const AskAuthorParams: Type.TObject<{
65
124
  id: Type.TOptional<Type.TString>;
66
125
  /** 题目标题(必须填写;缺失时两级兜底为自动占位标题) */
67
126
  title: Type.TString;
127
+ /** Tab 栏短标签(可选;缺省时 Tab 栏显示题号) */
128
+ tabLabel: Type.TOptional<Type.TString>;
68
129
  /** 题目背景与语境(可选) */
69
130
  description: Type.TOptional<Type.TString>;
70
131
  /** 是否允许多选(可选;默认 false,即单选) */
@@ -85,11 +146,43 @@ export declare const AskAuthorParams: Type.TObject<{
85
146
  preview: Type.TOptional<Type.TString>;
86
147
  /** 该选项专属补充说明的占位引导文案(可选) */
87
148
  customPlaceholder: Type.TOptional<Type.TString>;
149
+ /** 该选项的显示条件(可选;不成立时不展示,选中态同样不计入答卷) */
150
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
151
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
152
+ questionId: Type.TString;
153
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
154
+ option: Type.TOptional<Type.TString>;
155
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
156
+ answered: Type.TOptional<Type.TBoolean>;
157
+ }>, Type.TArray<Type.TObject<{
158
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
159
+ questionId: Type.TString;
160
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
161
+ option: Type.TOptional<Type.TString>;
162
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
163
+ answered: Type.TOptional<Type.TBoolean>;
164
+ }>>]>>;
88
165
  }>>;
89
166
  /** 是否允许自由补充说明(可选;默认 true) */
90
167
  allowCustom: Type.TOptional<Type.TBoolean>;
91
168
  /** 题目整体补充说明的占位引导词(可选) */
92
169
  customPlaceholder: Type.TOptional<Type.TString>;
170
+ /** 该题目的显示条件(可选;不成立时不展示,也不计入答卷) */
171
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
172
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
173
+ questionId: Type.TString;
174
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
175
+ option: Type.TOptional<Type.TString>;
176
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
177
+ answered: Type.TOptional<Type.TBoolean>;
178
+ }>, Type.TArray<Type.TObject<{
179
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
180
+ questionId: Type.TString;
181
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
182
+ option: Type.TOptional<Type.TString>;
183
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
184
+ answered: Type.TOptional<Type.TBoolean>;
185
+ }>>]>>;
93
186
  }>>>;
94
187
  /** 单题平铺模式题目标题(可选;仅在携带非空 `options` 时参与选题,缺省回退 `TEXTS.fallbacks.defaultQuestionTitle`) */
95
188
  question: Type.TOptional<Type.TString>;
@@ -111,6 +204,22 @@ export declare const AskAuthorParams: Type.TObject<{
111
204
  preview: Type.TOptional<Type.TString>;
112
205
  /** 该选项专属补充说明的占位引导文案(可选) */
113
206
  customPlaceholder: Type.TOptional<Type.TString>;
207
+ /** 该选项的显示条件(可选;不成立时不展示,选中态同样不计入答卷) */
208
+ showIf: Type.TOptional<Type.TUnion<[Type.TObject<{
209
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
210
+ questionId: Type.TString;
211
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
212
+ option: Type.TOptional<Type.TString>;
213
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
214
+ answered: Type.TOptional<Type.TBoolean>;
215
+ }>, Type.TArray<Type.TObject<{
216
+ /** 被引用的题目 ID(必须为本次表单中更早出现的题目) */
217
+ questionId: Type.TString;
218
+ /** 匹配的选项标签(可选;给出时条件等价于「该选项被选中」) */
219
+ option: Type.TOptional<Type.TString>;
220
+ /** 作答存在性(可选;缺省等价于 true,给出 `option` 时忽略) */
221
+ answered: Type.TOptional<Type.TBoolean>;
222
+ }>>]>>;
114
223
  }>>>;
115
224
  /** 单题平铺模式是否允许自由补充说明(可选;默认 true) */
116
225
  allowCustom: Type.TOptional<Type.TBoolean>;
@@ -126,4 +235,7 @@ export type RawParams = Static<typeof AskAuthorParams>;
126
235
  export type QuestionOption = Static<typeof OptionSchema>;
127
236
  /** 单个问题的运行时类型(由 `QuestionSchema` 经 `Static<typeof>` 派生,批量与平铺共用) */
128
237
  export type QuestionInput = Static<typeof QuestionSchema>;
129
- export {};
238
+ /** 单个显示条件的运行时类型(由 `ShowIfConditionSchema` 经 `Static<typeof>` 派生) */
239
+ export type VisibilityConditionInput = Static<typeof ShowIfConditionSchema>;
240
+ /** `showIf` 字段的运行时类型:单个条件或条件数组 */
241
+ export type ShowIfInput = VisibilityConditionInput | VisibilityConditionInput[];