@tsrx/mcp 0.0.29 → 0.0.30

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
@@ -89,7 +89,7 @@ Add the generic config above to your Codex MCP configuration.
89
89
  - `review-tsrx-accessibility` - review TSRX source for common accessibility issues
90
90
  before browser-based Axe validation, including missing button names, unlabeled
91
91
  form controls, and visible text written in a non-rendering shape.
92
- - `review-tsrx-styles` - review component-scoped style usage for malformed style
92
+ - `review-tsrx-styles` - review function-local style usage for malformed style
93
93
  blocks, broad selectors, root styling, and contrast risks.
94
94
  - `review-tsrx-components` - review component structure and suggest extraction
95
95
  points when control flow, repeated templates, or styles become dense.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "MCP server for TSRX documentation and project context",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.0.29",
6
+ "version": "0.0.30",
7
7
  "type": "module",
8
8
  "repository": {
9
9
  "type": "git",
@@ -37,8 +37,8 @@
37
37
  "@modelcontextprotocol/sdk": "^1.29.0",
38
38
  "prettier": "^3.8.3",
39
39
  "zod": "^4.3.6",
40
- "@tsrx/core": "0.1.16",
41
- "@tsrx/prettier-plugin": "0.3.68"
40
+ "@tsrx/core": "0.1.17",
41
+ "@tsrx/prettier-plugin": "0.3.69"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^24.3.0",
package/src/analyze.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import {
2
- COMPONENT_DO_WHILE_STATEMENT_ERROR,
3
- COMPONENT_FOR_IN_STATEMENT_ERROR,
4
- COMPONENT_FOR_STATEMENT_ERROR,
5
- COMPONENT_LOOP_BREAK_ERROR,
6
- COMPONENT_LOOP_RETURN_ERROR,
7
- COMPONENT_WHILE_STATEMENT_ERROR,
8
2
  DIAGNOSTIC_CODES,
3
+ TSRX_DO_WHILE_STATEMENT_ERROR,
4
+ TSRX_FOR_IN_STATEMENT_ERROR,
5
+ TSRX_FOR_STATEMENT_ERROR,
6
+ TSRX_LOOP_BREAK_ERROR,
7
+ TSRX_LOOP_RETURN_ERROR,
8
+ TSRX_RETURN_STATEMENT_ERROR,
9
+ TSRX_WHILE_STATEMENT_ERROR,
9
10
  } from '@tsrx/core';
10
11
  import { compile_tsrx } from './compile.js';
11
12
 
@@ -49,31 +50,6 @@ function create_advice(input) {
49
50
  });
50
51
  }
51
52
 
52
- const has_function_component_syntax = error_codes.has(DIAGNOSTIC_CODES.FUNCTION_COMPONENT_SYNTAX);
53
- if (has_function_component_syntax) {
54
- advice.push({
55
- kind: 'function-component-syntax',
56
- severity: 'warning',
57
- title: 'Use TSRX component declarations',
58
- message:
59
- '.tsrx component files should use the component keyword. A React-style function returning JSX is usually the wrong authoring shape for TSRX.',
60
- documentation: ['tsrx://docs/components.md'],
61
- });
62
- }
63
-
64
- const fired_jsx_return = error_codes.has(DIAGNOSTIC_CODES.JSX_RETURN_IN_COMPONENT);
65
-
66
- if (fired_jsx_return) {
67
- advice.push({
68
- kind: 'jsx-return-in-component',
69
- severity: 'error',
70
- title: 'Do not return JSX from component bodies',
71
- message:
72
- 'Inside a TSRX component body, template elements are statements. Replace `return <div />` with a template statement like `<div />`; use bare `return;` only for guard exits.',
73
- documentation: ['tsrx://docs/components.md', 'tsrx://docs/tsx-expression-values.md'],
74
- });
75
- }
76
-
77
53
  if (error_codes.has(DIAGNOSTIC_CODES.UNCLOSED_TAG)) {
78
54
  advice.push({
79
55
  kind: 'unclosed-tag',
@@ -107,25 +83,33 @@ function create_advice(input) {
107
83
  });
108
84
  }
109
85
 
110
- if (
111
- error_messages.has(COMPONENT_LOOP_RETURN_ERROR) ||
112
- error_messages.has(COMPONENT_LOOP_BREAK_ERROR)
113
- ) {
86
+ if (error_messages.has(TSRX_LOOP_RETURN_ERROR) || error_messages.has(TSRX_LOOP_BREAK_ERROR)) {
87
+ advice.push({
88
+ kind: 'tsrx-loop-control-flow',
89
+ severity: 'error',
90
+ title: 'Use continue inside TSRX for...of loops',
91
+ message:
92
+ 'Return statements are not valid inside TSRX templates, and break statements are not valid inside TSRX for...of loops. Use continue to skip the current rendered item. Nested functions inside the loop keep ordinary JavaScript control flow.',
93
+ documentation: ['tsrx://docs/control-flow.md'],
94
+ });
95
+ }
96
+
97
+ if (error_messages.has(TSRX_RETURN_STATEMENT_ERROR)) {
114
98
  advice.push({
115
- kind: 'component-loop-control-flow',
99
+ kind: 'tsrx-template-return',
116
100
  severity: 'error',
117
- title: 'Use continue inside component for...of loops',
101
+ title: 'Move returns outside TSRX templates',
118
102
  message:
119
- 'Top-level return and break statements are not valid inside a component for...of loop. Use continue to skip the current rendered item. Nested functions inside the loop keep ordinary JavaScript control flow.',
103
+ 'Return statements are ordinary JavaScript control flow for functions, not template control flow. Use guard clauses before returning TSRX, or render conditionally inside the template.',
120
104
  documentation: ['tsrx://docs/control-flow.md'],
121
105
  });
122
106
  }
123
107
 
124
108
  if (
125
- error_messages.has(COMPONENT_FOR_STATEMENT_ERROR) ||
126
- error_messages.has(COMPONENT_FOR_IN_STATEMENT_ERROR) ||
127
- error_messages.has(COMPONENT_WHILE_STATEMENT_ERROR) ||
128
- error_messages.has(COMPONENT_DO_WHILE_STATEMENT_ERROR)
109
+ error_messages.has(TSRX_FOR_STATEMENT_ERROR) ||
110
+ error_messages.has(TSRX_FOR_IN_STATEMENT_ERROR) ||
111
+ error_messages.has(TSRX_WHILE_STATEMENT_ERROR) ||
112
+ error_messages.has(TSRX_DO_WHILE_STATEMENT_ERROR)
129
113
  ) {
130
114
  advice.push({
131
115
  kind: 'unsupported-component-loop',
@@ -11,23 +11,22 @@ export const documentation_sections = [
11
11
  use_cases:
12
12
  'always, introduction, explain tsrx, compare jsx, language model context, runtime targets',
13
13
  content:
14
- '# TSRX Overview\n\nTSRX is a TypeScript language extension for authoring declarative UI in .tsrx files. It adds a small set of syntax forms on top of TypeScript, while letting each target compiler define the runtime semantics.\n\nCore ideas:\n- component declarations use the component keyword.\n- JSX-like elements can be written as statements inside component bodies.\n- control-flow statements can contain template output.\n- expression-position native TSRX must use <tsrx>...</tsrx>; JSX-style values use <>...</> or <tsx>...</tsx>.\n- lazy destructuring uses &[] and &{} for by-reference bindings.\n\nThe core language docs should stay target-neutral. After identifying the active runtime target, use target-specific docs, prompts, or skills for runtime imports, bundler setup, and semantics that are not defined by TSRX itself.\n\nSource: website-tsrx/src/pages/specification.tsrx',
14
+ '# TSRX Overview\n\nTSRX is a TypeScript language extension for authoring declarative UI in .tsrx files. It adds a small set of syntax forms on top of TypeScript, while letting each target compiler define the runtime semantics.\n\nCore ideas:\n- Components are ordinary TypeScript functions that return TSRX.\n- TSRX opens in expression position, then template children use a template statement list inside the fragment.\n- control-flow statements can contain template output.\n- native TSRX can be returned directly as `<div />` or `<>...</>`; JSX-style values can use `<tsx>...</tsx>` when needed.\n- lazy destructuring uses &[] and &{} for by-reference bindings.\n\nThe core language docs should stay target-neutral. After identifying the active runtime target, use target-specific docs, prompts, or skills for runtime imports, bundler setup, and semantics that are not defined by TSRX itself.\n\nSource: website-tsrx/src/pages/specification.tsrx',
15
15
  },
16
16
  {
17
17
  slug: 'components',
18
- title: 'Component Declarations',
18
+ title: 'Function Components',
19
19
  use_cases:
20
- 'components, component keyword, props, authoring .tsrx files, no jsx return syntax',
20
+ 'components, functions, props, authoring .tsrx files, jsx return syntax',
21
21
  content:
22
- '# Component Declarations\n\nComponents are declared with the component keyword, not as functions returning JSX.\n\n```tsx\ncomponent Button(props: { label: string }) {\n <button>{props.label}</button>\n}\n```\n\nInside a component body, template elements are statements. Do not generate `return <div />` from a component body. Use a bare `return;` only as a guard exit after emitting fallback template statements.\n\nSpecification grammar:\n\n```text\nComponentDeclaration :\n component BindingIdentifier ( FormalParametersopt ) { ComponentBody }\n\nComponentExpression :\n component BindingIdentifieropt ( FormalParametersopt ) { ComponentBody }\n```\n\nSource: website-tsrx/src/pages/specification.tsrx#components',
22
+ '# Function Components\n\nAuthor UI as ordinary TypeScript functions that return TSRX.\n\n```tsx\nfunction Button(props: { label: string }) {\n return <button>{props.label}</button>;\n}\n```\n\nInside the returned TSRX fragment, template elements and control flow share the same template statement list.\n\nSource: website-tsrx/src/pages/specification.tsrx#components',
23
23
  },
24
24
  {
25
25
  slug: 'text-and-template-expressions',
26
26
  title: 'Text and Template Expressions',
27
- use_cases:
28
- 'text children, quoted text, raw text errors, html, text directive, string literals',
27
+ use_cases: 'text children, quoted text, raw text errors, string literals',
29
28
  content:
30
- '# Text and Template Expressions\n\nRaw unquoted text children are not valid TSRX. Static text should be written as a direct double-quoted child, and dynamic values should be wrapped in braces.\n\n```tsx\ncomponent Greeting({ name }: { name: string }) {\n <h1>"Hello"</h1>\n <p>{name}</p>\n}\n```\n\nSingle-quoted strings and template literals remain JavaScript expressions, so they must be inside braces. Use `{text expression}` for explicit text and `{html expression}` only for trusted HTML.\n\nSpecification grammar:\n\n```text\nDoubleQuotedTextChild :\n " JSXStringCharactersopt "\n\nTemplateExpression :\n { AssignmentExpression }\n { text AssignmentExpression }\n { html AssignmentExpression }\n```\n\nSource: website-tsrx/src/pages/specification.tsrx#templates',
29
+ '# Text and Template Expressions\n\nRaw unquoted text children are not valid TSRX. Static text should be written as a direct double-quoted child, and dynamic values should be wrapped in braces.\n\n```tsx\nfunction Greeting({ name }: { name: string }) {\n return <>\n <h1>"Hello"</h1>\n <p>{name}</p>\n </>;\n}\n```\n\nSingle-quoted strings and template literals remain JavaScript expressions, so they must be inside braces. When you need explicit string coercion, write it in JavaScript with `String(value)`, `value + \'\'`, or a typed string value.\n\nSpecification grammar:\n\n```text\nDoubleQuotedTextChild :\n " JSXStringCharactersopt "\n\nTemplateExpression :\n { AssignmentExpression }\n```\n\nSource: website-tsrx/src/pages/specification.tsrx#templates',
31
30
  },
32
31
  {
33
32
  slug: 'tsx-expression-values',
@@ -35,7 +34,7 @@ export const documentation_sections = [
35
34
  use_cases:
36
35
  'fragments, tsrx tag, tsx tag, pass template as prop, return template from helper, render props, expression position jsx',
37
36
  content:
38
- '# Expression Values\n\nRegular template elements in component bodies are statements and have no value. When native TSRX must be used in expression position, wrap it in `<tsrx>...</tsrx>`. When JSX-style children must be used in expression position, wrap them in `<>...</>` or `<tsx>...</tsx>`.\n\n```tsx\ncomponent App() {\n const title = <tsrx><span>"Settings"</span></tsrx>;\n\n <Card title={title} />\n}\n```\n\nNative TSRX expression fragments can contain setup statements and template control flow:\n\n```tsx\nfunction badge(label: string) {\n return <tsrx>\n const normalized = label.trim();\n <span class="badge">{normalized}</span>\n </tsrx>;\n}\n```\n\nUse these wrappers for assigning UI to variables, returning UI from helper functions, or passing UI as props. Do not write `const el = <div />` directly in TSRX component code.\n\nSpecification grammar:\n\n```text\nTsrxExpression :\n <tsrx> TemplateChildrenopt </tsrx>\n\nTsxElement :\n <tsx> TsxChildrenopt </tsx>\n\nTsxCompatElement :\n <tsx: IdentifierName> TsxChildrenopt </tsx: IdentifierName>\n\nTsxFragmentShorthand :\n <> TsxChildrenopt </>\n```\n\nSource: website-tsrx/src/pages/specification.tsrx#tsx-islands',
37
+ '# Expression Values\n\nReturned TSRX opens in expression position. Inside the TSRX fragment, template elements are statements and control flow can emit UI.\n\n```tsx\nfunction App() {\n const title = <>"Settings"</>;\n\n return <Card title={title} />;\n}\n```\n\nNative TSRX expression fragments can contain setup statements and template control flow:\n\n```tsx\nfunction badge(label: string) {\n return <>\n const normalized = label.trim();\n <span class="badge">{normalized}</span>\n </>;\n}\n```\n\nUse fragments for assigning UI to variables, returning UI from helper functions, or passing UI as props.\n\nSpecification grammar:\n\n```text\nTsrxExpression :\n Element\n <> TemplateChildrenopt </>\n\nTsxElement :\n <tsx> TsxChildrenopt </tsx>\n\nTsxCompatElement :\n <tsx: IdentifierName> TsxChildrenopt </tsx: IdentifierName>\n```\n\nSource: website-tsrx/src/pages/specification.tsrx#tsx-islands',
39
38
  },
40
39
  {
41
40
  slug: 'control-flow',
@@ -43,7 +42,7 @@ export const documentation_sections = [
43
42
  use_cases:
44
43
  'if else, for loops, switch, try catch, conditional rendering, lists, guard returns',
45
44
  content:
46
- '# Control Flow\n\nStandard JavaScript control flow can contain template statements inside component bodies and nested element children.\n\n```tsx\ncomponent List({ items }: { items: string[] }) {\n if (items.length === 0) {\n <p>"No items"</p>\n return;\n }\n\n <ul>\n for (const item of items; index i; key item) {\n if (!item) continue;\n <li>{item}</li>\n }\n </ul>\n}\n```\n\nA bare `return;` exits the current render path. A return with a value is invalid inside a TSRX component body.\n\nInside a component `for...of` loop, `continue` skips the current rendered iteration and is the only supported top-level loop control-flow statement. Top-level `return` and `break` are invalid inside component `for...of` loops; use `continue` for item skips, `return;` for non-loop guard exits, and `break` only for `switch` cases.\n\nComponent rendering supports `for...of` list loops. Regular `for`, `for...in`, `while`, and `do...while` loops are not supported in component template scope. Move imperative loops into a nested function, event handler, effect, or helper where normal JavaScript control flow rules apply.\n\nSource: website-tsrx/src/pages/features.tsrx#for',
45
+ '# Control Flow\n\nStandard JavaScript control flow can contain template statements inside returned TSRX fragments and nested element children.\n\n```tsx\nfunction List({ items }: { items: string[] }) {\n return <>\n if (items.length === 0) {\n <p>"No items"</p>\n } else {\n <ul>\n for (const item of items; index i; key item) {\n if (!item) continue;\n <li>{item}</li>\n }\n </ul>\n }\n </>;\n}\n```\n\nUse normal function returns for guard exits before TSRX opens. Inside a nested TSRX loop body, `continue` skips the current rendered iteration.\n\n`return` statements are invalid anywhere inside returned TSRX element or fragment bodies. Inside a TSRX `for...of` loop, `continue` skips the current rendered iteration and is the only supported top-level loop control-flow statement. `break` is invalid inside TSRX `for...of` loops; use `continue` for item skips and `break` only for `switch` cases.\n\nTSRX rendering supports `for...of` list loops. Regular `for`, `for...in`, `while`, and `do...while` loops are not supported in TSRX template scope. Move imperative loops into a nested function, event handler, effect, or helper where normal JavaScript control flow rules apply.\n\nSource: website-tsrx/src/pages/features.tsrx#for',
47
46
  },
48
47
  {
49
48
  slug: 'lazy-destructuring',
@@ -56,9 +55,9 @@ export const documentation_sections = [
56
55
  slug: 'style-and-server',
57
56
  title: 'Style and Server Extensions',
58
57
  use_cases:
59
- 'style directive, scoped css, module server, submodule imports, compile-time identifiers',
58
+ 'style refs, scoped css, module server, submodule imports, compile-time identifiers',
60
59
  content:
61
- '# Style and Server Extensions\n\n`{style "className"}` is an attribute-value directive for scoped CSS class names declared in the current module.\n\n```tsx\n<Child className={style "card"} />\n```\n\n`module server { ... }` declares a server-oriented submodule in the Ripple host profile. Import exported functions with `import { load } from server` before use.\n\nSpecification grammar:\n\n```text\nStyleAttributeExpression :\n { style StringLiteral }\n\nSubmoduleDeclaration :\n module Identifier { ModuleItemListopt }\n\nSubmoduleImportDeclaration :\n import ImportClause from Identifier ;\n\n```\n\nSource: website-tsrx/src/pages/specification.tsrx#style',
60
+ '# Style and Server Extensions\n\nUse `<style ref>` to expose scoped CSS class names declared in the current module.\n\n```tsx\nlet styles;\nreturn <>\n <Child className={styles.card} />\n <style ref={(s) => styles = s}>\n .card { padding: 1rem; }\n </style>\n</>;\n```\n\n`module server { ... }` declares a server-oriented submodule in the Ripple host profile. Import exported functions with `import { load } from server` before use.\n\nSpecification grammar:\n\n```text\nStyleElement :\n <style JSXAttributesopt> CSSSource </style>\n\nSubmoduleDeclaration :\n module Identifier { ModuleItemListopt }\n\nSubmoduleImportDeclaration :\n import ImportClause from Identifier ;\n\n```\n\nSource: website-tsrx/src/pages/specification.tsrx#style',
62
61
  },
63
62
  {
64
63
  slug: 'target-integration',
package/src/server.js CHANGED
@@ -305,9 +305,9 @@ function create_tsrx_task_prompt(options) {
305
305
  1. Identify whether the task is about target-neutral TSRX syntax, target runtime behavior, or both.
306
306
  ${project_context_step}
307
307
  3. For syntax uncertainty, use \`list-sections\`, \`get-documentation\`, or read \`tsrx://docs/{slug}.md\`.
308
- 4. Keep core TSRX advice target-neutral: component declarations, statement templates, control flow, TSX expression values, lazy destructuring, style identifiers, and submodule declarations.
308
+ 4. Keep core TSRX advice target-neutral: component functions, statement templates, control flow, TSX expression values, lazy destructuring, style identifiers, and submodule declarations.
309
309
  5. Use \`tsrx://targets/{target}.md\` as the handoff point for target-specific responsibilities.
310
- 5a. In component template scope, render lists with \`for...of\`; use \`continue\` to skip an item; do not use top-level \`return\` or \`break\` inside the loop, and do not use regular \`for\`, \`for...in\`, \`while\`, or \`do...while\` loops there.
310
+ 5a. In component template scope, render lists with \`for...of\`; use \`continue\` to skip an item; do not use \`return\` anywhere inside TSRX element or fragment bodies, do not use \`break\` inside \`for...of\` template loops, and do not use regular \`for\`, \`for...in\`, \`while\`, or \`do...while\` loops there.
311
311
  ${file_validation_step}
312
312
  ${compile_step}
313
313
  ${authoring_step}