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 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
- - ~177KB minified, ~40KB brotli compressed
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` + `core.md` / `cli.md` /
150
- `advanced.md` / `testing.md`) packaged as a [Claude Code skill](https://docs.claude.com/en/docs/claude-code/skills).
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
 
@@ -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, RCDATA_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, SCOPE_SELECT, STANDARD_SVG_CAMEL_ELEMENTS, STANDARD_SVG_CAMEL_ATTRS, MATHML_CAMEL_ATTRS, SVG_ATTR_LOWERCASE_TO_CAMEL, MATHML_ATTR_LOWERCASE_TO_CAMEL, FOREIGN_BREAKOUT_TAGS, MATHML_TEXT_INTEGRATION_POINTS, BLOCK_LEVEL_AUTO_CLOSE_P, SELECT_VALID_CHILDREN, SELECT_BREAKOUT_TAGS, MODES, NS, FRAGMENT_CONTEXT_MODES;
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 opts = margaui ? "{ compileCss: (app) => compileClassesToStyleText(app, compile) }" : "{}";
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") {