tskb 0.0.1
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/LICENSE +21 -0
- package/README.md +1086 -0
- package/dist/cli/commands/build.d.ts +55 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +105 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/query.d.ts +10 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +399 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/visualize.d.ts +10 -0
- package/dist/cli/commands/visualize.d.ts.map +1 -0
- package/dist/cli/commands/visualize.js +26 -0
- package/dist/cli/commands/visualize.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +109 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/extraction/documentation.d.ts +28 -0
- package/dist/core/extraction/documentation.d.ts.map +1 -0
- package/dist/core/extraction/documentation.js +330 -0
- package/dist/core/extraction/documentation.js.map +1 -0
- package/dist/core/extraction/index.d.ts +11 -0
- package/dist/core/extraction/index.d.ts.map +1 -0
- package/dist/core/extraction/index.js +9 -0
- package/dist/core/extraction/index.js.map +1 -0
- package/dist/core/extraction/registry.d.ts +40 -0
- package/dist/core/extraction/registry.d.ts.map +1 -0
- package/dist/core/extraction/registry.js +604 -0
- package/dist/core/extraction/registry.js.map +1 -0
- package/dist/core/graph/builder.d.ts +37 -0
- package/dist/core/graph/builder.d.ts.map +1 -0
- package/dist/core/graph/builder.js +421 -0
- package/dist/core/graph/builder.js.map +1 -0
- package/dist/core/graph/index.d.ts +23 -0
- package/dist/core/graph/index.d.ts.map +1 -0
- package/dist/core/graph/index.js +25 -0
- package/dist/core/graph/index.js.map +1 -0
- package/dist/core/graph/types.d.ts +128 -0
- package/dist/core/graph/types.d.ts.map +1 -0
- package/dist/core/graph/types.js +9 -0
- package/dist/core/graph/types.js.map +1 -0
- package/dist/core/visualization/dot-generator.d.ts +13 -0
- package/dist/core/visualization/dot-generator.d.ts.map +1 -0
- package/dist/core/visualization/dot-generator.js +200 -0
- package/dist/core/visualization/dot-generator.js.map +1 -0
- package/dist/core/visualization/index.d.ts +20 -0
- package/dist/core/visualization/index.d.ts.map +1 -0
- package/dist/core/visualization/index.js +23 -0
- package/dist/core/visualization/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-runtime.d.ts +7 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +11 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/runtime/jsx.d.ts +84 -0
- package/dist/runtime/jsx.d.ts.map +1 -0
- package/dist/runtime/jsx.js +93 -0
- package/dist/runtime/jsx.js.map +1 -0
- package/dist/runtime/registry.d.ts +61 -0
- package/dist/runtime/registry.d.ts.map +1 -0
- package/dist/runtime/registry.js +2 -0
- package/dist/runtime/registry.js.map +1 -0
- package/dist/typescript/index.d.ts +7 -0
- package/dist/typescript/index.d.ts.map +1 -0
- package/dist/typescript/index.js +7 -0
- package/dist/typescript/index.js.map +1 -0
- package/dist/typescript/program.d.ts +33 -0
- package/dist/typescript/program.d.ts.map +1 -0
- package/dist/typescript/program.js +84 -0
- package/dist/typescript/program.js.map +1 -0
- package/package.json +73 -0
package/README.md
ADDED
|
@@ -0,0 +1,1086 @@
|
|
|
1
|
+
# \<tskb\>
|
|
2
|
+
|
|
3
|
+
Build living documentation as code. Declaratively define architecture in large TypeScript codebases and monorepos - turn the intent into a compiler-verified artifact.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/tskb)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Note
|
|
9
|
+
|
|
10
|
+
This is an `experimental concept` in early development. APIs and behavior may change. **Not ready for production use** - the package has not been extensively tested and should be considered a proof-of-concept.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
A TypeScript-native DSL for expressing architectural intent as typed declarations. Produces renderable docs/diagrams and a queryable knowledge graph, supporting type-checked snippet references, semantic relations, and constraints.
|
|
15
|
+
|
|
16
|
+
Write architecture documentation in `.tskb.tsx` files that get type-checked alongside your codebase. References to code modules, files, and exports are validated by TypeScript - `refactored code automatically invalidates stale documentation at compile-time.`
|
|
17
|
+
|
|
18
|
+
The output is a JSON knowledge graph optimized for AI assistants, visualization tools, and programmatic analysis.
|
|
19
|
+
|
|
20
|
+
## Why tskb?
|
|
21
|
+
|
|
22
|
+
Large TypeScript codebases face common challenges:
|
|
23
|
+
|
|
24
|
+
- **Tribal knowledge** - Architecture understanding locked in senior developers' heads, not accessible to new team members or AI assistants
|
|
25
|
+
- **Compound complexity** - As systems grow, the mental model of how everything connects becomes harder to maintain and communicate
|
|
26
|
+
- **Low documentation coverage** - Traditional docs fall out of sync with code, so teams stop writing them and stop trusting them
|
|
27
|
+
|
|
28
|
+
tskb solves this by making architecture documentation a first-class, compiler-verified artifact that evolves with your codebase.
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- Architecture as code - write docs in TSX files with type-checked references
|
|
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
|
|
39
|
+
|
|
40
|
+
## How It Works
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
44
|
+
│ Write Architecture Docs │
|
|
45
|
+
│ *.tskb.tsx files with type-safe references to your code │
|
|
46
|
+
└─────────────────┬───────────────────────────────────────────────┘
|
|
47
|
+
│
|
|
48
|
+
▼
|
|
49
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
50
|
+
│ TypeScript Validation │
|
|
51
|
+
│ Compiler checks all imports, types, and references │
|
|
52
|
+
│ ✓ Code exists ✓ Types match ✓ Paths correct │
|
|
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
|
+
```
|
|
69
|
+
|
|
70
|
+
## Quick Start
|
|
71
|
+
|
|
72
|
+
### 0. Set up documentation folder
|
|
73
|
+
|
|
74
|
+
Create a separate folder for your architecture docs with its own TypeScript configuration and dependencies.
|
|
75
|
+
|
|
76
|
+
**Directory structure:**
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
your-repo/
|
|
80
|
+
├── src/ # Your source code
|
|
81
|
+
├── docs/ # Documentation (created below)
|
|
82
|
+
│ ├── package.json
|
|
83
|
+
│ ├── tsconfig.json
|
|
84
|
+
│ └── *.tskb.tsx
|
|
85
|
+
└── package.json # Your main package.json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Create the docs folder:**
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# In your repo root (where your source files live)
|
|
92
|
+
mkdir docs
|
|
93
|
+
cd docs
|
|
94
|
+
npm init -y
|
|
95
|
+
npm install --save-dev tskb
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Why separate?** The docs folder is its own package that imports and references your source code. This keeps documentation dependencies isolated from your production code.
|
|
99
|
+
|
|
100
|
+
**Configure TypeScript (`docs/tsconfig.json`):**
|
|
101
|
+
|
|
102
|
+
The tsconfig needs to "see" your source files to validate imports:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"compilerOptions": {
|
|
107
|
+
"target": "ES2022",
|
|
108
|
+
"module": "NodeNext",
|
|
109
|
+
"moduleResolution": "NodeNext",
|
|
110
|
+
"jsx": "react-jsx",
|
|
111
|
+
"jsxImportSource": "tskb",
|
|
112
|
+
"rootDir": "../", // Include parent directory to access ../src
|
|
113
|
+
"baseUrl": "../", // Resolve imports from repo root
|
|
114
|
+
"paths": {
|
|
115
|
+
"@/*": ["src/*"] // Match your source code path aliases
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"include": ["**/*.tskb.tsx"]
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Add build script (`docs/package.json`):**
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"scripts": {
|
|
127
|
+
"generate": "tskb \"**/*.tskb.tsx\" --out dist/graph.json --tsconfig tsconfig.json"
|
|
128
|
+
},
|
|
129
|
+
"devDependencies": {
|
|
130
|
+
"tskb": "latest"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**For monorepos:** Install tskb as a workspace-level dependency, or in the specific docs package. The `rootDir` should point to the root of all packages you want to document.
|
|
136
|
+
|
|
137
|
+
### 1. Define your vocabulary
|
|
138
|
+
|
|
139
|
+
Create `.tskb.tsx` files declaring your architecture:
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
// docs/vocabulary.tskb.tsx
|
|
143
|
+
import type { Export, Folder, Term } from "tskb";
|
|
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
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 2. Write documentation
|
|
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
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
cd docs
|
|
258
|
+
npm run generate
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Or manually:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Build the knowledge graph
|
|
265
|
+
npx tskb "docs/**/*.tskb.tsx" --out ./dist/graph.json --tsconfig tsconfig.json
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Example output:
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
tskb build
|
|
272
|
+
Pattern: **/*.tskb.tsx
|
|
273
|
+
Tsconfig: tsconfig.json
|
|
274
|
+
|
|
275
|
+
Found 7 documentation files
|
|
276
|
+
Creating TypeScript program...
|
|
277
|
+
Extracting registry (Folders, Modules, Terms)...
|
|
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";
|
|
331
|
+
|
|
332
|
+
declare global {
|
|
333
|
+
namespace tskb {
|
|
334
|
+
interface Folders {
|
|
335
|
+
FeatureName: Folder<{
|
|
336
|
+
desc: "Description of what this folder contains";
|
|
337
|
+
path: "relative/path/from/repo/root";
|
|
338
|
+
}>;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Modules
|
|
345
|
+
|
|
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
|
+
interface Modules {
|
|
354
|
+
"task.service": Module<{
|
|
355
|
+
desc: "Task management service with CRUD operations";
|
|
356
|
+
path: typeof import("@/server/services/task.service");
|
|
357
|
+
}>;
|
|
358
|
+
"auth.middleware": Module<{
|
|
359
|
+
desc: "Authentication middleware for protected routes";
|
|
360
|
+
path: typeof import("@/server/middleware/auth.middleware");
|
|
361
|
+
}>;
|
|
362
|
+
}
|
|
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
|
+
|
|
378
|
+
declare global {
|
|
379
|
+
namespace tskb {
|
|
380
|
+
interface Exports {
|
|
381
|
+
TaskRepository: Export<{
|
|
382
|
+
desc: "Data access layer for task persistence with pagination";
|
|
383
|
+
type: typeof import("@/server/database/repositories/task.repository").TaskRepository;
|
|
384
|
+
}>;
|
|
385
|
+
AuthService: Export<{
|
|
386
|
+
desc: "Authentication service handling login and session management";
|
|
387
|
+
type: typeof import("@/server/services/auth.service").AuthService;
|
|
388
|
+
}>;
|
|
389
|
+
authenticate: Export<{
|
|
390
|
+
desc: "Middleware function to verify JWT tokens";
|
|
391
|
+
type: typeof import("@/server/middleware/auth.middleware").authenticate;
|
|
392
|
+
}>;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
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
|
+
interface Terms {
|
|
410
|
+
termName: Term<"Definition of this concept">;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Documentation Components
|
|
417
|
+
|
|
418
|
+
JSX components for writing docs:
|
|
419
|
+
|
|
420
|
+
- `<Doc>` - Document container
|
|
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:
|
|
429
|
+
|
|
430
|
+
```tsx
|
|
431
|
+
import { ref } from "tskb";
|
|
432
|
+
|
|
433
|
+
const FolderName = ref as tskb.Folders["FolderName"];
|
|
434
|
+
const ModuleName = ref as tskb.Modules["ModuleName"];
|
|
435
|
+
const termName = ref as tskb.Terms["termName"];
|
|
436
|
+
|
|
437
|
+
export default (
|
|
438
|
+
<Doc>
|
|
439
|
+
<P>
|
|
440
|
+
The {FolderName} contains {ModuleName} which implements {termName}.
|
|
441
|
+
</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
|
+
|
|
464
|
+
**Importing React components for type-safe examples:**
|
|
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>
|
|
477
|
+
|
|
478
|
+
<Snippet
|
|
479
|
+
code={() => {
|
|
480
|
+
// Type-safe! TypeScript validates AuthContext usage
|
|
481
|
+
const { user, login, logout } = useContext(AuthContext);
|
|
482
|
+
|
|
483
|
+
const handleLogin = async () => {
|
|
484
|
+
await login({ email: "user@example.com", password: "pass" });
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
return <div>{user?.name}</div>;
|
|
488
|
+
}}
|
|
489
|
+
/>
|
|
490
|
+
</Doc>
|
|
491
|
+
);
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**How it works:**
|
|
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.
|
|
519
|
+
|
|
520
|
+
### The power of JSX
|
|
521
|
+
|
|
522
|
+
Using JSX as the documentation format enables semantic, type-safe documentation that can be extended with custom components. The current component set (`<Doc>`, `<P>`, `<Snippet>`, etc.) is just the foundation.
|
|
523
|
+
|
|
524
|
+
**Future possibilities with custom JSX components:**
|
|
525
|
+
|
|
526
|
+
```tsx
|
|
527
|
+
// Architectural constraints
|
|
528
|
+
<Constraint type="layering">
|
|
529
|
+
<Layer name="UI" dependsOn={["Services"]} />
|
|
530
|
+
<Layer name="Services" dependsOn={["Data"]} />
|
|
531
|
+
<Layer name="Data" />
|
|
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"];
|
|
698
|
+
|
|
699
|
+
export default (
|
|
700
|
+
<Doc>
|
|
701
|
+
<P>
|
|
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:**
|
|
720
|
+
|
|
721
|
+
- ~~Implementation logic changes inside functions~~
|
|
722
|
+
- ~~Business rule modifications~~
|
|
723
|
+
- ~~Algorithm changes~~
|
|
724
|
+
- ~~Performance optimizations~~
|
|
725
|
+
|
|
726
|
+
`Describe structure, not behavior:`
|
|
727
|
+
|
|
728
|
+
```tsx
|
|
729
|
+
// Good - describes structure
|
|
730
|
+
const JwtTerm = ref as tskb.Terms["jwt"];
|
|
731
|
+
const AuthServiceModule = ref as tskb.Modules["auth.service"];
|
|
732
|
+
const AuthMiddlewareModule = ref as tskb.Modules["auth.middleware"];
|
|
733
|
+
|
|
734
|
+
export default (
|
|
735
|
+
<Doc>
|
|
736
|
+
<P>
|
|
737
|
+
Authentication uses {JwtTerm} tokens. Login logic in {AuthServiceModule}, validation in
|
|
738
|
+
{AuthMiddlewareModule}.
|
|
739
|
+
</P>
|
|
740
|
+
</Doc>
|
|
741
|
+
);
|
|
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
|
+
```
|
|
774
|
+
|
|
775
|
+
- `<pattern>` — Glob pattern for documentation files (e.g., `"docs/**/*.tskb.tsx"`)
|
|
776
|
+
- `--out` — Output path for knowledge graph JSON
|
|
777
|
+
- `--tsconfig` — Path to tsconfig.json
|
|
778
|
+
|
|
779
|
+
### Visualize
|
|
780
|
+
|
|
781
|
+
```bash
|
|
782
|
+
tskb visualize <input> --out <file>
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
- `<input>` — Path to knowledge graph JSON
|
|
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
|
|
806
|
+
|
|
807
|
+
Docs break when code changes, so you know immediately when they're out of sync. Works in CI.
|
|
808
|
+
|
|
809
|
+
### Onboarding
|
|
810
|
+
|
|
811
|
+
New team members can work with AI assistants that understand your architecture from day one - no need to wait for senior engineers to be available. Generate current architecture diagrams automatically and provide structured context that helps developers navigate unfamiliar codebases faster.
|
|
812
|
+
|
|
813
|
+
### Code reviews
|
|
814
|
+
|
|
815
|
+
Check if changes align with documented architecture. QA teams can understand the impact of changes much easier by referencing the knowledge graph - seeing which modules are affected and how components relate without diving through source code.
|
|
816
|
+
|
|
817
|
+
### AI-powered development
|
|
818
|
+
|
|
819
|
+
Copilot tools get a much clearer understanding of what's acceptable and where. The knowledge graph provides architectural guardrails - helping AI understand layer boundaries, valid dependencies, and project-specific patterns before suggesting code changes.
|
|
820
|
+
|
|
821
|
+
### Architecture analysis
|
|
822
|
+
|
|
823
|
+
Query the graph programmatically to find:
|
|
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
|
|
835
|
+
{
|
|
836
|
+
nodes: {
|
|
837
|
+
folders: Record<string, FolderNode>;
|
|
838
|
+
modules: Record<string, ModuleNode>;
|
|
839
|
+
exports: Record<string, ExportNode>;
|
|
840
|
+
terms: Record<string, TermNode>;
|
|
841
|
+
docs: Record<string, DocNode>;
|
|
842
|
+
},
|
|
843
|
+
edges: Array<{
|
|
844
|
+
from: string;
|
|
845
|
+
to: string;
|
|
846
|
+
type: "references" | "contains" | "belongs-to";
|
|
847
|
+
}>,
|
|
848
|
+
metadata: {
|
|
849
|
+
generatedAt: string;
|
|
850
|
+
version: string;
|
|
851
|
+
stats: { ... }
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
### Edge Types
|
|
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
|
|
866
|
+
|
|
867
|
+
**`contains`** - Hierarchical folder nesting based on filesystem paths
|
|
868
|
+
|
|
869
|
+
- Folder → Folder: Parent folder contains child folder (e.g., `src/server` contains `src/server/services`)
|
|
870
|
+
- Determined by path prefix matching: if child path starts with parent path + `/`, parent contains child
|
|
871
|
+
|
|
872
|
+
**`belongs-to`** - Module and export ownership based on resolved file paths
|
|
873
|
+
|
|
874
|
+
- Module → Folder: Module file is located within folder path
|
|
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
|
|
878
|
+
|
|
879
|
+
## Advanced
|
|
880
|
+
|
|
881
|
+
### Export<> primitive
|
|
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
|
+
}>;
|
|
896
|
+
|
|
897
|
+
// Reference a function export
|
|
898
|
+
AuthMiddleware: Export<{
|
|
899
|
+
desc: "Authentication middleware for protected routes";
|
|
900
|
+
type: typeof import("../src/server/middleware/auth.middleware.js").authenticate;
|
|
901
|
+
}>;
|
|
902
|
+
|
|
903
|
+
// Reference React Context
|
|
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
|
+
```
|
|
912
|
+
|
|
913
|
+
TypeScript validates import paths and export names at compile time. Refactoring tools can update references automatically.
|
|
914
|
+
|
|
915
|
+
### Distributed vocabulary
|
|
916
|
+
|
|
917
|
+
Vocabulary declarations merge across files using TypeScript's declaration merging:
|
|
918
|
+
|
|
919
|
+
```tsx
|
|
920
|
+
// In vocabulary/server-vocabulary.tskb.tsx
|
|
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"];
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
### JSX runtime configuration
|
|
958
|
+
|
|
959
|
+
```json
|
|
960
|
+
// tsconfig.json
|
|
961
|
+
{
|
|
962
|
+
"compilerOptions": {
|
|
963
|
+
"jsx": "react-jsx",
|
|
964
|
+
"jsxImportSource": "tskb"
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
```
|
|
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
|
+
}
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
## Examples
|
|
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.
|
|
988
|
+
|
|
989
|
+
See [Meta docs of the library itself](https://github.com/mitk0936/tskb/tree/main/docs/tskb-package) for self-documenting the tskb package itself ([visualization](https://github.com/mitk0936/tskb/blob/main/references/tskb-doc-diagram.svg)).
|
|
990
|
+
|
|
991
|
+
## Troubleshooting
|
|
992
|
+
|
|
993
|
+
**Import paths not resolving?**
|
|
994
|
+
|
|
995
|
+
Check your `tsconfig.json` settings:
|
|
996
|
+
|
|
997
|
+
- `baseUrl` should point to your repo root
|
|
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"`
|
|
1001
|
+
|
|
1002
|
+
**TypeScript errors in .tskb.tsx files?**
|
|
1003
|
+
|
|
1004
|
+
- Ensure `jsxImportSource: "tskb"` is set in tsconfig
|
|
1005
|
+
- Verify `tskb` is installed in the docs package
|
|
1006
|
+
- Check that `include` array contains `["**/*.tskb.tsx"]`
|
|
1007
|
+
- Make sure vocabulary files have `export {};` to enable declaration merging
|
|
1008
|
+
|
|
1009
|
+
**Monorepo path issues?**
|
|
1010
|
+
|
|
1011
|
+
- Set `rootDir` to the workspace root containing all packages
|
|
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
|
|
1015
|
+
|
|
1016
|
+
**Build output missing nodes or edges?**
|
|
1017
|
+
|
|
1018
|
+
- Check that folder paths exist and are relative to `rootDir`
|
|
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
|
|
1022
|
+
|
|
1023
|
+
## FAQ
|
|
1024
|
+
|
|
1025
|
+
**How is this different from JSDoc?**
|
|
1026
|
+
|
|
1027
|
+
JSDoc documents individual functions/classes in source files - what parameters they take, what they return. tskb documents architecture - how modules relate, where functionality lives, what patterns you use. JSDoc comments sit above functions; tskb files sit in a separate docs folder.
|
|
1028
|
+
|
|
1029
|
+
| | JSDoc | tskb |
|
|
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 |
|
|
1034
|
+
|
|
1035
|
+
**How is this different from MDX?**
|
|
1036
|
+
|
|
1037
|
+
MDX lets you write Markdown with embedded JSX components for rich documentation. tskb uses JSX but enforces type safety through TypeScript.
|
|
1038
|
+
|
|
1039
|
+
| | MDX | tskb |
|
|
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) |
|
|
1045
|
+
|
|
1046
|
+
**How is this different from Markdown?**
|
|
1047
|
+
|
|
1048
|
+
Markdown is great for writing documentation, but it has no understanding of your code structure. tskb builds on TypeScript to create type-safe architectural documentation.
|
|
1049
|
+
|
|
1050
|
+
| | Markdown (.md) | tskb |
|
|
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 |
|
|
1057
|
+
|
|
1058
|
+
**Note:** tskb can generate specialized Markdown files from your type-safe documentation - like `Agents.md` for AI agent configurations, `claude.md` for Claude-specific context, or `skills.md` for capability documentation. These are built from your validated architecture declarations, ensuring they stay accurate as your code evolves.
|
|
1059
|
+
|
|
1060
|
+
**Does this work with JavaScript?**
|
|
1061
|
+
|
|
1062
|
+
You need TypeScript for the `.tskb.tsx` files, but you can document JavaScript projects.
|
|
1063
|
+
|
|
1064
|
+
**Performance impact on CI?**
|
|
1065
|
+
|
|
1066
|
+
Depends on your docs and project size, but shouldn't take more than a normal TypeScript build. The build time is proportional to the number of documentation files and their complexity.
|
|
1067
|
+
|
|
1068
|
+
**What if I rename a file?**
|
|
1069
|
+
|
|
1070
|
+
Docs fail to compile. Fix the import path and you're done.
|
|
1071
|
+
|
|
1072
|
+
**Do I need to document everything?**
|
|
1073
|
+
|
|
1074
|
+
No. Start with the most important architecture - what you'd explain to a new team member joining the project. Document the core layers, key modules, and important patterns. Then grow the documentation gradually as needed.
|
|
1075
|
+
|
|
1076
|
+
Treat it as living docs: when working with AI assistants on specific features or refactorings, add the architectural insights from those sessions as documentation artifacts. This preserves optimized context for future AI interactions and team members. You can use AI assistants to help write the docs by pointing them at specific files or folders to document.
|
|
1077
|
+
|
|
1078
|
+
## Roadmap
|
|
1079
|
+
|
|
1080
|
+
- Knowledge graph optimizations and query capabilities
|
|
1081
|
+
- Context layer for better AI integration
|
|
1082
|
+
- MCP server implementation
|
|
1083
|
+
|
|
1084
|
+
## License
|
|
1085
|
+
|
|
1086
|
+
MIT © Dimitar Mihaylov
|