@writepanda/mcp 1.58.0 → 1.66.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 (2) hide show
  1. package/bin/server.mjs +105 -37
  2. package/package.json +43 -43
package/bin/server.mjs CHANGED
@@ -575,7 +575,7 @@ const TOOLS = [
575
575
  command: "project.open",
576
576
  },
577
577
 
578
- // ── compose: clips, motion graphics, FX, lower-thirds ──────────
578
+ // ── compose: clips, motion graphics, FX ────────────────────────
579
579
  {
580
580
  name: "project_add_clip",
581
581
  description:
@@ -646,6 +646,12 @@ const TOOLS = [
646
646
  description:
647
647
  "Optional CSS color string composited over the blurred backdrop. Editor default: 'rgba(10,10,10,0.18)' (slight dark glass). Only applied when backdropBlurStrength > 0.",
648
648
  },
649
+ layer: {
650
+ type: "string",
651
+ enum: ["overlay", "background"],
652
+ description:
653
+ "'background' renders this full-frame graphic BEHIND the camera (graphic-background + talking-head-card layout) — pair it with a CARD camera clip-transform (cam-right-portrait / cam-bottom-right-quarter) over the same span. The camera card composites on top in preview AND export. Default 'overlay' (on top).",
654
+ },
649
655
  expectedRevision: { type: "number" },
650
656
  },
651
657
  required: ["durationMs"],
@@ -780,54 +786,71 @@ const TOOLS = [
780
786
  src: { type: "string", description: "Direct path/URL (alternative to fxId)" },
781
787
  atMs: { type: "number" },
782
788
  durationMs: { type: "number", description: "Default 2500ms for bundled FX" },
789
+ speed: {
790
+ type: "number",
791
+ description:
792
+ "Playback-speed multiplier for the looping FX (0.25-4, default 1). 2 = twice as fast, 0.5 = half. Speeds up / slows down a film burn, light leak, etc. without re-rendering.",
793
+ },
783
794
  expectedRevision: { type: "number" },
784
795
  },
785
796
  required: ["atMs"],
786
797
  },
787
798
  command: "project.add-fx",
788
799
  },
800
+ {
801
+ name: "project_add_transition",
802
+ description:
803
+ "Place a transition at a cut between two clips. Drops a bundled transition overlay (a full-frame transparent WebM that goes opaque at its midpoint) CENTERED on atMs, so the opaque peak masks the cut and reads as a scene change. No render step. Pass atMs = the cut time (a clip boundary from project_read). Ids (asset_list_transitions): fade-black, fade-white, flash, light-sweep, film-burn, glitch.",
804
+ inputSchema: {
805
+ type: "object",
806
+ properties: {
807
+ id: { type: "string" },
808
+ path: { type: "string" },
809
+ transitionId: { type: "string", description: "Bundled id, e.g. fade-black. From asset_list_transitions." },
810
+ file: { type: "string", description: "Custom transition video (path / file:// URL). Use instead of transitionId." },
811
+ atMs: { type: "number", description: "Edited-timeline CUT time to center the transition on." },
812
+ durationMs: { type: "number", description: "Total length. Default 1000 (native length of the bundled set)." },
813
+ expectedRevision: { type: "number" },
814
+ },
815
+ required: ["atMs"],
816
+ },
817
+ command: "project.add-transition",
818
+ },
789
819
  {
790
820
  name: "project_add_lower_third",
791
- description: "Drop a lower-third name plate onto the timeline.",
821
+ description:
822
+ "One-call lower third: renders an lt-* nameplate motion template (hyperframes) with your name/title and places it on the timeline as a transparent overlay at atMs. ASYNC — returns { jobId, outputPath }; call job_wait — it resolves once the region is PLACED (result: { path, revision, outputPath, durationMs }), no separate project_add_motion_graphic call needed. Designs (see motion_list, category lower-third): lt-vox-marker (default, highlighter swipe), lt-broadcast-bar (news chyron), lt-glass-card (frosted), lt-kinetic-stack (bold word-by-word), lt-minimal-line (editorial), lt-corner-plate (documentary bracket + kicker slot), lt-accent-slab (knockout name), lt-avatar-pill (creator pill), lt-typewriter-tag (mono typing), lt-gradient-sweep (gradient glow).",
792
823
  inputSchema: {
793
824
  type: "object",
794
825
  properties: {
795
826
  id: { type: "string" },
796
827
  path: { type: "string" },
797
- content: { type: "string", description: "Primary text (name)" },
798
- subtitle: { type: "string", description: "Secondary text (title)" },
799
- atMs: { type: "number" },
800
- durationMs: { type: "number", description: "Default 5000ms" },
801
- designType: {
828
+ name: { type: "string", description: "Primary text (person/brand name)" },
829
+ title: { type: "string", description: "Secondary line (role / handle / tagline)" },
830
+ templateId: {
802
831
  type: "string",
803
- description:
804
- "slash-reveal | center-stack | split-horizontal | name-bar | border-frame | minimal-underline | box-reveal | corner-brackets. Default: slash-reveal.",
832
+ description: "lt-* design id. Default lt-vox-marker.",
805
833
  },
806
- accentColor: { type: "string", description: "Hex accent/background color" },
807
- textColor: { type: "string", description: "Hex text color. Default #ffffff" },
808
- backgroundColor: {
834
+ atMs: { type: "number", description: "Edited timeline time" },
835
+ aspectRatio: {
809
836
  type: "string",
810
- description: "Hex background fill. Default matches accentColor",
837
+ description: "16:9 | 9:16 | 1:1. Default 16:9 — match the project's aspect.",
811
838
  },
812
- backgroundRadius: {
813
- type: "number",
814
- description: "Corner radius in pixels. Default 8",
839
+ slots: {
840
+ type: "object",
841
+ description:
842
+ "Optional extra slot overrides (colors like accentColor/inkColor, or kicker for lt-corner-plate). Keys from motion_list. name/title args win over same-key entries.",
815
843
  },
816
- fontSize: { type: "number", description: "Primary text font size in px. Default 28" },
817
- fontFamily: { type: "string", description: "CSS font family name. Default Inter" },
818
844
  soundUrl: {
819
845
  type: "string",
820
846
  description:
821
- 'SFX played when the lower third enters. Bundled id (bundled:sound/<id>). Default bundled:sound/mouse-click. Pass "none" for silent.',
822
- },
823
- soundVolume: {
824
- type: "number",
825
- description: "Sound volume 0–1. Default 0.8.",
847
+ 'SFX on enter. Bundled id (bundled:sound/<id>). Default bundled:sound/mouse-click. Pass "none" for silent.',
826
848
  },
849
+ soundVolume: { type: "number", description: "Sound volume 0–1. Default 1." },
827
850
  anchorSourceMs: {
828
851
  type: "number",
829
852
  description:
830
- "Anchor the lower third to a SOURCE-time moment. Pass when atMs was derived from a transcript word's startMs — the lower third re-anchors automatically on subsequent transcript edits. Without it, the lower third drifts after any trim. Omit for free-floating placement.",
853
+ "Anchor to a SOURCE-time moment. Pass when atMs comes from a transcript word's startMs so the region survives later trims.",
831
854
  },
832
855
  anchorSourceEndMs: {
833
856
  type: "number",
@@ -835,7 +858,7 @@ const TOOLS = [
835
858
  },
836
859
  expectedRevision: { type: "number" },
837
860
  },
838
- required: ["content", "atMs"],
861
+ required: ["name", "atMs"],
839
862
  },
840
863
  command: "project.add-lower-third",
841
864
  },
@@ -887,7 +910,7 @@ const TOOLS = [
887
910
  {
888
911
  name: "project_set_region_sound",
889
912
  description:
890
- 'Set or clear the sound effect on an existing region (zoom / motionGraphic / lowerThird / fx). Use to swap the default zoom swoosh, add a ding to a motion graphic, or mute a lower-third click. Pass soundUrl="none" to clear.',
913
+ 'Set or clear the sound effect on an existing region (zoom / motionGraphic / fx). Use to swap the default zoom swoosh, add a ding to a motion graphic, or mute an effect sound. Pass soundUrl="none" to clear.',
891
914
  inputSchema: {
892
915
  type: "object",
893
916
  properties: {
@@ -896,7 +919,7 @@ const TOOLS = [
896
919
  regionId: { type: "string", description: "Target region id" },
897
920
  regionType: {
898
921
  type: "string",
899
- enum: ["zoom", "motionGraphic", "lowerThird", "fx"],
922
+ enum: ["zoom", "motionGraphic", "fx"],
900
923
  description: "Region kind that owns the id",
901
924
  },
902
925
  soundUrl: {
@@ -1001,6 +1024,7 @@ const TOOLS = [
1001
1024
  "cam-bottom-half",
1002
1025
  "cam-top-half",
1003
1026
  "cam-right-portrait",
1027
+ "cam-right-portrait-sm",
1004
1028
  "cam-left-portrait",
1005
1029
  "cam-bottom-right-quarter",
1006
1030
  "cam-bottom-left-quarter",
@@ -1014,7 +1038,7 @@ const TOOLS = [
1014
1038
  "layout-guest-full",
1015
1039
  ],
1016
1040
  description:
1017
- "cam-* (camera reposition into a sub-rect): cam-bottom-half / cam-top-half (9:16); cam-right-portrait / cam-left-portrait (16:9 ~35% card); cam-bottom-right-quarter / cam-bottom-left-quarter (corner card); cam-right-55/left-55/right-50/left-50 (designed splits). layout-* (PODCAST ONLY — whole-composite swap over time): layout-side-by-side, layout-podcast (two equal tiles), layout-host-full (speaker 1 only), layout-guest-full (speaker 2 only). IMPORTANT: layout-* presets only do anything on a PODCAST clip (kind='podcast' — a clip with BOTH a host and a guest source). On any other clip there is no second speaker, so they are a no-op; use cam-* there. Check clip.kind via project_read before using layout-*.",
1041
+ "cam-* (camera reposition into a sub-rect): cam-bottom-half / cam-top-half (9:16); cam-right-portrait / cam-left-portrait (16:9 ~35% card); cam-right-portrait-sm (small ~25% host card — for a full-frame graphic background); cam-bottom-right-quarter / cam-bottom-left-quarter (corner card); cam-right-55/left-55/right-50/left-50 (designed splits). layout-* (PODCAST ONLY — whole-composite swap over time): layout-side-by-side, layout-podcast (two equal tiles), layout-host-full (speaker 1 only), layout-guest-full (speaker 2 only). IMPORTANT: layout-* presets only do anything on a PODCAST clip (kind='podcast' — a clip with BOTH a host and a guest source). On any other clip there is no second speaker, so they are a no-op; use cam-* there. Check clip.kind via project_read before using layout-*.",
1018
1042
  },
1019
1043
  transitionMs: {
1020
1044
  type: "number",
@@ -1110,7 +1134,7 @@ const TOOLS = [
1110
1134
  {
1111
1135
  name: "project_move_clip",
1112
1136
  description:
1113
- "Reorder a clip on the main track. `clipId` identifies the clip; `toIndex` is its new 0-based position after the move. Project-level regions (zooms, trims, speeds, annotations, FX, lower-thirds, media overlays, clip transforms) automatically migrate to follow their original clips so the user-perceived edits stay attached to the same content — a zoom that was 'into the explanation in clip 2' is still pointing at the same explanation after clip 2 moves to position 0. Per-clip transcripts ride on the clips themselves and don't need separate migration.",
1137
+ "Reorder a clip on the main track. `clipId` identifies the clip; `toIndex` is its new 0-based position after the move. Project-level regions (zooms, trims, speeds, annotations, FX, media overlays, clip transforms) automatically migrate to follow their original clips so the user-perceived edits stay attached to the same content — a zoom that was 'into the explanation in clip 2' is still pointing at the same explanation after clip 2 moves to position 0. Per-clip transcripts ride on the clips themselves and don't need separate migration.",
1114
1138
  inputSchema: {
1115
1139
  type: "object",
1116
1140
  properties: {
@@ -1133,7 +1157,7 @@ const TOOLS = [
1133
1157
  {
1134
1158
  name: "project_remove_region",
1135
1159
  description:
1136
- "Delete an existing region (zoom, trim, speed, annotation, fx, lower-third, overlay, clip-transform, audio-overlay) by its id. Use project_read to find region ids — visual regions live under editor.*Regions; audio overlays live under audioOverlays[]. If the region belongs to a link group (designed-segment pair: a clip-transform parking the camera into one half + the panel motion-graphic on the other half), deleting either half also removes its peer so the pair stays coherent. Returns the updated project.",
1160
+ "Delete an existing region (zoom, trim, speed, annotation, fx, overlay, clip-transform, audio-overlay) by its id. Use project_read to find region ids — visual regions live under editor.*Regions; audio overlays live under audioOverlays[]. If the region belongs to a link group (designed-segment pair: a clip-transform parking the camera into one half + the panel motion-graphic on the other half), deleting either half also removes its peer so the pair stays coherent. Returns the updated project.",
1137
1161
  inputSchema: {
1138
1162
  type: "object",
1139
1163
  properties: {
@@ -1142,7 +1166,7 @@ const TOOLS = [
1142
1166
  regionType: {
1143
1167
  type: "string",
1144
1168
  description:
1145
- "zoom | trim | speed | annotation | fx | lower-third | overlay | clip-transform | audio-overlay",
1169
+ "zoom | trim | speed | annotation | fx | overlay | clip-transform | audio-overlay",
1146
1170
  },
1147
1171
  regionId: { type: "string", description: "id of the region to delete" },
1148
1172
  expectedRevision: { type: "number" },
@@ -1173,7 +1197,7 @@ const TOOLS = [
1173
1197
  {
1174
1198
  name: "project_update_region",
1175
1199
  description:
1176
- "Patch fields on an existing region without replacing it. Accepts any subset of the region's own properties — only the supplied fields are changed, everything else is preserved. Works on zoom (depth, focusX, focusY), trim (startMs, endMs), speed (startMs, endMs, speed), lower-third (content, subtitle, atMs, durationMs, designType, accentColor, textColor, backgroundColor, backgroundRadius, fontSize, fontFamily), fx (atMs, durationMs), annotation, overlay, clip-transform (startMs, endMs, preset, transitionMs), and audio-overlay (startMs, endMs, sourceStartMs, volume — lets you drag-trim an audio overlay without removing it). Time shifts on a link-grouped region (e.g. one half of a designed segment) propagate to every peer in the group so the pair stays coherent.",
1200
+ "Patch fields on an existing region without replacing it. Accepts any subset of the region's own properties — only the supplied fields are changed, everything else is preserved. Works on zoom (depth, focusX, focusY), trim (startMs, endMs), speed (startMs, endMs, speed), fx (atMs, durationMs, opacity, blendMode, speed), annotation, overlay, clip-transform (startMs, endMs, preset, transitionMs), and audio-overlay (startMs, endMs, sourceStartMs, volume — lets you drag-trim an audio overlay without removing it). Time shifts on a link-grouped region (e.g. one half of a designed segment) propagate to every peer in the group so the pair stays coherent.",
1177
1201
  inputSchema: {
1178
1202
  type: "object",
1179
1203
  properties: {
@@ -1182,13 +1206,13 @@ const TOOLS = [
1182
1206
  regionType: {
1183
1207
  type: "string",
1184
1208
  description:
1185
- "zoom | trim | speed | annotation | fx | lower-third | overlay | clip-transform | audio-overlay",
1209
+ "zoom | trim | speed | annotation | fx | overlay | clip-transform | audio-overlay",
1186
1210
  },
1187
1211
  regionId: { type: "string", description: "id of the region to update" },
1188
1212
  patch: {
1189
1213
  type: "object",
1190
1214
  description:
1191
- "Fields to update (partial). E.g. { depth: 4 } to change zoom depth, { content: 'New Name' } on a lower-third, or { startMs: 2000, endMs: 15000, sourceStartMs: 4000 } to shift + trim an audio overlay (play seconds 4–17 of the source from the 2s mark on the timeline).",
1215
+ "Fields to update (partial). E.g. { depth: 4 } to change zoom depth, or { startMs: 2000, endMs: 15000, sourceStartMs: 4000 } to shift + trim an audio overlay (play seconds 4–17 of the source from the 2s mark on the timeline).",
1192
1216
  },
1193
1217
  expectedRevision: { type: "number" },
1194
1218
  },
@@ -1843,7 +1867,7 @@ const TOOLS = [
1843
1867
  slots: {
1844
1868
  type: "object",
1845
1869
  description:
1846
- "Editable values keyed by slot key (see motion_list / the SKILL catalog): text strings, color hex strings, or list arrays. Omitted slots fall back to the template default.",
1870
+ "Editable values keyed by slot key (see motion_list / the SKILL catalog): text strings, color hex strings, or list arrays. An 'image'-typed slot (see its `type` in motion_list) takes an ABSOLUTE FILE PATH to an image — the server stages the file into the render, so you can pass a project-media path or a generated image (e.g. from media_generate_image). Omitted slots fall back to the template default.",
1847
1871
  },
1848
1872
  aspectRatio: {
1849
1873
  type: "string",
@@ -1862,6 +1886,43 @@ const TOOLS = [
1862
1886
  },
1863
1887
  command: "motion.generate",
1864
1888
  },
1889
+ // Video templates ("storyboards") — multi-scene, parameterized videos that
1890
+ // render several templates and concatenate them into one finished clip.
1891
+ {
1892
+ name: "motion_list_storyboards",
1893
+ description:
1894
+ "List the bundled VIDEO templates (storyboards). Unlike single-scene templates (motion_list), a storyboard is a whole short video: an ordered set of scenes plus a `params` brief you fill in once. Returns each storyboard's id, name, audience (youtube|podcaster|course), description, aspectRatios, and `params` (the brief: key, label, type string|color|asset, required, default — color params default to the workspace brand kit via brand.* sentinels). Use a storyboard when the user wants a finished intro/outro/episode-open/lesson-open rather than a single overlay. Render one with motion_generate_storyboard.",
1895
+ inputSchema: { type: "object", properties: {} },
1896
+ command: "motion.list-storyboards",
1897
+ },
1898
+ {
1899
+ name: "motion_generate_storyboard",
1900
+ description:
1901
+ "Render a multi-scene VIDEO template (storyboard) by id. Fill the brief via `params`; missing color params fall back to the workspace brand kit, missing required text params fail fast. The server renders each scene and concatenates them into one MP4. Async — returns { jobId, outputPath, sceneCount }; call job_wait, then pass that jobId as `fromJob` to project_add_motion_graphic. Discover storyboards + their params with motion_list_storyboards.",
1902
+ inputSchema: {
1903
+ type: "object",
1904
+ properties: {
1905
+ storyboardId: {
1906
+ type: "string",
1907
+ description:
1908
+ "Storyboard id from motion_list_storyboards (e.g. youtube-creator-intro, podcast-episode-open, course-lesson-open).",
1909
+ },
1910
+ params: {
1911
+ type: "object",
1912
+ description:
1913
+ "The brief, keyed by param key (see motion_list_storyboards). Text and color values. Omitted color params fall back to the workspace brand kit; omitted required text params cause a fast failure.",
1914
+ },
1915
+ aspectRatio: {
1916
+ type: "string",
1917
+ enum: ["16:9", "9:16", "1:1"],
1918
+ description: "Defaults to the storyboard's first listed aspect.",
1919
+ },
1920
+ outputName: { type: "string", description: "Optional filename stem (no extension)." },
1921
+ },
1922
+ required: ["storyboardId"],
1923
+ },
1924
+ command: "motion.generate-storyboard",
1925
+ },
1865
1926
  // Custom HTML authoring path is `motion_render_html` (for briefs no
1866
1927
  // bundled template fits).
1867
1928
  {
@@ -2016,6 +2077,13 @@ const TOOLS = [
2016
2077
  inputSchema: { type: "object", properties: {} },
2017
2078
  command: "asset.list-fx",
2018
2079
  },
2080
+ {
2081
+ name: "asset_list_transitions",
2082
+ description:
2083
+ "List every bundled transition (id, title, category, durationSeconds). Use the id with project_add_transition, centered on a cut.",
2084
+ inputSchema: { type: "object", properties: {} },
2085
+ command: "asset.list-transitions",
2086
+ },
2019
2087
  {
2020
2088
  name: "asset_list_music",
2021
2089
  description:
@@ -2077,7 +2145,7 @@ const TOOLS = [
2077
2145
  {
2078
2146
  name: "export_start",
2079
2147
  description:
2080
- "Render the project to MP4 via the same Tier-3 PixiJS pipeline the editor's Export Video button uses (v1.24+ — convergence release). When an editor window is already open on the target project, the agent reuses it. Otherwise the agent spawns a hidden editor window for the duration of the render and closes it after. ASYNC — returns { jobId, outputPath }; call job_wait. Honours every region/style/caption/FX/lower-third/motion-graphic in the project. Video overlays (motion graphics added via project_add_motion_graphic) — opaque MP4 and transparent WebM/VP9+alpha — composite inline in the export pipeline; no extra call needed.",
2148
+ "Render the project to MP4 via the same Tier-3 PixiJS pipeline the editor's Export Video button uses (v1.24+ — convergence release). When an editor window is already open on the target project, the agent reuses it. Otherwise the agent spawns a hidden editor window for the duration of the render and closes it after. ASYNC — returns { jobId, outputPath }; call job_wait. Honours every region/style/caption/FX/motion-graphic in the project. Video overlays (motion graphics added via project_add_motion_graphic) — opaque MP4 and transparent WebM/VP9+alpha — composite inline in the export pipeline; no extra call needed.",
2081
2149
  inputSchema: {
2082
2150
  type: "object",
2083
2151
  properties: {
@@ -2304,7 +2372,7 @@ const TOOLS = [
2304
2372
  const server = new Server(
2305
2373
  {
2306
2374
  name: "pandastudio",
2307
- version: "1.58.0",
2375
+ version: "1.66.0",
2308
2376
  },
2309
2377
  {
2310
2378
  capabilities: {
package/package.json CHANGED
@@ -1,45 +1,45 @@
1
1
  {
2
- "name": "@writepanda/mcp",
3
- "version": "1.58.0",
4
- "description": "Model Context Protocol server for PandaStudio. Exposes the desktop video editor's automation surface to Cursor, Continue, Cline, Claude Desktop, and any MCP-compliant client.",
5
- "keywords": [
6
- "pandastudio",
7
- "mcp",
8
- "model-context-protocol",
9
- "video-editor",
10
- "agent",
11
- "cursor",
12
- "continue",
13
- "cline",
14
- "claude-desktop"
15
- ],
16
- "author": "Kamala Kannan Sankarraj",
17
- "license": "MIT",
18
- "homepage": "https://www.writepanda.ai/cli",
19
- "repository": {
20
- "type": "git",
21
- "url": "git+https://github.com/kamskans/openscreen.git",
22
- "directory": "packages/mcp"
23
- },
24
- "bugs": {
25
- "url": "https://github.com/kamskans/openscreen/issues"
26
- },
27
- "type": "module",
28
- "engines": {
29
- "node": ">=18"
30
- },
31
- "bin": {
32
- "writepanda-mcp": "./bin/server.mjs"
33
- },
34
- "files": [
35
- "bin",
36
- "README.md",
37
- "LICENSE"
38
- ],
39
- "dependencies": {
40
- "@modelcontextprotocol/sdk": "^1.0.4"
41
- },
42
- "publishConfig": {
43
- "access": "public"
44
- }
2
+ "name": "@writepanda/mcp",
3
+ "version": "1.66.0",
4
+ "description": "Model Context Protocol server for PandaStudio. Exposes the desktop video editor's automation surface to Cursor, Continue, Cline, Claude Desktop, and any MCP-compliant client.",
5
+ "keywords": [
6
+ "pandastudio",
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "video-editor",
10
+ "agent",
11
+ "cursor",
12
+ "continue",
13
+ "cline",
14
+ "claude-desktop"
15
+ ],
16
+ "author": "Kamala Kannan Sankarraj",
17
+ "license": "MIT",
18
+ "homepage": "https://www.writepanda.ai/cli",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/kamskans/openscreen.git",
22
+ "directory": "packages/mcp"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/kamskans/openscreen/issues"
26
+ },
27
+ "type": "module",
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
31
+ "bin": {
32
+ "writepanda-mcp": "./bin/server.mjs"
33
+ },
34
+ "files": [
35
+ "bin",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.0.4"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
44
+ }
45
45
  }