truecanvas 0.1.0 → 0.3.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.
- package/README.md +54 -181
- package/dist/catalog-worker.js +1 -1
- package/dist/chunk-C4SATRZT.js +196 -0
- package/dist/chunk-PBKX3SBC.js +97 -0
- package/dist/chunk-TSHD2S36.js +28 -0
- package/dist/{chunk-753N4QRO.js → chunk-WU7NBTJH.js} +39 -20
- package/dist/{chunk-WB35FXGP.js → chunk-XWQ5MS24.js} +1071 -489
- package/dist/cli.js +676 -429
- package/dist/core/index.d.ts +179 -11
- package/dist/core/index.js +40 -25
- package/dist/editor/assets/Menu-BFifVcgz.js +9 -0
- package/dist/editor/assets/Menu-DXPm0EXo.css +1 -0
- package/dist/editor/assets/hub-UhU8yp5F.js +2 -0
- package/dist/editor/assets/main-UtSaCfnK.js +26 -0
- package/dist/editor/hub.html +3 -3
- package/dist/editor/index.html +3 -3
- package/dist/icons-worker.js +7 -0
- package/dist/next/index.d.ts +6 -1
- package/dist/next/index.js +16 -3
- package/dist/runtime/host.js +3 -1
- package/dist/vite/index.d.ts +33 -0
- package/dist/vite/index.js +81 -0
- package/package.json +15 -6
- package/dist/editor/assets/controls-BQYSgX53.css +0 -1
- package/dist/editor/assets/controls-BYFjuGCq.js +0 -9
- package/dist/editor/assets/hub-C4_700Hv.js +0 -2
- package/dist/editor/assets/main-CfAJbDf1.js +0 -25
package/dist/core/index.d.ts
CHANGED
|
@@ -85,6 +85,11 @@ interface ImportInfo {
|
|
|
85
85
|
source: string;
|
|
86
86
|
typeOnly: boolean;
|
|
87
87
|
names: string[];
|
|
88
|
+
/** named value imports, `{ Search as SearchIcon }` → { imported: "Search", local: "SearchIcon" } */
|
|
89
|
+
bindings: {
|
|
90
|
+
imported: string;
|
|
91
|
+
local: string;
|
|
92
|
+
}[];
|
|
88
93
|
defaultName: string | null;
|
|
89
94
|
start: number;
|
|
90
95
|
end: number;
|
|
@@ -92,6 +97,8 @@ interface ImportInfo {
|
|
|
92
97
|
lastSpecifierEnd: number | null;
|
|
93
98
|
}
|
|
94
99
|
interface CanvasDoc {
|
|
100
|
+
/** increases every time a doc is computed: lets clients drop a stale one that arrives late */
|
|
101
|
+
rev?: number;
|
|
95
102
|
name: string;
|
|
96
103
|
file: string;
|
|
97
104
|
frames: CanvasFrame[];
|
|
@@ -188,7 +195,11 @@ declare class CanvasEditor {
|
|
|
188
195
|
contentStart(n: CanvasNode): number;
|
|
189
196
|
contentEnd(n: CanvasNode): number;
|
|
190
197
|
childIndent(parent: CanvasNode): string;
|
|
191
|
-
/**
|
|
198
|
+
/**
|
|
199
|
+
* Re-indents lines 2..n of a snippet so it sits at `indent`. Lines that start
|
|
200
|
+
* inside a multi-line string or template literal are content, not code: they
|
|
201
|
+
* are kept exactly as written.
|
|
202
|
+
*/
|
|
192
203
|
shift(code: string, indent: string): string;
|
|
193
204
|
private openToClose;
|
|
194
205
|
private insertAt;
|
|
@@ -205,6 +216,14 @@ declare class CanvasEditor {
|
|
|
205
216
|
replace(node: CanvasNode, jsx: string): void;
|
|
206
217
|
private added;
|
|
207
218
|
ensureImport(name: string, from: string): void;
|
|
219
|
+
/**
|
|
220
|
+
* Imports `name` from `from` and returns the local name to write in JSX. When
|
|
221
|
+
* the name is already taken by something else (another import, a local
|
|
222
|
+
* component), it is imported under `alias` instead: `{ Search as SearchIcon }`.
|
|
223
|
+
*/
|
|
224
|
+
importAs(name: string, from: string, alias: string): string;
|
|
225
|
+
private importedAs;
|
|
226
|
+
private addImportLine;
|
|
208
227
|
/** Adds a whole import statement unless every name it binds is already imported. */
|
|
209
228
|
addImportStatement(statement: string): void;
|
|
210
229
|
private importsPrepended;
|
|
@@ -233,16 +252,23 @@ interface DarkMode {
|
|
|
233
252
|
/** Value written for light mode with the attribute strategy. */
|
|
234
253
|
lightValue?: string;
|
|
235
254
|
}
|
|
255
|
+
type Framework = "next" | "vite";
|
|
236
256
|
interface TruecanvasConfig {
|
|
237
257
|
root: string;
|
|
238
|
-
/**
|
|
258
|
+
/** The app's framework: Next.js (App Router) or Vite + React. Detected from package.json. */
|
|
259
|
+
framework: Framework;
|
|
260
|
+
/** Where your app's dev server runs. */
|
|
239
261
|
appUrl: string;
|
|
240
262
|
/** Port of the Truecanvas editor + MCP server. */
|
|
241
263
|
port: number;
|
|
242
264
|
/** Folder holding *.canvas.tsx files. */
|
|
243
265
|
canvasDir: string;
|
|
244
|
-
/** Next.js app directory ("app" or "src/app"). */
|
|
266
|
+
/** Next.js app directory ("app" or "src/app"); for Vite, the source folder. */
|
|
245
267
|
appDir: string;
|
|
268
|
+
/** Generated, dev-only render route (project-relative, gitignored). */
|
|
269
|
+
routeDir: string;
|
|
270
|
+
/** Vite: stylesheets every frame loads (default: the ones your entry module imports). */
|
|
271
|
+
css?: string[];
|
|
246
272
|
/** Globs of component files shown in the Components panel. */
|
|
247
273
|
components: string[];
|
|
248
274
|
darkMode: DarkMode;
|
|
@@ -332,7 +358,7 @@ declare class Comments {
|
|
|
332
358
|
|
|
333
359
|
interface GitFile {
|
|
334
360
|
path: string;
|
|
335
|
-
status: "modified" | "added" | "deleted" | "renamed" | "untracked";
|
|
361
|
+
status: "modified" | "added" | "deleted" | "renamed" | "untracked" | "conflicted";
|
|
336
362
|
staged: boolean;
|
|
337
363
|
}
|
|
338
364
|
interface GitStatus {
|
|
@@ -410,6 +436,12 @@ declare class Git {
|
|
|
410
436
|
publish(name: string, isPrivate: boolean): Promise<string>;
|
|
411
437
|
/** git reports paths from the repo root; we show them from the project root. */
|
|
412
438
|
private rel;
|
|
439
|
+
/**
|
|
440
|
+
* The project folder inside the repo ("apps/web/", or "" at the root), as git
|
|
441
|
+
* itself sees it. Asking git instead of comparing file system paths holds up
|
|
442
|
+
* through symlinks (macOS /var → /private/var), junctions and Windows short names.
|
|
443
|
+
*/
|
|
444
|
+
private prefix;
|
|
413
445
|
branches(): Promise<{
|
|
414
446
|
current: string | null;
|
|
415
447
|
local: string[];
|
|
@@ -463,6 +495,14 @@ type Command = {
|
|
|
463
495
|
component: string;
|
|
464
496
|
props?: Record<string, Literal>;
|
|
465
497
|
text?: string;
|
|
498
|
+
} | {
|
|
499
|
+
op: "insert_icon";
|
|
500
|
+
canvas: string;
|
|
501
|
+
parent: string;
|
|
502
|
+
index?: number;
|
|
503
|
+
library: string;
|
|
504
|
+
name: string;
|
|
505
|
+
className?: string;
|
|
466
506
|
} | {
|
|
467
507
|
op: "replace";
|
|
468
508
|
canvas: string;
|
|
@@ -665,7 +705,8 @@ declare class Workspace {
|
|
|
665
705
|
private sources;
|
|
666
706
|
private undoStacks;
|
|
667
707
|
private redoStacks;
|
|
668
|
-
|
|
708
|
+
/** Activity across canvases: labels only, never file copies. */
|
|
709
|
+
readonly feed: PublicEntry[];
|
|
669
710
|
private seq;
|
|
670
711
|
private queue;
|
|
671
712
|
private listeners;
|
|
@@ -684,8 +725,16 @@ declare class Workspace {
|
|
|
684
725
|
relFile(canvas: string): string;
|
|
685
726
|
read(canvas: string): string;
|
|
686
727
|
doc(canvas: string): CanvasDoc;
|
|
687
|
-
/**
|
|
728
|
+
/**
|
|
729
|
+
* A canvas doc with linked frames resolved to their page's layers. Resolving
|
|
730
|
+
* reads and parses every linked page and layout, so the result is reused
|
|
731
|
+
* until the canvas source or one of those files changes (checked with stat).
|
|
732
|
+
*/
|
|
688
733
|
docFrom(canvas: string, source: string): CanvasDoc;
|
|
734
|
+
/** a doc computed later reflects the files at least as recently: its rev is higher */
|
|
735
|
+
private revision;
|
|
736
|
+
private docCache;
|
|
737
|
+
private stamp;
|
|
689
738
|
/** Where a node's code lives: the canvas, or a linked page/layout file. */
|
|
690
739
|
nodeSource(canvas: string, id: string): {
|
|
691
740
|
node: CanvasNode;
|
|
@@ -735,11 +784,19 @@ declare class Workspace {
|
|
|
735
784
|
private routeLinked;
|
|
736
785
|
/** The page/layout file the command's layers live in, or null for the canvas. */
|
|
737
786
|
private targetOf;
|
|
787
|
+
/** Applies a command to the file being edited and returns its history label. */
|
|
738
788
|
private apply;
|
|
789
|
+
/** Edits to layers: props, text, classes, inserting, moving, wrapping. */
|
|
790
|
+
private applyLayerEdit;
|
|
791
|
+
/** Frames: creating, updating, backgrounds, presets, variant grids, main component frames. */
|
|
792
|
+
private applyFrameEdit;
|
|
793
|
+
/** Linked pages: adding a page, exploring a copy, applying it back. */
|
|
794
|
+
private applyPageEdit;
|
|
795
|
+
/** Scroll reveals and text animations. */
|
|
796
|
+
private applyMotionEdit;
|
|
797
|
+
/** New components, from scratch or from selected layers. */
|
|
798
|
+
private applyComponentEdit;
|
|
739
799
|
private autoImport;
|
|
740
|
-
private motion;
|
|
741
|
-
/** work resolved (async) in exec before the synchronous apply */
|
|
742
|
-
private pending;
|
|
743
800
|
private cleanCache;
|
|
744
801
|
isPrettierClean(source: string, file: string): Promise<boolean>;
|
|
745
802
|
/** Pretty-prints an agent's JSX snippet so it lands in the file readable. */
|
|
@@ -747,6 +804,12 @@ declare class Workspace {
|
|
|
747
804
|
private prettier;
|
|
748
805
|
format(source: string, file: string): Promise<string>;
|
|
749
806
|
private record;
|
|
807
|
+
/**
|
|
808
|
+
* Undo entries hold whole files (before and after). Keep their total under a
|
|
809
|
+
* budget by dropping the oldest entries across canvases, so long sessions on
|
|
810
|
+
* big pages don't grow without limit.
|
|
811
|
+
*/
|
|
812
|
+
private trimHistory;
|
|
750
813
|
/** Changes still in effect (not undone) on a canvas since a time, oldest first. */
|
|
751
814
|
changesSince(canvas: string, since: number): PublicEntry[];
|
|
752
815
|
historyState(canvas: string): {
|
|
@@ -809,7 +872,7 @@ declare const DEVICES: Device[];
|
|
|
809
872
|
declare function findDevice(id: string | null | undefined): Device | undefined;
|
|
810
873
|
|
|
811
874
|
/**
|
|
812
|
-
* Writes an older version of a canvas next to the generated route so
|
|
875
|
+
* Writes an older version of a canvas next to the generated route so the app can
|
|
813
876
|
* render it like any canvas ("__compare__<name>"). Relative imports are
|
|
814
877
|
* rewritten for the new location; alias imports (@/…) work unchanged.
|
|
815
878
|
*/
|
|
@@ -817,4 +880,109 @@ declare function writeCompare(config: TruecanvasConfig, canvas: string, source:
|
|
|
817
880
|
/** Per frame: same, changed, added (only now) or removed (only before). */
|
|
818
881
|
declare function frameChanges(before: string, after: string): Record<string, "changed" | "added" | "removed" | "same">;
|
|
819
882
|
|
|
820
|
-
|
|
883
|
+
interface IconLibrary {
|
|
884
|
+
id: string;
|
|
885
|
+
label: string;
|
|
886
|
+
/** npm package to install */
|
|
887
|
+
package: string;
|
|
888
|
+
/** module the icons are imported from */
|
|
889
|
+
from: string;
|
|
890
|
+
homepage: string;
|
|
891
|
+
/** keeps one name per icon: drops aliases and non-icon exports */
|
|
892
|
+
pick: (name: string, all: Set<string>) => boolean;
|
|
893
|
+
}
|
|
894
|
+
declare const ICON_LIBRARIES: IconLibrary[];
|
|
895
|
+
declare function iconLibrary(id: string): IconLibrary | undefined;
|
|
896
|
+
interface Icon {
|
|
897
|
+
name: string;
|
|
898
|
+
svg: string;
|
|
899
|
+
}
|
|
900
|
+
/** Every icon of an installed library, from the disk cache or rendered once. */
|
|
901
|
+
declare function loadIcons(root: string, id: string): Promise<Icon[]>;
|
|
902
|
+
/**
|
|
903
|
+
* Ranks icons for a query: exact name, prefix, a near-typo of the whole name,
|
|
904
|
+
* substring; letters-in-order matches only fill in when there are few direct
|
|
905
|
+
* matches, tightest first.
|
|
906
|
+
*/
|
|
907
|
+
declare function searchIcons(icons: Icon[], query: string, limit?: number): {
|
|
908
|
+
total: number;
|
|
909
|
+
icons: Icon[];
|
|
910
|
+
};
|
|
911
|
+
/** Which icon libraries are installed, for the picker and agents. */
|
|
912
|
+
declare function iconLibraries(root: string): {
|
|
913
|
+
id: string;
|
|
914
|
+
label: string;
|
|
915
|
+
package: string;
|
|
916
|
+
from: string;
|
|
917
|
+
homepage: string;
|
|
918
|
+
version: string | null;
|
|
919
|
+
}[];
|
|
920
|
+
|
|
921
|
+
interface ShadcnStatus {
|
|
922
|
+
/** components.json exists */
|
|
923
|
+
initialized: boolean;
|
|
924
|
+
/** where components land, relative to the project */
|
|
925
|
+
uiDir: string | null;
|
|
926
|
+
/** components already in the project */
|
|
927
|
+
installed: string[];
|
|
928
|
+
}
|
|
929
|
+
declare function shadcnStatus(root: string): ShadcnStatus;
|
|
930
|
+
/** Component names from the official registry, cached for an hour. */
|
|
931
|
+
declare function shadcnRegistry(): Promise<{
|
|
932
|
+
names: string[];
|
|
933
|
+
offline: boolean;
|
|
934
|
+
}>;
|
|
935
|
+
/** `shadcn init` with the defaults (writes components.json, lib/utils, theme CSS). */
|
|
936
|
+
declare function shadcnInit(root: string): Promise<{
|
|
937
|
+
ok: boolean;
|
|
938
|
+
out: string;
|
|
939
|
+
}>;
|
|
940
|
+
/** `shadcn add <names>`; initializes the project first when needed. */
|
|
941
|
+
declare function shadcnAdd(root: string, names: string[]): Promise<{
|
|
942
|
+
ok: boolean;
|
|
943
|
+
out: string;
|
|
944
|
+
added: string[];
|
|
945
|
+
}>;
|
|
946
|
+
|
|
947
|
+
interface InitReport {
|
|
948
|
+
done: string[];
|
|
949
|
+
todo: string[];
|
|
950
|
+
}
|
|
951
|
+
/** Does the app's next.config / vite.config already enable Truecanvas? */
|
|
952
|
+
declare function configStatus(root: string, framework?: Framework): {
|
|
953
|
+
file: string | null;
|
|
954
|
+
wrapped: boolean;
|
|
955
|
+
framework: Framework;
|
|
956
|
+
};
|
|
957
|
+
/**
|
|
958
|
+
* Sets up a Next.js or Vite project: enables the plugin in its config, adds a
|
|
959
|
+
* `canvas` script and ignores the generated route. Every step is idempotent
|
|
960
|
+
* and reported.
|
|
961
|
+
*/
|
|
962
|
+
declare function initProject(config: TruecanvasConfig): InitReport;
|
|
963
|
+
/**
|
|
964
|
+
* Wraps a next.config's export in withTruecanvas(), touching only the exported
|
|
965
|
+
* expression: comments and code after it stay as they are. Null when the
|
|
966
|
+
* export can't be found (the user is told to wrap it by hand).
|
|
967
|
+
*/
|
|
968
|
+
declare function wrapConfigExport(src: string): string | null;
|
|
969
|
+
/**
|
|
970
|
+
* Adds `truecanvas()` to a vite.config's plugins array, touching nothing
|
|
971
|
+
* else. Null when there's no plugins array to add it to.
|
|
972
|
+
*/
|
|
973
|
+
declare function addVitePlugin(src: string): string | null;
|
|
974
|
+
|
|
975
|
+
/**
|
|
976
|
+
* Generates the dev-only render route `/truecanvas/[canvas]` (Next: an App
|
|
977
|
+
* Router page; Vite: an entry module the plugin serves) and a registry that
|
|
978
|
+
* lazily imports each canvas. Idempotent.
|
|
979
|
+
*/
|
|
980
|
+
declare function syncRoute(config: TruecanvasConfig): boolean;
|
|
981
|
+
/**
|
|
982
|
+
* Stylesheets a Vite app loads globally: the ones its entry module (the
|
|
983
|
+
* script in index.html) imports. Root-relative ("/src/index.css"), or the
|
|
984
|
+
* package path for a package's stylesheet.
|
|
985
|
+
*/
|
|
986
|
+
declare function viteStylesheets(root: string): string[];
|
|
987
|
+
|
|
988
|
+
export { type Actor, type AttrRange, type CanvasDoc, CanvasEditor, type CanvasFrame, type CanvasNode, Catalog, type Command, Comments, type ComponentSpec, DEVICES, type DarkMode, type Device, EditError, type FrameLink, Git, type HistoryEntry, ICON_LIBRARIES, type Icon, type IconLibrary, type ImportInfo, type NodeKind, type Preset, type PropSpec, type PropValue, type ShadcnStatus, type TruecanvasConfig, Workspace, type WorkspaceEvent, addVitePlugin, allNodes, attrCode, componentJsx, configStatus, describeComponent, findDevice, findFrame, findNode, frameChanges, iconLibraries, iconLibrary, initProject, injectIds, loadConfig, loadIcons, outlineDoc, parseCanvas, readDesignTokens, searchIcons, shadcnAdd, shadcnInit, shadcnRegistry, shadcnStatus, syncRoute, textCode, viteStylesheets, wrapConfigExport, writeCompare };
|
package/dist/core/index.js
CHANGED
|
@@ -5,46 +5,46 @@ import {
|
|
|
5
5
|
EditError,
|
|
6
6
|
Git,
|
|
7
7
|
Workspace,
|
|
8
|
+
addVitePlugin,
|
|
8
9
|
allNodes,
|
|
9
10
|
attrCode,
|
|
10
11
|
componentJsx,
|
|
12
|
+
configStatus,
|
|
11
13
|
describeComponent,
|
|
12
14
|
findDevice,
|
|
13
15
|
findFrame,
|
|
14
16
|
findNode,
|
|
15
17
|
frameChanges,
|
|
16
|
-
|
|
17
|
-
loadConfig,
|
|
18
|
+
initProject,
|
|
18
19
|
outlineDoc,
|
|
19
20
|
parseCanvas,
|
|
20
|
-
parseModule,
|
|
21
21
|
readDesignTokens,
|
|
22
|
+
shadcnAdd,
|
|
23
|
+
shadcnInit,
|
|
24
|
+
shadcnRegistry,
|
|
25
|
+
shadcnStatus,
|
|
26
|
+
syncRoute,
|
|
22
27
|
textCode,
|
|
23
|
-
|
|
28
|
+
viteStylesheets,
|
|
29
|
+
wrapConfigExport,
|
|
24
30
|
writeCompare
|
|
25
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-XWQ5MS24.js";
|
|
32
|
+
import {
|
|
33
|
+
injectIds
|
|
34
|
+
} from "../chunk-TSHD2S36.js";
|
|
35
|
+
import {
|
|
36
|
+
loadConfig
|
|
37
|
+
} from "../chunk-PBKX3SBC.js";
|
|
26
38
|
import {
|
|
27
39
|
Catalog
|
|
28
|
-
} from "../chunk-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} catch {
|
|
37
|
-
return source;
|
|
38
|
-
}
|
|
39
|
-
const s = new MagicString(source);
|
|
40
|
-
walk(ast, (node) => {
|
|
41
|
-
if (node.type !== "JSXOpeningElement") return;
|
|
42
|
-
if (node.attributes.some((a) => a.type === "JSXAttribute" && a.name.name === "data-tc")) return;
|
|
43
|
-
const id = file ? `${file}#${idOf(node)}` : idOf(node);
|
|
44
|
-
s.appendLeft((node.typeParameters ?? node.name).end, ` data-tc="${id}"`);
|
|
45
|
-
});
|
|
46
|
-
return s.toString();
|
|
47
|
-
}
|
|
40
|
+
} from "../chunk-WU7NBTJH.js";
|
|
41
|
+
import {
|
|
42
|
+
ICON_LIBRARIES,
|
|
43
|
+
iconLibraries,
|
|
44
|
+
iconLibrary,
|
|
45
|
+
loadIcons,
|
|
46
|
+
searchIcons
|
|
47
|
+
} from "../chunk-C4SATRZT.js";
|
|
48
48
|
export {
|
|
49
49
|
CanvasEditor,
|
|
50
50
|
Catalog,
|
|
@@ -52,20 +52,35 @@ export {
|
|
|
52
52
|
DEVICES,
|
|
53
53
|
EditError,
|
|
54
54
|
Git,
|
|
55
|
+
ICON_LIBRARIES,
|
|
55
56
|
Workspace,
|
|
57
|
+
addVitePlugin,
|
|
56
58
|
allNodes,
|
|
57
59
|
attrCode,
|
|
58
60
|
componentJsx,
|
|
61
|
+
configStatus,
|
|
59
62
|
describeComponent,
|
|
60
63
|
findDevice,
|
|
61
64
|
findFrame,
|
|
62
65
|
findNode,
|
|
63
66
|
frameChanges,
|
|
67
|
+
iconLibraries,
|
|
68
|
+
iconLibrary,
|
|
69
|
+
initProject,
|
|
64
70
|
injectIds,
|
|
65
71
|
loadConfig,
|
|
72
|
+
loadIcons,
|
|
66
73
|
outlineDoc,
|
|
67
74
|
parseCanvas,
|
|
68
75
|
readDesignTokens,
|
|
76
|
+
searchIcons,
|
|
77
|
+
shadcnAdd,
|
|
78
|
+
shadcnInit,
|
|
79
|
+
shadcnRegistry,
|
|
80
|
+
shadcnStatus,
|
|
81
|
+
syncRoute,
|
|
69
82
|
textCode,
|
|
83
|
+
viteStylesheets,
|
|
84
|
+
wrapConfigExport,
|
|
70
85
|
writeCompare
|
|
71
86
|
};
|