@kirkchinese/dsh-citeciter 0.6.0 → 0.8.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.
Files changed (92) hide show
  1. package/README.md +83 -56
  2. package/README.zh.md +85 -56
  3. package/lib/client.js +6677 -953
  4. package/lib/index.js +1730 -538
  5. package/lib/{typert-common-C6yTitXx.js → typert-common-DxE1_Bn_.js} +1 -1
  6. package/lib/typert.host.js +2 -2
  7. package/lib/typert.remote-client.js +1 -1
  8. package/lib/types/actions.d.ts +47 -0
  9. package/lib/types/board-capture.d.ts +11 -0
  10. package/lib/types/board.d.ts +4 -4
  11. package/lib/types/citation-mapping.d.ts +8 -0
  12. package/lib/types/citer-agent-registry.d.ts +21 -0
  13. package/lib/types/citer-session-access.d.ts +11 -0
  14. package/lib/types/citer-session-store.d.ts +7 -0
  15. package/lib/types/citer-session-world.d.ts +21 -0
  16. package/lib/types/client/action-controller.d.ts +61 -0
  17. package/lib/types/client/action-executor.d.ts +6 -0
  18. package/lib/types/client/board-capture-target.d.ts +8 -0
  19. package/lib/types/client/citer-session-face.d.ts +59 -0
  20. package/lib/types/client/compact-navigation.d.ts +3 -0
  21. package/lib/types/client/companion-controller.d.ts +15 -4
  22. package/lib/types/client/components/ActionWheel.d.ts +12 -0
  23. package/lib/types/client/components/BoardCaptureSurface.d.ts +8 -0
  24. package/lib/types/client/components/BoardView.d.ts +5 -3
  25. package/lib/types/client/components/ChoicePopover.d.ts +8 -0
  26. package/lib/types/client/components/CiteLauncher.d.ts +9 -0
  27. package/lib/types/client/components/CitePanel.d.ts +7 -1
  28. package/lib/types/client/components/CompactBackButton.d.ts +4 -0
  29. package/lib/types/client/components/DocumentReader.d.ts +7 -1
  30. package/lib/types/client/components/FileAttachments.d.ts +9 -0
  31. package/lib/types/client/components/FileDropHint.d.ts +5 -0
  32. package/lib/types/client/components/LearningCards.d.ts +12 -0
  33. package/lib/types/client/components/LearningRoute.d.ts +7 -0
  34. package/lib/types/client/components/MessageAttachments.d.ts +12 -0
  35. package/lib/types/client/components/MessageFile.d.ts +8 -0
  36. package/lib/types/client/components/ModelChoice.d.ts +10 -0
  37. package/lib/types/client/components/NativeInteraction.d.ts +7 -0
  38. package/lib/types/client/components/NativeLearningDocument.d.ts +9 -0
  39. package/lib/types/client/components/NativeQueue.d.ts +6 -0
  40. package/lib/types/client/components/OverlayPortal.d.ts +10 -0
  41. package/lib/types/client/components/PermissionControl.d.ts +7 -0
  42. package/lib/types/client/components/QuestionCard.d.ts +10 -4
  43. package/lib/types/client/components/ReasoningDisclosure.d.ts +5 -0
  44. package/lib/types/client/components/ReferenceAttachments.d.ts +6 -0
  45. package/lib/types/client/components/TopicActions.d.ts +6 -0
  46. package/lib/types/client/components/TopicComposer.d.ts +36 -0
  47. package/lib/types/client/components/TopicHeader.d.ts +10 -0
  48. package/lib/types/client/components/TopicModelControls.d.ts +9 -0
  49. package/lib/types/client/components/TopicNavigation.d.ts +12 -0
  50. package/lib/types/client/components/TopicSettingsDialog.d.ts +21 -0
  51. package/lib/types/client/components/TopicTitle.d.ts +6 -0
  52. package/lib/types/client/components/UserMessageBody.d.ts +4 -0
  53. package/lib/types/client/components/WheelSettings.d.ts +7 -0
  54. package/lib/types/client/dock-geometry.d.ts +3 -3
  55. package/lib/types/client/draft-references.d.ts +20 -0
  56. package/lib/types/client/file-download.d.ts +16 -0
  57. package/lib/types/client/file-drop.d.ts +18 -0
  58. package/lib/types/client/host-dock.d.ts +2 -2
  59. package/lib/types/client/learning-route.d.ts +10 -0
  60. package/lib/types/client/native-composer.d.ts +18 -0
  61. package/lib/types/client/native-document.d.ts +13 -0
  62. package/lib/types/client/panel-drag.d.ts +10 -0
  63. package/lib/types/client/reader-controller.d.ts +6 -0
  64. package/lib/types/client/request-guard.d.ts +3 -2
  65. package/lib/types/client/submission-preference.d.ts +5 -0
  66. package/lib/types/client/transcript-position.d.ts +6 -0
  67. package/lib/types/client/types.d.ts +5 -4
  68. package/lib/types/client/view-actions.d.ts +1 -1
  69. package/lib/types/client/wheel-gesture.d.ts +13 -0
  70. package/lib/types/document-pages.d.ts +4 -0
  71. package/lib/types/documents.d.ts +7 -5
  72. package/lib/types/host-agent-modules.d.ts +15 -0
  73. package/lib/types/host-session-adapter.d.ts +31 -0
  74. package/lib/types/index.d.ts +5 -5
  75. package/lib/types/learning.d.ts +72 -0
  76. package/lib/types/native-attachment-read.d.ts +19 -0
  77. package/lib/types/native-session-contract.d.ts +198 -0
  78. package/lib/types/native-session-read.d.ts +4 -0
  79. package/lib/types/owned-session-cleanup.d.ts +2 -0
  80. package/lib/types/service.d.ts +1 -1
  81. package/lib/types/session-migration.d.ts +3 -0
  82. package/lib/types/source-session.d.ts +7 -0
  83. package/lib/types/source-storage.d.ts +12 -0
  84. package/lib/types/topic-index.d.ts +75 -0
  85. package/lib/types/topic-runtime.d.ts +19 -55
  86. package/lib/types/topic-stream.d.ts +14 -0
  87. package/lib/types/topic.d.ts +301 -2
  88. package/lib/types/typert-common.d.ts +210 -1
  89. package/lib/types/typert.host.d.ts +454 -3
  90. package/lib/{update-C0K5ekMg.js → update-0LcFDvI5.js} +279 -13
  91. package/package.json +86 -78
  92. package/lib/types/client/components/SelectionMenu.d.ts +0 -17
@@ -1,4 +1,62 @@
1
1
  import { z } from "zod";
2
+ //#region lib/types/native-session-contract.js
3
+ const attachmentId = z.string().min(1).transform((value) => value);
4
+ const nativeImageSchema = z.object({
5
+ attachmentId,
6
+ mediaType: z.enum([
7
+ "image/png",
8
+ "image/jpeg",
9
+ "image/webp",
10
+ "image/gif"
11
+ ]),
12
+ bytes: z.number().int().nonnegative(),
13
+ width: z.number().int().positive(),
14
+ height: z.number().int().positive(),
15
+ name: z.string().optional(),
16
+ originalDimensions: z.object({
17
+ width: z.number().int().positive(),
18
+ height: z.number().int().positive()
19
+ }).strict().optional()
20
+ }).strict().transform(({ name, originalDimensions, ...image }) => ({
21
+ ...image,
22
+ ...name === void 0 ? {} : { name },
23
+ ...originalDimensions === void 0 ? {} : { originalDimensions }
24
+ }));
25
+ const file = z.object({
26
+ attachmentId,
27
+ name: z.string(),
28
+ bytes: z.number().int().nonnegative()
29
+ }).strict();
30
+ /** Wire reference for an authorized attachment; generic files have no image metadata. */
31
+ const nativeAttachmentRefSchema = z.union([nativeImageSchema, file]);
32
+ const nativeAttachmentSchema = z.discriminatedUnion("type", [z.object({
33
+ type: z.literal("image"),
34
+ attachment: nativeImageSchema
35
+ }).strict(), z.object({
36
+ type: z.literal("file"),
37
+ attachment: file
38
+ }).strict()]);
39
+ /** Read-only control projection. The Agent inbox remains the only authoritative queue. */
40
+ const nativeStateSchema = z.object({
41
+ running: z.boolean(),
42
+ blank: z.boolean(),
43
+ error: z.string().nullable(),
44
+ queue: z.array(z.object({
45
+ id: z.string().min(1),
46
+ placement: z.enum([
47
+ "queued",
48
+ "steering",
49
+ "context"
50
+ ]),
51
+ rpcId: z.string().optional(),
52
+ text: z.string(),
53
+ attachments: z.array(nativeAttachmentSchema)
54
+ }).strict()),
55
+ receipts: z.array(z.object({
56
+ requestId: z.string().min(1),
57
+ attachments: z.array(nativeAttachmentSchema)
58
+ }).strict())
59
+ }).strict();
2
60
  /** Maximum combined UTF-8 element-content bytes retained on one board. */
3
61
  const BOARD_MAX_CONTENT_BYTES = 5e5;
4
62
  /** Element kinds the blackboard renders safely on the chalk canvas. */
@@ -253,6 +311,134 @@ Object.freeze({
253
311
  elements: [],
254
312
  invalid: 0
255
313
  });
314
+ //#endregion
315
+ //#region lib/types/learning.js
316
+ /** User-selected teaching stages; these indicate intent, never measured mastery. */
317
+ const LEARNING_STAGES = [
318
+ {
319
+ id: "logic",
320
+ label: "底层逻辑",
321
+ shortLabel: "逻辑",
322
+ hint: "从定义、成立条件和因果机制讲起。",
323
+ instruction: "请讲清当前主题的底层逻辑:先给出定义和成立条件,再解释因果机制与为什么成立。区分来源证据、一般知识和假设。只讲这一阶段,不自动推进。"
324
+ },
325
+ {
326
+ id: "qualitative",
327
+ label: "定性分析",
328
+ shortLabel: "定性",
329
+ hint: "看方向、边界,以及改变条件会发生什么。",
330
+ instruction: "请对当前主题做定性分析:解释变量或因素之间的关系、变化方向、边界与反例,用一个具体情境说明。只讲这一阶段,不自动推进。"
331
+ },
332
+ {
333
+ id: "quantitative",
334
+ label: "定量分析(板书)",
335
+ shortLabel: "定量",
336
+ hint: "把变量、推导和算例写到板书上。",
337
+ instruction: "请对当前主题做定量分析,并调用 blackboard_apply 整理板书:注明变量、单位、假设、推导步骤与一个可核查算例。示例数值必须标明是假设,不得伪造来源数据。如果此主题不适合定量或信息不足,请明确说明原因。只讲这一阶段,不自动推进。"
338
+ },
339
+ {
340
+ id: "connections",
341
+ label: "概念关联",
342
+ shortLabel: "关联",
343
+ hint: "说明它与哪些概念相连,以及为什么。",
344
+ instruction: "请围绕当前主题给出 2–4 个最有帮助的概念关联,逐一解释是前提、推论、类比还是对比,说明关联理由与类比的边界。需要时用板书画关系。只讲这一阶段,不自动推进。"
345
+ },
346
+ {
347
+ id: "summary",
348
+ label: "总结学习卡片",
349
+ shortLabel: "总结",
350
+ hint: "先核对与纠错,再整理成学习卡片。",
351
+ instruction: "请先核对本 Topic 的结论与已有板书:检查定义、成立条件、推导、数值和前后矛盾,不要把此前的模型回答当作证据;必要时读取可用来源。纠正发现的错误,将无法核实的内容明确标为“未核实”或省略,不要补造来源与定位。然后调用 learning_cards 生成 1–6 张学习卡片,每张包含核心结论、一个具体例子、可选自测问题和参考答案;逐项检查这些字段的一致性,纠错必须同步到例子和参考答案。涉及来源事实时保留真实可用的定位,区分来源证据与一般知识。完成后简短说明纠正了什么、还有哪些内容未核实;不安排复习计划。"
352
+ }
353
+ ];
354
+ /** Make the entire stage instruction visible and durable as an ordinary Topic user message. */
355
+ function learningQuestion(stageId, question = "") {
356
+ const stage = LEARNING_STAGES.find((candidate) => candidate.id === stageId);
357
+ return `【学习阶段:${stage.label}】\n${stage.instruction}${question.trim() === "" ? "" : `\n\n我的问题:${question.trim()}`}`;
358
+ }
359
+ const learningCardSchema = z.object({
360
+ title: z.string().trim().min(1).max(100),
361
+ summary: z.string().trim().min(1).max(2e3),
362
+ example: z.string().trim().min(1).max(1500),
363
+ question: z.string().trim().min(1).max(500),
364
+ answer: z.string().trim().min(1).max(2e3)
365
+ }).strict();
366
+ const learningCardsInputSchema = z.object({ cards: z.array(learningCardSchema).min(1).max(8) }).strict();
367
+ /** Shared teaching contract appended to every scenario's logged tutor section. */
368
+ const LEARNING_PROMPT = `The optional learning route is 底层逻辑 → 定性分析 → 定量分析(板书) → 概念关联 → 总结学习卡片. A user may select or skip any stage. Respond to the current request only; never advance automatically or claim that a stage proves mastery. Never schedule spaced repetition or reminders. Do not require quizzes before continuing.
369
+
370
+ Use learning_cards only when the user asks to summarize or revise learning cards. Before composing cards in this same turn, check the Topic's conclusions and existing board for incorrect definitions, missing conditions, faulty derivations or arithmetic, and contradictions. Earlier assistant output is not evidence. Read available sources when needed; distinguish source evidence from general knowledge. Correct errors before saving, and explicitly label unresolved claims as 未核实 (unverified) or omit them. Check every card's summary, example, question and reference answer for consistency: a correction in the summary must also reach its example and answer. Briefly report corrections and unresolved points; do not present this self-check as independent verification.
371
+
372
+ Each successful learning_cards call replaces the visible card set for this Topic; older sets remain in its log. Send the complete desired set in one call, not separate calls for individual cards. Write concise, source-grounded summaries and examples, plus a question and reference answer for optional self-testing. Preserve real available source locators inside summaries; do not invent offsets, sources or evidence. Cards and blackboard tools only record learning material inside this independent Topic; they never write to the workspace or source Session.`;
373
+ //#endregion
374
+ //#region lib/types/actions.js
375
+ /** One persisted wheel slot; its prompt is sent as a durable user message. */
376
+ const citeActionSchema = z.object({
377
+ label: z.string().trim().min(1).max(20),
378
+ prompt: z.string().max(4e3),
379
+ ask: z.boolean(),
380
+ scenario: z.enum(["qa", "present"]),
381
+ presentation: z.enum(["side", "floating"])
382
+ }).strict().refine((action) => action.ask || action.prompt.trim() !== "", "直接执行的模式需要提示词");
383
+ const wheelSlotsSchema = z.array(citeActionSchema.nullable()).length(8);
384
+ const wheelTriggerSchema = z.enum([
385
+ "right-button",
386
+ "Alt",
387
+ "Control",
388
+ "Shift",
389
+ "Meta"
390
+ ]);
391
+ const actionModelSchema = z.object({
392
+ provider: z.string().min(1).max(200),
393
+ model: z.string().min(1).max(200)
394
+ }).strict();
395
+ /** Clockwise from twelve o'clock. Empty slots retain their positions. */
396
+ const DEFAULT_WHEEL_SLOTS = [
397
+ {
398
+ label: "自由提问",
399
+ prompt: "",
400
+ ask: true,
401
+ scenario: "qa",
402
+ presentation: "side"
403
+ },
404
+ {
405
+ label: "解释这段",
406
+ prompt: learningQuestion("logic"),
407
+ ask: false,
408
+ scenario: "present",
409
+ presentation: "side"
410
+ },
411
+ {
412
+ label: "找错误",
413
+ prompt: "请审查引用内容的错误、遗漏和成立条件。区分可确认的错误与需要补充的信息。",
414
+ ask: false,
415
+ scenario: "qa",
416
+ presentation: "floating"
417
+ },
418
+ {
419
+ label: "翻译",
420
+ prompt: "请将引用内容翻译为中文,保留重要术语的原文。",
421
+ ask: false,
422
+ scenario: "qa",
423
+ presentation: "floating"
424
+ },
425
+ {
426
+ label: "定量板书",
427
+ prompt: learningQuestion("quantitative"),
428
+ ask: false,
429
+ scenario: "present",
430
+ presentation: "side"
431
+ },
432
+ {
433
+ label: "总结卡片",
434
+ prompt: learningQuestion("summary", "围绕本次引用的内容整理。"),
435
+ ask: false,
436
+ scenario: "present",
437
+ presentation: "side"
438
+ },
439
+ null,
440
+ null
441
+ ];
256
442
  /** Host settings namespace mirrored by the browser settings scope. */
257
443
  const CITECITER_SETTINGS_NAMESPACE = "citeciter";
258
444
  /** Topic-scoped system prompt section. */
@@ -289,7 +475,17 @@ const citeCiterSettingsSchema = z.object({
289
475
  promptTemplates: z.array(promptTemplateSchema).max(8).optional(),
290
476
  shortcutOpenPanel: z.string().max(40).optional(),
291
477
  boardAnimations: z.boolean().optional(),
292
- updateNotifications: z.boolean().optional()
478
+ activeRecall: z.boolean().optional(),
479
+ updateNotifications: z.boolean().optional(),
480
+ wheelSlots: wheelSlotsSchema.optional(),
481
+ wheelTrigger: wheelTriggerSchema.optional(),
482
+ defaultCiterModel: actionModelSchema.nullable().optional(),
483
+ defaultPermission: z.enum([
484
+ "read-only",
485
+ "workspace-write",
486
+ "danger-full-access"
487
+ ]).optional(),
488
+ learningRoute: z.boolean().optional()
293
489
  }).strict();
294
490
  /** Settings used before an optional DSH settings provider becomes available. */
295
491
  const DEFAULT_CITECITER_SETTINGS = Object.freeze({
@@ -300,6 +496,9 @@ const DEFAULT_CITECITER_SETTINGS = Object.freeze({
300
496
  reopenLastTopic: true,
301
497
  followupQuestions: true,
302
498
  boardAnimations: true,
499
+ activeRecall: false,
500
+ defaultPermission: "read-only",
501
+ learningRoute: false,
303
502
  updateNotifications: true,
304
503
  promptTemplates: [
305
504
  {
@@ -449,6 +648,8 @@ const modelConfigSchema = z.object({
449
648
  }).strict();
450
649
  /** Fields shared by the canonical Topic metadata schema and its on-disk reader. */
451
650
  const topicMetadataFields = {
651
+ hosted: z.boolean().optional(),
652
+ storage: z.literal("source").optional(),
452
653
  topicId: z.number().int().positive(),
453
654
  createRequestId: z.string().min(1).optional(),
454
655
  sessionId: z.string().min(1),
@@ -511,7 +712,15 @@ function parseTopicMetadataFile(raw) {
511
712
  documentId: documentId ?? null
512
713
  });
513
714
  }
715
+ const permissionSchema = z.enum([
716
+ "read-only",
717
+ "workspace-write",
718
+ "danger-full-access"
719
+ ]);
514
720
  const topicSummarySchema = z.object({
721
+ permission: permissionSchema.optional(),
722
+ hosted: z.boolean().optional(),
723
+ storage: z.literal("source").optional(),
515
724
  topicId: z.number().int().positive(),
516
725
  sessionId: z.string().min(1),
517
726
  sourceSessionId: z.string().min(1),
@@ -529,6 +738,11 @@ const topicSummarySchema = z.object({
529
738
  observedThroughSeq: z.number().int().nonnegative().nullable(),
530
739
  modelConfig: modelConfigSchema
531
740
  }).strict();
741
+ const messageAttachmentSchema = z.object({
742
+ kind: z.enum(["image", "file"]),
743
+ id: z.string().min(1),
744
+ name: z.string()
745
+ }).strict();
532
746
  const topicMessageIdentitySchema = {
533
747
  id: z.string().min(1),
534
748
  seq: z.number().int().nonnegative()
@@ -537,11 +751,13 @@ const topicMessageSchema = z.discriminatedUnion("role", [
537
751
  z.object({
538
752
  ...topicMessageIdentitySchema,
539
753
  role: z.literal("user"),
754
+ attachments: z.array(messageAttachmentSchema).optional(),
540
755
  text: z.string()
541
756
  }).strict(),
542
757
  z.object({
543
758
  ...topicMessageIdentitySchema,
544
759
  role: z.literal("assistant"),
760
+ renderKey: z.string().optional(),
545
761
  text: z.string(),
546
762
  reasoning: z.string().nullable(),
547
763
  streaming: z.boolean()
@@ -555,6 +771,7 @@ const topicMessageSchema = z.discriminatedUnion("role", [
555
771
  z.object({
556
772
  ...topicMessageIdentitySchema,
557
773
  role: z.literal("tool"),
774
+ attachments: z.array(messageAttachmentSchema).optional(),
558
775
  name: z.string().min(1),
559
776
  arguments: z.string(),
560
777
  result: z.string().nullable(),
@@ -591,6 +808,8 @@ const pendingQuestionSchema = z.object({
591
808
  questions: z.array(questionItemSchema).min(1)
592
809
  }).strict();
593
810
  const topicSnapshotSchema = z.object({
811
+ captureId: z.string().optional(),
812
+ documentTitle: z.string().optional(),
594
813
  topic: topicSummarySchema,
595
814
  messages: z.array(topicMessageSchema),
596
815
  pendingQuestion: pendingQuestionSchema.nullable(),
@@ -611,6 +830,7 @@ const providerOptionSchema = z.object({
611
830
  name: z.string().min(1),
612
831
  models: z.array(modelOptionSchema)
613
832
  }).strict();
833
+ const draftQuestionSchema = z.string().trim().max(12e3);
614
834
  const questionSchema = z.string().trim().min(1).max(12e3);
615
835
  const topicSessionIdSchema = z.string().min(1);
616
836
  const createModeSchema = z.enum([
@@ -653,46 +873,53 @@ const documentContentSchema = z.object({
653
873
  title: z.string().trim().min(1).max(200),
654
874
  format: documentFormatSchema,
655
875
  content: z.string(),
656
- truncated: z.boolean()
876
+ truncated: z.boolean(),
877
+ page: z.number().int().nonnegative().default(0),
878
+ pageCount: z.number().int().positive().default(1)
657
879
  }).strict();
658
880
  const createRequestSchema = z.union([
659
881
  z.object({
660
882
  action: z.literal("create"),
883
+ modelRoute: actionModelSchema.optional(),
661
884
  requestId: z.string().min(1),
662
885
  sourceSessionId: z.string().min(1),
663
- question: questionSchema,
886
+ question: draftQuestionSchema,
664
887
  mode: z.literal("observer"),
665
888
  scenario: z.enum(["qa", "present"]).optional()
666
889
  }).strict(),
667
890
  z.object({
668
891
  action: z.literal("create"),
892
+ modelRoute: actionModelSchema.optional(),
669
893
  requestId: z.string().min(1),
670
894
  citation: citationDraftSchema,
671
- question: questionSchema,
895
+ question: draftQuestionSchema,
672
896
  mode: createModeSchema,
673
897
  scenario: topicScenarioSchema.optional()
674
898
  }).strict(),
675
899
  z.object({
676
900
  action: z.literal("create"),
901
+ modelRoute: actionModelSchema.optional(),
677
902
  requestId: z.string().min(1),
678
903
  selectionClaim: citationSelectionClaimSchema,
679
- question: questionSchema,
904
+ question: draftQuestionSchema,
680
905
  mode: createModeSchema,
681
906
  scenario: topicScenarioSchema.optional()
682
907
  }).strict(),
683
908
  z.object({
684
909
  action: z.literal("create"),
910
+ modelRoute: actionModelSchema.optional(),
685
911
  requestId: z.string().min(1),
686
912
  toolClaim: toolEvidenceClaimSchema,
687
- question: questionSchema,
913
+ question: draftQuestionSchema,
688
914
  mode: createModeSchema,
689
915
  scenario: topicScenarioSchema.optional()
690
916
  }).strict(),
691
917
  z.object({
692
918
  action: z.literal("create"),
919
+ modelRoute: actionModelSchema.optional(),
693
920
  requestId: z.string().min(1),
694
921
  documentClaim: documentEvidenceClaimSchema,
695
- question: questionSchema,
922
+ question: draftQuestionSchema,
696
923
  mode: createModeSchema,
697
924
  scenario: topicScenarioSchema.optional()
698
925
  }).strict()
@@ -704,10 +931,27 @@ const citeCiterRequestSchema = z.union([createRequestSchema, z.discriminatedUnio
704
931
  sourceSessionId: z.string().min(1),
705
932
  includeArchived: z.boolean().optional()
706
933
  }).strict(),
934
+ z.object({
935
+ action: z.literal("board-capture"),
936
+ topicSessionId: topicSessionIdSchema,
937
+ id: z.string().min(1),
938
+ png: z.string().max(8e6).regex(/^[A-Za-z0-9+/]+={0,2}$/).optional(),
939
+ error: z.string().max(500).optional()
940
+ }).strict(),
707
941
  z.object({
708
942
  action: z.literal("get"),
709
943
  topicSessionId: topicSessionIdSchema
710
944
  }).strict(),
945
+ z.object({
946
+ action: z.literal("native-state"),
947
+ topicSessionId: topicSessionIdSchema,
948
+ requestIds: z.array(z.string().min(1).max(100)).max(32)
949
+ }).strict(),
950
+ z.object({
951
+ action: z.literal("native-attachment"),
952
+ topicSessionId: topicSessionIdSchema,
953
+ attachmentId: z.string().min(1).max(200)
954
+ }).strict(),
711
955
  z.object({
712
956
  action: z.literal("ask"),
713
957
  requestId: z.string().min(1).optional(),
@@ -745,6 +989,11 @@ const citeCiterRequestSchema = z.union([createRequestSchema, z.discriminatedUnio
745
989
  confirmSessionId: topicSessionIdSchema
746
990
  }).strict(),
747
991
  z.object({ action: z.literal("models") }).strict(),
992
+ z.object({
993
+ action: z.literal("set-permission"),
994
+ topicSessionId: topicSessionIdSchema,
995
+ mode: permissionSchema
996
+ }).strict(),
748
997
  z.object({
749
998
  action: z.literal("set-model-route"),
750
999
  topicSessionId: topicSessionIdSchema,
@@ -773,11 +1022,21 @@ const citeCiterRequestSchema = z.union([createRequestSchema, z.discriminatedUnio
773
1022
  z.object({ action: z.literal("documents") }).strict(),
774
1023
  z.object({
775
1024
  action: z.literal("document-get"),
776
- documentId: z.string().min(1)
1025
+ documentId: z.string().min(1),
1026
+ page: z.number().int().nonnegative().optional()
777
1027
  }).strict()
778
1028
  ])]);
779
1029
  /** Strict response union returned by the single Remote command endpoint. */
780
1030
  const citeCiterResponseSchema = z.discriminatedUnion("kind", [
1031
+ z.object({
1032
+ kind: z.literal("native-state"),
1033
+ state: nativeStateSchema
1034
+ }).strict(),
1035
+ z.object({
1036
+ kind: z.literal("native-attachment"),
1037
+ attachment: nativeAttachmentRefSchema,
1038
+ data: z.string().regex(/^[A-Za-z0-9+/]*={0,2}$/)
1039
+ }).strict(),
781
1040
  z.object({
782
1041
  kind: z.literal("topic"),
783
1042
  topic: topicSnapshotSchema
@@ -850,6 +1109,13 @@ function stableVersionParts(version) {
850
1109
  ];
851
1110
  }
852
1111
  const stableVersionSchema = z.string().refine((version) => stableVersionParts(version) !== null, "expected a stable MAJOR.MINOR.PATCH version with safe integer components");
1112
+ /** Installed development builds may use a valid SemVer prerelease suffix; registry latest stays stable. */
1113
+ const installedVersionSchema = z.string().refine((version) => {
1114
+ const [core, ...suffix] = version.split("-");
1115
+ if (core === void 0 || stableVersionParts(core) === null) return false;
1116
+ if (suffix.length === 0) return true;
1117
+ return suffix.join("-").split(".").every((part) => /^[0-9A-Za-z-]+$/u.test(part) && (!/^\d+$/u.test(part) || part === "0" || !part.startsWith("0")));
1118
+ }, "expected a stable version or a valid prerelease");
853
1119
  /** Stable failure identifiers consumed by the Web settings and notification UI. */
854
1120
  const updateCheckErrorCodeSchema = z.enum([
855
1121
  "installed-version-invalid",
@@ -863,7 +1129,7 @@ const updateCheckErrorCodeSchema = z.enum([
863
1129
  /** Strict result of one read-only npm `latest` check. */
864
1130
  const updateCheckResponseSchema = z.discriminatedUnion("kind", [z.object({
865
1131
  kind: z.literal("success"),
866
- installedVersion: stableVersionSchema,
1132
+ installedVersion: installedVersionSchema,
867
1133
  latestVersion: stableVersionSchema,
868
1134
  updateAvailable: z.boolean(),
869
1135
  checkedAt: z.number().int().nonnegative(),
@@ -982,7 +1248,7 @@ var UpdateChecker = class {
982
1248
  checkedAt: this.now()
983
1249
  };
984
1250
  }
985
- if (stableVersionParts(installedVersion) === null) return {
1251
+ if (!installedVersionSchema.safeParse(installedVersion).success) return {
986
1252
  kind: "error",
987
1253
  code: "installed-version-invalid",
988
1254
  checkedAt: this.now()
@@ -1021,7 +1287,7 @@ var UpdateChecker = class {
1021
1287
  code: "registry-response-invalid",
1022
1288
  checkedAt: this.now()
1023
1289
  };
1024
- const comparison = compareStableVersions(installedVersion, latest.data.version);
1290
+ const comparison = compareStableVersions(installedVersion.split("-")[0], latest.data.version);
1025
1291
  if (comparison === null) return {
1026
1292
  kind: "error",
1027
1293
  code: "registry-version-invalid",
@@ -1032,7 +1298,7 @@ var UpdateChecker = class {
1032
1298
  kind: "success",
1033
1299
  installedVersion,
1034
1300
  latestVersion: latest.data.version,
1035
- updateAvailable: comparison < 0,
1301
+ updateAvailable: comparison < 0 || comparison === 0 && installedVersion.includes("-"),
1036
1302
  checkedAt
1037
1303
  };
1038
1304
  this.cached = {
@@ -1070,4 +1336,4 @@ function waitForCaller(operation, signal) {
1070
1336
  });
1071
1337
  }
1072
1338
  //#endregion
1073
- export { topicSummarySchema as C, boardBatchSchema as E, topicSnapshotSchema as S, applyBoardOps as T, documentSummarySchema as _, CITECITER_SETTINGS_NAMESPACE as a, toolEvidenceClaimSchema as b, canonicalCitationIdentity as c, citationSelectionClaimSchema as d, citeCiterRequestSchema as f, documentEvidenceClaimSchema as g, documentContentSchema as h, CITATION_CONTEXT_NAME as i, citationDraftSchema as l, citeCiterSettingsSchema as m, updateCheckErrorCodeSchema as n, DEFAULT_CITECITER_SETTINGS as o, citeCiterResponseSchema as p, updateCheckResponseSchema as r, TUTOR_SECTION_NAME as s, UpdateChecker as t, citationRecordSchema as u, parseTopicMetadataFile as v, EMPTY_BOARD_STATE as w, topicMetadataSchema as x, renderCitationContext as y };
1339
+ export { topicSummarySchema as C, EMPTY_BOARD_STATE as D, learningCardsInputSchema as E, applyBoardOps as O, topicSnapshotSchema as S, LEARNING_PROMPT as T, documentSummarySchema as _, CITECITER_SETTINGS_NAMESPACE as a, toolEvidenceClaimSchema as b, canonicalCitationIdentity as c, citationSelectionClaimSchema as d, citeCiterRequestSchema as f, documentEvidenceClaimSchema as g, documentContentSchema as h, CITATION_CONTEXT_NAME as i, boardBatchSchema as k, citationDraftSchema as l, citeCiterSettingsSchema as m, updateCheckErrorCodeSchema as n, DEFAULT_CITECITER_SETTINGS as o, citeCiterResponseSchema as p, updateCheckResponseSchema as r, TUTOR_SECTION_NAME as s, UpdateChecker as t, citationRecordSchema as u, parseTopicMetadataFile as v, DEFAULT_WHEEL_SLOTS as w, topicMetadataSchema as x, renderCitationContext as y };