@techninja/clearstack 0.3.11 → 0.3.12

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.
@@ -267,6 +267,25 @@ This prevents premature extraction while keeping the eventual split obvious.
267
267
  function moveObj(o, dx, dy) { ... }
268
268
  ```
269
269
 
270
+ ### When a File Exceeds 150 Lines
271
+
272
+ The **only correct response** is to split the file into two or more files.
273
+ Never do any of the following to reduce line count:
274
+
275
+ - Remove or shorten JSDoc comments
276
+ - Collapse multi-line expressions onto one line
277
+ - Remove blank lines between logical sections
278
+ - Combine unrelated functions into one
279
+ - Delete code that is still needed
280
+
281
+ These make the code harder to read, which defeats the purpose of the limit.
282
+ The limit exists to force decomposition, not compression.
283
+
284
+ The spec checker runs formatters (Prettier, ESLint `--fix`) **before**
285
+ counting lines, so the line count always reflects the formatted result.
286
+ Write code in its natural readable form, run `npm run spec all`, and if
287
+ a file is over the limit, split it.
288
+
270
289
  ---
271
290
 
272
291
  ## npm Scripts: One Entry Point Per Domain
@@ -328,6 +347,53 @@ multiple keys.
328
347
  Spec is the inner dev loop — run it constantly. Tests are the commit gate —
329
348
  run them before pushing. CI runs both, in parallel.
330
349
 
350
+ ### Spec Output Contract
351
+
352
+ The spec checker is designed for **minimal, complete output**. Every check
353
+ prints exactly one line: ✅ on pass, ❌ on fail with the violating file and
354
+ reason. The final summary is 2 lines (`N/N checks passed`).
355
+
356
+ Total output for a passing run is ~12 lines. A failing run adds one line
357
+ per violation with the exact file path and what to fix.
358
+
359
+ **Do not pipe, grep, tail, or filter spec output.** It is already the
360
+ minimal actionable result. Filtering it discards the violation details
361
+ that tell you which file to fix, forcing redundant re-runs.
362
+
363
+ To narrow scope, run a targeted check instead of filtering `all`:
364
+
365
+ ```bash
366
+ # Run everything
367
+ npm run spec all
368
+
369
+ # Run one check by key
370
+ npm run spec code # line counts (code files ≤150)
371
+ npm run spec docs # line counts (doc files ≤500)
372
+ npm run spec imports # import map aliases (no ../)
373
+ npm run spec types # JSDoc types (tsc --checkJs)
374
+ npm run spec audit # security audit
375
+
376
+ # Parent keys run all children
377
+ npm run spec lint # ESLint + Stylelint + Markdown lint
378
+ npm run spec format # Prettier (all formatters)
379
+
380
+ # Child keys run one
381
+ npm run spec lint es # ESLint only
382
+ npm run spec lint css # Stylelint only
383
+ npm run spec lint md # Markdown lint only
384
+ npm run spec format prettier
385
+ ```
386
+
387
+ ```bash
388
+ # ❌ Wrong — discards violation file paths
389
+ npm run spec all 2>&1 | tail -3
390
+ npm run spec all 2>&1 | grep -E "pass|fail"
391
+ ```
392
+
393
+ This matters especially for LLM-assisted development: the spec output is
394
+ structured so an LLM can read it in one pass, identify the failing file,
395
+ and fix it without re-running the check. Filtering breaks that loop.
396
+
331
397
  ---
332
398
 
333
399
  ## Session Retrospective
package/lib/check.js CHANGED
@@ -69,12 +69,6 @@ export function buildChecks(dir, cfg, cmds) {
69
69
  const css = () => countFiles(dir, ['.css'], cfg.ignore);
70
70
  const md = () => countFiles(dir, ['.md'], cfg.ignore);
71
71
  return [
72
- { key: 'code', name: `Code (max ${cfg.codeMax} lines)`,
73
- run: () => checkFileLines(dir, cfg.codeExt, cfg.codeMax, cfg.ignore, `Code (max ${cfg.codeMax} lines)`) },
74
- { key: 'docs', name: `Docs (max ${cfg.docsMax} lines)`,
75
- run: () => checkFileLines(dir, cfg.docsExt, cfg.docsMax, cfg.ignore, `Docs (max ${cfg.docsMax} lines)`) },
76
- { key: 'imports', name: 'Import map aliases (no ../ imports)',
77
- run: () => checkImports(dir, cfg.ignore, 'Import map aliases (no ../ imports)') },
78
72
  { key: 'es', name: 'ESLint', parent: 'lint',
79
73
  run: () => runCmd('ESLint', cmds.lint, dir, `${js()} files`) },
80
74
  { key: 'css', name: 'Stylelint', parent: 'lint',
@@ -83,6 +77,12 @@ export function buildChecks(dir, cfg, cmds) {
83
77
  run: () => runCmd('Markdown', cmds.mdlint, dir, `${md()} files`) },
84
78
  { key: 'prettier', name: 'Prettier', parent: 'format',
85
79
  run: () => runCmd('Prettier', cmds.prettier, dir, `${js()} files`) },
80
+ { key: 'code', name: `Code (max ${cfg.codeMax} lines)`,
81
+ run: () => checkFileLines(dir, cfg.codeExt, cfg.codeMax, cfg.ignore, `Code (max ${cfg.codeMax} lines)`) },
82
+ { key: 'docs', name: `Docs (max ${cfg.docsMax} lines)`,
83
+ run: () => checkFileLines(dir, cfg.docsExt, cfg.docsMax, cfg.ignore, `Docs (max ${cfg.docsMax} lines)`) },
84
+ { key: 'imports', name: 'Import map aliases (no ../ imports)',
85
+ run: () => checkImports(dir, cfg.ignore, 'Import map aliases (no ../ imports)') },
86
86
  { key: 'types', name: 'JSDoc types (tsc --checkJs)',
87
87
  run: () => runCmd('JSDoc types', cmds.types, dir, `${js()} files`) },
88
88
  { key: 'audit', name: 'Security audit',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techninja/clearstack",
3
- "version": "0.3.11",
3
+ "version": "0.3.12",
4
4
  "type": "module",
5
5
  "description": "A no-build web component framework specification — scaffold, validate, and evolve spec-compliant projects",
6
6
  "bin": {
@@ -267,6 +267,25 @@ This prevents premature extraction while keeping the eventual split obvious.
267
267
  function moveObj(o, dx, dy) { ... }
268
268
  ```
269
269
 
270
+ ### When a File Exceeds 150 Lines
271
+
272
+ The **only correct response** is to split the file into two or more files.
273
+ Never do any of the following to reduce line count:
274
+
275
+ - Remove or shorten JSDoc comments
276
+ - Collapse multi-line expressions onto one line
277
+ - Remove blank lines between logical sections
278
+ - Combine unrelated functions into one
279
+ - Delete code that is still needed
280
+
281
+ These make the code harder to read, which defeats the purpose of the limit.
282
+ The limit exists to force decomposition, not compression.
283
+
284
+ The spec checker runs formatters (Prettier, ESLint `--fix`) **before**
285
+ counting lines, so the line count always reflects the formatted result.
286
+ Write code in its natural readable form, run `npm run spec all`, and if
287
+ a file is over the limit, split it.
288
+
270
289
  ---
271
290
 
272
291
  ## npm Scripts: One Entry Point Per Domain
@@ -328,6 +347,53 @@ multiple keys.
328
347
  Spec is the inner dev loop — run it constantly. Tests are the commit gate —
329
348
  run them before pushing. CI runs both, in parallel.
330
349
 
350
+ ### Spec Output Contract
351
+
352
+ The spec checker is designed for **minimal, complete output**. Every check
353
+ prints exactly one line: ✅ on pass, ❌ on fail with the violating file and
354
+ reason. The final summary is 2 lines (`N/N checks passed`).
355
+
356
+ Total output for a passing run is ~12 lines. A failing run adds one line
357
+ per violation with the exact file path and what to fix.
358
+
359
+ **Do not pipe, grep, tail, or filter spec output.** It is already the
360
+ minimal actionable result. Filtering it discards the violation details
361
+ that tell you which file to fix, forcing redundant re-runs.
362
+
363
+ To narrow scope, run a targeted check instead of filtering `all`:
364
+
365
+ ```bash
366
+ # Run everything
367
+ npm run spec all
368
+
369
+ # Run one check by key
370
+ npm run spec code # line counts (code files ≤150)
371
+ npm run spec docs # line counts (doc files ≤500)
372
+ npm run spec imports # import map aliases (no ../)
373
+ npm run spec types # JSDoc types (tsc --checkJs)
374
+ npm run spec audit # security audit
375
+
376
+ # Parent keys run all children
377
+ npm run spec lint # ESLint + Stylelint + Markdown lint
378
+ npm run spec format # Prettier (all formatters)
379
+
380
+ # Child keys run one
381
+ npm run spec lint es # ESLint only
382
+ npm run spec lint css # Stylelint only
383
+ npm run spec lint md # Markdown lint only
384
+ npm run spec format prettier
385
+ ```
386
+
387
+ ```bash
388
+ # ❌ Wrong — discards violation file paths
389
+ npm run spec all 2>&1 | tail -3
390
+ npm run spec all 2>&1 | grep -E "pass|fail"
391
+ ```
392
+
393
+ This matters especially for LLM-assisted development: the spec output is
394
+ structured so an LLM can read it in one pass, identify the failing file,
395
+ and fix it without re-running the check. Filtering breaks that loop.
396
+
331
397
  ---
332
398
 
333
399
  ## Session Retrospective