tkeron 5.3.0 → 6.0.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.
@@ -1,240 +0,0 @@
1
- # MCP Server
2
-
3
- Tkeron includes a Model Context Protocol (MCP) server that exposes comprehensive documentation to AI agents and development tools.
4
-
5
- ## What is MCP?
6
-
7
- The Model Context Protocol is a standard for providing context to AI agents. Tkeron's MCP server allows AI assistants to access up-to-date documentation about how to use Tkeron, its capabilities, and limitations.
8
-
9
- ## Installation
10
-
11
- The MCP server is included when you install Tkeron globally:
12
-
13
- ```bash
14
- bun install -g tkeron
15
- ```
16
-
17
- This installs three commands:
18
-
19
- - `tk` / `tkeron` - The main CLI tool
20
- - `tkeron-mcp` - The MCP server
21
-
22
- ## Configuration
23
-
24
- ### VS Code
25
-
26
- Add to your MCP configuration file (`~/.config/Code/User/mcp.json`):
27
-
28
- ```json
29
- {
30
- "servers": {
31
- "tkeron": {
32
- "command": "tkeron-mcp"
33
- }
34
- }
35
- }
36
- ```
37
-
38
- If the global command is not found, use Bun directly:
39
-
40
- ```json
41
- {
42
- "servers": {
43
- "tkeron": {
44
- "command": "bun",
45
- "args": ["run", "/absolute/path/to/tkeron/mcp-server.ts"]
46
- }
47
- }
48
- }
49
- ```
50
-
51
- **Note:** This is the VS Code format. Other editors (Cursor, Windsurf, etc.) may use different configuration formats.
52
-
53
- ````
54
-
55
- **Find the path:**
56
- ```bash
57
- # If tkeron is installed globally
58
- dirname $(which tk)
59
- # Returns something like: /home/user/.bun/bin
60
-
61
- # The mcp-server.ts is in the same directory
62
- ls $(dirname $(which tk))/mcp-server.ts
63
- ````
64
-
65
- ### Claude Desktop
66
-
67
- Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or equivalent on other platforms:
68
-
69
- ```json
70
- {
71
- "mcpServers": {
72
- "tkeron": {
73
- "command": "tkeron-mcp"
74
- }
75
- }
76
- }
77
- ```
78
-
79
- ### Other MCP Clients
80
-
81
- Any MCP-compatible client can use the server. Configure it to run:
82
-
83
- ```bash
84
- tkeron-mcp
85
- ```
86
-
87
- The server communicates via stdio transport.
88
-
89
- ## Available Resources
90
-
91
- The MCP server exposes the following documentation resources:
92
-
93
- | URI | Description |
94
- | -------------------------------- | ---------------------------------------------------- |
95
- | `tkeron://overview` | What Tkeron is, what it does, and what it's not |
96
- | `tkeron://getting-started` | Installation, first project, and basic workflow |
97
- | `tkeron://components-html` | Create reusable HTML components with .com.html files |
98
- | `tkeron://components-typescript` | Build dynamic components with .com.ts files |
99
- | `tkeron://pre-rendering` | Transform HTML at build time with .pre.ts files |
100
- | `tkeron://cli-reference` | Complete command-line interface documentation |
101
- | `tkeron://best-practices` | Patterns, anti-patterns, and limitations |
102
- | `tkeron://common-issues` | Troubleshooting guide and common mistakes |
103
- | `tkeron://testing` | How to test tkeron projects with getBuildResult() |
104
-
105
- ## What AI Agents Can Do
106
-
107
- With access to the MCP server, AI agents can:
108
-
109
- - ✅ Understand Tkeron's capabilities and limitations
110
- - ✅ Help users create components correctly
111
- - ✅ Suggest appropriate patterns for different use cases
112
- - ✅ Identify when Tkeron is NOT the right tool
113
- - ✅ Provide accurate CLI commands and options
114
- - ✅ Debug common issues with components and pre-rendering
115
- - ✅ Recommend best practices and avoid anti-patterns
116
- - ✅ **Prevent common mistakes** (script references, component naming, dependencies)
117
- - ✅ **List and explore example projects**
118
- - ✅ **Retrieve example code and structures**
119
- - ✅ **Initialize, build, and develop projects via terminal** (`tk init`, `tk build`, `tk dev`)
120
-
121
- ## Available Tools
122
-
123
- The MCP server provides the following tools for AI agents:
124
-
125
- ### Example Management Tools
126
-
127
- - **`list_examples`**: List all available Tkeron example projects
128
- - No parameters required
129
- - Returns example names, descriptions, and paths
130
- - Helps users discover what's possible with Tkeron
131
-
132
- - **`get_example`**: Get the complete source code of an example
133
- - Parameters: `example` (name of the example project)
134
- - Returns file structure and all source code
135
- - Useful for learning patterns and bootstrapping projects
136
-
137
- > **Note:** The MCP server only provides documentation and examples. It does NOT modify files. The AI agent should use terminal commands (`tk init`, `tk build`, `tk dev`) to manage projects.
138
-
139
- ## Benefits
140
-
141
- ### For Users
142
-
143
- - Get accurate help from AI assistants
144
- - AI understands your project structure
145
- - Contextual suggestions based on Tkeron's docs
146
- - Fewer mistakes and faster development
147
-
148
- ### For AI Agents
149
-
150
- - Access to authoritative, up-to-date documentation
151
- - Clear understanding of limitations and constraints
152
- - Examples and patterns to reference
153
- - Ability to distinguish between what Tkeron can and can't do
154
-
155
- ## Verification
156
-
157
- To verify the MCP server is working:
158
-
159
- 1. Install Tkeron globally
160
- 2. Configure your MCP client
161
- 3. Restart your IDE/editor
162
- 4. Ask your AI assistant: "What is Tkeron?"
163
-
164
- The assistant should be able to provide an accurate description based on the documentation.
165
-
166
- ## Troubleshooting
167
-
168
- ### "Command not found: tkeron-mcp"
169
-
170
- Make sure Tkeron is installed globally:
171
-
172
- ```bash
173
- bun install -g tkeron
174
- which tkeron-mcp
175
- ```
176
-
177
- ### "Cannot find module"
178
-
179
- Ensure all dependencies are installed:
180
-
181
- ```bash
182
- cd $(dirname $(which tkeron-mcp))
183
- bun install
184
- ```
185
-
186
- ### MCP Client Not Connecting
187
-
188
- Check your configuration file syntax:
189
-
190
- - Valid JSON
191
- - Correct command path
192
- - Proper permissions on the executable
193
-
194
- ### Resources Not Loading
195
-
196
- Verify the docs directory exists:
197
-
198
- ```bash
199
- ls $(dirname $(which tkeron-mcp))/docs/
200
- ```
201
-
202
- All markdown files should be present.
203
-
204
- ## For Developers
205
-
206
- ### Adding New Resources
207
-
208
- To add new documentation resources:
209
-
210
- 1. Create a new `.md` file in `docs/`
211
- 2. Add an entry to the `DOCS` array in `mcp-server.ts`:
212
-
213
- ```typescript
214
- {
215
- uri: "tkeron://new-topic",
216
- name: "New Topic",
217
- description: "Description of the topic",
218
- file: "new-topic.md",
219
- }
220
- ```
221
-
222
- 3. Rebuild and publish the package
223
-
224
- ### Testing Locally
225
-
226
- Run the MCP server directly:
227
-
228
- ```bash
229
- bun run mcp-server.ts
230
- ```
231
-
232
- It will wait for stdio input (this is normal for MCP servers).
233
-
234
- Test with an MCP client or use the MCP inspector tool.
235
-
236
- ## Related Documentation
237
-
238
- - [Overview](./overview.md) - Learn what Tkeron is
239
- - [Getting Started](./getting-started.md) - Start using Tkeron
240
- - [Best Practices](./best-practices.md) - Patterns and anti-patterns
package/mcp-server.ts DELETED
@@ -1,272 +0,0 @@
1
- #!/usr/bin/env bun
2
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { readFileSync, existsSync, readdirSync, statSync } from "fs";
5
- import { join, dirname } from "path";
6
- import { fileURLToPath } from "url";
7
-
8
- const getBaseDir = () => {
9
- if (import.meta.dir) {
10
- return import.meta.dir;
11
- }
12
- const currentFile = import.meta.url
13
- ? fileURLToPath(import.meta.url)
14
- : __filename;
15
- return dirname(currentFile);
16
- };
17
-
18
- const BASE_DIR = getBaseDir();
19
- const DOCS_DIR = join(BASE_DIR, "docs");
20
- const EXAMPLES_DIR = join(BASE_DIR, "examples");
21
-
22
- const getVersion = (): string => {
23
- const pkgPath = join(BASE_DIR, "package.json");
24
- if (existsSync(pkgPath)) {
25
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
26
- return pkg.version || "0.0.0";
27
- }
28
- return "0.0.0";
29
- };
30
-
31
- const DOCS = [
32
- {
33
- uri: "tkeron://overview",
34
- name: "Tkeron Overview",
35
- description: "What tkeron is, what it does, and what it's not",
36
- file: "overview.md",
37
- },
38
- {
39
- uri: "tkeron://getting-started",
40
- name: "Getting Started",
41
- description: "Installation, first project, and basic workflow",
42
- file: "getting-started.md",
43
- },
44
- {
45
- uri: "tkeron://components-html",
46
- name: "HTML Components",
47
- description: "Create reusable HTML components with .com.html files",
48
- file: "components-html.md",
49
- },
50
- {
51
- uri: "tkeron://components-typescript",
52
- name: "TypeScript Components",
53
- description: "Build dynamic components with .com.ts files",
54
- file: "components-typescript.md",
55
- },
56
- {
57
- uri: "tkeron://components-markdown",
58
- name: "Markdown Components",
59
- description: "Create components with Markdown using .com.md files",
60
- file: "components-markdown.md",
61
- },
62
- {
63
- uri: "tkeron://pre-rendering",
64
- name: "Pre-rendering",
65
- description: "Transform HTML at build time with .pre.ts files",
66
- file: "pre-rendering.md",
67
- },
68
- {
69
- uri: "tkeron://cli-reference",
70
- name: "CLI Reference",
71
- description: "Complete command-line interface documentation",
72
- file: "cli-reference.md",
73
- },
74
- {
75
- uri: "tkeron://best-practices",
76
- name: "Best Practices",
77
- description: "Patterns, anti-patterns, and limitations",
78
- file: "best-practices.md",
79
- },
80
- {
81
- uri: "tkeron://common-issues",
82
- name: "Common Issues and Solutions",
83
- description:
84
- "Troubleshooting guide: script references, component naming, dependencies, and common mistakes",
85
- file: "common-issues.md",
86
- },
87
- {
88
- uri: "tkeron://testing",
89
- name: "Testing Tkeron Projects",
90
- description:
91
- "How to test tkeron projects using getBuildResult(), DOM assertions, and bounded content verification",
92
- file: "testing.md",
93
- },
94
- ];
95
-
96
- const EXAMPLE_DESCRIPTIONS: { [key: string]: string } = {
97
- init_sample:
98
- "Complete starter template with all features (used by 'tk init')",
99
- basic_build: "Simple HTML + TypeScript bundling",
100
- with_assets: "HTML in multiple directories with asset references",
101
- with_pre: "Pre-rendering HTML at build time with .pre.ts files",
102
- with_com_html_priority:
103
- "Static HTML components (.com.html) with local override priority",
104
- with_com_ts: "TypeScript components (.com.ts) generating HTML at build time",
105
- with_com_ts_priority:
106
- "TypeScript components (.com.ts) with local override priority",
107
- with_com_mixed_priority:
108
- "Mixed .com.html and .com.ts showing processing order",
109
- with_com_html_in_ts:
110
- "HTML template (.com.html) injected into .com.ts as com.innerHTML before execution",
111
- with_component_iteration:
112
- "Component iteration: .com.ts with logic, .com.html for templates",
113
- };
114
-
115
- const readDirRecursive = (
116
- dir: string,
117
- baseDir: string = dir,
118
- ): { [key: string]: string } => {
119
- const files: { [key: string]: string } = {};
120
- const items = readdirSync(dir);
121
-
122
- for (const item of items) {
123
- const fullPath = join(dir, item);
124
- const relativePath = fullPath.substring(baseDir.length + 1);
125
-
126
- if (statSync(fullPath).isDirectory()) {
127
- Object.assign(files, readDirRecursive(fullPath, baseDir));
128
- } else {
129
- files[relativePath] = readFileSync(fullPath, "utf-8");
130
- }
131
- }
132
-
133
- return files;
134
- };
135
-
136
- const server = new McpServer({
137
- name: "tkeron-mcp",
138
- version: getVersion(),
139
- });
140
-
141
- for (const doc of DOCS) {
142
- server.registerResource(
143
- doc.name,
144
- doc.uri,
145
- { description: doc.description, mimeType: "text/markdown" },
146
- () => {
147
- const filePath = join(DOCS_DIR, doc.file);
148
-
149
- if (!existsSync(filePath)) {
150
- throw new Error(`Documentation file not found: ${doc.file}`);
151
- }
152
-
153
- const content = readFileSync(filePath, "utf-8");
154
-
155
- return {
156
- contents: [
157
- {
158
- uri: doc.uri,
159
- mimeType: "text/markdown",
160
- text: content,
161
- },
162
- ],
163
- };
164
- },
165
- );
166
- }
167
-
168
- server.registerTool(
169
- "list_examples",
170
- {
171
- description:
172
- "List all available Tkeron example projects with their descriptions",
173
- annotations: { readOnlyHint: true },
174
- },
175
- () => {
176
- const examples = readdirSync(EXAMPLES_DIR).filter((name) => {
177
- const examplePath = join(EXAMPLES_DIR, name);
178
- return (
179
- statSync(examplePath).isDirectory() &&
180
- existsSync(join(examplePath, "websrc"))
181
- );
182
- });
183
-
184
- const exampleList = examples.map((name) => ({
185
- name,
186
- description: EXAMPLE_DESCRIPTIONS[name] || "No description available",
187
- path: `examples/${name}`,
188
- }));
189
-
190
- return {
191
- content: [
192
- {
193
- type: "text" as const,
194
- text: JSON.stringify(exampleList, null, 2),
195
- },
196
- ],
197
- };
198
- },
199
- );
200
-
201
- server.registerTool(
202
- "get_example",
203
- {
204
- description:
205
- "Get the source code and structure of a specific Tkeron example project",
206
- inputSchema: {
207
- example: {
208
- type: "string",
209
- description:
210
- "Example name (e.g., 'basic_build', 'with_component_iteration')",
211
- },
212
- } as any,
213
- annotations: { readOnlyHint: true },
214
- },
215
- ({ example: exampleName }: { example: string }) => {
216
- const examplePath = join(EXAMPLES_DIR, exampleName);
217
-
218
- if (!existsSync(examplePath)) {
219
- return {
220
- content: [
221
- {
222
- type: "text" as const,
223
- text: `Example not found: ${exampleName}. Use the list_examples tool to see available examples.`,
224
- },
225
- ],
226
- isError: true,
227
- };
228
- }
229
-
230
- const srcPath = join(examplePath, "websrc");
231
-
232
- if (!existsSync(srcPath)) {
233
- return {
234
- content: [
235
- {
236
- type: "text" as const,
237
- text: `Example ${exampleName} does not have a websrc directory`,
238
- },
239
- ],
240
- isError: true,
241
- };
242
- }
243
-
244
- const sourceFiles = readDirRecursive(srcPath);
245
-
246
- const result = {
247
- example: exampleName,
248
- path: `examples/${exampleName}`,
249
- files: sourceFiles,
250
- };
251
-
252
- return {
253
- content: [
254
- {
255
- type: "text" as const,
256
- text: JSON.stringify(result, null, 2),
257
- },
258
- ],
259
- };
260
- },
261
- );
262
-
263
- const main = async () => {
264
- const transport = new StdioServerTransport();
265
- await server.connect(transport);
266
- console.error(`[tkeron-mcp] Server v${getVersion()} started`);
267
- };
268
-
269
- main().catch((error) => {
270
- console.error(`[tkeron-mcp] Fatal error:`, error);
271
- process.exit(1);
272
- });
@@ -1,31 +0,0 @@
1
- import { readdir, rm } from "fs/promises";
2
- import { join } from "path";
3
- import type { Logger } from "@tkeron/tools";
4
-
5
- export const TEMP_DIR_PREFIX = ".tktmp_build-";
6
-
7
- export const cleanupOrphanedTempDirs = async (
8
- parentDir: string,
9
- log: Logger,
10
- ): Promise<void> => {
11
- try {
12
- const entries = await readdir(parentDir, { withFileTypes: true });
13
- const orphanedDirs = entries.filter(
14
- (entry) => entry.isDirectory() && entry.name.startsWith(TEMP_DIR_PREFIX),
15
- );
16
-
17
- await Promise.all(
18
- orphanedDirs.map(async (dir) => {
19
- const dirPath = join(parentDir, dir.name);
20
- try {
21
- await rm(dirPath, { recursive: true, force: true });
22
- log.log(`🧹 Cleaned up orphaned temp directory: ${dir.name}`);
23
- } catch (error) {
24
- log.warn(
25
- `Warning: Failed to cleanup orphaned temp directory ${dirPath}`,
26
- );
27
- }
28
- }),
29
- );
30
- } catch (error) {}
31
- };
package/src/promptUser.ts DELETED
@@ -1,15 +0,0 @@
1
- export const promptUser = async (question: string): Promise<boolean> => {
2
- const readline = await import("readline");
3
- const rl = readline.createInterface({
4
- input: process.stdin,
5
- output: process.stdout,
6
- });
7
-
8
- return new Promise((resolve) => {
9
- rl.question(question, (answer) => {
10
- rl.close();
11
- const response = answer.trim().toLowerCase();
12
- resolve(response === "y" || response === "yes");
13
- });
14
- });
15
- };
@@ -1,6 +0,0 @@
1
- export const setupSigintHandler = (stopCallback: () => Promise<void>) => {
2
- process.on("SIGINT", async () => {
3
- await stopCallback();
4
- process.exit(0);
5
- });
6
- };