tutuca 0.9.98 → 0.9.99
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 +5 -3
- package/dist/tutuca-cli.js +19 -11
- package/dist/tutuca-components.js +2444 -0
- package/dist/tutuca-dev.ext.js +16 -16
- package/dist/tutuca-dev.js +16 -16
- package/dist/tutuca-dev.min.js +2 -2
- package/dist/tutuca-storybook.js +125 -6
- package/package.json +3 -1
- package/skill/tutuca/cli.md +10 -68
- package/skill/tutuca/core.md +25 -74
- package/skill/tutuca/semantics.md +4 -3
- package/skill/tutuca/testing.md +3 -6
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Zero-dependency batteries included SPA framework.
|
|
|
7
7
|
- **Fits in your head** (and the context window)
|
|
8
8
|
- **View source friendly** — step through the whole stack
|
|
9
9
|
- **As much HTML as possible, as little JS as needed**
|
|
10
|
-
- ~
|
|
10
|
+
- ~182KB minified, ~41KB brotli compressed
|
|
11
11
|
|
|
12
12
|
## Quick Start
|
|
13
13
|
|
|
@@ -95,6 +95,7 @@ tutuca help [command]
|
|
|
95
95
|
| `lint <module> [name]` | Run lint checks — all, or one by name (exit 2 on errors) |
|
|
96
96
|
| `render <module> [name] [--title t] [--view v]` | Render examples to HTML |
|
|
97
97
|
| `test <module> [name] [--grep p] [--bail]` | Run `getTests()` (exit 4 on failures) |
|
|
98
|
+
| `storybook [dir]` | Serve a live storybook, auto-discovering co-located `*.dev.js` modules (`--port`, `--out`, `--dry-run`, `--no-margaui`, `--no-check`, `--no-tests`; no module path needed) |
|
|
98
99
|
| `feedback [message]` | Append a feedback note (positional or stdin) to `~/.tutuca/feedback.jsonl` (no module path needed) |
|
|
99
100
|
| `install-skill [--user\|--project] [--margaui-skill\|--immutable-skill\|--all] [--dot-agents] [--dry-run] [--force]` | Install bundled Claude Code skills (no module path needed) |
|
|
100
101
|
| `agent-context` | Print a versioned JSON schema of the entire CLI surface (no module path needed) |
|
|
@@ -146,8 +147,9 @@ The invocation stays short even without wrapping, but common patterns:
|
|
|
146
147
|
|
|
147
148
|
## Use with Claude Code
|
|
148
149
|
|
|
149
|
-
Tutuca ships an LLM-facing reference (`SKILL.md`
|
|
150
|
-
`
|
|
150
|
+
Tutuca ships an LLM-facing reference (`SKILL.md` plus topic files such as
|
|
151
|
+
`core.md`, `cli.md`, `advanced.md`, `testing.md`, `storybook.md`, and more)
|
|
152
|
+
packaged as a [Claude Code skill](https://docs.claude.com/en/docs/claude-code/skills).
|
|
151
153
|
Once installed, Claude auto-loads it whenever a session touches tutuca
|
|
152
154
|
components, views, macros, or the CLI.
|
|
153
155
|
|
package/dist/tutuca-cli.js
CHANGED
|
@@ -11394,7 +11394,7 @@ var init_html_tokenizer = __esm(() => {
|
|
|
11394
11394
|
});
|
|
11395
11395
|
|
|
11396
11396
|
// tools/core/htmllinter-tables.js
|
|
11397
|
-
var VOID_ELEMENTS, RAW_TEXT_ELEMENTS,
|
|
11397
|
+
var VOID_ELEMENTS, RAW_TEXT_ELEMENTS, SPECIAL_ELEMENTS, FORMATTING_ELEMENTS, DEFAULT_SCOPE_BOUNDARIES, MATHML_TEXT_INTEGRATION_POINT_NAMES, SVG_HTML_INTEGRATION_POINT_NAMES, SCOPE_LIST_ITEM, SCOPE_BUTTON, SCOPE_DEFAULT, SCOPE_TABLE, STANDARD_SVG_CAMEL_ELEMENTS, STANDARD_SVG_CAMEL_ATTRS, MATHML_CAMEL_ATTRS, SVG_ATTR_LOWERCASE_TO_CAMEL, MATHML_ATTR_LOWERCASE_TO_CAMEL, FOREIGN_BREAKOUT_TAGS, BLOCK_LEVEL_AUTO_CLOSE_P, SELECT_BREAKOUT_TAGS, MODES, NS, FRAGMENT_CONTEXT_MODES;
|
|
11398
11398
|
var init_htmllinter_tables = __esm(() => {
|
|
11399
11399
|
VOID_ELEMENTS = new Set([
|
|
11400
11400
|
"area",
|
|
@@ -11421,7 +11421,6 @@ var init_htmllinter_tables = __esm(() => {
|
|
|
11421
11421
|
"xmp",
|
|
11422
11422
|
"plaintext"
|
|
11423
11423
|
]);
|
|
11424
|
-
RCDATA_ELEMENTS = new Set(["textarea", "title"]);
|
|
11425
11424
|
SPECIAL_ELEMENTS = new Set([
|
|
11426
11425
|
"address",
|
|
11427
11426
|
"applet",
|
|
@@ -11536,7 +11535,6 @@ var init_htmllinter_tables = __esm(() => {
|
|
|
11536
11535
|
SCOPE_BUTTON = new Set([...DEFAULT_SCOPE_BOUNDARIES, "button"]);
|
|
11537
11536
|
SCOPE_DEFAULT = DEFAULT_SCOPE_BOUNDARIES;
|
|
11538
11537
|
SCOPE_TABLE = new Set(["html", "table", "template"]);
|
|
11539
|
-
SCOPE_SELECT = new Set;
|
|
11540
11538
|
STANDARD_SVG_CAMEL_ELEMENTS = new Set([
|
|
11541
11539
|
"altGlyph",
|
|
11542
11540
|
"altGlyphDef",
|
|
@@ -11688,7 +11686,6 @@ var init_htmllinter_tables = __esm(() => {
|
|
|
11688
11686
|
"ul",
|
|
11689
11687
|
"var"
|
|
11690
11688
|
]);
|
|
11691
|
-
MATHML_TEXT_INTEGRATION_POINTS = new Set(["mi", "mo", "mn", "ms", "mtext"]);
|
|
11692
11689
|
BLOCK_LEVEL_AUTO_CLOSE_P = new Set([
|
|
11693
11690
|
"address",
|
|
11694
11691
|
"article",
|
|
@@ -11731,7 +11728,6 @@ var init_htmllinter_tables = __esm(() => {
|
|
|
11731
11728
|
"dd",
|
|
11732
11729
|
"dt"
|
|
11733
11730
|
]);
|
|
11734
|
-
SELECT_VALID_CHILDREN = new Set(["option", "optgroup", "hr", "script", "template"]);
|
|
11735
11731
|
SELECT_BREAKOUT_TAGS = new Set(["input", "keygen", "textarea", "select"]);
|
|
11736
11732
|
MODES = Object.freeze({
|
|
11737
11733
|
inBody: "inBody",
|
|
@@ -16115,7 +16111,8 @@ function buildImports(base, { margaui }) {
|
|
|
16115
16111
|
tutuca: dev,
|
|
16116
16112
|
"tutuca/extra": dev,
|
|
16117
16113
|
"tutuca/dev": dev,
|
|
16118
|
-
"tutuca/storybook": `${base}/tutuca-storybook.js
|
|
16114
|
+
"tutuca/storybook": `${base}/tutuca-storybook.js`,
|
|
16115
|
+
"tutuca/components": `${base}/tutuca-components.js`
|
|
16119
16116
|
};
|
|
16120
16117
|
if (margaui)
|
|
16121
16118
|
imports.margaui = MARGAUI_CDN;
|
|
@@ -16141,19 +16138,27 @@ ${JSON.stringify({ imports }, null, 6)}
|
|
|
16141
16138
|
</html>
|
|
16142
16139
|
`;
|
|
16143
16140
|
}
|
|
16144
|
-
function renderBootstrap(devModuleUrls, { margaui, check }) {
|
|
16141
|
+
function renderBootstrap(devModuleUrls, { margaui, check, inspect: inspect3 }) {
|
|
16145
16142
|
const lines = ['import { mountStorybook } from "tutuca/storybook";'];
|
|
16146
16143
|
if (margaui) {
|
|
16147
16144
|
lines.push('import { compileClassesToStyleText } from "tutuca/extra";');
|
|
16148
16145
|
lines.push('import { compile } from "margaui";');
|
|
16149
16146
|
}
|
|
16147
|
+
if (inspect3) {
|
|
16148
|
+
lines.push('import { shadowCheckComponent, runTests, expect } from "tutuca/dev";');
|
|
16149
|
+
}
|
|
16150
16150
|
if (check)
|
|
16151
16151
|
lines.push('import { check } from "tutuca/dev";');
|
|
16152
16152
|
devModuleUrls.forEach((url, i) => {
|
|
16153
16153
|
lines.push(`import * as m${i} from ${JSON.stringify(url)};`);
|
|
16154
16154
|
});
|
|
16155
16155
|
const modules = devModuleUrls.map((_, i) => `m${i}`).join(", ");
|
|
16156
|
-
const
|
|
16156
|
+
const optParts = [];
|
|
16157
|
+
if (margaui)
|
|
16158
|
+
optParts.push("compileCss: (app) => compileClassesToStyleText(app, compile)");
|
|
16159
|
+
if (inspect3)
|
|
16160
|
+
optParts.push("dev: { shadowCheckComponent, runTests, expect }");
|
|
16161
|
+
const opts = optParts.length ? `{ ${optParts.join(", ")} }` : "{}";
|
|
16157
16162
|
lines.push("");
|
|
16158
16163
|
lines.push(`const app = await mountStorybook("#app", [${modules}], ${opts});`);
|
|
16159
16164
|
if (check)
|
|
@@ -16267,6 +16272,7 @@ async function run4(argv, opts = {}) {
|
|
|
16267
16272
|
out: { type: "string" },
|
|
16268
16273
|
"no-margaui": { type: "boolean", default: false },
|
|
16269
16274
|
"no-check": { type: "boolean", default: false },
|
|
16275
|
+
"no-inspect": { type: "boolean", default: false },
|
|
16270
16276
|
"no-tests": { type: "boolean", default: false },
|
|
16271
16277
|
"dry-run": { type: "boolean", default: false },
|
|
16272
16278
|
help: { type: "boolean", short: "h", default: false }
|
|
@@ -16275,7 +16281,7 @@ async function run4(argv, opts = {}) {
|
|
|
16275
16281
|
});
|
|
16276
16282
|
if (parsed.values.help) {
|
|
16277
16283
|
process.stdout.write(`tutuca storybook [dir] [--port <n>] [--out <dir>] [--dry-run]
|
|
16278
|
-
[--no-margaui] [--no-check] [--no-tests]
|
|
16284
|
+
[--no-margaui] [--no-check] [--no-inspect] [--no-tests]
|
|
16279
16285
|
|
|
16280
16286
|
Auto-discovers co-located *.dev.js modules (recursively, skipping
|
|
16281
16287
|
node_modules/dotdirs) and serves a live storybook that mounts them via
|
|
@@ -16290,6 +16296,7 @@ async function run4(argv, opts = {}) {
|
|
|
16290
16296
|
shown instead of serving; pass --json for structured output
|
|
16291
16297
|
--no-margaui skip margaui styling (renders functional but unstyled)
|
|
16292
16298
|
--no-check skip the in-browser check(app) dev validation
|
|
16299
|
+
--no-inspect skip the per-example Component/Instance/Data/Lint/Test tabs
|
|
16293
16300
|
--no-tests skip running the modules' getTests() before serving
|
|
16294
16301
|
`);
|
|
16295
16302
|
return;
|
|
@@ -16312,6 +16319,7 @@ async function run4(argv, opts = {}) {
|
|
|
16312
16319
|
}
|
|
16313
16320
|
const margaui = !parsed.values["no-margaui"];
|
|
16314
16321
|
const check = !parsed.values["no-check"];
|
|
16322
|
+
const inspect3 = !parsed.values["no-inspect"];
|
|
16315
16323
|
const self = findSelf();
|
|
16316
16324
|
if (parsed.values.out) {
|
|
16317
16325
|
const outDir = resolve5(parsed.values.out);
|
|
@@ -16320,7 +16328,7 @@ async function run4(argv, opts = {}) {
|
|
|
16320
16328
|
const imports2 = buildImports(base2, { margaui });
|
|
16321
16329
|
const bootstrapName = "tutuca-storybook.bootstrap.js";
|
|
16322
16330
|
writeFileSync(resolve5(outDir, "index.html"), renderIndexHtml(imports2, { margaui, bootstrapUrl: `./${bootstrapName}` }));
|
|
16323
|
-
writeFileSync(resolve5(outDir, bootstrapName), renderBootstrap(devModuleUrls, { margaui, check }));
|
|
16331
|
+
writeFileSync(resolve5(outDir, bootstrapName), renderBootstrap(devModuleUrls, { margaui, check, inspect: inspect3 }));
|
|
16324
16332
|
process.stdout.write(`wrote static storybook → ${relative2(process.cwd(), outDir) || "."}/
|
|
16325
16333
|
index.html + ${bootstrapName} (${devModuleUrls.length} dev modules, CDN import map)
|
|
16326
16334
|
Host it from the project root so /*.dev.js paths resolve.
|
|
@@ -16405,7 +16413,7 @@ async function run4(argv, opts = {}) {
|
|
|
16405
16413
|
const { base, serveDist } = resolveTutucaBase(projectDir, self, false);
|
|
16406
16414
|
const imports = buildImports(base, { margaui });
|
|
16407
16415
|
const indexHtml = renderIndexHtml(imports, { margaui, bootstrapUrl: BOOTSTRAP_URL });
|
|
16408
|
-
const bootstrapJs = renderBootstrap(devModuleUrls, { margaui, check });
|
|
16416
|
+
const bootstrapJs = renderBootstrap(devModuleUrls, { margaui, check, inspect: inspect3 });
|
|
16409
16417
|
const server = createServer((req, res) => {
|
|
16410
16418
|
const path = req.url.split("?")[0];
|
|
16411
16419
|
if (path === "/" || path === "/index.html") {
|