Outline Module Guide

The Outline Module (outline) is the first plugin for the Knowledge Platform. It lets you create hierarchical document outlines — think chapter/section structures, research note hierarchies, or book tables of contents — stored as typed graphs.

What It Does

An outline is a rooted tree of text items. Each item has a title, optional body content, and a sibling position for ordering. Items are linked by ParentOf edges (parent points to child).

graph TD
    ROOT["My Book (root)"]
    CH1["Chapter 1: Introduction"]
    CH2["Chapter 2: Background"]
    CH3["Chapter 3: Methodology"]
    S1_1["1.1 Motivation"]
    S1_2["1.2 Scope"]
    S2_1["2.1 Prior Work"]

    ROOT -->|ParentOf| CH1
    ROOT -->|ParentOf| CH2
    ROOT -->|ParentOf| CH3
    CH1 -->|ParentOf| S1_1
    CH1 -->|ParentOf| S1_2
    CH2 -->|ParentOf| S2_1

Getting Started: UI Walkthrough

1. Create a Workspace

From the File menu, choose New Workspace, enter a name (e.g. "My Research"), and confirm.

2. Create an Outline

Select the Outline tab, then use File → New Outline or the toolbar action New Outline. Enter a name (e.g. "Literature Review") and confirm. The outline is created with a single root item whose title matches the outline name.

3. The Outline Panel

The Outline tab shows two areas:

  • Tree view (left): the hierarchical structure of all items.
  • Detail panel (right): the selected item's title and editable content (body text).

A toolbar above the tree provides quick actions:

Button Action
Add Root Item Create a new top-level item
Add Child Item Create a child under the currently selected item
Edit Item Open the edit dialog for the selected item
Remove Item Delete the selected item and all its children

4. Adding Items

Add a root-level item:

  1. Click Add Root Item in the toolbar.
  2. Type a title (and optionally body content) in the dialog.
  3. Click OK. The new item appears at the top level of the tree.

Add a child item:

  1. Select an existing item in the tree.
  2. Click Add Child Item.
  3. Enter a title and optional content.
  4. Click OK. The new item appears under the selected item.

You can also right-click any item in the tree for a context menu with the same options.

5. Editing an Item

  1. Select an item.
  2. Click Edit Item (or double-click, or right-click → Edit).
  3. Modify the title and/or content in the dialog.
  4. Click OK. The tree view and detail panel update immediately.

You can also edit the selected item's body text directly in the right-hand panel and click Save Content.

6. Removing an Item

Removal is recursive

Removing an item also removes all its descendants. This cannot be undone in the current release.

  1. Select the item you want to remove.
  2. Click Remove Item or press Delete.
  3. Confirm in the dialog.
  4. The item and its entire sub-tree are removed.

Using the Outline API (Programmatic)

For scripting or building custom integrations, use OutlineService directly.

Setup

from knowledge_platform.core.engine import GraphEngine
from knowledge_platform.domain.registry import TypeRegistry
from knowledge_platform.modules.outline.graph_type import OutlineGraphType
from knowledge_platform.modules.outline.service import OutlineService
from knowledge_platform.persistence.store import SqliteGraphRepository
from knowledge_platform.services.graph_service import GraphService
from knowledge_platform.services.workspace_service import WorkspaceService
from pathlib import Path

# Wire the stack
repo = SqliteGraphRepository(":memory:")
engine = GraphEngine(repo)
type_registry = TypeRegistry()
type_registry.register(OutlineGraphType())
graph_service = GraphService(engine, type_registry)
workspace_service = WorkspaceService(base_directory=Path("/tmp/ws"))

# Create workspace and outline service
workspace = workspace_service.create_workspace("Research")
outline_service = OutlineService(graph_service)

Creating an Outline

graph = outline_service.create_outline(workspace.id, "Literature Review")
# Graph contains one root OutlineItem with title="Literature Review"

Adding Items

# Get the auto-created root node
from knowledge_platform.modules.outline.projection import OutlineTreeProjection

projection = OutlineTreeProjection()
roots = projection.project(graph)
root = roots[0]

# Add chapters under the root
ch1 = outline_service.add_item(graph.id, root.node_id, "Chapter 1: Related Work", position=0)
ch2 = outline_service.add_item(graph.id, root.node_id, "Chapter 2: Methodology", position=1)

# Add sections under Chapter 1
s1_1 = outline_service.add_item(graph.id, ch1.id, "1.1 Classical Approaches", position=0)
s1_2 = outline_service.add_item(graph.id, ch1.id, "1.2 Modern Methods", position=1)

# Add a root-level item (no parent)
appendix = outline_service.add_item(graph.id, None, "Appendix A", position=10)

Getting the Tree

graph = outline_service.get_outline(graph.id)  # reload latest state
roots = outline_service.get_tree(graph.id)

for root_node in roots:
    print(root_node.title)
    for child in root_node.children:
        print(f"  {child.title} (position={child.position})")
        for grandchild in child.children:
            print(f"    {grandchild.title}")

Flat Depth-First Iteration

from knowledge_platform.modules.outline.projection import OutlineTreeProjection

projection = OutlineTreeProjection()
roots = projection.project(graph)
flat = projection.flat_list(roots)

for item in flat:
    indent = "  " * item.depth
    print(f"{indent}{item.title}")

Output:

Literature Review
  Chapter 1: Related Work
    1.1 Classical Approaches
    1.2 Modern Methods
  Chapter 2: Methodology
Appendix A

Updating an Item

Only non-None arguments are changed. Omit a field to leave it unchanged:

# Update title only
outline_service.update_item(ch1.id, title="Chapter 1: Literature Review")

# Update content only
outline_service.update_item(s1_1.id, content="Survey of methods from 1990–2010.")

# Update position only
outline_service.update_item(appendix.id, position=2)

Moving an Item

# Move s1_2 to be a child of ch2 at position 0
outline_service.move_item(
    graph_id=graph.id,
    node_id=s1_2.id,
    new_parent_id=ch2.id,
    new_position=0,
)

This: 1. Removes the existing ParentOf edge from ch1 → s1_2. 2. Creates a new ParentOf edge from ch2 → s1_2. 3. Updates s1_2.position to 0.

Removing an Item and Its Subtree

# This removes ch1 AND s1_1 AND s1_2 (all descendants)
outline_service.remove_item(graph.id, ch1.id)

Removal is bottom-up: deepest descendants are removed first to avoid dangling references.

Listing All Outlines in a Workspace

outlines = outline_service.list_outlines(workspace.id)
for g in outlines:
    print(g.name)

Data Model Reference

OutlineItem Attributes

Attribute Type Required Description
title str Yes Display heading for this item
content str No Optional body text or notes
position int No Sibling sort order (ascending, default 0)

ParentOf Edge

Property Value
Allowed source types OutlineItem
Allowed target types OutlineItem
Attributes None
Direction Parent → Child

Tree Rules

Rule Description
One root per well-formed outline A node with no incoming ParentOf edges is a root
Siblings ordered by position Lower position values appear first
Cascade delete Removing an item removes its entire subtree

Limitations (Current Release)

  • No drag-and-drop reordering in the tree view — use the move_item() API.
  • No undo/redo — changes are immediately persisted.
  • Positions are not automatically renumbered — gaps are allowed (e.g. 0, 10, 20).
  • No multi-selection for bulk operations.