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.
@@ -12,7 +12,7 @@
12
12
  box-sizing: border-box;
13
13
  }
14
14
  body {
15
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
15
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
16
16
  line-height: 1.6;
17
17
  color: #1a1a1a;
18
18
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
@@ -49,7 +49,7 @@
49
49
  backdrop-filter: blur(10px);
50
50
  padding: 1.5rem;
51
51
  border-radius: 12px;
52
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
52
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
53
53
  grid-row: span 2;
54
54
  }
55
55
  .hero .features {
@@ -67,17 +67,22 @@
67
67
  width: 200px;
68
68
  height: 200px;
69
69
  margin-bottom: 1rem;
70
- filter: drop-shadow(0 4px 6px rgba(0,0,0,0.2));
70
+ filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.2));
71
71
  animation: float 3s ease-in-out infinite;
72
72
  }
73
73
  @keyframes float {
74
- 0%, 100% { transform: translateY(0); }
75
- 50% { transform: translateY(-10px); }
74
+ 0%,
75
+ 100% {
76
+ transform: translateY(0);
77
+ }
78
+ 50% {
79
+ transform: translateY(-10px);
80
+ }
76
81
  }
77
82
  h1 {
78
83
  font-size: 2rem;
79
84
  margin-bottom: 0.25rem;
80
- text-shadow: 0 2px 4px rgba(0,0,0,0.2);
85
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
81
86
  }
82
87
  .subtitle {
83
88
  font-size: 0.9rem;
@@ -87,12 +92,14 @@
87
92
  background: white;
88
93
  padding: 1.25rem;
89
94
  border-radius: 12px;
90
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
91
- transition: transform 0.2s, box-shadow 0.2s;
95
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
96
+ transition:
97
+ transform 0.2s,
98
+ box-shadow 0.2s;
92
99
  }
93
100
  section:hover {
94
101
  transform: translateY(-4px);
95
- box-shadow: 0 8px 12px rgba(0,0,0,0.15);
102
+ box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
96
103
  }
97
104
  h2 {
98
105
  color: #667eea;
@@ -118,12 +125,14 @@
118
125
  cursor: pointer;
119
126
  font-size: 1rem;
120
127
  font-weight: 600;
121
- transition: transform 0.1s, box-shadow 0.2s;
122
- box-shadow: 0 2px 4px rgba(0,0,0,0.2);
128
+ transition:
129
+ transform 0.1s,
130
+ box-shadow 0.2s;
131
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
123
132
  }
124
133
  button:hover {
125
134
  transform: scale(1.05);
126
- box-shadow: 0 4px 8px rgba(0,0,0,0.3);
135
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
127
136
  }
128
137
  button:active {
129
138
  transform: scale(0.98);
@@ -141,18 +150,20 @@
141
150
  background: #f0f0f0;
142
151
  padding: 0.2rem 0.4rem;
143
152
  border-radius: 4px;
144
- font-family: 'Courier New', monospace;
153
+ font-family: "Courier New", monospace;
145
154
  font-size: 0.9em;
146
155
  }
147
156
  p {
148
157
  margin-bottom: 0.5rem;
149
158
  }
150
159
  a {
151
- transition: transform 0.2s, box-shadow 0.2s;
160
+ transition:
161
+ transform 0.2s,
162
+ box-shadow 0.2s;
152
163
  }
153
164
  a:hover {
154
165
  transform: translateY(-2px);
155
- box-shadow: 0 4px 8px rgba(0,0,0,0.3);
166
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
156
167
  }
157
168
  .crypto-prices-container {
158
169
  display: grid;
@@ -165,7 +176,7 @@
165
176
  padding: 1.25rem;
166
177
  border-radius: 12px;
167
178
  color: white;
168
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
179
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
169
180
  transition: transform 0.2s;
170
181
  }
171
182
  .crypto-card:hover {
@@ -182,7 +193,7 @@
182
193
  font-size: 1rem;
183
194
  }
184
195
  .crypto-symbol {
185
- background: rgba(255,255,255,0.2);
196
+ background: rgba(255, 255, 255, 0.2);
186
197
  padding: 0.25rem 0.5rem;
187
198
  border-radius: 4px;
188
199
  font-size: 0.75rem;
@@ -207,20 +218,42 @@
207
218
  <html-components-card></html-components-card>
208
219
  <ts-components-card></ts-components-card>
209
220
  <counter-card></counter-card>
210
-
221
+
211
222
  <!-- Crypto Prices - fetched at build time -->
212
- <section style="grid-column: span 3;">
223
+ <section style="grid-column: span 3">
213
224
  <h2>💰 Asset Prices (Build Time)</h2>
214
- <p style="font-size: 0.85rem; margin-bottom: 0.75rem;">Real cryptocurrency prices fetched from CoinGecko API at build time:</p>
225
+ <p style="font-size: 0.85rem; margin-bottom: 0.75rem">
226
+ Real cryptocurrency prices fetched from CoinGecko API at build time:
227
+ </p>
215
228
  <div id="crypto-prices" class="crypto-prices-container"></div>
216
229
  </section>
217
-
230
+
218
231
  <!-- Pre-rendered content with external API data -->
219
- <section style="grid-column: span 3;">
232
+ <section style="grid-column: span 3">
220
233
  <h2>💬 Quote of the Build</h2>
221
- <p style="font-size: 0.85rem; margin-bottom: 0.75rem;">This content was fetched from an external API at build time:</p>
222
- <div id="pre-rendered-quote" style="margin: 1rem 0; padding: 0.75rem; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #667eea;"></div>
223
- <div id="build-metadata" style="margin-top: 1rem; padding-top: 0.75rem; border-top: 1px solid #eee; font-size: 0.75rem; color: #999;"></div>
234
+ <p style="font-size: 0.85rem; margin-bottom: 0.75rem">
235
+ This content was fetched from an external API at build time:
236
+ </p>
237
+ <div
238
+ id="pre-rendered-quote"
239
+ style="
240
+ margin: 1rem 0;
241
+ padding: 0.75rem;
242
+ background: #f8f9fa;
243
+ border-radius: 8px;
244
+ border-left: 4px solid #667eea;
245
+ "
246
+ ></div>
247
+ <div
248
+ id="build-metadata"
249
+ style="
250
+ margin-top: 1rem;
251
+ padding-top: 0.75rem;
252
+ border-top: 1px solid #eee;
253
+ font-size: 0.75rem;
254
+ color: #999;
255
+ "
256
+ ></div>
224
257
  </section>
225
258
  </div>
226
259
  </div>
@@ -1,8 +1,12 @@
1
1
  // Pre-rendering - runs at build time
2
2
  // Demonstrates importing any TypeScript module for pre-rendering
3
- import { getRandomQuote, getBuildMetadata, getCryptoPrices } from './api-service';
3
+ import {
4
+ getRandomQuote,
5
+ getBuildMetadata,
6
+ getCryptoPrices,
7
+ } from "./api-service";
4
8
 
5
- const buildTimeElement = document.getElementById('build-time');
9
+ const buildTimeElement = document.getElementById("build-time");
6
10
 
7
11
  if (buildTimeElement) {
8
12
  const now = new Date();
@@ -10,7 +14,7 @@ if (buildTimeElement) {
10
14
  }
11
15
 
12
16
  // Fetch data from external API at build time
13
- const quoteElement = document.getElementById('pre-rendered-quote');
17
+ const quoteElement = document.getElementById("pre-rendered-quote");
14
18
  if (quoteElement) {
15
19
  const quote = await getRandomQuote();
16
20
  quoteElement.innerHTML = `
@@ -22,7 +26,7 @@ if (quoteElement) {
22
26
  }
23
27
 
24
28
  // Add build metadata
25
- const metadataElement = document.getElementById('build-metadata');
29
+ const metadataElement = document.getElementById("build-metadata");
26
30
  if (metadataElement) {
27
31
  const metadata = await getBuildMetadata();
28
32
  metadataElement.innerHTML = `
@@ -38,15 +42,17 @@ if (metadataElement) {
38
42
  }
39
43
 
40
44
  // Fetch crypto prices at build time
41
- const cryptoPricesElement = document.getElementById('crypto-prices');
45
+ const cryptoPricesElement = document.getElementById("crypto-prices");
42
46
  if (cryptoPricesElement) {
43
47
  const prices = await getCryptoPrices();
44
-
45
- const pricesHtml = prices.map(crypto => {
46
- const changeColor = crypto.price_change_percentage_24h >= 0 ? '#10b981' : '#ef4444';
47
- const changeSymbol = crypto.price_change_percentage_24h >= 0 ? '▲' : '▼';
48
-
49
- return `
48
+
49
+ const pricesHtml = prices
50
+ .map((crypto) => {
51
+ const changeColor =
52
+ crypto.price_change_percentage_24h >= 0 ? "#10b981" : "#ef4444";
53
+ const changeSymbol = crypto.price_change_percentage_24h >= 0 ? "▲" : "▼";
54
+
55
+ return `
50
56
  <div class="crypto-card">
51
57
  <div class="crypto-header">
52
58
  <span class="crypto-name">${crypto.name}</span>
@@ -58,9 +64,8 @@ if (cryptoPricesElement) {
58
64
  </div>
59
65
  </div>
60
66
  `;
61
- }).join('');
62
-
67
+ })
68
+ .join("");
69
+
63
70
  cryptoPricesElement.innerHTML = pricesHtml;
64
71
  }
65
-
66
-
@@ -1,6 +1,11 @@
1
1
  <section>
2
2
  <h2>⚡ TypeScript Components</h2>
3
- <p style="margin-bottom: 0.75rem;">Dynamic generation with <code>.com.ts</code>:</p>
3
+ <p style="margin-bottom: 0.75rem">
4
+ Dynamic generation with <code>.com.ts</code>:
5
+ </p>
4
6
  <user-badge count="3"></user-badge>
5
- <p style="font-size: 0.85rem; color: #666; margin-top: 0.75rem;">✓ Loops & conditionals<br>✓ Read attributes dynamically<br>✓ Build-time code execution</p>
7
+ <p style="font-size: 0.85rem; color: #666; margin-top: 0.75rem">
8
+ ✓ Loops & conditionals<br />✓ Read attributes dynamically<br />✓ Build-time
9
+ code execution
10
+ </p>
6
11
  </section>
package/index.ts CHANGED
@@ -3,6 +3,7 @@ import { getCommands } from "@tkeron/commands";
3
3
  import { buildWrapper } from "./src/buildWrapper";
4
4
  import { develop } from "./src/develop";
5
5
  import { initWrapper } from "./src/initWrapper";
6
+ import { skillsWrapper } from "./src/skillsWrapper";
6
7
  import { showBanner } from "./src/banner";
7
8
  import packageJson from "./package.json";
8
9
 
@@ -36,5 +37,19 @@ getCommands("tkeron", packageJson.version)
36
37
  .addOption("force")
37
38
  .setCallback(initWrapper)
38
39
 
40
+ .commands()
41
+
42
+ .addCommand("skills")
43
+ .addDescription("Install AI agent skills into the current project")
44
+ .addPositionedArgument("target")
45
+ .addOption("force")
46
+ .addOption({
47
+ name: "dryRun",
48
+ aliases: ["dry-run"],
49
+ type: "boolean",
50
+ description: "Preview what would be installed without making changes",
51
+ })
52
+ .setCallback(skillsWrapper)
53
+
39
54
  .commands()
40
55
  .start();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tkeron",
3
- "version": "5.3.0",
3
+ "version": "6.0.0",
4
4
  "description": "CLI build tool for vanilla web development with TypeScript.",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -12,8 +12,7 @@
12
12
  },
13
13
  "bin": {
14
14
  "tkeron": "./index.ts",
15
- "tk": "./index.ts",
16
- "tkeron-mcp": "./mcp-server.ts"
15
+ "tk": "./index.ts"
17
16
  },
18
17
  "scripts": {
19
18
  "tk": "bun index.ts ",
@@ -23,15 +22,14 @@
23
22
  "author": "tkeron",
24
23
  "license": "MIT",
25
24
  "dependencies": {
26
- "@modelcontextprotocol/sdk": "^1.29.0",
27
- "@tkeron/commands": "0.4.7",
28
- "@tkeron/html-parser": "1.5.6",
29
- "@tkeron/tools": "^0.4.1"
25
+ "@tkeron/commands": "0.4.8",
26
+ "@tkeron/html-parser": "1.5.7",
27
+ "@tkeron/tools": "^0.5.0"
30
28
  },
31
29
  "devDependencies": {
32
- "@types/bun": "^1.3.11",
33
- "prettier": "^3.8.1",
34
- "typescript": "^6.0.2"
30
+ "@types/bun": "^1.3.14",
31
+ "prettier": "^3.8.3",
32
+ "typescript": "^6.0.3"
35
33
  },
36
34
  "keywords": [
37
35
  "cli",
@@ -41,9 +39,7 @@
41
39
  "pre-rendering",
42
40
  "static-site-generator",
43
41
  "backend-driven",
44
- "mcp",
45
- "model-context-protocol",
46
- "ai-integration"
42
+ "ai-agents"
47
43
  ],
48
44
  "publishConfig": {
49
45
  "access": "public"
@@ -0,0 +1,286 @@
1
+ ---
2
+ name: tkeron
3
+ description: "Tkeron core overview: what it is, full CLI reference (build, dev, init, skills), file-type summary, build lifecycle, IDE support files, environment variables, build-time vs runtime. Load this skill first when starting any tkeron task — it is the entry point that points to the other tkeron-* skills."
4
+ ---
5
+
6
+ # Tkeron — Core
7
+
8
+ ## What It Is
9
+
10
+ CLI build tool for vanilla web development. Compiles TypeScript, processes HTML/TS/Markdown components, runs pre-/post-rendering scripts, generates static files ready to deploy. Powered by **Bun**. Zero frameworks. Zero runtime. Zero external bundlers.
11
+
12
+ ## The tkeron skill set
13
+
14
+ | Skill | When to load it |
15
+ | ------------------------ | -------------------------------------------------------------------------- |
16
+ | `tkeron` (this one) | Always first. CLI, lifecycle, file-type overview. |
17
+ | `tkeron-components` | Creating/editing `.com.html`, `.com.ts`, `.com.md`, `.pre.ts`, `.post.ts`. |
18
+ | `tkeron-organization` | Designing project structure, deciding when to componentize, naming. |
19
+ | `tkeron-patterns` | Implementing features — best patterns, anti-patterns, max-pre-render rule. |
20
+ | `tkeron-testing` | Writing tests with `getBuildResult` from `tkeron`. |
21
+ | `tkeron-troubleshooting` | Build fails, dev server crashes, component is not replaced, common errors. |
22
+
23
+ ---
24
+
25
+ ## Input and Output
26
+
27
+ ```
28
+ project/
29
+ ├── tkeron.d.ts # IDE types (com, document globals)
30
+ ├── tsconfig.json # TS config for IDE
31
+ ├── websrc/ # ← INPUT (all source files live here)
32
+ │ ├── index.html # Pages (root = sitemap)
33
+ │ ├── index.ts # Browser TypeScript (compiled to .js)
34
+ │ ├── index.pre.ts # Pre-rendering (build time, before components)
35
+ │ ├── index.post.ts # Post-processing (build time, after components)
36
+ │ ├── about.html # More pages at root = more routes
37
+ │ ├── docs/ # Subdirectories = sub-routes
38
+ │ │ └── *.html
39
+ │ ├── components/ # Components (NOT routes) — see tkeron-organization
40
+ │ ├── styles/ # CSS, assets
41
+ │ └── utils/ # Helpers imported by .com.ts or .pre.ts
42
+ └── web/ # ← OUTPUT (generated by tk build)
43
+ ├── index.html # Processed HTML (components inlined)
44
+ ├── index.js # TS compiled
45
+ └── styles/ # CSS copied
46
+ ```
47
+
48
+ **Fixed directories**: `websrc/` is input, `web/` is output. No configuration. Convention over configuration.
49
+
50
+ > **IMPORTANT**: `web/` is generated by `tk build` and `tk dev`. It MUST be in `.gitignore`. **Never edit or commit its contents** — any manual change is overwritten on the next build.
51
+
52
+ **Files NOT copied to output**: `*.com.html`, `*.com.ts`, `*.com.md`, `*.pre.ts`, `*.post.ts`.
53
+
54
+ ---
55
+
56
+ ## CLI Reference
57
+
58
+ ```bash
59
+ tk # Banner + version
60
+ tk init <name> # New project in <name>/
61
+ tk init . # Initialize in current directory
62
+ tk init <name> --force # Overwrite existing
63
+ tk build # Compile websrc/ → web/
64
+ tk b # Alias for build
65
+ tk dev # Dev server on localhost:3000 + hot reload
66
+ tk dev 8080 # Custom port
67
+ tk dev 8080 0.0.0.0 # Custom port + host
68
+ tk skills # Install AI agent skills (auto-detect env)
69
+ tk skills <dir> # Install into a custom directory
70
+ tk skills --force # Overwrite existing skill files
71
+ ```
72
+
73
+ | Command | Aliases | What it does |
74
+ | ------------ | ---------------- | ------------------------------------------- |
75
+ | `tk build` | `tk b` | Full build of `websrc/` → `web/` |
76
+ | `tk develop` | `tk dev`, `tk d` | Dev server + watch + hot reload (singleton) |
77
+ | `tk init` | `tk i` | Create project from template |
78
+ | `tk skills` | — | Install AI agent skills |
79
+
80
+ ### `tk dev` — important
81
+
82
+ - Defaults: port `3000`, host `localhost`. Positional args: `tk dev <port> <host>`.
83
+ - **Singleton per port**: only one instance at a time. Check `fuser 3000/tcp 2>/dev/null` before launching.
84
+ - Watches `websrc/`, rebuilds on save, broadcasts via SSE on `/dev-reload`, injects the reload script before `</body>`.
85
+ - Clean URLs: `/about` serves `about.html`, `/blog/` serves `blog/index.html`.
86
+ - **In agent sessions**: ALWAYS run `tk dev` in background (it blocks indefinitely). NEVER run it synchronously.
87
+ - If it crashes after a `websrc/` edit → see `tkeron-troubleshooting`.
88
+
89
+ ### `tk build` — required after editing `websrc/`
90
+
91
+ > **RULE**: After any change in `websrc/`, run `tk build` and then read the relevant files in `web/` (`web/*.html`, `web/*.js`) to verify components were inlined and TS compiled as expected.
92
+
93
+ If output is wrong → fix in `websrc/` and rebuild. **NEVER edit `web/` directly.**
94
+
95
+ ### `tk init` — what it creates
96
+
97
+ ```
98
+ project/
99
+ ├── websrc/
100
+ │ ├── index.html # Sample home page
101
+ │ ├── index.ts # Sample browser TS
102
+ │ ├── index.pre.ts # Sample pre-render
103
+ │ ├── api-service.ts # Sample service
104
+ │ ├── *.com.html # Sample HTML components
105
+ │ └── user-badge.com.ts # Sample TS component
106
+ ├── tkeron.d.ts # IDE types
107
+ └── tsconfig.json # TS config for IDE
108
+ ```
109
+
110
+ Behavior:
111
+
112
+ - In an empty/new directory: creates the full template.
113
+ - In a directory with an existing `websrc/` or `tkeron.d.ts`: prompts before overwriting (use `--force` to skip the prompt).
114
+ - Always preserves any pre-existing fields in your `tsconfig.json` and merges the tkeron defaults.
115
+
116
+ ### `tk skills` — environment auto-detection
117
+
118
+ `tk skills` (no argument) detects the AI environment from the current directory and installs into the matching folder:
119
+
120
+ | Detected marker | Environment | Install target | Special transform |
121
+ | ------------------------- | ----------- | ----------------- | ---------------------------------------- |
122
+ | `.cursor/` | cursor | `.cursor/rules/` | adds `alwaysApply: false` to frontmatter |
123
+ | `.github/` | copilot | `.github/skills/` | none |
124
+ | `.claude/` or `CLAUDE.md` | claude | `.claude/rules/` | none |
125
+
126
+ - Multiple environments detected → installs into all of them.
127
+ - None detected → prompts to create `./skills/`.
128
+ - Explicit target (`tk skills my-skills-dir`) → installs there, no env detection, no transform.
129
+ - Conflicts (skill file already exists) → fails with a clear message; use `--force` to overwrite.
130
+
131
+ ---
132
+
133
+ ## Build Lifecycle — Exact Order
134
+
135
+ ```
136
+ websrc/ ─────────────────────────────────────────────────→ web/
137
+
138
+ [1] .pre.ts Run pre-render scripts (Bun runtime)
139
+ Each .pre.ts modifies its paired .html
140
+ — runs BEFORE components, can inject custom elements
141
+
142
+ [2] Iterative loop (max 10 iterations, until no more changes):
143
+ ├─ .com.ts Execute TypeScript components
144
+ ├─ .com.html Inline HTML components
145
+ └─ .com.md Render Markdown components
146
+
147
+ [3] .post.ts Run post-render scripts (Bun runtime)
148
+ Each .post.ts mutates its paired .html with the
149
+ components ALREADY resolved — final DOM walk
150
+
151
+ [4] .ts → .js Compile TypeScript (Bun.build)
152
+
153
+ [5] Asset copy Copy everything else to the output
154
+ ```
155
+
156
+ **Key order**: `.pre.ts` runs FIRST (can inject custom elements that the component loop then processes). `.post.ts` runs LAST (sees the fully-resolved DOM — perfect for `loading="lazy"`, `rel="noopener"`, TOCs, heading `id`s).
157
+
158
+ Limits: max **10 iterations**, max **50 nesting levels**, no circular dependencies.
159
+
160
+ ---
161
+
162
+ ## File Types — Summary
163
+
164
+ | Extension | When it runs | Runtime | Special variable | Copied to web/ |
165
+ | ----------- | ------------------------ | ---------- | -------------------- | -------------- |
166
+ | `.html` | — | — | — | ✅ (processed) |
167
+ | `.ts` | Browser | V8/Browser | `window`, `document` | ✅ (→ .js) |
168
+ | `.com.html` | Build time | — | — | ❌ |
169
+ | `.com.ts` | Build time | Bun | `com` | ❌ |
170
+ | `.com.md` | Build time | — | — | ❌ |
171
+ | `.pre.ts` | Build time (BEFORE coms) | Bun | `document` | ❌ |
172
+ | `.post.ts` | Build time (AFTER coms) | Bun | `document` | ❌ |
173
+
174
+ > Full reference (the `com` API, attribute reading, nesting, examples) lives in `tkeron-components`.
175
+
176
+ ### `.html` — Page essentials
177
+
178
+ ```html
179
+ <!DOCTYPE html>
180
+ <html lang="en">
181
+ <head>
182
+ <meta charset="UTF-8" />
183
+ <title>My Site</title>
184
+ <link rel="stylesheet" href="./styles.css" />
185
+ </head>
186
+ <body>
187
+ <site-header></site-header>
188
+ <main>Content</main>
189
+ <script type="module" src="./index.ts"></script>
190
+ </body>
191
+ </html>
192
+ ```
193
+
194
+ **Two non-negotiable rules**:
195
+
196
+ 1. **`src="index.ts"` with `type="module"`**, NEVER `.js`. Tkeron compiles and rewrites the reference.
197
+ 2. **Relative paths only** (`./`, `../`). NEVER absolute (`/styles.css`) — Bun cannot resolve them at build time. Applies to `.html`, `.com.html`, and `url()` in CSS.
198
+
199
+ ---
200
+
201
+ ## IDE — Support Files
202
+
203
+ Generated by `tk init`. For the IDE only, do not affect the build.
204
+
205
+ ### `tkeron.d.ts`
206
+
207
+ ```typescript
208
+ declare module "*.com.ts" {
209
+ global {
210
+ const com: HTMLElement;
211
+ }
212
+ }
213
+
214
+ declare module "*.pre.ts" {
215
+ global {
216
+ const document: Document;
217
+ }
218
+ }
219
+
220
+ declare module "*.post.ts" {
221
+ global {
222
+ const document: Document;
223
+ }
224
+ }
225
+ ```
226
+
227
+ ### `tsconfig.json`
228
+
229
+ ```json
230
+ {
231
+ "compilerOptions": {
232
+ "target": "ESNext",
233
+ "module": "ESNext",
234
+ "lib": ["ESNext", "DOM"],
235
+ "moduleResolution": "bundler",
236
+ "strict": true,
237
+ "skipLibCheck": true
238
+ },
239
+ "include": ["websrc/**/*", "tkeron.d.ts"]
240
+ }
241
+ ```
242
+
243
+ ---
244
+
245
+ ## Environment Variables
246
+
247
+ ```typescript
248
+ // In .pre.ts, .post.ts or .com.ts (build time)
249
+ process.env.TKERON_VERSION; // tkeron version (injected automatically)
250
+ process.env.NODE_ENV; // development / production
251
+ process.env.MY_VAR; // any custom variable
252
+ ```
253
+
254
+ ```bash
255
+ NODE_ENV=production MY_VAR=value tk build
256
+ ```
257
+
258
+ Browser `.ts` files do **not** see `process.env` — `process` does not exist in the browser. To pass build-time values to the runtime, write them into the DOM from a `.pre.ts` (e.g. `<meta name="config" content="...">`) and read them from `.ts`.
259
+
260
+ ---
261
+
262
+ ## Type Checking
263
+
264
+ Tkeron does NOT type-check, it only compiles. To check types:
265
+
266
+ ```bash
267
+ bun x tsc --noEmit && tk build
268
+ ```
269
+
270
+ ---
271
+
272
+ ## Build Time vs Runtime — Quick Reference
273
+
274
+ | Aspect | Build (`.pre.ts`, `.com.ts`, `.post.ts`) | Runtime (`.ts` → `.js`) |
275
+ | -------------- | ---------------------------------------- | ----------------------- |
276
+ | When it runs | `tk build` | User's browser |
277
+ | Runtime | Bun | V8/Browser |
278
+ | `fetch()` | ✅ | ✅ |
279
+ | `window` | ❌ | ✅ |
280
+ | `localStorage` | ❌ | ✅ |
281
+ | DOM events | ❌ (lost in output) | ✅ |
282
+ | npm packages | ✅ | ❌ (not bundled) |
283
+ | Bun APIs | ✅ | ❌ |
284
+ | `process.env` | ✅ | ❌ |
285
+
286
+ For full do/don't rules and the **maximum pre-render** rule, load `tkeron-patterns`.