Build a Small Workspace [[guide_workspace: HowTo]]HowTo
- goalbuild a multi-file workspace with namespaces and cross-file references
- audiencedeveloper
- prerequisitesWrite Your First QMD.md File
- outcomea validated multi-file workspace graph
- aboutWorkspace, Object, Reference
🤖 Content Generator
- target: [[#guide_workspace.content]]
- about: Workspace, Object, Reference
- sources_hash: f39f157d605d3ef0
Prompt [[guide_workspace_gen_prompt: text]]textGuides Namespace 83%Workspace Workspace 82%Content Generator ContentGenerator 78%
Write a guide: "Build a multi-file QMDC workspace from scratch."
Steps:
- Create a project folder with
readme.qmd.mdcontaining[[myproject:__Workspace]] - Create a subfolder
api/withreadme.qmd.mdcontaining[[api:__Namespace]] - Add a file
api/endpoints.qmd.mdwith 2-3 objects - Add cross-file references between objects
- Validate:
qmdc workspace validate . - Query:
qmdc query . "SELECT __id, __file FROM objects"
Show the full file tree and contents at each step. Explain namespaces, cross-file references, and how the workspace stitches files together into one graph.
End with: "Your workspace is ready. For workspace syntax details, see the Workspaces page."
This guide walks you through creating a multi-file QMDC workspace from scratch. By the end you'll have a project with namespaces, cross-file References, and a single queryable graph spanning multiple files.
Prerequisites: complete Write Your First QMD.md File first so you're familiar with objects and fields.
Step 1: Create the workspace root
Create a project folder with a single anchor file:
myproject/
└── readme.qmd.md
myproject/readme.qmd.md:
# My Project [[myproject: __Workspace]]
- description: A sample multi-file QMDC workspace
The [[myproject: __Workspace]] declaration marks this directory as a Workspace root. Every .qmd.md file inside — at any depth — becomes part of one graph.
Step 2: Add a namespace
Namespaces partition your workspace into logical sections. Create a subfolder with its own readme.qmd.md:
myproject/
├── readme.qmd.md
└── api/
└── readme.qmd.md
myproject/api/readme.qmd.md:
# API [[api: __Namespace]]
- description: Public API layer
[[api: __Namespace]] makes the api/ folder a namespace. All Objects in files under this folder automatically receive __namespace: api.
Step 3: Add objects in the namespace
Create a file with a few objects:
myproject/
├── readme.qmd.md
└── api/
├── readme.qmd.md
└── endpoints.qmd.md
myproject/api/endpoints.qmd.md:
# API Endpoints
## List Users [[list_users: Endpoint]]
- method: GET
- path: /api/users
- returns: array
## Get User [[get_user: Endpoint]]
- method: GET
- path: /api/users/:id
- returns: object
## Create User [[create_user: Endpoint]]
- method: POST
- path: /api/users
- returns: object
Each heading with [[id: Kind]] defines an Object. The workspace automatically assigns __file: api/endpoints.qmd.md and __namespace: api to each.
Step 4: Add cross-file references
Connect objects across files. Edit the root to reference the endpoints:
myproject/readme.qmd.md (updated):
# My Project [[myproject: __Workspace]]
- description: A sample multi-file QMDC workspace
## Architecture [[architecture]]
- public_endpoints: [[[#api:list_users]], [[#api:get_user]], [[#api:create_user]]]
The syntax [[#api:list_users]] is a cross-namespace Reference — it targets list_users in the api namespace. Within the same namespace you'd write just [[#list_users]].
Add a reference between objects in the same file too:
myproject/api/endpoints.qmd.md (updated — last object only):
## Create User [[create_user: Endpoint]]
- method: POST
- path: /api/users
- depends: [[#get_user]]
- returns: object
Every reference produces a typed edge in the graph. Here depends becomes the edge_type.
Step 5: Validate the workspace
qmdc workspace validate .
Validation checks that:
- There is exactly one
__Workspacedeclaration and no nested workspaces - All
[[#...]]references resolve to existing objects - No ID collisions exist within the same Kind
Fix any warnings before moving on.
Step 6: Query the graph
qmdc query . "SELECT __id, __file FROM objects"
Expected output:
| __id | __file |
|---|---|
| myproject | readme.qmd.md |
| architecture | readme.qmd.md |
| api | api/readme.qmd.md |
| list_users | api/endpoints.qmd.md |
| get_user | api/endpoints.qmd.md |
| create_user | api/endpoints.qmd.md |
Query the edges to see how objects connect:
qmdc query . "SELECT source_id, target_id, edge_type FROM edges"
| source_id | target_id | edge_type |
|---|---|---|
| architecture | list_users | public_endpoints |
| architecture | get_user | public_endpoints |
| architecture | create_user | public_endpoints |
| create_user | get_user | depends |
How it all fits together
| Concept | Declared via | Purpose |
|---|---|---|
| Workspace | [[id: __Workspace]] in root readme.qmd.md |
Top-level container — all files in the tree become one graph |
| Namespace | [[id: __Namespace]] in a subfolder's readme.qmd.md |
Logical partition; objects inherit __namespace automatically |
| Cross-file reference | [[#namespace:id]] or [[#namespace:Kind:id]] |
Typed edge between objects in different files/namespaces |
The workspace layer:
- Parses each
.qmd.mdfile independently - Indexes all objects by
namespace:Kind:id - Resolves every
[[#...]]reference and reports broken links - Assigns metadata (
__file,__namespace,__workspace) to each object - Builds the edge graph with typed relationships
Your workspace is ready. For the complete workspace syntax rules, see the Workspace reference page. To learn what you can do with the graph, continue to Query Your Markdown Graph.