cmd-peek
CLI Command: peek
API: GET /api/oculus/peek/{slug}?path={path}
Files: oculus/api.py:peek_path(), oculus/path_parser.py:resolve_path()
Read values at hierarchical paths using unified addressing grammar. Supports prose sections, YAML/JSON fence data, nested dict keys, and deep heading navigation.
Usage
CLI Examples
# Read prose from a section
oculus peek my-node introduction
# Read YAML fence data
oculus peek my-node config.yaml
# Read nested key in YAML
oculus peek my-node config.yaml.database.host
# Read at specific cache level
oculus peek my-node config.yaml --level substituted
# Read H3 section via path
oculus peek my-node level-2.level-3API Examples
# Read prose section
curl "http://localhost:7778/api/oculus/peek/my-node?path=introduction"
# Read YAML fence data at substituted level
curl "http://localhost:7778/api/oculus/peek/my-node?path=config.yaml&level=substituted"
# Read nested key
curl "http://localhost:7778/api/oculus/peek/my-node?path=config.yaml.database.host"API Request Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
slug |
string | required | Node slug (in URL path) |
path |
string | required | Path to data (query param) |
level |
string | clouds |
Cache level: raw, substituted, interpolated, rendered/clouds |
format |
string | json |
Output format (json, yaml, markdown, text) |
API Response Schema
{
"slug": "node-slug",
"path": "section.yaml.key",
"value": "the value at path",
"format": "json"
}Unified Addressing Grammar
Unified Addressing Grammar
Paths use a proper tokenizer and recursive descent parser - no regex. The grammar is explicit and predictable.
Formal Grammar
path := segment ('.' segment)* level_suffix?
segment := identifier bracket_suffix? | 'fences' bracket_suffix? | 'meta'
bracket_suffix := '[' bracket_content ']'
bracket_content := number | '*' | query
query := key '=' value (',' key '=' value)*
level_suffix := '@L' digit+
identifier := (letter | digit | '_' | '-' | ':')+Implementation: oculus/path_tokenizer.py (tokenizer + recursive descent parser)
Level Suffix (@L3, @L4, @L5)
The level suffix specifies which cache level to read from:
| Suffix | Level | Returns |
|---|---|---|
@L3 |
Sprout | Code/AST (substituted variables) |
@L4 |
Rendered | Executed data |
@L5 |
Clouds | Middleware-rendered output |
# Read YAML at sprout level (variables resolved, not executed)
oculus peek my-node config.yaml@L3
# Read executed fence data
oculus peek my-node config.yaml@L4
# Read fully rendered output
oculus peek my-node config.yaml@L5Address Components
| Component | Syntax | Example |
|---|---|---|
| Section | section.subsection |
config.database |
| Type | .yaml, .json, .python |
config.yaml |
| Index | [0], [1] |
config[0], config.yaml[1] |
| Label | .my-label (if not a type) |
config.pantry |
| Data path | .key.subkey |
config.yaml.host |
| Level | @L3, @L4, @L5 |
config.yaml@L4 |
Path Patterns
| Pattern | Target | Example |
|---|---|---|
section |
Prose content | introduction |
section.key |
DWIM: single fence → key key |
config.host |
section[0] |
First fence (any type) | data[0] |
section[0].key |
First fence, key key |
data[0].location |
section.yaml |
First YAML fence data | config.yaml |
section.yaml[0] |
Explicit first YAML fence | config.yaml[0] |
section.yaml[1] |
Second YAML fence | config.yaml[1] |
section.yaml.key |
First YAML fence, key key |
config.yaml.database.host |
section.yaml[1].key |
Second YAML fence, key key |
config.yaml[1].port |
section.label |
Fence with label="label" | config.pantry |
section.label.key |
Labeled fence, key key |
config.pantry.items |
section.fences[*] |
All fences | config.fences[*] |
section.fences[type=ruby] |
Filtered fences | config.fences[type=ruby] |
section.meta |
Section metadata | config.meta |
section.yaml@L4 |
YAML fence at level 4 | config.yaml@L4 |
DWIM Resolution
When addressing a fence without explicit type/index:
- Navigate to section via graph
- Collect all fences in section
- Apply filters (type, index, label) if provided
- If exactly 1 fence matches → use it
- If 0 matches → error: fence not found
- If N matches (N>1) → error: ambiguous
Section Index vs Type Index
section[n]→ nth fence in section (any type)section.type[n]→ nth fence of that specific type
Test Suite
Live test results for peek operations (executed via graphnode).
Test Results
| Test | Operation | Path | Status | Details |
|---|---|---|---|---|
| Read Prose Section | peek | introduction | 🟢 PASS | Status:200 |
| Read Multi-para Prose | peek | notes | 🟢 PASS | Status:200 |
| Read YAML Fence | peek | config.yaml | 🟢 PASS | Status:200, host=localhost |
| Read YAML Nested Key | peek | config.yaml.database | 🟢 PASS | Status:200 |
| Read YAML Deep Path | peek | config.yaml.database.port | 🟢 PASS | Status:200, value=5432 |
| Read YAML List | peek | config.yaml.features | 🟢 PASS | Status:200, len=3 |
| Read JSON Fence | peek | json-data.json | 🟢 PASS | Status:200 |
| Read JSON Deep Path | peek | json-data.json.settings.count | 🟢 PASS | Status:200, value=10 |
| Read JSON Array | peek | json-data.json.users | 🟢 PASS | Status:200, len=1 |
| Read H2 Section | peek | level-2 | 🟢 PASS | Status:200 |
| Read H3 Section | peek | level-2.level-3 | 🟢 PASS | Status:200 |
| Read H4 Section | peek | level-2.level-3.level-4 | 🟢 PASS | Status:200 |
| Peek at RAW level | peek | config.yaml@raw | 🟢 PASS | Status:200 |
| Peek at SUBSTITUTED level | peek | config.yaml@sub | 🟢 PASS | Status:200 |
| 404 on Missing Section | peek | nonexistent | 🟢 PASS | Status:404 |
| Error on Missing Node | peek | missing-node | 🟢 PASS | Status:500 |
| Peek After Poke | peek | config...host | 🟢 PASS | value=newhost.example.com |
| Peek After Append | peek | config...features | 🟢 PASS | len=4 |
| Boundary: H2 Entry Index | peek | readings (entry_index) | 🟢 PASS | H2 direct lookup |
| Boundary: H2→YAML | peek | readings.yaml | 🟢 PASS | Section→fence traversal |
| Boundary: H2→YAML→Key | peek | readings.yaml.creating-tools | 🟢 PASS | Deep path traversal |
| Boundary: Sibling Isolation | peek | pantry siblings | 🟢 PASS | Correct section isolation |
| Boundary: Cache Level Sprout | peek | character-data (sprout) | 🟢 PASS | Parsed YAML data |
| Boundary: Missing Section | peek | nonexistent-section | 🟢 PASS | Graceful 404 |
Summary
path: summary❌ Fence Execution Error: "'peek-test-data' - Curiouser and curiouser! That path seems to have vanished. Perhaps you meant: 'peek-test-fixture'?"
Data Source: [[peek-test-data]]
Implementation Notes
- Peek uses the hierarchical graph for O(1) section lookup
- Entry Index: H1/H2 sections are indexed directly for fast access
- Nested Sections (H3+): When a section isn't in the entry_index, peek performs a recursive tree search before treating the path as a data path. This DWIM behavior means
peek node:demoscene-enginefinds an H3 section without requiring the full pathparent.child.demoscene-engine - Path resolution walks the graph tree using section slugs
- Fence data is accessed via the unified addressing grammar
- Section → Content: When pointing to a header (not a fence), peek returns the full section content (prose + fences reconstructed as markdown)
- Missing sections return 404 with
PathResolutionError - Missing nodes return 500 (node not found)
Slots
North
slots:
- slug: oculus-cli
context: []
- slug: pattern-looking-glass-development
context: []South
slots:
- slug: peek-test-data
context: []East
slots:
- slug: cmd-poke
context: []
- slug: nav-provider
context: []West
slots:
- slug: pattern-embedded-tests
context: []
- slug: cmd-look
context:
- Linking look and peek as related reading commandsProvenance
Document
- Status: 🔴 Unverified
Fences
cmd-peek-cli-examples-fence-0
- Status: 🔴 Unverified
cmd-peek-api-examples-fence-0
- Status: 🔴 Unverified
cmd-peek-api-response-schema-fence-0
- Status: 🔴 Unverified
cmd-peek-formal-grammar-fence-0
- Status: 🔴 Unverified
cmd-peek-level-suffix-l3-l4-l5-fence-0
- Status: 🔴 Unverified
cmd-peek-summary-fence-0
- Status: 🔴 Unverified
cmd-peek-north-fence-0
- Status: 🔴 Unverified
cmd-peek-south-fence-0
- Status: 🔴 Unverified
cmd-peek-east-fence-0
- Status: 🔴 Unverified
cmd-peek-west-fence-0
- Status: 🔴 Unverified