JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 120
  • Score
    100M100P100Q84126F
  • License MIT

TS Knowledge Base. 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.

Package Exports

  • tskb
  • tskb/jsx-runtime

Readme

tskb

Let your AI assistant document your codebase as it works. Architecture knowledge accumulates in a compiler-verified artifact — query it, ask questions about your system, navigate it with your AI.

Your AI writes the docs. You navigate them.

npm version License: MIT


⚠️ Status

Experimental / early concept.

  • APIs and output may evolve
  • Not production-ready
  • Best viewed as a proof-of-concept and research tool

What is tskb?

tskb is a TypeScript-native DSL for expressing architectural intent as code.

Your AI assistant writes and maintains documentation in .tskb.tsx files that:

  • are type-checked by the TypeScript compiler
  • reference real folders, files, and exports
  • fail the build when documentation and code drift apart

The result is a structured knowledge graph you can:

  • query with natural language through your AI assistant
  • navigate programmatically via the CLI
  • visualize (Graphviz, diagrams)

Refactor your code → stale documentation breaks at compile time. The AI fixes it.


Why tskb exists

Large TypeScript codebases eventually suffer from:

  • Tribal knowledge - architecture lives in senior developers’ heads
  • Compound complexity - the mental model becomes fragile and expensive to communicate
  • Documentation decay - Markdown and diagrams drift silently

tskb addresses this by making architecture documentation:

  • typed
  • validated
  • enforced at build time

Core features

  • AI-maintained docs — generated skills let your AI assistant write, update, and validate docs during development sessions
  • Architecture as code using TSX
  • Compiler-verified references via typeof import()
  • Type-checked code snippets (not copied text)
  • Doc priority (essential, constraint, supplementary) to control AI guidance and enforce architectural rules
  • Flows — named, ordered sequences through the system (<Flow> + <Step>), surfaced in queries and AI skill files
  • Native IDE support (autocomplete, refactoring, go-to-definition)
  • Zero runtime impact (pure build-time tooling)
  • CLI for querying (ls, pick, search, docs, flows, context commands)
  • JSON knowledge graph output
  • Graphviz visualization
  • Monorepo-friendly by design
  • Optimized for AI assistants & programmatic consumption

0) Install and setup

Install tskb:

npm install --save-dev tskb

Run the interactive scaffolder:

npx tskb init

This will ask you:

  1. Where to put the docs folder (default: docs/)
  2. The glob pattern and tsconfig path
  3. Whether to enable Claude Code (.claude/skills/) and/or GitHub Copilot (.github/instructions/) integrations

It creates everything you need:

your-repo/
├── docs/
│   ├── tsconfig.json          # TypeScript config for docs (jsxImportSource: "tskb")
│   └── architecture.tskb.tsx  # Starter doc — edit this first
├── package.json               # "docs" script added automatically
├── .claude/skills/            # Created if Claude Code was selected
└── .github/                   # Created if Copilot was selected

Build the knowledge graph:

npm run docs

Verify:

npx tskb ls --plain       # Should show your folder structure
npx tskb docs --plain     # Should list your starter doc

For monorepos: create docs/ at workspace root, and ensure tsconfig.json can resolve all packages you want to document.


Define your vocabulary

Declare architecture primitives using TypeScript declaration merging. All primitives are declared inside the global tskb namespace.

// docs/vocabulary.tskb.tsx
import type { Folder, File, Export, Term } from "tskb";

declare global {
  namespace tskb {
    interface Folders {
      DataLayer: Folder<{
        desc: "Data access layer with repositories and database logic";
        path: "src/server/database";
      }>;
      ServiceLayer: Folder<{
        desc: "Business logic and application services";
        path: "src/server/services";
      }>;
      APILayer: Folder<{
        desc: "HTTP controllers and route handlers";
        path: "src/server/controllers";
      }>;
    }

    interface Modules {
      AuthServiceModule: Module<{
        desc: "Authentication service module";
        type: typeof import("../src/server/services/auth.service.js");
      }>;
    }

    interface Exports {
      UserRepository: Export<{
        desc: "User data access using repository pattern";
        type: typeof import("../src/server/database/repositories/user.repository.js").UserRepository;
      }>;
      AuthService: Export<{
        desc: "Authentication and authorization business logic";
        type: typeof import("../src/server/services/auth.service.js").AuthService;
      }>;
    }

    interface Files {
      "api-spec": File<{
        desc: "OpenAPI specification for the REST API";
        path: "docs/openapi.yml";
      }>;
    }

    interface Terms {
      "repository-pattern": Term<"Repository Pattern for data access abstraction">;
      jwt: Term<"JSON Web Tokens for stateless authentication">;
      "layered-architecture": Term<"Layered architecture pattern (API → Service → Data)">;
    }

    interface Externals {
      postgres: External<{
        desc: "Primary relational database";
        kind: "database";
        url: "https://www.postgresql.org";
      }>;
      redis: External<{
        desc: "Session cache and pub/sub messaging";
        kind: "cache";
        url: "https://redis.io";
      }>;
    }
  }
}

Documentation format

This is the format your AI assistant writes into. Multiple docs across multiple teams share the same global vocabulary — the AI navigates and extends it as the codebase evolves.

// docs/authentication.tskb.tsx
import { Doc, H1, H2, P, Snippet, ref } from "tskb";
import type { AuthService } from "../src/server/services/auth.service.js";
import type { UserRepository } from "../src/server/database/repositories/user.repository.js";
import type { LoginCredentials, AuthResponse } from "../src/shared/types/auth.types.js";

// Reference the global vocabulary
const ServiceLayer = ref as tskb.Folders["ServiceLayer"];
const DataLayer = ref as tskb.Folders["DataLayer"];
const AuthServiceExport = ref as tskb.Exports["AuthService"];
const UserRepositoryExport = ref as tskb.Exports["UserRepository"];
const Jwt = ref as tskb.Terms["jwt"];
const RepositoryPattern = ref as tskb.Terms["repository-pattern"];

export default (
  <Doc
    explains="Authentication architecture: login flow, JWT tokens, and service-repository interaction"
    priority="essential"
  >
    <H1>Authentication Architecture</H1>

    <P>
      The {AuthServiceExport} in the {ServiceLayer} handles authentication using {Jwt}. It depends
      on {UserRepositoryExport} in the {DataLayer} following the {RepositoryPattern}.
    </P>

    <H2>Example: Login Flow</H2>

    <Snippet
      code={async () => {
        const authService: AuthService = new AuthService();
        const credentials: LoginCredentials = {
          email: "user@example.com",
          password: "hashedPassword",
        };
        const response: AuthResponse = await authService.login(credentials);
        return response.tokens.accessToken;
      }}
    />
  </Doc>
);

Snippet type checking

<Snippet> is not a string literal.

  • Snippet bodies are fully type-checked
  • Real types and APIs can be imported
  • Broken examples fail the documentation build
// docs/repository-pattern.tskb.tsx
import { Doc, H1, P, Snippet } from "tskb";
import type { UserRepository } from "../src/server/database/repositories/user.repository.js";
import type { User } from "../src/shared/types/user.types.js";
import type { Database } from "../src/server/database/connection.js";

export default (
  <Doc explains="Repository pattern implementation for data access abstraction">
    <H1>Repository Pattern Example</H1>

    <P>The UserRepository demonstrates the repository pattern for data access abstraction.</P>

    <Snippet
      code={async () => {
        const db: Database = new Database(config);
        const userRepository: UserRepository = new UserRepository(db);
        const user: User | null = await userRepository.findByEmail("test@example.com");
        return user?.id;
      }}
    />
  </Doc>
);

If the API changes:

❌ Property 'findByEmail' does not exist on type 'UserRepository'.

The snippet is never executed - it is parsed, validated, and stringified.


What tskb produces: a semantic architecture graph

tskb builds a typed, semantic knowledge graph describing your system.

The graph captures:

  • Nodes - folders, modules, exports, files, terms, docs
  • Edges - explicit and inferred relationships
  • Hierarchy - nested architectural contexts
  • Semantics - intent expressed through JSX

This graph is the primary output. Everything else (diagrams, markdown, AI context) is derived from it.


Output schema (high level)

{
  nodes: {
    folders: Record<string, FolderNode>;   // id, desc, path
    modules: Record<string, ModuleNode>;   // id, desc, resolvedPath, typeSignature, imports
    exports: Record<string, ExportNode>;   // id, desc, resolvedPath, typeSignature
    files:   Record<string, FileNode>;     // id, desc, path
    terms:   Record<string, TermNode>;     // id, desc
    flows:   Record<string, FlowNode>;     // id, desc, priority, steps[]
    docs:    Record<string, DocNode>;       // id, explains, priority, filePath, content
  },
  edges: Array<{
    from: string;
    to: string;
    type: "references" | "contains" | "belongs-to" | "imports" | "related-to" | "flow-step";
    label?: string;
  }>,
  metadata: {
    generatedAt: string;
    version: string;
    stats: { folderCount, moduleCount, exportCount, fileCount, termCount, flowCount, docCount, edgeCount };
  }
}

DocNode.priority controls visibility:

  • "essential" — included in generated skill/instructions files and ls output
  • "constraint" — architectural rule shown in pick and search results, must be followed when working on referenced areas
  • "supplementary" — graph-only (default), queryable via search/pick

The schema is intentionally graph-first and machine-oriented.


Nested contexts

Folders define architectural contexts, not just paths.

From folder paths, tskb infers:

  • hierarchical containment (contains)
  • ownership of modules and exports (belongs-to)
  • the most specific enclosing context

Your architecture becomes a tree of nested contexts, not a flat list.


Relations

Relations in the graph come from two sources:

Explicit intent

When you reference entities in JSX:

<P>Authentication is handled by {AuthService}.</P>

tskb records a semantic edge:

Doc → AuthService (references)

Semantic Relations with <Relation />

To express a semantic relationship between two nodes, use the <Relation /> JSX tag:

<Relation from={AuthService} to={UserRepository} label="depends on" />

This creates a related-to edge in the graph, optionally labeled for richer semantics:

AuthService → UserRepository (related-to, label: "depends on")
  • from and to must be node constants (extracted from the registry)
  • label is optional and can be any string describing the relationship

These relations are visible in CLI output (e.g., pick), and the label is included if present.

Inferred structure

From filesystem paths and imports:

  • Folder → Folder (contains)
  • Module → Folder (belongs-to)
  • Module → Module (imports) — from resolved import statements
  • Export → Module (belongs-to)
  • File → Folder (belongs-to)

The graph combines authored intent with structural truth.


Flows

Flows model named, ordered sequences through the system — login pipelines, build processes, request handling chains.

import { Doc, H1, Flow, Step, ref } from "tskb";

const AuthMiddleware = ref as tskb.Exports["AuthMiddleware"];
const AuthService = ref as tskb.Modules["AuthServiceModule"];
const UserRepository = ref as tskb.Exports["UserRepository"];

export default (
  <Doc explains="Authentication flows">
    <H1>Auth Flows</H1>

    <Flow name="login" desc="User login from HTTP request to session token" priority="essential">
      <Step node={AuthMiddleware} label="Validates request format" />
      <Step node={AuthService} label="Checks credentials, generates JWT" />
      <Step node={UserRepository} label="Queries user record" />
    </Flow>
  </Doc>
);

Each <Flow> becomes a first-class node in the graph with flow-step edges connecting it to its participants. Only <Step> children are allowed (validated at build time).

Priority controls visibility:

  • priority="essential" — included in generated skill/instructions files and tskb flows output
  • priority="supplementary" (default) — graph-only, queryable via tskb flows and search

Why JSX: semantics, not rendering

JSX in tskb is not about UI.

It is a semantic DSL that allows you to declare meaning in a structured, type-safe way. Each JSX element becomes semantic data — not HTML.

JSX provides composability, static analysis, and extensibility without inventing a new syntax.


Querying the graph

These commands are embedded in the generated skill files — AI assistants use them automatically during sessions to orient themselves and look things up. You can also run them directly:

List folder structure

npx tskb ls              # List top-level folders (depth=1)
npx tskb ls --depth 4    # List folders up to depth 4
npx tskb ls --depth -1   # List all folders (unlimited depth)

Returns essential docs first, then folders ordered by depth.

Pick a node

npx tskb pick "ServiceLayer"              # Pick a folder by ID
npx tskb pick "src/server/services"       # Pick by filesystem path
npx tskb pick "auth.AuthService"          # Pick a module by ID

Returns type-specific data: parent, children, modules, exports, files, and referencing docs with their priority. When picking a doc node, the full content is included inline. Constraint docs in the results indicate rules that must be followed.

Search the graph

npx tskb search "auth"                    # Single keyword
npx tskb search "build command"           # Multi-word fuzzy search

Returns ranked results with scores across all node types. Doc results include priority so constraint and essential docs are immediately visible.

List and search docs

npx tskb docs                            # List all docs sorted by priority
npx tskb docs "auth"                     # Search docs by query (matches explains, content, filePath)

Lists all docs sorted by priority (constraints first, then essential, then supplementary). With a query, returns fuzzy-matched results with scores, filtered to relevant matches. Use pick on a doc nodeId to get its full content.

List and search flows

npx tskb flows                           # List all flows sorted by priority
npx tskb flows "build"                   # Search flows by query

Lists all flows sorted by priority. Essential flows are shown first. Use pick on a flow nodeId to see its steps and referenced nodes.

Get full context for an area

npx tskb context "ServiceLayer"          # Depth 1 (default): node + immediate children + docs
npx tskb context "ServiceLayer" --depth 2 # Deeper: includes grandchildren and their docs
npx tskb context "src/server/services"   # Also works with filesystem paths

Returns the target node, all neighborhood nodes (child folders, modules, exports) up to the specified depth, and all referencing docs — deduplicated and sorted by priority. Constraint doc IDs are surfaced at the top level so they can't be missed.

All commands output JSON by default. Use --plain for structured plain text optimized for AI assistants (fewer tokens, no JSON overhead), or --optimized for compact JSON.


Visualize

The build command automatically generates a Graphviz DOT file in .tskb/graph.dot.

To render it as an image:

dot -Tpng .tskb/graph.dot -o .tskb/graph.png

Or view it interactively:

xdot .tskb/graph.dot

Workflow integration

Pre-commit hook

Validate docs on every commit:

npm install --save-dev husky
npx husky init
echo "npm run docs" > .husky/pre-commit

CI/CD (GitHub Actions)

- name: Validate architecture docs
  run: npm run docs

- name: Upload graph artifact
  uses: actions/upload-artifact@v3
  with:
    name: architecture-graph
    path: .tskb/

This ensures documentation stays synchronized with code changes.


AI assistant integration

TSKB closes a loop: your AI assistant writes the docs, then reads them — so architectural knowledge accumulates and carries forward across sessions. You navigate the graph, ask questions about your system, interrupt when something is wrong, and steer what gets documented.

  • Auto-generated integrations: Build produces a Claude Code skill (.claude/skills/tskb/SKILL.md) and Copilot instructions (.github/instructions/tskb.instructions.md) with folder tree, essential doc summaries, command response shapes, and workflow guidance baked in
  • Doc priority: Controls what AI assistants see — essential docs appear in generated files and ls output, constraint docs surface in pick/search with their priority visible, supplementary docs are graph-only
  • Constraint docs: Mark docs with priority="constraint" to define architectural rules. When an AI picks a node, constraint docs referencing that area appear in the results — signaling rules that must be followed before making changes
  • Docs command: docs lists or searches all documentation, with fuzzy matching across explains, content, and file paths — essential docs are boosted in search results
  • Context command: context returns a node's full neighborhood (children, modules, exports) with referencing docs — replacing multi-step pick → read → pick workflows with a single call
  • Plain text mode: --plain outputs structured text instead of JSON — ~30% fewer tokens for AI consumption while preserving all semantic content
  • Flows command: flows lists or searches named sequences through the system — essential flows are included in generated skill/instructions files
  • Structured queries: AI can use ls, pick, search, docs, flows, and context to navigate architecture — all return JSON (or plain text with --plain) with priority metadata on doc results

The AI assistant both writes and reads the graph. During development it documents what it builds; at the start of a session it consults what was documented before. You can query it at any point.

How it works in practice: The generated skill files embed the CLI commands and teach assistants when and how to use them — no manual instruction needed. At the start of a session the assistant already knows the folder tree and essential docs; when it needs more detail it runs search, context, or pick on its own:

  1. Folder tree and essential doc summaries are baked into the skill — loaded before the first message
  2. search finds relevant nodes for a task
  3. docs filters documentation by topic
  4. context gets the full neighborhood — nodes, docs, and constraints in one call
  5. pick reads a single node or full doc content
  6. Only the files that matter get read

This dramatically reduces tokens spent on exploration and increases accuracy.

Generated skills

The build produces two skills for each integration (Claude Code and GitHub Copilot):

Skill Purpose Generated files
tskb Codebase map — folder tree, essential doc summaries, CLI commands. Loaded on every prompt. .claude/skills/tskb/SKILL.md
.github/instructions/tskb.instructions.md
tskb-update How the AI writes and maintains .tskb.tsx files — JSX syntax, registry primitives, when to trigger an update, best practices. Activates when working with .tskb.tsx files. .claude/skills/tskb-update/SKILL.md
.github/instructions/tskb-update.instructions.md

How they work:

  • Claude Code: Skills in .claude/skills/ are loaded automatically based on context. The main tskb skill is always available; tskb-update activates when working with .tskb.tsx files.
  • GitHub Copilot: Instructions in .github/instructions/ use applyTo frontmatter patterns. tskb.instructions.md applies to all files (**), tskb-update.instructions.md applies to **/*.tskb.tsx.
  • Content is auto-generated: Every npm run docs build regenerates these files from the current graph. Don't edit them manually — they'll be overwritten.

To enable these integrations, select them during npx tskb init or create the directories manually (.claude/skills/ and/or .github/). The build detects their presence and writes the corresponding files.


How is this different?

vs ADRs / Markdown docs: Type-checked and validated against real code, not just text files that drift.

vs Structurizr / C4 / PlantUML: Native TypeScript (not a custom DSL), produces a queryable knowledge graph (not just static diagrams).

vs TypeDoc: Documents architecture and intent (why components exist, how they relate), not just API surfaces (what methods exist).

Unique to tskb:

  • Type-checks architecture docs at compile time
  • Validates against actual code via typeof import()
  • CLI for querying the graph (no file scanning needed)
  • Documents whole systems (multiple packages, monorepos)
  • Type-checked code snippets (not string literals)
  • First-class flows — named, ordered sequences as graph nodes
  • Doc priority system (essential, constraint, supplementary) for AI guidance
  • Optimized for AI assistants with structured queries and constraint enforcement

Roadmap

  • Architectural constraints validation
  • Interactive visualization (beyond Graphviz)
  • Plugin system for custom node types

License

MIT © Dimitar Mihaylov