tsquare 0.12.1 → 0.12.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.12.3
4
+
5
+ The language hasn't changed. Screens whose content fits render exactly as in 0.12.2 (the same pixels; the SVG's internal mask ids differ). Screens whose content is taller than the screen are fixed:
6
+
7
+ - **Content taller than its screen no longer pushes things out of it.** The screen's body grew with its content, so a toast or a tab bar ended up below the frame and wasn't drawn, a modal was centered too low, and a bottom drawer started too low with its end cut off. The content is now cut off at the bottom of the screen, as it already looked, and bars and overlays are placed in the visible screen. Of 438 boards in the examples and eval outputs, 434 render the same pixels; one modal moves up 18px to the middle of its screen, and three gain 4 to 8 pixels of the frame's bottom border that overflowing content used to cover.
8
+
9
+ ## 0.12.2
10
+
11
+ The language and the renderer haven't changed: every wireframe renders exactly as in 0.12.1, and render URLs give the same images.
12
+
13
+ - **Loads in Docusaurus:** Docusaurus loads its config, and the remark plugins in it, through jiti 1, which turned `import { z } from "zod"` into `undefined`, so importing tsquare there failed with "Cannot read properties of undefined (reading 'enum')". tsquare now imports zod as `import * as z from "zod"` (the form zod recommends), and a test loads the build through jiti 1.
14
+
3
15
  ## 0.12.1
4
16
 
5
17
  The language and the renderer haven't changed: every wireframe renders exactly as in 0.12.0, and render URLs give the same images.
package/README.md CHANGED
@@ -52,10 +52,29 @@ A wireframe can be embedded anywhere an image works (Notion, GitHub, docs sites)
52
52
 
53
53
  The playground's **Copy link** menu makes these; [Embedding](docs/embedding.md) has the steps for Notion, GitHub and your own site. The text is compressed into the URL, not encrypted, so anyone with the link can read it; see [privacy](https://tsquare.dev/privacy). `encodeWireframe` and `decodeWireframe` in the library produce and read the same links.
54
54
 
55
- ## In your editor and notes
55
+ ## Use it with
56
+
57
+ **With AI**
58
+
59
+ - **Claude:** the [tsquare skill](https://tsquare.dev/docs/ai#the-claude-skill) teaches Claude the language and how to check its own wireframes.
60
+ - **Any model:** the [system prompt](https://tsquare.dev/docs/ai#the-prompt), or the hosted [MCP server](https://tsquare.dev/docs/ai#connect-over-mcp) for Claude, ChatGPT, Cursor, VS Code and other tools that take a remote MCP URL.
61
+
62
+ **In your docs**
63
+
64
+ - **Docusaurus, Astro, MDX:** [`remark-tsquare`](https://tsquare.dev/docs/markdown-plugins#remark-tsquare) draws ```` ```tsquare ```` code blocks when the site is built.
65
+ - **VitePress, Eleventy:** [`markdown-it-tsquare`](https://tsquare.dev/docs/markdown-plugins#markdown-it-tsquare), the same for sites built on markdown-it.
66
+ - **Any web page:** [one script tag](https://tsquare.dev/docs/embedding#pages-written-in-markdown) draws the code blocks in the reader's browser, with no build step.
67
+ - **Notion, GitHub and anywhere an image works:** [image links](#image-links).
68
+
69
+ **In your app**
70
+
71
+ - **React:** [`@tsquare-js/react`](https://tsquare.dev/docs/react) shows boards, a zoomable viewer, an editor and a playground, including boards in a model's reply while it's still streaming in.
72
+ - **Node or the browser:** the [library](#library) itself.
73
+
74
+ **In your editor and notes**
56
75
 
57
76
  - **VS Code** (and Cursor, VSCodium, Windsurf): the [tsquare extension](https://marketplace.visualstudio.com/items?itemName=tsquare-js.tsquare-vscode) gives `.tsq` files a live preview, problems as you type, highlighting and autocomplete. Also on [Open VSX](https://open-vsx.org/extension/tsquare-js/tsquare-vscode).
58
- - **Obsidian**: the [tsquare plugin](https://community.obsidian.md/plugins/tsquare) draws ```` ```tsquare ```` code blocks in your notes, on desktop and mobile. See [the Obsidian page](https://tsquare.dev/docs/obsidian).
77
+ - **Obsidian:** the [tsquare plugin](https://community.obsidian.md/plugins/tsquare) draws ```` ```tsquare ```` code blocks in your notes, on desktop and mobile. See [the Obsidian page](https://tsquare.dev/docs/obsidian).
59
78
 
60
79
  ## The language
61
80
 
@@ -117,10 +136,14 @@ tsquare prompt # system prompt for models
117
136
  tsquare playground [--port 4321] # live editor, component reference, prompt
118
137
  ```
119
138
 
120
- Use `-` to read from stdin. In this repo, run them through npm: `npm run check -- file.tsq`. Files use the `.tsq` extension; the CLI reads any text file.
139
+ Run them with `npx tsquare …` (nothing to install), or install the `tsquare` command with `npm install -g tsquare`. Use `-` to read from stdin. In this repo, run them through npm: `npm run check -- file.tsq`. Files use the `.tsq` extension; the CLI reads any text file.
121
140
 
122
141
  ## Library
123
142
 
143
+ ```bash
144
+ npm install tsquare
145
+ ```
146
+
124
147
  ```ts
125
148
  import { renderWireframe, compileWireframe, formatIssues } from "tsquare";
126
149
 
@@ -128,7 +151,7 @@ const { issues } = compileWireframe(source); // problems by line, empt
128
151
  const png = await renderWireframe(source, { format: "png", scale: 2 });
129
152
  ```
130
153
 
131
- `tsquare/playground` exports the playground's request handler, for hosting it inside your own Node server. `tsquare/viewer` is the playground's zoomable board (zoom, pan, pinch, a chip per screen) for your own page: pass it the elements, then `show()` the SVG from `renderWireframeSvg` with the size and screens from `boardLayout`. It sets the styles its zoom math needs itself; give the stage a size, and optionally style the classes it toggles on the stage: `panning` (while dragging), `animate` (while fitting or zooming to a screen, e.g. `.animate > * { transition: transform .25s }`) and `stale` (from `setStale`, e.g. `.stale img { opacity: .35 }`). Call `destroy()` when you remove it. `languageData()` lists every component, prop, option word, icon and accent, for editor highlighting and autocomplete. In a browser bundle (esbuild, Vite, webpack) the same imports render SVG with no setup; PNG and share links need Node. On a page without a build step, `<script src="https://cdn.jsdelivr.net/npm/tsquare@0.11/dist/tsquare.min.js"></script>` draws every ```` ```tsquare ```` code block on the page (see [Embedding](docs/embedding.md#pages-written-in-markdown)). See [Using it with AI](docs/ai.md) for the prompt and the repair loop.
154
+ `tsquare/playground` exports the playground's request handler, for hosting it inside your own Node server. `tsquare/viewer` is the playground's zoomable board (zoom, pan, pinch, a chip per screen) for your own page: pass it the elements, then `show()` the SVG from `renderWireframeSvg` with the size and screens from `boardLayout`. It sets the styles its zoom math needs itself; give the stage a size, and optionally style the classes it toggles on the stage: `panning` (while dragging), `animate` (while fitting or zooming to a screen, e.g. `.animate > * { transition: transform .25s }`) and `stale` (from `setStale`, e.g. `.stale img { opacity: .35 }`). Call `destroy()` when you remove it. `languageData()` lists every component, prop, option word, icon and accent, for editor highlighting and autocomplete. In a browser bundle (esbuild, Vite, webpack) the same imports render SVG with no setup; PNG and share links need Node. On a page without a build step, `<script src="https://cdn.jsdelivr.net/npm/tsquare@0.12/dist/tsquare.min.js"></script>` draws every ```` ```tsquare ```` code block on the page (see [Embedding](docs/embedding.md#pages-written-in-markdown)). See [Using it with AI](docs/ai.md) for the prompt and the repair loop.
132
155
 
133
156
  ### The editor: `tsquare/editor`
134
157
 
@@ -308,16 +308,16 @@ var require_swap = __commonJS({
308
308
  b[n] = b[m2];
309
309
  b[m2] = i2;
310
310
  };
311
- var swap32 = (array) => {
312
- const len = array.length;
311
+ var swap32 = (array3) => {
312
+ const len = array3.length;
313
313
  for (let i2 = 0; i2 < len; i2 += 4) {
314
- swap(array, i2, i2 + 3);
315
- swap(array, i2 + 1, i2 + 2);
314
+ swap(array3, i2, i2 + 3);
315
+ swap(array3, i2 + 1, i2 + 2);
316
316
  }
317
317
  };
318
- var swap32LE = (array) => {
318
+ var swap32LE = (array3) => {
319
319
  if (isBigEndian) {
320
- swap32(array);
320
+ swap32(array3);
321
321
  }
322
322
  };
323
323
  module.exports = {
@@ -2112,8 +2112,8 @@ var require_escape_html = __commonJS({
2112
2112
  "use strict";
2113
2113
  var matchHtmlRegExp = /["'&<>]/;
2114
2114
  module.exports = escapeHtml;
2115
- function escapeHtml(string) {
2116
- var str = "" + string;
2115
+ function escapeHtml(string3) {
2116
+ var str = "" + string3;
2117
2117
  var match = matchHtmlRegExp.exec(str);
2118
2118
  if (!match) {
2119
2119
  return str;
@@ -3481,8 +3481,8 @@ var $557adaaeb0c7885f$var$LineBreaker = class {
3481
3481
  }
3482
3482
  return null;
3483
3483
  }
3484
- constructor(string) {
3485
- this.string = string;
3484
+ constructor(string3) {
3485
+ this.string = string3;
3486
3486
  this.pos = 0;
3487
3487
  this.lastPos = 0;
3488
3488
  this.curClass = null;
@@ -6053,12 +6053,12 @@ Parser.prototype.parseFixed = function() {
6053
6053
  Parser.prototype.parseString = function(length) {
6054
6054
  var dataView = this.data;
6055
6055
  var offset = this.offset + this.relativeOffset;
6056
- var string = "";
6056
+ var string3 = "";
6057
6057
  this.relativeOffset += length;
6058
6058
  for (var i2 = 0; i2 < length; i2++) {
6059
- string += String.fromCharCode(dataView.getUint8(offset + i2));
6059
+ string3 += String.fromCharCode(dataView.getUint8(offset + i2));
6060
6060
  }
6061
- return string;
6061
+ return string3;
6062
6062
  };
6063
6063
  Parser.prototype.parseTag = function() {
6064
6064
  return this.parseString(4);
@@ -19953,7 +19953,7 @@ async function renderToSvg(spec, options = {}) {
19953
19953
 
19954
19954
  // src/catalog.ts
19955
19955
  import { defineCatalog } from "@json-render/core";
19956
- import { z } from "zod";
19956
+ import * as z from "zod";
19957
19957
 
19958
19958
  // src/layout.ts
19959
19959
  var theme = {
@@ -20823,21 +20823,21 @@ function Screen({ element, children }) {
20823
20823
  children: [
20824
20824
  s.chrome && s.device === "phone" ? /* @__PURE__ */ jsx3(StatusBar, {}) : null,
20825
20825
  s.chrome && s.device === "desktop" ? /* @__PURE__ */ jsx3(BrowserBar, {}) : null,
20826
- /* @__PURE__ */ jsxs(Box, { style: { position: "relative", flexGrow: 1, flexDirection: "column", overflow: "hidden" }, children: [
20826
+ /* @__PURE__ */ jsxs(Box, { style: { position: "relative", flexGrow: 1, flexBasis: "0px", flexDirection: "column", overflow: "hidden" }, children: [
20827
20827
  top,
20828
- /* @__PURE__ */ jsx3(
20828
+ /* @__PURE__ */ jsx3(Box, { style: { flexGrow: 1, flexBasis: "0px", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ jsx3(
20829
20829
  Box,
20830
20830
  {
20831
20831
  style: {
20832
20832
  flexGrow: 1,
20833
+ flexShrink: 0,
20833
20834
  flexDirection: "column",
20834
20835
  padding: s.padding,
20835
- gap: p.gap ?? 14,
20836
- overflow: "hidden"
20836
+ gap: p.gap ?? 14
20837
20837
  },
20838
20838
  children: withDir(body, "column")
20839
20839
  }
20840
- ),
20840
+ ) }),
20841
20841
  bottom,
20842
20842
  overlays.map((o2) => isValidElement(o2) ? cloneElement(o2, { aboveTabBar: bottom.length > 0 }) : o2),
20843
20843
  p.__mark ? /* @__PURE__ */ jsx3(Marker, { color: p.__mark }) : null
@@ -23264,7 +23264,7 @@ function decodeWireframe(data) {
23264
23264
  }
23265
23265
 
23266
23266
  // src/mcp.ts
23267
- import { z as z2 } from "zod";
23267
+ import * as z2 from "zod";
23268
23268
 
23269
23269
  // src/escape.ts
23270
23270
  var escapeAttr = (s) => s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/[\r\n]+/g, " ");
package/dist/catalog.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import * as z from "zod";
2
2
  /**
3
3
  * Props every element except Board and Screen accepts, on top of its own. Kept out of each
4
4
  * component's schema so the prompt describes them once.
@@ -6,7 +6,7 @@ import {
6
6
  componentDefinitions,
7
7
  iconNames,
8
8
  takesUniversalProps
9
- } from "./chunk-EY7YIRMK.js";
9
+ } from "./chunk-H4Y6VBEX.js";
10
10
 
11
11
  // src/playground/language-data.ts
12
12
  function unwrap(t) {
@@ -51,7 +51,7 @@ function estimateNoteHeight(text, width) {
51
51
 
52
52
  // src/catalog.ts
53
53
  import { defineCatalog } from "@json-render/core";
54
- import { z } from "zod";
54
+ import * as z from "zod";
55
55
 
56
56
  // src/suggest.ts
57
57
  function editDistance(a, b) {
@@ -870,21 +870,21 @@ function Screen({ element, children }) {
870
870
  children: [
871
871
  s.chrome && s.device === "phone" ? /* @__PURE__ */ jsx(StatusBar, {}) : null,
872
872
  s.chrome && s.device === "desktop" ? /* @__PURE__ */ jsx(BrowserBar, {}) : null,
873
- /* @__PURE__ */ jsxs(Box, { style: { position: "relative", flexGrow: 1, flexDirection: "column", overflow: "hidden" }, children: [
873
+ /* @__PURE__ */ jsxs(Box, { style: { position: "relative", flexGrow: 1, flexBasis: "0px", flexDirection: "column", overflow: "hidden" }, children: [
874
874
  top,
875
- /* @__PURE__ */ jsx(
875
+ /* @__PURE__ */ jsx(Box, { style: { flexGrow: 1, flexBasis: "0px", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ jsx(
876
876
  Box,
877
877
  {
878
878
  style: {
879
879
  flexGrow: 1,
880
+ flexShrink: 0,
880
881
  flexDirection: "column",
881
882
  padding: s.padding,
882
- gap: p.gap ?? 14,
883
- overflow: "hidden"
883
+ gap: p.gap ?? 14
884
884
  },
885
885
  children: withDir(body, "column")
886
886
  }
887
- ),
887
+ ) }),
888
888
  bottom,
889
889
  overlays.map((o2) => isValidElement(o2) ? cloneElement(o2, { aboveTabBar: bottom.length > 0 }) : o2),
890
890
  p.__mark ? /* @__PURE__ */ jsx(Marker, { color: p.__mark }) : null
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  printWireframeText,
7
7
  renderWireframe,
8
8
  wireframePrompt
9
- } from "./chunks/chunk-EY7YIRMK.js";
9
+ } from "./chunks/chunk-H4Y6VBEX.js";
10
10
 
11
11
  // src/cli.ts
12
12
  import { readFile, writeFile } from "node:fs/promises";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  languageData
3
- } from "./chunks/chunk-QWQT7224.js";
3
+ } from "./chunks/chunk-2FU5Z5ON.js";
4
4
  import {
5
5
  DEVICES,
6
6
  RENAMED_PROPS,
@@ -24,7 +24,7 @@ import {
24
24
  upgradeSpec,
25
25
  upgradeWireframe,
26
26
  wireframePrompt
27
- } from "./chunks/chunk-EY7YIRMK.js";
27
+ } from "./chunks/chunk-H4Y6VBEX.js";
28
28
 
29
29
  // src/deflate.ts
30
30
  import { deflateRawSync, inflateRawSync } from "node:zlib";
@@ -49,7 +49,7 @@ function decodeWireframe(data) {
49
49
  }
50
50
 
51
51
  // src/mcp.ts
52
- import { z } from "zod";
52
+ import * as z from "zod";
53
53
 
54
54
  // src/escape.ts
55
55
  var escapeAttr = (s) => s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/[\r\n]+/g, " ");
package/dist/mcp.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * Problems come back as a result with isError, not a thrown error, so the model reads them and fixes
7
7
  * its text: the messages are the same line-numbered ones `tsquare check` prints.
8
8
  */
9
- import { z } from "zod";
9
+ import * as z from "zod";
10
10
  export type ToolContent = {
11
11
  type: "text";
12
12
  text: string;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  languageData
3
- } from "../chunks/chunk-QWQT7224.js";
3
+ } from "../chunks/chunk-2FU5Z5ON.js";
4
4
  import {
5
5
  boardLayout,
6
6
  compileWireframe,
@@ -9,7 +9,7 @@ import {
9
9
  renderWireframePng,
10
10
  renderWireframeSvg,
11
11
  wireframePrompt
12
- } from "../chunks/chunk-EY7YIRMK.js";
12
+ } from "../chunks/chunk-H4Y6VBEX.js";
13
13
 
14
14
  // src/playground/index.ts
15
15
  import { createServer } from "node:http";