@zseven-w/dsh-openpencil 0.1.0-rc.1

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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/THIRD_PARTY_NOTICES.md +69 -0
  4. package/cordis.patch.yml +6 -0
  5. package/docs/images/dsh-openpencil-overview.png +0 -0
  6. package/lib/client/details-compat.d.ts +28 -0
  7. package/lib/client/details-compat.js +10 -0
  8. package/lib/client/editor-bridge.d.ts +84 -0
  9. package/lib/client/editor-bridge.js +127 -0
  10. package/lib/client/editor-dock-layout.d.ts +15 -0
  11. package/lib/client/editor-dock-layout.js +43 -0
  12. package/lib/client/editor-recovery.d.ts +27 -0
  13. package/lib/client/editor-recovery.js +83 -0
  14. package/lib/client/editor-successor.d.ts +28 -0
  15. package/lib/client/editor-successor.js +109 -0
  16. package/lib/client/presentation-hydration.d.ts +36 -0
  17. package/lib/client/presentation-hydration.js +168 -0
  18. package/lib/client/selection-polling.d.ts +24 -0
  19. package/lib/client/selection-polling.js +79 -0
  20. package/lib/client/selection-store.d.ts +26 -0
  21. package/lib/client/selection-store.js +85 -0
  22. package/lib/client.js +4033 -0
  23. package/lib/design-tools.d.ts +21 -0
  24. package/lib/design-tools.js +214 -0
  25. package/lib/editor-host.d.ts +62 -0
  26. package/lib/editor-host.js +1147 -0
  27. package/lib/editor-recovery.d.ts +38 -0
  28. package/lib/editor-recovery.js +319 -0
  29. package/lib/index.d.ts +24 -0
  30. package/lib/index.js +132 -0
  31. package/lib/mcp-client.d.ts +47 -0
  32. package/lib/mcp-client.js +148 -0
  33. package/lib/new-tool.d.ts +23 -0
  34. package/lib/new-tool.js +136 -0
  35. package/lib/presentation-hydration.d.ts +55 -0
  36. package/lib/presentation-hydration.js +561 -0
  37. package/lib/renderer.d.ts +203 -0
  38. package/lib/renderer.js +772 -0
  39. package/lib/tool-names.d.ts +13 -0
  40. package/lib/tool-names.js +19 -0
  41. package/lib/tool.d.ts +27 -0
  42. package/lib/tool.js +221 -0
  43. package/lib/types/client/details-compat.d.ts +28 -0
  44. package/lib/types/client/editor-bridge.d.ts +84 -0
  45. package/lib/types/client/editor-dock-layout.d.ts +15 -0
  46. package/lib/types/client/editor-modal.d.ts +54 -0
  47. package/lib/types/client/editor-panel.d.ts +127 -0
  48. package/lib/types/client/editor-recovery.d.ts +27 -0
  49. package/lib/types/client/editor-successor.d.ts +28 -0
  50. package/lib/types/client/editor-workbench-host.d.ts +43 -0
  51. package/lib/types/client/frame-gallery.d.ts +98 -0
  52. package/lib/types/client/index.d.ts +176 -0
  53. package/lib/types/client/presentation-hydration.d.ts +36 -0
  54. package/lib/types/client/selection-dock.d.ts +18 -0
  55. package/lib/types/client/selection-polling.d.ts +24 -0
  56. package/lib/types/client/selection-store.d.ts +26 -0
  57. package/lib/types/tool-names.d.ts +13 -0
  58. package/lib/viewer-assets/canvaskit/canvaskit.js +288 -0
  59. package/lib/viewer-assets/canvaskit/canvaskit.wasm +0 -0
  60. package/lib/viewer-assets/manifest.json +22 -0
  61. package/lib/viewer-assets/op_web_sdk_bg.wasm +0 -0
  62. package/lib/viewer-assets/sdk.js +225 -0
  63. package/lib/viewer-assets.d.ts +74 -0
  64. package/lib/viewer-assets.js +303 -0
  65. package/package.json +95 -0
  66. package/scripts/build-client.mjs +27 -0
  67. package/scripts/run-tool.mjs +63 -0
  68. package/scripts/sync-viewer-assets.mjs +304 -0
  69. package/scripts/test-host.mjs +311 -0
  70. package/scripts/test-viewer-assets.mjs +54 -0
  71. package/src/client/details-compat.ts +44 -0
  72. package/src/client/editor-bridge.ts +170 -0
  73. package/src/client/editor-dock-layout.ts +56 -0
  74. package/src/client/editor-modal.tsx +607 -0
  75. package/src/client/editor-panel.tsx +823 -0
  76. package/src/client/editor-recovery.ts +116 -0
  77. package/src/client/editor-successor.ts +136 -0
  78. package/src/client/editor-workbench-host.tsx +280 -0
  79. package/src/client/frame-gallery.tsx +546 -0
  80. package/src/client/index.tsx +987 -0
  81. package/src/client/presentation-hydration.ts +210 -0
  82. package/src/client/react-dom-compat.d.ts +22 -0
  83. package/src/client/selection-dock.tsx +89 -0
  84. package/src/client/selection-polling.ts +93 -0
  85. package/src/client/selection-store.ts +108 -0
  86. package/src/design-tools.ts +242 -0
  87. package/src/editor-host.ts +1238 -0
  88. package/src/editor-recovery.ts +374 -0
  89. package/src/index.ts +219 -0
  90. package/src/mcp-client.ts +193 -0
  91. package/src/new-tool.ts +160 -0
  92. package/src/presentation-hydration.ts +634 -0
  93. package/src/renderer.ts +884 -0
  94. package/src/tool-names.ts +21 -0
  95. package/src/tool.ts +258 -0
  96. package/src/viewer-assets.ts +353 -0
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Offscreen rendering + signed HTTP delivery for `.op` documents.
3
+ *
4
+ * `openpencil_render` snapshots the source document, uses OpenPencil's own
5
+ * headless exporter for design-fidelity PNG output, retaining every
6
+ * top-level frame for the conversation gallery, and only invokes Jian
7
+ * as an explicitly disclosed runtime-preview fallback when the exact binary
8
+ * is unavailable. Content-addressed image/document capabilities bind name,
9
+ * byte length, and SHA-256 without exposing arbitrary host paths. Serving
10
+ * refuses symbolic links so a delivered artifact cannot be redirected.
11
+ *
12
+ * Model-visible result values stay plain JSON; the browser-only envelope
13
+ * rides `presentationMeta` (see `tool.ts`). Never return an ImageBlock.
14
+ * @module dsh-openpencil/renderer
15
+ */
16
+ import type { IncomingMessage, ServerResponse } from 'node:http';
17
+ import type { JsonValue } from '@deepseek-ai/dsh-tools';
18
+ import type { ViewerGrant } from './viewer-assets.js';
19
+ import type { EditorGrant } from './editor-host.js';
20
+ import { OPENPENCIL_RENDER_TOOL_NAME } from './tool-names.js';
21
+ /** HTTP prefix owned by the render capability route. */
22
+ export declare const RENDER_ROUTE_PREFIX = "/_dsh/dsh-openpencil/render";
23
+ /** Presentation metadata key reserved by the browser half of this package. */
24
+ export declare const PRESENTATION_META_KEY = "$dshOpenPencil";
25
+ /** Refuse to deliver anything above this size (also enforced at render time). */
26
+ export declare const MAX_RENDER_BYTES: number;
27
+ /** Refuse unusually large source documents before copying them into managed state. */
28
+ export declare const MAX_DOCUMENT_BYTES: number;
29
+ /** One render delivery capability. */
30
+ interface LegacyRenderTokenPayload {
31
+ v: 1;
32
+ path: string;
33
+ filename: string;
34
+ bytes: number;
35
+ }
36
+ interface ArtifactTokenPayload {
37
+ v: 2;
38
+ kind: 'image' | 'document';
39
+ filename: string;
40
+ bytes: number;
41
+ sha256: string;
42
+ }
43
+ type RenderTokenPayload = LegacyRenderTokenPayload | ArtifactTokenPayload;
44
+ /** Browser grant paired to one rendered PNG. */
45
+ export interface RenderGrant {
46
+ path: string;
47
+ previewUrl: string;
48
+ downloadUrl: string;
49
+ width?: number;
50
+ height?: number;
51
+ id?: string;
52
+ name?: string;
53
+ index?: number;
54
+ }
55
+ /** One immutable top-level frame retained from an exact render. */
56
+ export interface RenderFrame {
57
+ path: string;
58
+ filename: string;
59
+ mimeType: 'image/png';
60
+ bytes: number;
61
+ width: number;
62
+ height: number;
63
+ sha256: string;
64
+ /** Canonical top-level node identity and user-facing name. */
65
+ id?: string;
66
+ name?: string;
67
+ index?: number;
68
+ }
69
+ export interface DocumentSnapshot {
70
+ path: string;
71
+ filename: string;
72
+ mimeType: 'application/json';
73
+ bytes: number;
74
+ sha256: string;
75
+ }
76
+ export interface DocumentGrant extends DocumentSnapshot {
77
+ url: string;
78
+ previewUrl: string;
79
+ downloadUrl: string;
80
+ }
81
+ /** Canonical result shape the tool returns and the envelope enriches. */
82
+ export interface RenderResult {
83
+ path: string;
84
+ filename: string;
85
+ mimeType: 'image/png';
86
+ kind: 'image';
87
+ description: string;
88
+ sourceTool: typeof OPENPENCIL_RENDER_TOOL_NAME;
89
+ previewIntent: 'image';
90
+ bytes: number;
91
+ width?: number;
92
+ height?: number;
93
+ sha256?: string;
94
+ sourcePath?: string;
95
+ renderer?: 'openpencil' | 'jian';
96
+ rendererBinary?: string;
97
+ fidelity?: 'exact' | 'runtime-preview';
98
+ warnings?: string[];
99
+ /** Ordered top-level frames. The first entry is also exposed by legacy image fields. */
100
+ frames?: RenderFrame[];
101
+ frameCount?: number;
102
+ editable?: boolean;
103
+ /** Live-card intent: expand the editor once after a newly-created design renders. */
104
+ autoOpenEditor?: boolean;
105
+ document?: DocumentSnapshot;
106
+ note?: string;
107
+ }
108
+ /** Plugin-managed state root (mirrors the dsh-vision-toolkit convention). */
109
+ export declare function stateRoot(): string;
110
+ /** Plugin-managed render output directory. */
111
+ export declare function renderDir(): string;
112
+ /** Content-addressed immutable `.op` snapshots served to the web viewer. */
113
+ export declare function snapshotDir(): string;
114
+ /** Load or atomically create the per-DSH-home signing key. */
115
+ export declare function prepareRenderAccessKey(): Promise<Buffer>;
116
+ /** Signed render-capability encoder and safe route handler. */
117
+ export declare class RenderAccessController {
118
+ private readonly key;
119
+ private routeCount;
120
+ constructor(key: Buffer);
121
+ /** Whether at least one HTTP carrier currently owns the route. */
122
+ get routeAvailable(): boolean;
123
+ /** Mark one route attachment; the returned disposer removes that attachment. */
124
+ attachRoute(): () => void;
125
+ /** Mint a deterministic, tamper-evident capability for one render result. */
126
+ sign(result: RenderResult): string;
127
+ /** Mint an immutable capability without embedding an absolute local path. */
128
+ signArtifact(artifact: Omit<ArtifactTokenPayload, 'v'>): string;
129
+ /** Verify and decode one capability without touching the filesystem. */
130
+ verify(token: string): RenderTokenPayload | undefined;
131
+ /** Serve one GET/HEAD capability request. */
132
+ handle(req: IncomingMessage, res: ServerResponse): Promise<void>;
133
+ }
134
+ /** Expand `~` / `~/` prefixes (the model frequently writes home-relative paths). */
135
+ export declare function expandUserHome(raw: string): string;
136
+ /**
137
+ * Validate the `.op` input path: expand `~`, resolve against the session
138
+ * workspace, realpath, and require a regular `.op` file.
139
+ */
140
+ export declare function resolveInputFile(raw: string, cwd: string): Promise<string>;
141
+ /** Freeze source bytes before rendering so preview and web viewer cannot diverge. */
142
+ export declare function createDocumentSnapshot(input: string): Promise<DocumentSnapshot>;
143
+ /** Locate the exact OpenPencil renderer, preferring an explicit override. */
144
+ export declare function findOpenPencilBinary(): string | undefined;
145
+ /** Locate the `jian` binary: env override, known build location, then PATH. */
146
+ export declare function findJianBinary(): string;
147
+ /** Parse the physical size from `jian render`'s success line. */
148
+ export declare function parseRenderSize(stdout: string): {
149
+ width?: number;
150
+ height?: number;
151
+ };
152
+ /**
153
+ * Run `jian render` for one input and wait for the PNG on disk.
154
+ * Observes `signal` so caller cancellation stops the child promptly.
155
+ */
156
+ export declare function runJianRender(options: {
157
+ binary: string;
158
+ input: string;
159
+ out: string;
160
+ width?: number;
161
+ height?: number;
162
+ scale?: number;
163
+ signal: AbortSignal;
164
+ }): Promise<{
165
+ stdout: string;
166
+ stderr: string;
167
+ }>;
168
+ export declare class RendererBinaryMissingError extends Error {
169
+ constructor(message: string, options?: ErrorOptions);
170
+ }
171
+ /** Render all top-level active-page nodes through OpenPencil's exact scene exporter. */
172
+ export declare function runOpenPencilRender(options: {
173
+ binary: string;
174
+ input: string;
175
+ scale?: number;
176
+ signal: AbortSignal;
177
+ }): Promise<{
178
+ png: string;
179
+ frames: Array<{
180
+ png: string;
181
+ id?: string;
182
+ name?: string;
183
+ index: number;
184
+ }>;
185
+ warnings: string[];
186
+ stdout: string;
187
+ stderr: string;
188
+ }>;
189
+ /**
190
+ * Purely enrich a canonical tool-result value with a browser render grant.
191
+ * Returns the value unchanged when no route/artifact exists.
192
+ */
193
+ export declare function projectRenderGrant(value: JsonValue, controller: RenderAccessController, viewer?: ViewerGrant, editor?: EditorGrant): JsonValue;
194
+ /** Reserve a fresh output path inside the managed render directory. */
195
+ export declare function createRenderOutput(): Promise<string>;
196
+ /** Stat + cap-check a freshly rendered PNG. */
197
+ export declare function verifyRenderOutput(out: string): Promise<{
198
+ bytes: number;
199
+ width: number;
200
+ height: number;
201
+ sha256: string;
202
+ }>;
203
+ export {};