@kirkchinese/dsh-citeciter 0.9.0-beta.2 → 0.9.0-beta.3

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 (37) hide show
  1. package/README.md +11 -8
  2. package/README.zh.md +11 -8
  3. package/lib/client.js +2175 -2344
  4. package/lib/index.js +1546 -307
  5. package/lib/{typert-common-g1lnIG8u.js → typert-common-B3cX-hWj.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 +7 -0
  9. package/lib/types/blackboard-tool.d.ts +6 -0
  10. package/lib/types/board-animation.d.ts +278 -0
  11. package/lib/types/board-capture-protocol.d.ts +61 -1
  12. package/lib/types/board-capture.d.ts +2 -0
  13. package/lib/types/board.d.ts +62 -3
  14. package/lib/types/client/board-timeline.d.ts +30 -0
  15. package/lib/types/client/companion-controller.d.ts +1 -1
  16. package/lib/types/client/components/BoardCaptureSurface.d.ts +3 -1
  17. package/lib/types/client/components/BoardView.d.ts +3 -1
  18. package/lib/types/client/components/PermissionControl.d.ts +1 -1
  19. package/lib/types/client/components/TopicActions.d.ts +1 -1
  20. package/lib/types/client/components/TopicModelControls.d.ts +1 -1
  21. package/lib/types/host-agent-modules.d.ts +4 -1
  22. package/lib/types/line-diff.d.ts +12 -0
  23. package/lib/types/message-projection.d.ts +1 -0
  24. package/lib/types/observer.d.ts +0 -30
  25. package/lib/types/source-read-tool.d.ts +3 -3
  26. package/lib/types/source-session.d.ts +3 -0
  27. package/lib/types/source-transcript.d.ts +58 -0
  28. package/lib/types/topic-context.d.ts +74 -0
  29. package/lib/types/topic-log.d.ts +2 -0
  30. package/lib/types/topic-runtime.d.ts +4 -0
  31. package/lib/types/topic.d.ts +198 -14
  32. package/lib/types/typert-common.d.ts +124 -5
  33. package/lib/types/typert.host.d.ts +311 -14
  34. package/lib/types/workspace-changes.d.ts +90 -0
  35. package/lib/{update-B_0nN1_f.js → update-CGteMuNJ.js} +651 -4
  36. package/package.json +62 -64
  37. package/lib/types/client/components/ChoicePopover.d.ts +0 -8
@@ -1,4 +1,4 @@
1
- import { d as citeCiterRequestSchema, f as citeCiterResponseSchema, r as updateCheckResponseSchema } from "./update-B_0nN1_f.js";
1
+ import { d as citeCiterRequestSchema, f as citeCiterResponseSchema, r as updateCheckResponseSchema } from "./update-CGteMuNJ.js";
2
2
  //#region lib/types/typert-codec.js
3
3
  /** Official Typert lazily resolves schemas after module registration. */
4
4
  function strictCodec(typeSymbol, schema) {
@@ -1,5 +1,5 @@
1
- import { S as topicSummarySchema, c as citationDraftSchema, d as citeCiterRequestSchema, f as citeCiterResponseSchema, l as citationRecordSchema, r as updateCheckResponseSchema, x as topicSnapshotSchema } from "./update-B_0nN1_f.js";
2
- import { n as updateCheckDescriptor, r as namedSchema, t as citeCiterRequestDescriptor } from "./typert-common-g1lnIG8u.js";
1
+ import { S as topicSummarySchema, c as citationDraftSchema, d as citeCiterRequestSchema, f as citeCiterResponseSchema, l as citationRecordSchema, r as updateCheckResponseSchema, x as topicSnapshotSchema } from "./update-CGteMuNJ.js";
2
+ import { n as updateCheckDescriptor, r as namedSchema, t as citeCiterRequestDescriptor } from "./typert-common-B3cX-hWj.js";
3
3
  //#region lib/types/typert.host.js
4
4
  /** Handwritten strict Host contribution matching the single Remote decorator. */
5
5
  const TYPERT = {
@@ -1,4 +1,4 @@
1
- import { n as updateCheckDescriptor, t as citeCiterRequestDescriptor } from "./typert-common-g1lnIG8u.js";
1
+ import { n as updateCheckDescriptor, t as citeCiterRequestDescriptor } from "./typert-common-B3cX-hWj.js";
2
2
  //#region lib/types/typert.remote-client.js
3
3
  /** Browser contribution mounted by the CiteCiter Client fiber. */
4
4
  const TYPERT_REMOTE = {
@@ -61,5 +61,12 @@ export declare const DEFAULT_WHEEL_SLOTS: readonly (CiteAction | null)[];
61
61
  * @returns `draft` for questions the user writes, otherwise the preference.
62
62
  */
63
63
  export declare function actionDelivery(action: CiteAction, preference: ActionDelivery | undefined): ActionDelivery;
64
+ /**
65
+ * Explain a preset action the host refused to send, which then moves into the composer.
66
+ * The composer already explains a missing model, so that reason is not repeated.
67
+ * @param reason - the host's refusal message.
68
+ * @returns one message for the panel.
69
+ */
70
+ export declare function undeliveredActionMessage(reason: string): string;
64
71
  /** Combine a mode and optional user question without hidden system state. */
65
72
  export declare function actionQuestion(action: CiteAction, question: string): string;
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Create the blackboard_animate tool. A successful call validates the timeline against the current
3
+ * board and records it; the board keeps one timeline, replaced by the next successful call.
4
+ * @returns a tool definition for one Topic tool registry.
5
+ */
6
+ export declare function createBlackboardAnimateTool(): import("@deepseek-ai/dsh-tools").ToolDefinition;
1
7
  /**
2
8
  * Create the blackboard_apply tool. A successful call only validates and records the batch;
3
9
  * the board itself is replayed from committed results.
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Board animation timelines: a declarative spec of verbs, keyframes, SVG paths and restricted
3
+ * parametric expressions over existing board elements, plus a pure sampler shared by the Host
4
+ * validator, the browser player and frame capture. Coordinates are canvas percentages.
5
+ */
6
+ import { z } from 'zod';
7
+ export declare const ANIMATION_MAX_TRACKS = 40;
8
+ export declare const ANIMATION_MAX_BEATS = 20;
9
+ export declare const ANIMATION_MAX_FRAMES = 40;
10
+ export declare const ANIMATION_MAX_DURATION_MS = 30000;
11
+ declare const easingSchema: z.ZodEnum<{
12
+ linear: "linear";
13
+ "ease-in": "ease-in";
14
+ "ease-out": "ease-out";
15
+ "ease-in-out": "ease-in-out";
16
+ }>;
17
+ export type AnimationEasing = z.infer<typeof easingSchema>;
18
+ /** One verb applied to one board element. */
19
+ export declare const animationTrackSchema: z.ZodObject<{
20
+ target: z.ZodString;
21
+ verb: z.ZodEnum<{
22
+ appear: "appear";
23
+ disappear: "disappear";
24
+ move: "move";
25
+ scale: "scale";
26
+ rotate: "rotate";
27
+ highlight: "highlight";
28
+ reveal: "reveal";
29
+ follow: "follow";
30
+ keyframes: "keyframes";
31
+ parametric: "parametric";
32
+ }>;
33
+ startMs: z.ZodOptional<z.ZodNumber>;
34
+ endMs: z.ZodOptional<z.ZodNumber>;
35
+ easing: z.ZodOptional<z.ZodEnum<{
36
+ linear: "linear";
37
+ "ease-in": "ease-in";
38
+ "ease-out": "ease-out";
39
+ "ease-in-out": "ease-in-out";
40
+ }>>;
41
+ to: z.ZodOptional<z.ZodObject<{
42
+ x: z.ZodNumber;
43
+ y: z.ZodNumber;
44
+ }, z.core.$strict>>;
45
+ scale: z.ZodOptional<z.ZodNumber>;
46
+ degrees: z.ZodOptional<z.ZodNumber>;
47
+ direction: z.ZodOptional<z.ZodEnum<{
48
+ left: "left";
49
+ right: "right";
50
+ up: "up";
51
+ down: "down";
52
+ }>>;
53
+ path: z.ZodOptional<z.ZodString>;
54
+ orient: z.ZodOptional<z.ZodBoolean>;
55
+ frames: z.ZodOptional<z.ZodArray<z.ZodObject<{
56
+ atMs: z.ZodNumber;
57
+ x: z.ZodOptional<z.ZodNumber>;
58
+ y: z.ZodOptional<z.ZodNumber>;
59
+ opacity: z.ZodOptional<z.ZodNumber>;
60
+ scale: z.ZodOptional<z.ZodNumber>;
61
+ rotate: z.ZodOptional<z.ZodNumber>;
62
+ }, z.core.$strict>>>;
63
+ x: z.ZodOptional<z.ZodString>;
64
+ y: z.ZodOptional<z.ZodString>;
65
+ t: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
66
+ }, z.core.$strict>;
67
+ export type AnimationTrack = z.infer<typeof animationTrackSchema>;
68
+ /** One complete timeline as written by the model. */
69
+ export declare const animationSpecSchema: z.ZodObject<{
70
+ durationMs: z.ZodNumber;
71
+ loop: z.ZodOptional<z.ZodBoolean>;
72
+ beats: z.ZodOptional<z.ZodArray<z.ZodObject<{
73
+ atMs: z.ZodNumber;
74
+ caption: z.ZodString;
75
+ }, z.core.$strict>>>;
76
+ tracks: z.ZodArray<z.ZodObject<{
77
+ target: z.ZodString;
78
+ verb: z.ZodEnum<{
79
+ appear: "appear";
80
+ disappear: "disappear";
81
+ move: "move";
82
+ scale: "scale";
83
+ rotate: "rotate";
84
+ highlight: "highlight";
85
+ reveal: "reveal";
86
+ follow: "follow";
87
+ keyframes: "keyframes";
88
+ parametric: "parametric";
89
+ }>;
90
+ startMs: z.ZodOptional<z.ZodNumber>;
91
+ endMs: z.ZodOptional<z.ZodNumber>;
92
+ easing: z.ZodOptional<z.ZodEnum<{
93
+ linear: "linear";
94
+ "ease-in": "ease-in";
95
+ "ease-out": "ease-out";
96
+ "ease-in-out": "ease-in-out";
97
+ }>>;
98
+ to: z.ZodOptional<z.ZodObject<{
99
+ x: z.ZodNumber;
100
+ y: z.ZodNumber;
101
+ }, z.core.$strict>>;
102
+ scale: z.ZodOptional<z.ZodNumber>;
103
+ degrees: z.ZodOptional<z.ZodNumber>;
104
+ direction: z.ZodOptional<z.ZodEnum<{
105
+ left: "left";
106
+ right: "right";
107
+ up: "up";
108
+ down: "down";
109
+ }>>;
110
+ path: z.ZodOptional<z.ZodString>;
111
+ orient: z.ZodOptional<z.ZodBoolean>;
112
+ frames: z.ZodOptional<z.ZodArray<z.ZodObject<{
113
+ atMs: z.ZodNumber;
114
+ x: z.ZodOptional<z.ZodNumber>;
115
+ y: z.ZodOptional<z.ZodNumber>;
116
+ opacity: z.ZodOptional<z.ZodNumber>;
117
+ scale: z.ZodOptional<z.ZodNumber>;
118
+ rotate: z.ZodOptional<z.ZodNumber>;
119
+ }, z.core.$strict>>>;
120
+ x: z.ZodOptional<z.ZodString>;
121
+ y: z.ZodOptional<z.ZodString>;
122
+ t: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
123
+ }, z.core.$strict>>;
124
+ }, z.core.$strict>;
125
+ export type AnimationSpec = z.infer<typeof animationSpecSchema>;
126
+ /** The board's current timeline: the spec of the latest successful call, keyed by that call. */
127
+ export declare const boardTimelineSchema: z.ZodObject<{
128
+ id: z.ZodString;
129
+ spec: z.ZodObject<{
130
+ durationMs: z.ZodNumber;
131
+ loop: z.ZodOptional<z.ZodBoolean>;
132
+ beats: z.ZodOptional<z.ZodArray<z.ZodObject<{
133
+ atMs: z.ZodNumber;
134
+ caption: z.ZodString;
135
+ }, z.core.$strict>>>;
136
+ tracks: z.ZodArray<z.ZodObject<{
137
+ target: z.ZodString;
138
+ verb: z.ZodEnum<{
139
+ appear: "appear";
140
+ disappear: "disappear";
141
+ move: "move";
142
+ scale: "scale";
143
+ rotate: "rotate";
144
+ highlight: "highlight";
145
+ reveal: "reveal";
146
+ follow: "follow";
147
+ keyframes: "keyframes";
148
+ parametric: "parametric";
149
+ }>;
150
+ startMs: z.ZodOptional<z.ZodNumber>;
151
+ endMs: z.ZodOptional<z.ZodNumber>;
152
+ easing: z.ZodOptional<z.ZodEnum<{
153
+ linear: "linear";
154
+ "ease-in": "ease-in";
155
+ "ease-out": "ease-out";
156
+ "ease-in-out": "ease-in-out";
157
+ }>>;
158
+ to: z.ZodOptional<z.ZodObject<{
159
+ x: z.ZodNumber;
160
+ y: z.ZodNumber;
161
+ }, z.core.$strict>>;
162
+ scale: z.ZodOptional<z.ZodNumber>;
163
+ degrees: z.ZodOptional<z.ZodNumber>;
164
+ direction: z.ZodOptional<z.ZodEnum<{
165
+ left: "left";
166
+ right: "right";
167
+ up: "up";
168
+ down: "down";
169
+ }>>;
170
+ path: z.ZodOptional<z.ZodString>;
171
+ orient: z.ZodOptional<z.ZodBoolean>;
172
+ frames: z.ZodOptional<z.ZodArray<z.ZodObject<{
173
+ atMs: z.ZodNumber;
174
+ x: z.ZodOptional<z.ZodNumber>;
175
+ y: z.ZodOptional<z.ZodNumber>;
176
+ opacity: z.ZodOptional<z.ZodNumber>;
177
+ scale: z.ZodOptional<z.ZodNumber>;
178
+ rotate: z.ZodOptional<z.ZodNumber>;
179
+ }, z.core.$strict>>>;
180
+ x: z.ZodOptional<z.ZodString>;
181
+ y: z.ZodOptional<z.ZodString>;
182
+ t: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
183
+ }, z.core.$strict>>;
184
+ }, z.core.$strict>;
185
+ }, z.core.$strict>;
186
+ export type BoardTimeline = z.infer<typeof boardTimelineSchema>;
187
+ type Expression = (t: number) => number;
188
+ /**
189
+ * Compile a restricted arithmetic expression of `t`: numbers, `+ - * / ^`, parentheses,
190
+ * the constants pi, e, tau and a fixed set of Math functions. Nothing else is accepted.
191
+ * @throws an Error naming the first unexpected token.
192
+ */
193
+ export declare function compileExpression(source: string): Expression;
194
+ interface Point {
195
+ readonly x: number;
196
+ readonly y: number;
197
+ }
198
+ /** A sampled path: points with cumulative arc length. */
199
+ export interface SampledPath {
200
+ readonly points: readonly Point[];
201
+ readonly lengths: readonly number[];
202
+ readonly total: number;
203
+ }
204
+ /**
205
+ * Sample an SVG path (M L H V C S Q T A Z, absolute and relative) into a polyline.
206
+ * @throws an Error for unsupported commands or malformed numbers.
207
+ */
208
+ export declare function samplePath(d: string): SampledPath;
209
+ /** Position and tangent angle (degrees) at a fraction of a sampled path's length. */
210
+ export declare function pointAlong(path: SampledPath, fraction: number): {
211
+ readonly x: number;
212
+ readonly y: number;
213
+ readonly angle: number;
214
+ };
215
+ /** Render-ready transform of one element at one time. */
216
+ export interface ElementFrame {
217
+ /** Translation in canvas percent. */
218
+ readonly dx: number;
219
+ readonly dy: number;
220
+ readonly scale: number;
221
+ readonly rotate: number;
222
+ readonly opacity: number;
223
+ /** Hidden fraction (0-100) clipped from `clipSide`. */
224
+ readonly clip: number;
225
+ readonly clipSide: 'left' | 'right' | 'top' | 'bottom';
226
+ /** Highlight glow strength, 0-1. */
227
+ readonly glow: number;
228
+ }
229
+ type Prop = 'dx' | 'dy' | 'scale' | 'rotate' | 'opacity' | 'clip' | 'glow' | 'slideX' | 'slideY';
230
+ interface Segment {
231
+ readonly start: number;
232
+ readonly end: number;
233
+ /** Value shown before the segment starts when it is the first for its property. */
234
+ readonly before?: number;
235
+ readonly at: (t: number, from: number) => number;
236
+ }
237
+ interface CompiledElement {
238
+ readonly segments: ReadonlyMap<Prop, readonly Segment[]>;
239
+ /** Value of each segment's property at its start, from the segments before it. */
240
+ readonly from: ReadonlyMap<Segment, number>;
241
+ readonly clipSide: ElementFrame['clipSide'];
242
+ }
243
+ /** A timeline compiled against the board element envelopes it animates. */
244
+ export interface CompiledTimeline {
245
+ readonly durationMs: number;
246
+ readonly loop: boolean;
247
+ readonly beats: readonly {
248
+ readonly atMs: number;
249
+ readonly caption: string;
250
+ }[];
251
+ readonly elements: ReadonlyMap<string, CompiledElement>;
252
+ }
253
+ /** Envelope fields a timeline needs from each target. */
254
+ export interface AnimationTargetEnvelope {
255
+ readonly id: string;
256
+ readonly x: number;
257
+ readonly y: number;
258
+ readonly w: number;
259
+ readonly h: number;
260
+ }
261
+ /**
262
+ * Validate and compile a timeline against the current board.
263
+ * @param spec - parsed timeline spec.
264
+ * @param targets - current board element envelopes.
265
+ * @returns the compiled timeline.
266
+ * @throws an Error describing the first invalid track.
267
+ */
268
+ export declare function compileTimeline(spec: AnimationSpec, targets: readonly AnimationTargetEnvelope[]): CompiledTimeline;
269
+ /**
270
+ * Sample every animated element at one time.
271
+ * @param timeline - compiled timeline.
272
+ * @param atMs - time within the timeline; clamped to its duration.
273
+ * @returns frames keyed by element id; elements without tracks are absent.
274
+ */
275
+ export declare function sampleTimeline(timeline: CompiledTimeline, atMs: number): Map<string, ElementFrame>;
276
+ /** Caption of the latest beat at or before a time, or null. */
277
+ export declare function beatAt(timeline: CompiledTimeline, atMs: number): string | null;
278
+ export {};
@@ -29,10 +29,10 @@ export declare const boardCaptureJobSchema: z.ZodObject<{
29
29
  focused: z.ZodBoolean;
30
30
  animation: z.ZodOptional<z.ZodObject<{
31
31
  name: z.ZodEnum<{
32
+ highlight: "highlight";
32
33
  "fade-in": "fade-in";
33
34
  "slide-in": "slide-in";
34
35
  pulse: "pulse";
35
- highlight: "highlight";
36
36
  }>;
37
37
  durationMs: z.ZodNumber;
38
38
  iterations: z.ZodNumber;
@@ -40,6 +40,66 @@ export declare const boardCaptureJobSchema: z.ZodObject<{
40
40
  }, z.core.$strict>>;
41
41
  }, z.core.$strict>>;
42
42
  invalid: z.ZodNumber;
43
+ timeline: z.ZodOptional<z.ZodNullable<z.ZodObject<{
44
+ id: z.ZodString;
45
+ spec: z.ZodObject<{
46
+ durationMs: z.ZodNumber;
47
+ loop: z.ZodOptional<z.ZodBoolean>;
48
+ beats: z.ZodOptional<z.ZodArray<z.ZodObject<{
49
+ atMs: z.ZodNumber;
50
+ caption: z.ZodString;
51
+ }, z.core.$strict>>>;
52
+ tracks: z.ZodArray<z.ZodObject<{
53
+ target: z.ZodString;
54
+ verb: z.ZodEnum<{
55
+ appear: "appear";
56
+ disappear: "disappear";
57
+ move: "move";
58
+ scale: "scale";
59
+ rotate: "rotate";
60
+ highlight: "highlight";
61
+ reveal: "reveal";
62
+ follow: "follow";
63
+ keyframes: "keyframes";
64
+ parametric: "parametric";
65
+ }>;
66
+ startMs: z.ZodOptional<z.ZodNumber>;
67
+ endMs: z.ZodOptional<z.ZodNumber>;
68
+ easing: z.ZodOptional<z.ZodEnum<{
69
+ linear: "linear";
70
+ "ease-in": "ease-in";
71
+ "ease-out": "ease-out";
72
+ "ease-in-out": "ease-in-out";
73
+ }>>;
74
+ to: z.ZodOptional<z.ZodObject<{
75
+ x: z.ZodNumber;
76
+ y: z.ZodNumber;
77
+ }, z.core.$strict>>;
78
+ scale: z.ZodOptional<z.ZodNumber>;
79
+ degrees: z.ZodOptional<z.ZodNumber>;
80
+ direction: z.ZodOptional<z.ZodEnum<{
81
+ left: "left";
82
+ right: "right";
83
+ up: "up";
84
+ down: "down";
85
+ }>>;
86
+ path: z.ZodOptional<z.ZodString>;
87
+ orient: z.ZodOptional<z.ZodBoolean>;
88
+ frames: z.ZodOptional<z.ZodArray<z.ZodObject<{
89
+ atMs: z.ZodNumber;
90
+ x: z.ZodOptional<z.ZodNumber>;
91
+ y: z.ZodOptional<z.ZodNumber>;
92
+ opacity: z.ZodOptional<z.ZodNumber>;
93
+ scale: z.ZodOptional<z.ZodNumber>;
94
+ rotate: z.ZodOptional<z.ZodNumber>;
95
+ }, z.core.$strict>>>;
96
+ x: z.ZodOptional<z.ZodString>;
97
+ y: z.ZodOptional<z.ZodString>;
98
+ t: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
99
+ }, z.core.$strict>>;
100
+ }, z.core.$strict>;
101
+ }, z.core.$strict>>>;
43
102
  }, z.core.$strict>;
103
+ atMs: z.ZodOptional<z.ZodNumber>;
44
104
  }, z.core.$strict>;
45
105
  export type BoardCaptureJob = z.infer<typeof boardCaptureJobSchema>;
@@ -2,6 +2,8 @@ import type { Context } from '@deepseek-ai/cordis';
2
2
  import type { Agent } from '@deepseek-ai/dsh-agent';
3
3
  import type { BoardSnapshot } from './board.ts';
4
4
  import type { BoardCaptureJob } from './board-capture-protocol.ts';
5
+ /** Most frames one blackboard_view call may request. */
6
+ export declare const BOARD_VIEW_MAX_FRAMES = 6;
5
7
  /** Correlates one model-requested render with one client reply; bytes become a durable DSH attachment. */
6
8
  export declare class BoardCaptureBroker {
7
9
  private readonly pending;
@@ -74,10 +74,10 @@ export declare const boardOpSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
74
74
  op: z.ZodLiteral<"animate">;
75
75
  id: z.ZodString;
76
76
  animation: z.ZodEnum<{
77
+ highlight: "highlight";
77
78
  "fade-in": "fade-in";
78
79
  "slide-in": "slide-in";
79
80
  pulse: "pulse";
80
- highlight: "highlight";
81
81
  }>;
82
82
  durationMs: z.ZodOptional<z.ZodNumber>;
83
83
  iterations: z.ZodOptional<z.ZodNumber>;
@@ -135,10 +135,10 @@ export declare const boardBatchSchema: z.ZodArray<z.ZodDiscriminatedUnion<[z.Zod
135
135
  op: z.ZodLiteral<"animate">;
136
136
  id: z.ZodString;
137
137
  animation: z.ZodEnum<{
138
+ highlight: "highlight";
138
139
  "fade-in": "fade-in";
139
140
  "slide-in": "slide-in";
140
141
  pulse: "pulse";
141
- highlight: "highlight";
142
142
  }>;
143
143
  durationMs: z.ZodOptional<z.ZodNumber>;
144
144
  iterations: z.ZodOptional<z.ZodNumber>;
@@ -205,10 +205,10 @@ export declare const boardSnapshotSchema: z.ZodObject<{
205
205
  focused: z.ZodBoolean;
206
206
  animation: z.ZodOptional<z.ZodObject<{
207
207
  name: z.ZodEnum<{
208
+ highlight: "highlight";
208
209
  "fade-in": "fade-in";
209
210
  "slide-in": "slide-in";
210
211
  pulse: "pulse";
211
- highlight: "highlight";
212
212
  }>;
213
213
  durationMs: z.ZodNumber;
214
214
  iterations: z.ZodNumber;
@@ -216,6 +216,65 @@ export declare const boardSnapshotSchema: z.ZodObject<{
216
216
  }, z.core.$strict>>;
217
217
  }, z.core.$strict>>;
218
218
  invalid: z.ZodNumber;
219
+ timeline: z.ZodOptional<z.ZodNullable<z.ZodObject<{
220
+ id: z.ZodString;
221
+ spec: z.ZodObject<{
222
+ durationMs: z.ZodNumber;
223
+ loop: z.ZodOptional<z.ZodBoolean>;
224
+ beats: z.ZodOptional<z.ZodArray<z.ZodObject<{
225
+ atMs: z.ZodNumber;
226
+ caption: z.ZodString;
227
+ }, z.core.$strict>>>;
228
+ tracks: z.ZodArray<z.ZodObject<{
229
+ target: z.ZodString;
230
+ verb: z.ZodEnum<{
231
+ appear: "appear";
232
+ disappear: "disappear";
233
+ move: "move";
234
+ scale: "scale";
235
+ rotate: "rotate";
236
+ highlight: "highlight";
237
+ reveal: "reveal";
238
+ follow: "follow";
239
+ keyframes: "keyframes";
240
+ parametric: "parametric";
241
+ }>;
242
+ startMs: z.ZodOptional<z.ZodNumber>;
243
+ endMs: z.ZodOptional<z.ZodNumber>;
244
+ easing: z.ZodOptional<z.ZodEnum<{
245
+ linear: "linear";
246
+ "ease-in": "ease-in";
247
+ "ease-out": "ease-out";
248
+ "ease-in-out": "ease-in-out";
249
+ }>>;
250
+ to: z.ZodOptional<z.ZodObject<{
251
+ x: z.ZodNumber;
252
+ y: z.ZodNumber;
253
+ }, z.core.$strict>>;
254
+ scale: z.ZodOptional<z.ZodNumber>;
255
+ degrees: z.ZodOptional<z.ZodNumber>;
256
+ direction: z.ZodOptional<z.ZodEnum<{
257
+ left: "left";
258
+ right: "right";
259
+ up: "up";
260
+ down: "down";
261
+ }>>;
262
+ path: z.ZodOptional<z.ZodString>;
263
+ orient: z.ZodOptional<z.ZodBoolean>;
264
+ frames: z.ZodOptional<z.ZodArray<z.ZodObject<{
265
+ atMs: z.ZodNumber;
266
+ x: z.ZodOptional<z.ZodNumber>;
267
+ y: z.ZodOptional<z.ZodNumber>;
268
+ opacity: z.ZodOptional<z.ZodNumber>;
269
+ scale: z.ZodOptional<z.ZodNumber>;
270
+ rotate: z.ZodOptional<z.ZodNumber>;
271
+ }, z.core.$strict>>>;
272
+ x: z.ZodOptional<z.ZodString>;
273
+ y: z.ZodOptional<z.ZodString>;
274
+ t: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
275
+ }, z.core.$strict>>;
276
+ }, z.core.$strict>;
277
+ }, z.core.$strict>>>;
219
278
  }, z.core.$strict>;
220
279
  export type BoardSnapshot = z.infer<typeof boardSnapshotSchema>;
221
280
  /** Empty snapshot used before any board commit. */
@@ -0,0 +1,30 @@
1
+ import { type CSSProperties } from 'react';
2
+ import type { CompiledTimeline, ElementFrame } from '../board-animation.ts';
3
+ /**
4
+ * Inline style for one sampled element frame. Translation is converted from canvas percent
5
+ * to the element's own percent, so no layout measurement is needed.
6
+ * @param frame - sampled frame.
7
+ * @param size - the element envelope's width and height in canvas percent.
8
+ */
9
+ export declare function frameStyle(frame: ElementFrame, size: {
10
+ readonly w: number;
11
+ readonly h: number;
12
+ }): CSSProperties;
13
+ /** Playback state of one board timeline. */
14
+ export interface TimelinePlayer {
15
+ readonly t: number;
16
+ readonly playing: boolean;
17
+ readonly toggle: () => void;
18
+ readonly seek: (atMs: number) => void;
19
+ }
20
+ /**
21
+ * Drive a compiled timeline with requestAnimationFrame. A new timeline plays once when motion is
22
+ * allowed; otherwise it rests on its final frame. A frozen time (frame capture) never plays.
23
+ * @param timeline - compiled timeline, or null.
24
+ * @param key - identity of the timeline; a new key restarts playback.
25
+ * @param options - whether to autoplay and an optional frozen time.
26
+ */
27
+ export declare function useTimelinePlayer(timeline: CompiledTimeline | null, key: string | null, options: {
28
+ readonly autoplay: boolean;
29
+ readonly frozenAt?: number | undefined;
30
+ }): TimelinePlayer;
@@ -7,7 +7,7 @@ import type { ChatSnapshot } from '@deepseek-ai/dsh-client-ui-chat/client';
7
7
  import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
8
8
  import { type CiteCiterRequest, type CiteCiterResponse, type CiteCiterSettings, type ProviderOption, type QuestionAnswer, type TopicSnapshot, type TopicSummary } from '../topic.ts';
9
9
  import { type DocumentClaimIntent } from './request-guard.ts';
10
- import type { ActionDelivery, ActionModel } from '../actions.ts';
10
+ import { type ActionDelivery, type ActionModel } from '../actions.ts';
11
11
  import type { CiteSelection } from './types.ts';
12
12
  import { type DraftReference } from './draft-references.ts';
13
13
  export type CompanionPhase = 'idle' | 'creating' | 'ready' | 'running' | 'stopping' | 'stopped' | 'error';
@@ -1,8 +1,10 @@
1
1
  import type { BoardSnapshot } from '../../board.ts';
2
2
  /** Reuses the exact board renderer when its visible tab is closed; no synthetic drawing or extra conversation is created. */
3
- export declare function BoardCaptureSurface({ id, sessionId, board, reply }: {
3
+ export declare function BoardCaptureSurface({ id, sessionId, board, atMs, reply }: {
4
4
  readonly id: string;
5
5
  readonly sessionId: string;
6
6
  readonly board: BoardSnapshot | undefined;
7
+ /** Timeline time to freeze; frames always render offscreen so playback state cannot leak in. */
8
+ readonly atMs?: number | undefined;
7
9
  readonly reply: (sessionId: string, id: string, png?: string, error?: string) => Promise<void>;
8
10
  }): import("react").JSX.Element;
@@ -5,10 +5,12 @@ import { type BoardElementState, type BoardSnapshot } from '../../board.ts';
5
5
  * @param props - snapshot, motion preference, optional compact reading mode and citation action.
6
6
  * @returns the safe blackboard canvas.
7
7
  */
8
- export declare function BoardView({ snapshot, animations, onQuoteElement, compact, sessionId, }: {
8
+ export declare function BoardView({ snapshot, animations, onQuoteElement, compact, sessionId, frameAtMs, }: {
9
9
  readonly snapshot: BoardSnapshot | undefined;
10
10
  readonly animations: boolean;
11
11
  readonly onQuoteElement?: (element: BoardElementState) => void;
12
12
  readonly compact?: boolean;
13
13
  readonly sessionId?: string;
14
+ /** Freeze the board's timeline at this time, for frame capture. */
15
+ readonly frameAtMs?: number;
14
16
  }): import("react").JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import type { CiteCiterSettings } from '../../topic.ts';
2
2
  export type PermissionMode = NonNullable<CiteCiterSettings['defaultPermission']>;
3
- /** Explicit permission selection; receives the Host's effective value. */
3
+ /** Explicit permission selection in the host's menu; receives the Host's effective value. */
4
4
  export declare function PermissionControl({ value, onChange }: {
5
5
  readonly value: PermissionMode;
6
6
  readonly onChange: (mode: PermissionMode) => void;
@@ -11,7 +11,7 @@ export interface TopicMenu {
11
11
  readonly onArchive: (archived: boolean) => void;
12
12
  readonly onDelete: () => void;
13
13
  }
14
- /** The "⋯" menu: rename, learning route, document reader, archive and permanent deletion. */
14
+ /** The "⋯" menu in the host's menu: rename, learning route, document reader, archive and permanent deletion. */
15
15
  export declare function TopicActions({ menu }: {
16
16
  readonly menu: TopicMenu;
17
17
  }): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import type { ProviderOption, TopicModelConfig } from '../../topic.ts';
2
- /** Model and reasoning hierarchy. Route changes are committed by the injected controller. */
2
+ /** Model and reasoning choices in the host's menu. Route changes are committed by the injected controller. */
3
3
  export declare function TopicModelControls({ providers, route, saving, onModel, onReasoning }: {
4
4
  readonly providers: readonly ProviderOption[];
5
5
  readonly route: TopicModelConfig;
@@ -1,6 +1,7 @@
1
1
  import type { Context, Plugin } from '@deepseek-ai/cordis';
2
2
  import type AgentLoop from '@deepseek-ai/dsh-agent-loop';
3
3
  import type SessionStore from '@deepseek-ai/dsh-session';
4
+ import type { Config as JsonlPersistenceConfig } from '@deepseek-ai/dsh-session-persistence-jsonl';
4
5
  import type SessionTitleService from '@deepseek-ai/dsh-session-title';
5
6
  interface HostScope {
6
7
  readonly ctx: Context;
@@ -17,6 +18,8 @@ export interface SessionTitleLlmConfig {
17
18
  export interface HostAgentModules {
18
19
  readonly AgentLoop: typeof AgentLoop;
19
20
  readonly SessionStore: typeof SessionStore;
21
+ /** DSH's JSONL session persistence, which registers `ctx.sessionPersistence`. */
22
+ readonly SessionPersistence: Plugin<JsonlPersistenceConfig>;
20
23
  readonly SessionTitleService: typeof SessionTitleService;
21
24
  /** DSH's own first-prompt model title provider, the one `dsh-base` mounts for host sessions. */
22
25
  readonly SessionTitleProvider: Plugin<SessionTitleLlmConfig>;
@@ -27,7 +30,7 @@ export interface HostAgentModules {
27
30
  * File URLs bypass peer routing and can create a second private scope identity,
28
31
  * particularly when Electron ASAR paths use different casing on Windows.
29
32
  * Bare imports also leave CLI symlinks and Desktop packaging to the host resolver.
30
- * @returns the host's AgentLoop, SessionStore, title service and provider, and scope factory.
33
+ * @returns the host's AgentLoop, SessionStore, session persistence, title service and provider, and scope factory.
31
34
  */
32
35
  export declare function loadHostAgentModules(): Promise<HostAgentModules>;
33
36
  export {};
@@ -0,0 +1,12 @@
1
+ /** A small, bounded line diff for rendering edit payloads that carry old and new text. */
2
+ /**
3
+ * Render a unified-style line diff (hunks only, no file headers).
4
+ * @param oldText - previous text.
5
+ * @param newText - replacement text.
6
+ * @param options - context lines around changes and the LCS size limit.
7
+ * @returns hunks text, an empty string when both texts have identical lines, or null when the changed region exceeds the limit.
8
+ */
9
+ export declare function unifiedLineDiff(oldText: string, newText: string, options?: {
10
+ readonly context?: number;
11
+ readonly maxCells?: number;
12
+ }): string | null;
@@ -6,6 +6,7 @@ interface ContextMessage {
6
6
  source: {
7
7
  kind: string;
8
8
  plugin?: string;
9
+ form?: unknown;
9
10
  };
10
11
  }
11
12
  /** Project the installed SDK's validated log. 0.1.7 split plugin context into developer/message. */