tskb 0.0.1 → 0.1.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.
- package/README.md +284 -866
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,837 +1,327 @@
|
|
|
1
|
-
#
|
|
1
|
+
# tskb
|
|
2
2
|
|
|
3
|
-
Build living documentation as code
|
|
3
|
+
Build **living architecture documentation as code**. Declaratively define architectural intent in large TypeScript codebases and monorepos, and turn that intent into a **compiler-verified artifact**.
|
|
4
|
+
|
|
5
|
+
> **Documentation physically bound to your code, so you can trust it.**
|
|
4
6
|
|
|
5
7
|
[](https://www.npmjs.com/package/tskb)
|
|
6
8
|
[](https://opensource.org/licenses/MIT)
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
---
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
## ⚠️ Status
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
**Experimental / early concept**.
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
- APIs and output may evolve
|
|
17
|
+
- Not production-ready
|
|
18
|
+
- Best viewed as a proof-of-concept and research tool
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
---
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
## What is tskb?
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
**tskb** is a TypeScript-native DSL for expressing **architectural intent** as code.
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
You write documentation in `.tskb.tsx` files that:
|
|
23
27
|
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
28
|
+
- are **type-checked by the TypeScript compiler**
|
|
29
|
+
- reference **real folders, files, and exports**
|
|
30
|
+
- fail the build when documentation and code drift apart
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
The result is a **structured knowledge graph** that can be:
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
- visualized (Graphviz, diagrams)
|
|
35
|
+
- queried programmatically
|
|
36
|
+
- consumed efficiently by AI assistants
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
- Documentation validated by TypeScript compiler alongside your codebase
|
|
34
|
-
- Out-of-the-box IDE support - autocomplete, refactoring, go-to-definition (native TypeScript)
|
|
35
|
-
- Zero runtime impact - purely build-time tooling, no production dependencies
|
|
36
|
-
- Generate JSON knowledge graphs optimized for `AI assistant integration` and programmatic analysis
|
|
37
|
-
- Visualize architecture as Graphviz diagrams
|
|
38
|
-
- Works with monorepos and complex project structures
|
|
38
|
+
> Refactor your code → stale documentation breaks at compile time.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
---
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
▼
|
|
56
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
57
|
-
│ Build Knowledge Graph │
|
|
58
|
-
│ npx tskb build → generates structured JSON │
|
|
59
|
-
└─────────────────┬───────────────────────────────────────────────┘
|
|
60
|
-
│
|
|
61
|
-
├──────────────────────┬──────────────────────┐
|
|
62
|
-
▼ ▼ ▼
|
|
63
|
-
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
64
|
-
│ AI Assistants │ │ Visualization │ │ CI/CD Checks │
|
|
65
|
-
│ Optimized │ │ Graphviz │ │ Architecture │
|
|
66
|
-
│ Context │ │ Diagrams │ │ Validation │
|
|
67
|
-
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
68
|
-
```
|
|
42
|
+
## Why tskb exists
|
|
43
|
+
|
|
44
|
+
Large TypeScript codebases eventually suffer from:
|
|
45
|
+
|
|
46
|
+
- **Tribal knowledge** - architecture lives in senior developers’ heads
|
|
47
|
+
- **Compound complexity** - the mental model becomes fragile and expensive to communicate
|
|
48
|
+
- **Documentation decay** - Markdown and diagrams drift silently
|
|
49
|
+
|
|
50
|
+
tskb addresses this by making architecture documentation:
|
|
51
|
+
|
|
52
|
+
- **typed**
|
|
53
|
+
- **validated**
|
|
54
|
+
- **enforced at build time**
|
|
69
55
|
|
|
70
|
-
|
|
56
|
+
---
|
|
71
57
|
|
|
72
|
-
|
|
58
|
+
## Core features
|
|
73
59
|
|
|
74
|
-
|
|
60
|
+
- Architecture as code using TSX
|
|
61
|
+
- Compiler-verified references via `typeof import()`
|
|
62
|
+
- **Type-checked code snippets** (not copied text)
|
|
63
|
+
- Native IDE support (autocomplete, refactors)
|
|
64
|
+
- Zero runtime impact (pure build-time tooling)
|
|
65
|
+
- JSON knowledge graph output
|
|
66
|
+
- Graphviz visualization
|
|
67
|
+
- Monorepo-friendly by design
|
|
68
|
+
- Optimized for AI context & RAG pipelines
|
|
75
69
|
|
|
76
|
-
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Quick start (recommended setup)
|
|
73
|
+
|
|
74
|
+
### 0) Create a dedicated docs package
|
|
75
|
+
|
|
76
|
+
Keep docs isolated from production dependencies while still “seeing” your source code.
|
|
77
|
+
|
|
78
|
+
**Repo structure:**
|
|
77
79
|
|
|
78
80
|
```
|
|
79
81
|
your-repo/
|
|
80
82
|
├── src/ # Your source code
|
|
81
|
-
├── docs/ #
|
|
83
|
+
├── docs/ # tskb docs package (created below)
|
|
82
84
|
│ ├── package.json
|
|
83
85
|
│ ├── tsconfig.json
|
|
84
86
|
│ └── *.tskb.tsx
|
|
85
|
-
└── package.json
|
|
87
|
+
└── package.json
|
|
86
88
|
```
|
|
87
89
|
|
|
88
|
-
**Create
|
|
90
|
+
**Create it:**
|
|
89
91
|
|
|
90
92
|
```bash
|
|
91
|
-
# In your repo root (where your source files live)
|
|
92
93
|
mkdir docs
|
|
93
94
|
cd docs
|
|
94
95
|
npm init -y
|
|
95
96
|
npm install --save-dev tskb
|
|
96
97
|
```
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
> For monorepos: put `docs/` at workspace root (or as a workspace), and ensure `rootDir` / `baseUrl` point to the workspace root that contains all packages you want to document.
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
---
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
### 1) Configure TypeScript for docs
|
|
104
|
+
|
|
105
|
+
`docs/tsconfig.json` should be able to type-check your real code.
|
|
103
106
|
|
|
104
107
|
```json
|
|
105
108
|
{
|
|
106
109
|
"compilerOptions": {
|
|
107
|
-
"target": "
|
|
110
|
+
"target": "esnext",
|
|
108
111
|
"module": "NodeNext",
|
|
109
112
|
"moduleResolution": "NodeNext",
|
|
113
|
+
|
|
114
|
+
"strict": true,
|
|
115
|
+
"skipLibCheck": true,
|
|
116
|
+
"forceConsistentCasingInFileNames": true,
|
|
117
|
+
"resolveJsonModule": true,
|
|
118
|
+
"allowJs": true,
|
|
119
|
+
"esModuleInterop": true,
|
|
120
|
+
|
|
110
121
|
"jsx": "react-jsx",
|
|
111
122
|
"jsxImportSource": "tskb",
|
|
112
|
-
|
|
113
|
-
"
|
|
123
|
+
|
|
124
|
+
"rootDir": "../",
|
|
125
|
+
"baseUrl": "../",
|
|
126
|
+
|
|
114
127
|
"paths": {
|
|
115
|
-
"@/*": ["src/*"]
|
|
128
|
+
"@/*": ["src/*"]
|
|
116
129
|
}
|
|
117
130
|
},
|
|
118
131
|
"include": ["**/*.tskb.tsx"]
|
|
119
132
|
}
|
|
120
133
|
```
|
|
121
134
|
|
|
122
|
-
|
|
135
|
+
Notes:
|
|
123
136
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
"scripts": {
|
|
127
|
-
"generate": "tskb \"**/*.tskb.tsx\" --out dist/graph.json --tsconfig tsconfig.json"
|
|
128
|
-
},
|
|
129
|
-
"devDependencies": {
|
|
130
|
-
"tskb": "latest"
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
```
|
|
137
|
+
- `moduleResolution: "NodeNext"` means ESM-style imports with **explicit extensions** (often `.js`).
|
|
138
|
+
- `rootDir` / `baseUrl` typically point to repo root so the docs program can resolve your code.
|
|
134
139
|
|
|
135
|
-
|
|
140
|
+
---
|
|
136
141
|
|
|
137
|
-
###
|
|
142
|
+
### 2) Add a build script
|
|
138
143
|
|
|
139
|
-
|
|
144
|
+
`docs/package.json`:
|
|
140
145
|
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
declare global {
|
|
146
|
-
namespace tskb {
|
|
147
|
-
interface Folders {
|
|
148
|
-
Server: Folder<{
|
|
149
|
-
desc: "Node.js backend API with services, controllers, and middleware";
|
|
150
|
-
path: "src/server";
|
|
151
|
-
}>;
|
|
152
|
-
Client: Folder<{
|
|
153
|
-
desc: "React frontend with components and state management";
|
|
154
|
-
path: "src/client";
|
|
155
|
-
}>;
|
|
156
|
-
Repositories: Folder<{
|
|
157
|
-
desc: "Data access layer abstracting database operations";
|
|
158
|
-
path: "src/server/database/repositories";
|
|
159
|
-
}>;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
interface Exports {
|
|
163
|
-
AuthService: Export<{
|
|
164
|
-
desc: "Handles user authentication, registration, and token management";
|
|
165
|
-
type: typeof import("../src/server/services/auth.service.js").AuthService;
|
|
166
|
-
}>;
|
|
167
|
-
TaskRepository: Export<{
|
|
168
|
-
desc: "Data access layer for task persistence with pagination";
|
|
169
|
-
type: typeof import("../src/server/database/repositories/task.repository.js").TaskRepository;
|
|
170
|
-
}>;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
interface Terms {
|
|
174
|
-
jwt: Term<"JSON Web Token - stateless authentication using signed tokens">;
|
|
175
|
-
repositoryPattern: Term<"Data access pattern isolating database logic from business logic">;
|
|
176
|
-
}
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"scripts": {
|
|
149
|
+
"generate": "tskb "**/*.tskb.tsx" --out dist/graph.json --tsconfig tsconfig.json"
|
|
177
150
|
}
|
|
178
151
|
}
|
|
179
152
|
```
|
|
180
153
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
Create documentation files that reference your vocabulary.
|
|
184
|
-
|
|
185
|
-
- Reference terms/exports defined in ANY .tskb.tsx file in your project
|
|
186
|
-
- TypeScript declaration merging makes all vocabulary globally available
|
|
187
|
-
- No need for a central registry - enables `distributed authorship` in large projects
|
|
188
|
-
|
|
189
|
-
```tsx
|
|
190
|
-
// docs/authentication-system.tskb.tsx
|
|
191
|
-
import { Doc, H1, H2, P, Snippet, ref } from "tskb";
|
|
192
|
-
import { UserRepository } from "../src/server/database/repositories/user.repository.js";
|
|
193
|
-
import { LoginCredentials, AuthResponse } from "../src/shared/types/auth.types.js";
|
|
194
|
-
|
|
195
|
-
// Create type-safe references to your vocabulary
|
|
196
|
-
const JwtTerm = ref as tskb.Terms["jwt"];
|
|
197
|
-
const AuthServiceExport = ref as tskb.Exports["AuthService"];
|
|
198
|
-
const ServerFolder = ref as tskb.Folders["Server"];
|
|
199
|
-
|
|
200
|
-
export default (
|
|
201
|
-
<Doc>
|
|
202
|
-
<H1>Authentication System</H1>
|
|
203
|
-
|
|
204
|
-
<P>
|
|
205
|
-
The authentication system in {ServerFolder} provides secure user login and session management
|
|
206
|
-
using {JwtTerm} tokens.
|
|
207
|
-
</P>
|
|
208
|
-
|
|
209
|
-
<H2>Server-Side Authentication</H2>
|
|
210
|
-
|
|
211
|
-
<P>
|
|
212
|
-
The {AuthServiceExport} handles core authentication logic including password validation, token
|
|
213
|
-
generation, and user verification.
|
|
214
|
-
</P>
|
|
215
|
-
|
|
216
|
-
<Snippet
|
|
217
|
-
code={() => {
|
|
218
|
-
const jwt = require("jsonwebtoken");
|
|
219
|
-
|
|
220
|
-
class AuthService {
|
|
221
|
-
constructor(private userRepository: UserRepository) {}
|
|
222
|
-
|
|
223
|
-
async login(credentials: LoginCredentials): Promise<AuthResponse> {
|
|
224
|
-
const user = await this.userRepository.findByEmail(credentials.email);
|
|
225
|
-
if (!user) throw new Error("User not found");
|
|
226
|
-
|
|
227
|
-
const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET);
|
|
228
|
-
return { token, user };
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}}
|
|
232
|
-
/>
|
|
233
|
-
</Doc>
|
|
234
|
-
);
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
If `UserRepository.findByEmail()` signature changes or gets removed, this doc won't compile.
|
|
238
|
-
|
|
239
|
-
Example of validation failure:
|
|
240
|
-
|
|
241
|
-
```
|
|
242
|
-
tskb build
|
|
243
|
-
Pattern: **/*.tskb.tsx
|
|
244
|
-
Tsconfig: tsconfig.json
|
|
245
|
-
|
|
246
|
-
Found 11 documentation files
|
|
247
|
-
Creating TypeScript program...
|
|
248
|
-
❌ Error: TypeScript compilation errors:
|
|
249
|
-
docs/authentication-system.tskb.tsx (18,56): Property 'findByEmail' does not exist on type 'UserRepository'.
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
The build fails immediately when documentation references code that doesn't exist.
|
|
253
|
-
|
|
254
|
-
### 3. Generate the knowledge graph
|
|
154
|
+
Run it:
|
|
255
155
|
|
|
256
156
|
```bash
|
|
257
157
|
cd docs
|
|
258
158
|
npm run generate
|
|
259
159
|
```
|
|
260
160
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
```bash
|
|
264
|
-
# Build the knowledge graph
|
|
265
|
-
npx tskb "docs/**/*.tskb.tsx" --out ./dist/graph.json --tsconfig tsconfig.json
|
|
266
|
-
```
|
|
161
|
+
---
|
|
267
162
|
|
|
268
|
-
|
|
163
|
+
## Define your vocabulary
|
|
269
164
|
|
|
270
|
-
|
|
271
|
-
tskb build
|
|
272
|
-
Pattern: **/*.tskb.tsx
|
|
273
|
-
Tsconfig: tsconfig.json
|
|
165
|
+
Declare architecture primitives using TypeScript declaration merging.
|
|
274
166
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
Base directory: D:\tskb
|
|
279
|
-
├─ 7 folders
|
|
280
|
-
│ └─ Paths: 7 valid, 0 missing
|
|
281
|
-
├─ 14 modules
|
|
282
|
-
│ └─ Imports: 14 valid, 0 missing
|
|
283
|
-
└─ 19 terms
|
|
284
|
-
Extracting documentation...
|
|
285
|
-
└─ 4 docs
|
|
286
|
-
Building knowledge graph...
|
|
287
|
-
├─ 7 folder nodes
|
|
288
|
-
├─ 14 module nodes
|
|
289
|
-
├─ 24 export nodes
|
|
290
|
-
├─ 19 term nodes
|
|
291
|
-
├─ 4 doc nodes
|
|
292
|
-
└─ 90 edges
|
|
293
|
-
Writing graph to ./dist/graph.json...
|
|
294
|
-
|
|
295
|
-
Done!
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
Visualize the graph:
|
|
299
|
-
|
|
300
|
-
```bash
|
|
301
|
-
# Generate visualization
|
|
302
|
-
npx tskb visualize ./dist/graph.json --out ./dist/architecture.dot
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
### 4. View the results
|
|
306
|
-
|
|
307
|
-
```bash
|
|
308
|
-
# Render as PNG (requires Graphviz)
|
|
309
|
-
dot -Tpng ./dist/architecture.dot -o ./dist/architecture.png
|
|
310
|
-
|
|
311
|
-
# Or view interactively
|
|
312
|
-
xdot ./dist/architecture.dot
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
Output is a JSON graph you can query programmatically or feed to AI tools.
|
|
316
|
-
|
|
317
|
-
## Installation
|
|
318
|
-
|
|
319
|
-
```bash
|
|
320
|
-
npm install --save-dev tskb
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
## Core Concepts
|
|
324
|
-
|
|
325
|
-
### Folders
|
|
326
|
-
|
|
327
|
-
Represent logical groupings in your codebase (features, layers, packages):
|
|
328
|
-
|
|
329
|
-
```typescript
|
|
330
|
-
import type { Folder } from "tskb";
|
|
167
|
+
```tsx
|
|
168
|
+
// docs/vocabulary.tskb.tsx
|
|
169
|
+
import type { Folder, Export, Term } from "tskb";
|
|
331
170
|
|
|
332
171
|
declare global {
|
|
333
172
|
namespace tskb {
|
|
334
173
|
interface Folders {
|
|
335
|
-
|
|
336
|
-
desc: "
|
|
337
|
-
path: "
|
|
174
|
+
DataLayer: Folder<{
|
|
175
|
+
desc: "Data access layer with repositories and database logic";
|
|
176
|
+
path: "src/server/database";
|
|
177
|
+
}>;
|
|
178
|
+
ServiceLayer: Folder<{
|
|
179
|
+
desc: "Business logic and application services";
|
|
180
|
+
path: "src/server/services";
|
|
181
|
+
}>;
|
|
182
|
+
APILayer: Folder<{
|
|
183
|
+
desc: "HTTP controllers and route handlers";
|
|
184
|
+
path: "src/server/controllers";
|
|
338
185
|
}>;
|
|
339
186
|
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Modules
|
|
345
187
|
|
|
346
|
-
Modules represent entire files in your codebase. Use when documenting a file as a whole unit:
|
|
347
|
-
|
|
348
|
-
```typescript
|
|
349
|
-
import type { Module } from "tskb";
|
|
350
|
-
|
|
351
|
-
declare global {
|
|
352
|
-
namespace tskb {
|
|
353
188
|
interface Modules {
|
|
354
|
-
|
|
355
|
-
desc: "
|
|
356
|
-
path: typeof import("
|
|
357
|
-
}>;
|
|
358
|
-
"auth.middleware": Module<{
|
|
359
|
-
desc: "Authentication middleware for protected routes";
|
|
360
|
-
path: typeof import("@/server/middleware/auth.middleware");
|
|
189
|
+
AuthServiceModule: Module<{
|
|
190
|
+
desc: "Authentication service module";
|
|
191
|
+
path: typeof import("../src/server/services/auth.service.js");
|
|
361
192
|
}>;
|
|
362
193
|
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
**When to use Modules:** Reference entire files when describing file-level organization or when the file exports multiple related items as a cohesive unit.
|
|
368
|
-
|
|
369
|
-
### Exports
|
|
370
|
-
|
|
371
|
-
Exports represent specific named exports from your modules (classes, functions, constants). Use when you need to reference individual exports with precise type safety:
|
|
372
|
-
|
|
373
|
-
**When to use Exports:** Reference specific classes, functions, or constants when documenting their role in the architecture. Provides exact type checking for that export.
|
|
374
|
-
|
|
375
|
-
```typescript
|
|
376
|
-
import type { Export } from "tskb";
|
|
377
194
|
|
|
378
|
-
declare global {
|
|
379
|
-
namespace tskb {
|
|
380
195
|
interface Exports {
|
|
381
|
-
|
|
382
|
-
desc: "
|
|
383
|
-
type: typeof import("
|
|
196
|
+
UserRepository: Export<{
|
|
197
|
+
desc: "User data access using repository pattern";
|
|
198
|
+
type: typeof import("../src/server/database/repositories/user.repository.js").UserRepository;
|
|
384
199
|
}>;
|
|
385
200
|
AuthService: Export<{
|
|
386
|
-
desc: "Authentication
|
|
387
|
-
type: typeof import("
|
|
388
|
-
}>;
|
|
389
|
-
authenticate: Export<{
|
|
390
|
-
desc: "Middleware function to verify JWT tokens";
|
|
391
|
-
type: typeof import("@/server/middleware/auth.middleware").authenticate;
|
|
201
|
+
desc: "Authentication and authorization business logic";
|
|
202
|
+
type: typeof import("../src/server/services/auth.service.js").AuthService;
|
|
392
203
|
}>;
|
|
393
204
|
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
```
|
|
397
205
|
|
|
398
|
-
The `Export<>` primitive uses TypeScript's `typeof import()` syntax to create type-safe references to actual code exports. This ensures documentation stays in sync with your codebase.
|
|
399
|
-
|
|
400
|
-
### Terms
|
|
401
|
-
|
|
402
|
-
Represent domain concepts, patterns, or terminology:
|
|
403
|
-
|
|
404
|
-
```typescript
|
|
405
|
-
import type { Term } from "tskb";
|
|
406
|
-
|
|
407
|
-
declare global {
|
|
408
|
-
namespace tskb {
|
|
409
206
|
interface Terms {
|
|
410
|
-
|
|
207
|
+
"repository-pattern": Term<"Repository Pattern for data access abstraction">;
|
|
208
|
+
jwt: Term<"JSON Web Tokens for stateless authentication">;
|
|
209
|
+
"layered-architecture": Term<"Layered architecture pattern (API → Service → Data)">;
|
|
411
210
|
}
|
|
412
211
|
}
|
|
413
212
|
}
|
|
414
213
|
```
|
|
415
214
|
|
|
416
|
-
|
|
215
|
+
---
|
|
417
216
|
|
|
418
|
-
|
|
217
|
+
## Write documentation
|
|
419
218
|
|
|
420
|
-
|
|
421
|
-
- `<H1>`, `<H2>`, `<H3>` - Headings
|
|
422
|
-
- `<P>` - Paragraphs
|
|
423
|
-
- `<List>`, `<Li>` - Lists
|
|
424
|
-
- `<Snippet>` - Code snippets
|
|
425
|
-
|
|
426
|
-
**Referencing entities:**
|
|
427
|
-
|
|
428
|
-
Extract references to constants before using in JSX. The `ref` constant is exported from tskb and acts as a type-safe reference placeholder:
|
|
219
|
+
Reference your global vocabulary to document architecture. Multiple teams can author docs that all use the same shared architectural terms.
|
|
429
220
|
|
|
430
221
|
```tsx
|
|
431
|
-
|
|
222
|
+
// docs/authentication.tskb.tsx
|
|
223
|
+
import { Doc, H1, H2, P, Snippet, ref } from "tskb";
|
|
224
|
+
import type { AuthService } from "../src/server/services/auth.service.js";
|
|
225
|
+
import type { UserRepository } from "../src/server/database/repositories/user.repository.js";
|
|
226
|
+
import type { LoginCredentials, AuthResponse } from "../src/shared/types/auth.types.js";
|
|
432
227
|
|
|
433
|
-
|
|
434
|
-
const
|
|
435
|
-
const
|
|
228
|
+
// Reference the global vocabulary
|
|
229
|
+
const ServiceLayer = ref as tskb.Folders["ServiceLayer"];
|
|
230
|
+
const DataLayer = ref as tskb.Folders["DataLayer"];
|
|
231
|
+
const AuthServiceExport = ref as tskb.Exports["AuthService"];
|
|
232
|
+
const UserRepositoryExport = ref as tskb.Exports["UserRepository"];
|
|
233
|
+
const Jwt = ref as tskb.Terms["jwt"];
|
|
234
|
+
const RepositoryPattern = ref as tskb.Terms["repository-pattern"];
|
|
436
235
|
|
|
437
236
|
export default (
|
|
438
237
|
<Doc>
|
|
238
|
+
<H1>Authentication Architecture</H1>
|
|
239
|
+
|
|
439
240
|
<P>
|
|
440
|
-
The {
|
|
241
|
+
The {AuthServiceExport} in the {ServiceLayer} handles authentication using {Jwt}. It depends
|
|
242
|
+
on {UserRepositoryExport} in the {DataLayer} following the {RepositoryPattern}.
|
|
441
243
|
</P>
|
|
442
|
-
</Doc>
|
|
443
|
-
);
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
**Why extract to constants?** JSX children need constant references, not inline type assertions. This pattern enables TypeScript to validate your vocabulary references while keeping JSX readable.
|
|
447
|
-
|
|
448
|
-
**Code snippets:**
|
|
449
|
-
|
|
450
|
-
The `<Snippet>` component extracts code as a string for documentation - the function is never executed:
|
|
451
|
-
|
|
452
|
-
```tsx
|
|
453
|
-
<Snippet
|
|
454
|
-
code={() => {
|
|
455
|
-
// Your code here - will be stringified, not executed
|
|
456
|
-
const result = doSomething();
|
|
457
|
-
return result;
|
|
458
|
-
}}
|
|
459
|
-
/>
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
The arrow function body is converted to a formatted code string. You can import types and reference them inside snippets - TypeScript validates everything, but the code is only used for documentation.
|
|
463
244
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
You can import React components from your application to use in code snippets with full TypeScript support:
|
|
467
|
-
|
|
468
|
-
```tsx
|
|
469
|
-
// Import with .js extension (NodeNext resolves to .tsx source)
|
|
470
|
-
import { useContext } from "react";
|
|
471
|
-
import { AuthContext } from "examples/taskflow-app/src/client/contexts/AuthContext.js";
|
|
472
|
-
import { Doc, H2, Snippet } from "tskb";
|
|
473
|
-
|
|
474
|
-
export default (
|
|
475
|
-
<Doc>
|
|
476
|
-
<H2>Client Authentication Context</H2>
|
|
245
|
+
<H2>Example: Login Flow</H2>
|
|
477
246
|
|
|
478
247
|
<Snippet
|
|
479
|
-
code={() => {
|
|
480
|
-
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
await login({ email: "user@example.com", password: "pass" });
|
|
248
|
+
code={async () => {
|
|
249
|
+
const authService: AuthService = new AuthService();
|
|
250
|
+
const credentials: LoginCredentials = {
|
|
251
|
+
email: "user@example.com",
|
|
252
|
+
password: "hashedPassword",
|
|
485
253
|
};
|
|
486
|
-
|
|
487
|
-
return
|
|
254
|
+
const response: AuthResponse = await authService.login(credentials);
|
|
255
|
+
return response.tokens.accessToken;
|
|
488
256
|
}}
|
|
489
257
|
/>
|
|
490
258
|
</Doc>
|
|
491
259
|
);
|
|
492
260
|
```
|
|
493
261
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
- With `moduleResolution: "NodeNext"`, TypeScript follows Node.js ESM rules
|
|
497
|
-
- Import paths use `.js` extensions (required for ESM)
|
|
498
|
-
- TypeScript automatically resolves to `.tsx` source files during type-checking
|
|
499
|
-
- Your JSX uses tskb's runtime via `jsxImportSource: "tskb"`
|
|
500
|
-
- Imported components provide types but aren't executed (just stringified)
|
|
501
|
-
- Works with workspace packages, monorepos, and relative imports
|
|
502
|
-
|
|
503
|
-
**Required tsconfig settings:**
|
|
504
|
-
|
|
505
|
-
```json
|
|
506
|
-
{
|
|
507
|
-
"compilerOptions": {
|
|
508
|
-
"module": "NodeNext",
|
|
509
|
-
"moduleResolution": "NodeNext",
|
|
510
|
-
"jsx": "react-jsx",
|
|
511
|
-
"jsxImportSource": "tskb",
|
|
512
|
-
"allowJs": true,
|
|
513
|
-
"esModuleInterop": true
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
**Why `.js` extensions in imports?** With `moduleResolution: "NodeNext"`, TypeScript follows Node.js ESM rules which require explicit file extensions. TypeScript automatically resolves `.js` to `.tsx` source files during type-checking - you get full type safety while following ESM standards.
|
|
262
|
+
---
|
|
519
263
|
|
|
520
|
-
|
|
264
|
+
## Snippet type checking
|
|
521
265
|
|
|
522
|
-
|
|
266
|
+
`<Snippet>` is **not** a string literal.
|
|
523
267
|
|
|
524
|
-
|
|
268
|
+
- Snippet bodies are fully type-checked
|
|
269
|
+
- Real types and APIs can be imported
|
|
270
|
+
- Broken examples fail the documentation build
|
|
525
271
|
|
|
526
272
|
```tsx
|
|
527
|
-
//
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
</Constraint>
|
|
533
|
-
|
|
534
|
-
// Explicit relationships
|
|
535
|
-
<Relation from={AuthServiceExport} to={UserRepositoryExport} type="depends-on">
|
|
536
|
-
Uses repository for user authentication
|
|
537
|
-
</Relation>
|
|
538
|
-
|
|
539
|
-
// Data flow diagrams
|
|
540
|
-
<Flow>
|
|
541
|
-
<Step component={UIComponent}>User submits form</Step>
|
|
542
|
-
<Step component={ServiceLayer}>Validates and processes</Step>
|
|
543
|
-
<Step component={DataLayer}>Persists to database</Step>
|
|
544
|
-
</Flow>
|
|
545
|
-
|
|
546
|
-
// Layer validation
|
|
547
|
-
<Layers>
|
|
548
|
-
<Layer name="presentation" cannot="import-from" layer="data" />
|
|
549
|
-
<Layer name="business" can="import-from" layer="data" />
|
|
550
|
-
</Layers>
|
|
551
|
-
|
|
552
|
-
// Custom diagrams
|
|
553
|
-
<SequenceDiagram>
|
|
554
|
-
<Actor name="Client" />
|
|
555
|
-
<Actor name="Server" />
|
|
556
|
-
<Message from="Client" to="Server">POST /login</Message>
|
|
557
|
-
<Message from="Server" to="Client">200 {token}</Message>
|
|
558
|
-
</SequenceDiagram>
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
These custom components could be implemented through a future plugin system, enabling domain-specific architectural documentation while maintaining type safety through the TypeScript compiler.
|
|
562
|
-
|
|
563
|
-
## Documentation Guidelines
|
|
564
|
-
|
|
565
|
-
### Structure over implementation
|
|
566
|
-
|
|
567
|
-
Documentation should describe what exists and where, not how it works. Focus on architecture and relationships between components.
|
|
568
|
-
|
|
569
|
-
**Do:**
|
|
570
|
-
|
|
571
|
-
- Declare root-level folders first (core layers, major features)
|
|
572
|
-
- Point to where things live with short descriptions
|
|
573
|
-
- Document important relationships between modules
|
|
574
|
-
- Reference actual files/exports using `typeof import()`
|
|
575
|
-
- Focus on architecture and structure
|
|
576
|
-
|
|
577
|
-
**Don't:**
|
|
578
|
-
|
|
579
|
-
- ~~Explain implementation details (that's in the code)~~
|
|
580
|
-
- ~~Duplicate API documentation (use TSDoc for that)~~
|
|
581
|
-
- ~~Write long explanations about how code works~~
|
|
582
|
-
- ~~Document every single file or function~~
|
|
583
|
-
|
|
584
|
-
### Start with the Foundation
|
|
585
|
-
|
|
586
|
-
**1. Declare major folders first:**
|
|
587
|
-
|
|
588
|
-
```tsx
|
|
589
|
-
import type { Folder } from "tskb";
|
|
590
|
-
|
|
591
|
-
declare global {
|
|
592
|
-
namespace tskb {
|
|
593
|
-
interface Folders {
|
|
594
|
-
// Top-level architecture
|
|
595
|
-
"src.client": Folder<{
|
|
596
|
-
desc: "Frontend React application";
|
|
597
|
-
path: "src/client";
|
|
598
|
-
}>;
|
|
599
|
-
"src.server": Folder<{
|
|
600
|
-
desc: "Backend Node.js API";
|
|
601
|
-
path: "src/server";
|
|
602
|
-
}>;
|
|
603
|
-
"src.shared": Folder<{
|
|
604
|
-
desc: "Shared types and utilities";
|
|
605
|
-
path: "src/shared";
|
|
606
|
-
}>;
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
**2. Declare important modules:**
|
|
613
|
-
|
|
614
|
-
```tsx
|
|
615
|
-
import type { Export } from "tskb";
|
|
616
|
-
|
|
617
|
-
declare global {
|
|
618
|
-
namespace tskb {
|
|
619
|
-
interface Exports {
|
|
620
|
-
// Core modules that matter architecturally
|
|
621
|
-
"api.client": Export<{
|
|
622
|
-
desc: "HTTP client for API communication - entry point for all server requests";
|
|
623
|
-
type: typeof import("@/client/services/api.client");
|
|
624
|
-
}>;
|
|
625
|
-
|
|
626
|
-
"auth.service": Export<{
|
|
627
|
-
desc: "Authentication service - handles login, logout, session management";
|
|
628
|
-
type: typeof import("@/server/services/auth.service");
|
|
629
|
-
}>;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
```
|
|
634
|
-
|
|
635
|
-
**3. Define domain terms:**
|
|
636
|
-
|
|
637
|
-
```tsx
|
|
638
|
-
import type { Term } from "tskb";
|
|
639
|
-
|
|
640
|
-
declare global {
|
|
641
|
-
namespace tskb {
|
|
642
|
-
interface Terms {
|
|
643
|
-
// Architectural patterns, not every concept
|
|
644
|
-
jwt: Term<"JSON Web Token for stateless authentication">;
|
|
645
|
-
repository: Term<"Data access pattern isolating database logic from business logic">;
|
|
646
|
-
contextProvider: Term<"React pattern for sharing state across component tree">;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
### Documentation Structure
|
|
653
|
-
|
|
654
|
-
**High-level architecture overview:**
|
|
655
|
-
|
|
656
|
-
```tsx
|
|
657
|
-
import { Doc, H1, H2, P, ref } from "tskb";
|
|
658
|
-
|
|
659
|
-
const ClientFolder = ref as tskb.Folders["src.client"];
|
|
660
|
-
const ServerFolder = ref as tskb.Folders["src.server"];
|
|
661
|
-
const SharedFolder = ref as tskb.Folders["src.shared"];
|
|
662
|
-
const ClientMainModule = ref as tskb.Modules["client.main"];
|
|
663
|
-
const ServerMainModule = ref as tskb.Modules["server.main"];
|
|
664
|
-
const ApiClientModule = ref as tskb.Modules["api.client"];
|
|
665
|
-
const AuthServiceModule = ref as tskb.Modules["auth.service"];
|
|
666
|
-
const ContextProviderTerm = ref as tskb.Terms["contextProvider"];
|
|
667
|
-
const RepositoryTerm = ref as tskb.Terms["repository"];
|
|
668
|
-
|
|
669
|
-
export default (
|
|
670
|
-
<Doc>
|
|
671
|
-
<H1>System Architecture</H1>
|
|
672
|
-
|
|
673
|
-
<P>
|
|
674
|
-
The application has three main layers: {ClientFolder}, {ServerFolder}, and {SharedFolder}.
|
|
675
|
-
</P>
|
|
676
|
-
|
|
677
|
-
<H2>Client Layer</H2>
|
|
678
|
-
<P>
|
|
679
|
-
Entry point: {ClientMainModule}. Uses {ContextProviderTerm} pattern for state. API calls go
|
|
680
|
-
through {ApiClientModule}.
|
|
681
|
-
</P>
|
|
682
|
-
|
|
683
|
-
<H2>Server Layer</H2>
|
|
684
|
-
<P>
|
|
685
|
-
Entry point: {ServerMainModule}. Uses {RepositoryTerm} pattern for data access. Authentication
|
|
686
|
-
via {AuthServiceModule}.
|
|
687
|
-
</P>
|
|
688
|
-
</Doc>
|
|
689
|
-
);
|
|
690
|
-
```
|
|
691
|
-
|
|
692
|
-
**Focus on relationships, not details:**
|
|
693
|
-
|
|
694
|
-
```tsx
|
|
695
|
-
const TaskContextModule = ref as tskb.Modules["TaskContext"];
|
|
696
|
-
const TaskApiServiceModule = ref as tskb.Modules["task-api.service"];
|
|
697
|
-
const ApiClientModule = ref as tskb.Modules["api.client"];
|
|
273
|
+
// docs/repository-pattern.tskb.tsx
|
|
274
|
+
import { Doc, H1, P, Snippet } from "tskb";
|
|
275
|
+
import type { UserRepository } from "../src/server/database/repositories/user.repository.js";
|
|
276
|
+
import type { User } from "../src/shared/types/user.types.js";
|
|
277
|
+
import type { Database } from "../src/server/database/connection.js";
|
|
698
278
|
|
|
699
279
|
export default (
|
|
700
280
|
<Doc>
|
|
701
|
-
<
|
|
702
|
-
{TaskContextModule} provides task state to all components. It calls {TaskApiServiceModule}
|
|
703
|
-
which uses {ApiClientModule} for HTTP requests.
|
|
704
|
-
</P>
|
|
705
|
-
</Doc>
|
|
706
|
-
);
|
|
707
|
-
```
|
|
708
|
-
|
|
709
|
-
### What gets validated
|
|
710
|
-
|
|
711
|
-
**tskb catches:**
|
|
712
|
-
|
|
713
|
-
- Referenced module/folder doesn't exist
|
|
714
|
-
- Wrong import paths
|
|
715
|
-
- Files moved or renamed
|
|
716
|
-
- Removed exports
|
|
717
|
-
- Changed type signatures in code snippets
|
|
718
|
-
|
|
719
|
-
**tskb doesn't catch:**
|
|
281
|
+
<H1>Repository Pattern Example</H1>
|
|
720
282
|
|
|
721
|
-
|
|
722
|
-
- ~~Business rule modifications~~
|
|
723
|
-
- ~~Algorithm changes~~
|
|
724
|
-
- ~~Performance optimizations~~
|
|
283
|
+
<P>The UserRepository demonstrates the repository pattern for data access abstraction.</P>
|
|
725
284
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
const
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
export default (
|
|
735
|
-
<Doc>
|
|
736
|
-
<P>
|
|
737
|
-
Authentication uses {JwtTerm} tokens. Login logic in {AuthServiceModule}, validation in
|
|
738
|
-
{AuthMiddlewareModule}.
|
|
739
|
-
</P>
|
|
285
|
+
<Snippet
|
|
286
|
+
code={async () => {
|
|
287
|
+
const db: Database = new Database(config);
|
|
288
|
+
const userRepository: UserRepository = new UserRepository(db);
|
|
289
|
+
const user: User | null = await userRepository.findByEmail("test@example.com");
|
|
290
|
+
return user?.id;
|
|
291
|
+
}}
|
|
292
|
+
/>
|
|
740
293
|
</Doc>
|
|
741
294
|
);
|
|
742
|
-
|
|
743
|
-
// Bad - explains implementation
|
|
744
|
-
<P>
|
|
745
|
-
The authentication service uses bcrypt with 10 salt rounds to hash passwords, then compares using
|
|
746
|
-
a constant-time comparison function to prevent timing attacks. It generates a JWT with HMAC-SHA256
|
|
747
|
-
signing algorithm...
|
|
748
|
-
</P>;
|
|
749
|
-
```
|
|
750
|
-
|
|
751
|
-
### File organization
|
|
752
|
-
|
|
753
|
-
One file per major subsystem:
|
|
754
|
-
|
|
755
|
-
```
|
|
756
|
-
docs/
|
|
757
|
-
├── architecture-overview.tskb.tsx # Top-level structure
|
|
758
|
-
├── client-layer.tskb.tsx # Frontend architecture
|
|
759
|
-
├── server-layer.tskb.tsx # Backend architecture
|
|
760
|
-
├── data-layer.tskb.tsx # Database and repositories
|
|
761
|
-
├── authentication.tskb.tsx # Auth subsystem
|
|
762
|
-
└── vocabulary.tskb.tsx # Shared terms and concepts
|
|
763
|
-
```
|
|
764
|
-
|
|
765
|
-
Vocabulary declarations merge across files automatically (TypeScript declaration merging).
|
|
766
|
-
|
|
767
|
-
## CLI
|
|
768
|
-
|
|
769
|
-
### Build
|
|
770
|
-
|
|
771
|
-
```bash
|
|
772
|
-
tskb <pattern> --out <file> --tsconfig <path>
|
|
773
295
|
```
|
|
774
296
|
|
|
775
|
-
|
|
776
|
-
- `--out` — Output path for knowledge graph JSON
|
|
777
|
-
- `--tsconfig` — Path to tsconfig.json
|
|
778
|
-
|
|
779
|
-
### Visualize
|
|
297
|
+
If the API changes:
|
|
780
298
|
|
|
781
|
-
```
|
|
782
|
-
|
|
299
|
+
```text
|
|
300
|
+
❌ Property 'findByEmail' does not exist on type 'UserRepository'.
|
|
783
301
|
```
|
|
784
302
|
|
|
785
|
-
-
|
|
786
|
-
- `--out` — Output path for DOT file
|
|
787
|
-
|
|
788
|
-
## Use Cases
|
|
789
|
-
|
|
790
|
-
### AI assistants
|
|
791
|
-
|
|
792
|
-
The knowledge graph provides optimized architectural intent for AI tools - a structured, queryable representation of your system's design, relationships, and patterns. Instead of having AI read thousands of files to understand your architecture, it gets a focused map showing:
|
|
793
|
-
|
|
794
|
-
- What components exist and their purpose
|
|
795
|
-
- How modules relate to each other
|
|
796
|
-
- Where specific functionality lives
|
|
797
|
-
- What patterns and terms your team uses
|
|
798
|
-
|
|
799
|
-
This reduces AI hallucinations and improves response accuracy by giving context without noise.
|
|
800
|
-
|
|
801
|
-
**Early tests show 10x-15x token optimization** - AI assistants can understand project architecture much faster by consuming the knowledge graph instead of scanning the entire codebase.
|
|
802
|
-
|
|
803
|
-
**Note:** Context layer integration for AI assistants is currently in development and experimentation.
|
|
804
|
-
|
|
805
|
-
### Living documentation
|
|
303
|
+
The snippet is never executed - it is parsed, validated, and stringified.
|
|
806
304
|
|
|
807
|
-
|
|
305
|
+
---
|
|
808
306
|
|
|
809
|
-
|
|
307
|
+
## What tskb produces: a semantic architecture graph
|
|
810
308
|
|
|
811
|
-
|
|
309
|
+
tskb builds a **typed, semantic knowledge graph** describing your system.
|
|
812
310
|
|
|
813
|
-
|
|
311
|
+
The graph captures:
|
|
814
312
|
|
|
815
|
-
|
|
313
|
+
- **Nodes** - folders, modules, exports, terms, docs
|
|
314
|
+
- **Edges** - explicit and inferred relationships
|
|
315
|
+
- **Hierarchy** - nested architectural contexts
|
|
316
|
+
- **Semantics** - intent expressed through JSX
|
|
816
317
|
|
|
817
|
-
|
|
318
|
+
This graph is the primary output. Everything else (diagrams, markdown, AI context) is derived from it.
|
|
818
319
|
|
|
819
|
-
|
|
320
|
+
---
|
|
820
321
|
|
|
821
|
-
|
|
322
|
+
## Output schema (high level)
|
|
822
323
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
- Orphaned modules (no documentation)
|
|
826
|
-
- Missing references
|
|
827
|
-
- Undocumented patterns
|
|
828
|
-
- Architectural drift
|
|
829
|
-
|
|
830
|
-
## Output Schema
|
|
831
|
-
|
|
832
|
-
The generated JSON contains:
|
|
833
|
-
|
|
834
|
-
```typescript
|
|
324
|
+
```ts
|
|
835
325
|
{
|
|
836
326
|
nodes: {
|
|
837
327
|
folders: Record<string, FolderNode>;
|
|
@@ -848,238 +338,166 @@ The generated JSON contains:
|
|
|
848
338
|
metadata: {
|
|
849
339
|
generatedAt: string;
|
|
850
340
|
version: string;
|
|
851
|
-
stats: {
|
|
341
|
+
stats: {
|
|
342
|
+
folders: number;
|
|
343
|
+
modules: number;
|
|
344
|
+
exports: number;
|
|
345
|
+
terms: number;
|
|
346
|
+
docs: number;
|
|
347
|
+
edges: number;
|
|
348
|
+
};
|
|
852
349
|
}
|
|
853
350
|
}
|
|
854
351
|
```
|
|
855
352
|
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
The knowledge graph uses three types of relationships:
|
|
859
|
-
|
|
860
|
-
**`references`** - Documentation references architectural entities
|
|
861
|
-
|
|
862
|
-
- Doc → Module: Documentation describes this module
|
|
863
|
-
- Doc → Export: Documentation describes this export
|
|
864
|
-
- Doc → Folder: Documentation describes this folder
|
|
865
|
-
- Doc → Term: Documentation uses this term
|
|
353
|
+
The schema is intentionally **graph-first** and machine-oriented.
|
|
866
354
|
|
|
867
|
-
|
|
355
|
+
---
|
|
868
356
|
|
|
869
|
-
|
|
870
|
-
- Determined by path prefix matching: if child path starts with parent path + `/`, parent contains child
|
|
357
|
+
## Nested contexts
|
|
871
358
|
|
|
872
|
-
|
|
359
|
+
Folders define **architectural contexts**, not just paths.
|
|
873
360
|
|
|
874
|
-
|
|
875
|
-
- Export → Module: Export is from the same source file as module
|
|
876
|
-
- Export → Folder: Export file is within folder path (when no matching module exists)
|
|
877
|
-
- Determined by comparing resolved filesystem paths to find the most specific container
|
|
361
|
+
From folder paths, tskb infers:
|
|
878
362
|
|
|
879
|
-
|
|
363
|
+
- hierarchical containment (`contains`)
|
|
364
|
+
- ownership of modules and exports (`belongs-to`)
|
|
365
|
+
- the most specific enclosing context
|
|
880
366
|
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
The `Export<>` primitive creates type-safe references to actual code exports using TypeScript's `typeof import()` syntax:
|
|
884
|
-
|
|
885
|
-
```tsx
|
|
886
|
-
import type { Export } from "tskb";
|
|
887
|
-
|
|
888
|
-
declare global {
|
|
889
|
-
namespace tskb {
|
|
890
|
-
interface Exports {
|
|
891
|
-
// Reference a class export
|
|
892
|
-
TaskRepository: Export<{
|
|
893
|
-
desc: "Data access layer for task persistence with pagination and filtering";
|
|
894
|
-
type: typeof import("../src/server/database/repositories/task.repository.js").TaskRepository;
|
|
895
|
-
}>;
|
|
367
|
+
Your architecture becomes a **tree of nested contexts**, not a flat list.
|
|
896
368
|
|
|
897
|
-
|
|
898
|
-
AuthMiddleware: Export<{
|
|
899
|
-
desc: "Authentication middleware for protected routes";
|
|
900
|
-
type: typeof import("../src/server/middleware/auth.middleware.js").authenticate;
|
|
901
|
-
}>;
|
|
369
|
+
---
|
|
902
370
|
|
|
903
|
-
|
|
904
|
-
TaskContext: Export<{
|
|
905
|
-
desc: "React Context managing task state and CRUD operations";
|
|
906
|
-
type: typeof import("../src/client/contexts/TaskContext.js").TaskContext;
|
|
907
|
-
}>;
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
```
|
|
371
|
+
## Relations
|
|
912
372
|
|
|
913
|
-
|
|
373
|
+
Relations in the graph come from two sources:
|
|
914
374
|
|
|
915
|
-
###
|
|
375
|
+
### Explicit intent
|
|
916
376
|
|
|
917
|
-
|
|
377
|
+
When you reference entities in JSX:
|
|
918
378
|
|
|
919
379
|
```tsx
|
|
920
|
-
|
|
921
|
-
import type { Export } from "tskb";
|
|
922
|
-
|
|
923
|
-
declare global {
|
|
924
|
-
namespace tskb {
|
|
925
|
-
interface Exports {
|
|
926
|
-
TaskService: Export<{
|
|
927
|
-
desc: "Manages task CRUD operations and business logic";
|
|
928
|
-
type: typeof import("../../src/server/services/task.service.js").TaskService;
|
|
929
|
-
}>;
|
|
930
|
-
TaskRepository: Export<{
|
|
931
|
-
desc: "Data access layer for task persistence";
|
|
932
|
-
type: typeof import("../../src/server/database/repositories/task.repository.js").TaskRepository;
|
|
933
|
-
}>;
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
// In vocabulary/client-vocabulary.tskb.tsx
|
|
939
|
-
import type { Export } from "tskb";
|
|
940
|
-
|
|
941
|
-
declare global {
|
|
942
|
-
namespace tskb {
|
|
943
|
-
interface Exports {
|
|
944
|
-
TaskContext: Export<{
|
|
945
|
-
desc: "React Context managing task state";
|
|
946
|
-
type: typeof import("../../src/client/contexts/TaskContext.js").TaskContext;
|
|
947
|
-
}>;
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
// Both are available in any .tskb.tsx file after declaration merging
|
|
953
|
-
const TaskServiceExport = ref as tskb.Exports["TaskService"];
|
|
954
|
-
const TaskContextExport = ref as tskb.Exports["TaskContext"];
|
|
380
|
+
<P>Authentication is handled by {AuthService}.</P>
|
|
955
381
|
```
|
|
956
382
|
|
|
957
|
-
|
|
383
|
+
tskb records a semantic edge:
|
|
958
384
|
|
|
959
|
-
```json
|
|
960
|
-
// tsconfig.json
|
|
961
|
-
{
|
|
962
|
-
"compilerOptions": {
|
|
963
|
-
"jsx": "react-jsx",
|
|
964
|
-
"jsxImportSource": "tskb"
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
385
|
```
|
|
968
|
-
|
|
969
|
-
### Path resolution
|
|
970
|
-
|
|
971
|
-
For accurate path resolution, set `rootDir` in your tsconfig:
|
|
972
|
-
|
|
973
|
-
```json
|
|
974
|
-
{
|
|
975
|
-
"compilerOptions": {
|
|
976
|
-
"rootDir": ".",
|
|
977
|
-
"baseUrl": ".",
|
|
978
|
-
"paths": {
|
|
979
|
-
"@/*": ["src/*"]
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
}
|
|
386
|
+
Doc → AuthService (references)
|
|
983
387
|
```
|
|
984
388
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
See [Sample demo app docs](https://github.com/mitk0936/tskb/tree/main/docs/taskflow-app) for a full-stack TypeScript app with ADRs, design constraints, and layer documentation.
|
|
389
|
+
### Inferred structure
|
|
988
390
|
|
|
989
|
-
|
|
391
|
+
From filesystem paths and imports:
|
|
990
392
|
|
|
991
|
-
|
|
393
|
+
- Folder → Folder (`contains`)
|
|
394
|
+
- Module → Folder (`belongs-to`)
|
|
395
|
+
- Export → Module (`belongs-to`)
|
|
992
396
|
|
|
993
|
-
**
|
|
397
|
+
The graph combines **authored intent** with **structural truth**.
|
|
994
398
|
|
|
995
|
-
|
|
399
|
+
---
|
|
996
400
|
|
|
997
|
-
|
|
998
|
-
- `rootDir` should include parent directories to access source files
|
|
999
|
-
- Path aliases in `paths` should match your source code configuration
|
|
1000
|
-
- Verify `.js` extensions are used for imports with `moduleResolution: "NodeNext"`
|
|
401
|
+
## Why JSX: semantics, not rendering
|
|
1001
402
|
|
|
1002
|
-
|
|
403
|
+
JSX in tskb is **not about UI**.
|
|
1003
404
|
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
- Check that `include` array contains `["**/*.tskb.tsx"]`
|
|
1007
|
-
- Make sure vocabulary files have `export {};` to enable declaration merging
|
|
405
|
+
It is a **semantic DSL** that allows you to declare meaning in a structured, type-safe way.
|
|
406
|
+
Each JSX element becomes semantic data - not HTML.
|
|
1008
407
|
|
|
1009
|
-
|
|
408
|
+
JSX provides composability, static analysis, and extensibility without inventing a new syntax.
|
|
1010
409
|
|
|
1011
|
-
|
|
1012
|
-
- Use relative imports `../../../packages/...` or configure workspace path aliases
|
|
1013
|
-
- Install tskb at workspace level or in the docs package
|
|
1014
|
-
- Verify TypeScript can resolve imports from all documented packages
|
|
410
|
+
---
|
|
1015
411
|
|
|
1016
|
-
|
|
412
|
+
## Defining semantics with JSX
|
|
1017
413
|
|
|
1018
|
-
|
|
1019
|
-
- Verify module imports resolve correctly (use TypeScript's "Go to Definition")
|
|
1020
|
-
- Ensure vocabulary declarations use `typeof import()` correctly
|
|
1021
|
-
- Check console output for validation warnings about missing paths
|
|
414
|
+
Because JSX is just TypeScript, it can evolve into richer semantics:
|
|
1022
415
|
|
|
1023
|
-
|
|
416
|
+
```tsx
|
|
417
|
+
<Relation from={AuthService} to={UserRepository} type="depends-on" />
|
|
1024
418
|
|
|
1025
|
-
|
|
419
|
+
<Constraint kind="layering">
|
|
420
|
+
<Layer name="ui" cannotImport="data" />
|
|
421
|
+
</Constraint>
|
|
1026
422
|
|
|
1027
|
-
|
|
423
|
+
<Flow>
|
|
424
|
+
<Step component={LoginForm} />
|
|
425
|
+
<Step component={AuthService} />
|
|
426
|
+
<Step component={UserRepository} />
|
|
427
|
+
</Flow>
|
|
428
|
+
```
|
|
1028
429
|
|
|
1029
|
-
|
|
1030
|
-
| --------------- | ------------------------------------------------ | ----------------------------------------------------------- |
|
|
1031
|
-
| **Level** | API-level (function signatures, parameter types) | Architecture-level (module relationships, system structure) |
|
|
1032
|
-
| **Type Safety** | No type-safe references to other modules | `typeof import()` ensures references are compiler-validated |
|
|
1033
|
-
| **Output** | Extracted to HTML/JSON for display | Builds queryable knowledge graph for AI and analysis |
|
|
430
|
+
These are **semantic primitives** that compile into graph structure - not UI components.
|
|
1034
431
|
|
|
1035
|
-
|
|
432
|
+
---
|
|
1036
433
|
|
|
1037
|
-
|
|
434
|
+
## Example real output
|
|
1038
435
|
|
|
1039
|
-
|
|
1040
|
-
| -------------- | -------------------------------------------------------- | ------------------------------------------------------------ |
|
|
1041
|
-
| **Purpose** | General-purpose documentation with JSX for interactivity | Architecture documentation with type-checked code references |
|
|
1042
|
-
| **Validation** | No compiler validation of code references | TypeScript compiler validates all imports and types |
|
|
1043
|
-
| **Output** | Renders to HTML/React for display | Generates knowledge graph for programmatic analysis |
|
|
1044
|
-
| **Focus** | Content-focused (guides, tutorials, marketing pages) | Structure-focused (architecture, relationships, patterns) |
|
|
436
|
+
This is the **actual CLI output** users will see:
|
|
1045
437
|
|
|
1046
|
-
|
|
438
|
+
```text
|
|
439
|
+
tskb build
|
|
440
|
+
Pattern: **/*.tskb.tsx
|
|
441
|
+
Tsconfig: tsconfig.json
|
|
1047
442
|
|
|
1048
|
-
|
|
443
|
+
Found 7 documentation files
|
|
444
|
+
Creating TypeScript program...
|
|
445
|
+
Extracting registry (Folders, Modules, Terms)...
|
|
446
|
+
Base directory: D:\tskb
|
|
447
|
+
├─ 7 folders
|
|
448
|
+
│ └─ Paths: 7 valid, 0 missing
|
|
449
|
+
├─ 14 modules
|
|
450
|
+
│ └─ Imports: 14 valid, 0 missing
|
|
451
|
+
└─ 19 terms
|
|
452
|
+
Extracting documentation...
|
|
453
|
+
└─ 4 docs
|
|
454
|
+
Building knowledge graph...
|
|
455
|
+
├─ 7 folder nodes
|
|
456
|
+
├─ 14 module nodes
|
|
457
|
+
├─ 24 export nodes
|
|
458
|
+
├─ 19 term nodes
|
|
459
|
+
├─ 4 doc nodes
|
|
460
|
+
└─ 90 edges
|
|
461
|
+
Writing graph to ./dist/graph.json...
|
|
462
|
+
```
|
|
1049
463
|
|
|
1050
|
-
|
|
1051
|
-
| ------------------- | ---------------------------------------------- | ----------------------------------------------------------- |
|
|
1052
|
-
| **Code References** | Plain text - breaks silently when code changes | Type-checked via `typeof import()` - breaks at compile time |
|
|
1053
|
-
| **Structure** | Free-form text | Structured declarations (Folders, Exports, Terms) |
|
|
1054
|
-
| **Validation** | None - links and references are just strings | TypeScript compiler validates all references |
|
|
1055
|
-
| **Output** | Rendered as HTML/text | Knowledge graph + can generate .md files (Agents.md, etc.) |
|
|
1056
|
-
| **AI Integration** | AI parses raw text | AI gets structured graph built from type-safe documentation |
|
|
464
|
+
---
|
|
1057
465
|
|
|
1058
|
-
|
|
466
|
+
## Visualize
|
|
1059
467
|
|
|
1060
|
-
|
|
468
|
+
```bash
|
|
469
|
+
npx tskb visualize ./dist/graph.json --out ./dist/architecture.dot
|
|
470
|
+
dot -Tpng ./dist/architecture.dot -o ./dist/architecture.png
|
|
471
|
+
```
|
|
1061
472
|
|
|
1062
|
-
|
|
473
|
+
---
|
|
1063
474
|
|
|
1064
|
-
|
|
475
|
+
## How is this different?
|
|
1065
476
|
|
|
1066
|
-
|
|
477
|
+
**vs ADRs / Markdown docs:** Type-checked and validated against real code, not just text files that drift.
|
|
1067
478
|
|
|
1068
|
-
**
|
|
479
|
+
**vs Structurizr / C4 / PlantUML:** Native TypeScript (not a custom DSL), produces a queryable knowledge graph (not just static diagrams).
|
|
1069
480
|
|
|
1070
|
-
|
|
481
|
+
**vs TypeDoc:** Documents _architecture and intent_ (why components exist, how they relate), not just API surfaces (what methods exist).
|
|
1071
482
|
|
|
1072
|
-
**
|
|
483
|
+
**Unique to tskb:**
|
|
1073
484
|
|
|
1074
|
-
|
|
485
|
+
- Type-checks architecture docs at compile time
|
|
486
|
+
- Validates against actual code via `typeof import()`
|
|
487
|
+
- Documents whole systems (multiple packages, monorepos, microservices)
|
|
488
|
+
- Type-checked code snippets (not string literals)
|
|
489
|
+
- Semantic knowledge graph optimized for AI/RAG
|
|
1075
490
|
|
|
1076
|
-
|
|
491
|
+
---
|
|
1077
492
|
|
|
1078
493
|
## Roadmap
|
|
1079
494
|
|
|
1080
|
-
-
|
|
1081
|
-
-
|
|
1082
|
-
-
|
|
495
|
+
- Graph querying & optimization
|
|
496
|
+
- AI context layer (MCP)
|
|
497
|
+
- Architectural constraints
|
|
498
|
+
- Plugin system
|
|
499
|
+
|
|
500
|
+
---
|
|
1083
501
|
|
|
1084
502
|
## License
|
|
1085
503
|
|