





























@@ -11,9 +11,9 @@ title: "Path"
11111212Plugin-provided shell access to the `oc://` addressing substrate: one
1313kind-dispatched path scheme for inspecting and editing addressable workspace
14-files (markdown, jsonc, jsonl). Self-hosters, plugin authors, and editor
15-extensions use it to read, find, or update a narrow location without
16-hand-rolling per-file parsers.
14+files (markdown, jsonc, jsonl, yaml/yml/lobster). Self-hosters, plugin
15+authors, and editor extensions use it to read, find, or update a narrow
16+location without hand-rolling per-file parsers.
17171818The CLI mirrors the substrate's public verbs:
1919@@ -33,9 +33,10 @@ openclaw plugins enable oc-path
3333## Why use it
34343535OpenClaw state is spread across human-edited markdown, commented JSONC config,
36-and append-only JSONL logs. Shell scripts, hooks, and agents often need one
37-small value from those files: a frontmatter key, a plugin setting, a log record
38-field, or a bullet item under a named section.
36+append-only JSONL logs, and YAML workflow/spec files. Shell scripts, hooks,
37+and agents often need one small value from those files: a frontmatter key, a
38+plugin setting, a log record field, a YAML step, or a bullet item under a named
39+section.
39404041`openclaw path` gives those callers a stable address instead of a one-off grep,
4142regex, or parser for each file kind. The same `oc://` path can be validated,
@@ -105,9 +106,10 @@ result.
1051061. Parses the `oc://` address into slots: file, section, item, field, and
106107 optional session.
1071082. Chooses the file-kind adapter from the target extension (`.md`, `.jsonc`,
108-`.jsonl`, and related aliases).
109+`.jsonl`, `.yaml`, `.yml`, `.lobster`, and related aliases).
1091103. Resolves the slots against that file kind's AST: markdown headings/items,
110- JSONC object keys/array indexes, or JSONL line records.
111+ JSONC object keys/array indexes, JSONL line records, or YAML map/sequence
112+ nodes.
1111134. For `set`, emits edited bytes through the same adapter so the untouched
112114 parts of the file keep their comments, line endings, and nearby formatting
113115 where the kind supports it.
@@ -156,7 +158,8 @@ four slots:
156158- **Wildcards** — `*` (single sub-segment) and `**` (zero-or-more,
157159 recursive). `find` accepts these; `resolve` and `set` reject them as
158160 ambiguous.
159-- **Positional** — `$last` resolves to the last index / last-declared key.
161+- **Positional** — `$first` / `$last` resolve to the first / last index or
162+ declared key.
160163- **Ordinal** — `#N` for Nth match by document order.
161164- **Insertion markers** — `+`, `+key`, `+nnn` for keyed / indexed
162165 insertion (use with `set`).
@@ -174,11 +177,12 @@ Non-canonical query parameters are ignored except for the first non-empty
174177175178## Addressing by file kind
176179177-| Kind | Addressing model |
178-| ---------- | ----------------------------------------------------------------------------------------- |
179-| Markdown | H2 sections by slug, bullet items by slug or `#N`, frontmatter via `[frontmatter]`. |
180-| JSONC/JSON | Object keys and array indexes; dots split nested sub-segments unless quoted. |
181-| JSONL | Top-level line addresses (`L1`, `L2`, `$last`), then JSONC-style descent inside the line. |
180+| Kind | Addressing model |
181+| ----------------- | --------------------------------------------------------------------------------------------------- |
182+| Markdown | H2 sections by slug, bullet items by slug or `#N`, frontmatter via `[frontmatter]`. |
183+| JSONC/JSON | Object keys and array indexes; dots split nested sub-segments unless quoted. |
184+| JSONL | Top-level line addresses (`L1`, `L2`, `$first`, `$last`), then JSONC-style descent inside the line. |
185+| YAML/YML/.lobster | Map keys and sequence indexes; comments and flow style are handled by the YAML document API. |
182186183187`resolve` returns a structured match: `root`, `node`, `leaf`, or
184188`insertion-point`, with a 1-based line number. Leaf values are surfaced as text
@@ -199,6 +203,10 @@ the per-kind AST shape.
199203- JSONL leaf writes coerce like JSONC inside a line. Whole-line replacement and
200204 append parse `<value>` as JSON. Rendered JSONL preserves the file's dominant
201205 LF/CRLF line-ending convention.
206+- YAML leaf writes coerce to the existing scalar type (`string`, finite
207+`number`, `true`/`false`, or `null`). YAML insertions use the bundled
208+`yaml` package's document API for map/sequence updates. Malformed YAML
209+ documents with parser errors are refused before mutation with `parse-error`.
202210203211Use `--dry-run` before user-visible writes when the exact bytes matter. The
204212substrate preserves byte-identical output for parse/emit round-trips, but a
@@ -252,6 +260,12 @@ openclaw path set 'oc://session.jsonl/+' '{"event":"checkpoint","ok":true}' --fi
252260# Resolve the last JSONL value line
253261openclaw path resolve 'oc://session.jsonl/$last/event' --file ./logs/session.jsonl
254262263+# Resolve a YAML workflow step
264+openclaw path resolve 'oc://workflow.yaml/steps/0/id'
265+266+# Update a YAML scalar
267+openclaw path set 'oc://workflow.yaml/steps/$last/id' 'classify-renamed' --dry-run
268+255269# Address markdown frontmatter
256270openclaw path resolve 'oc://AGENTS.md/[frontmatter]/name'
257271@@ -352,6 +366,37 @@ leaf @ L2: "2" (number)
352366Each line is a record. Address by predicate (`[event=action]`) when you do not
353367know the line number, or by the canonical `LN` segment when you do.
354368369+### YAML
370+371+```text
372+# workflow.yaml
373+name: inbox-triage
374+steps:
375+ - id: fetch
376+ command: gmail.search
377+ - id: classify
378+ command: openclaw.invoke
379+```
380+381+```bash
382+$ openclaw path resolve 'oc://workflow.yaml/steps/0/id' --file workflow.yaml --human
383+leaf @ L3: "fetch" (string)
384+385+$ openclaw path set 'oc://workflow.yaml/steps/$last/id' 'classify-renamed' --file workflow.yaml --dry-run
386+--dry-run: would write 99 bytes to /…/workflow.yaml
387+name: inbox-triage
388+steps:
389+ - id: fetch
390+ command: gmail.search
391+ - id: classify-renamed
392+ command: openclaw.invoke
393+```
394+395+YAML uses the `yaml` package's `Document` API rather than a hand-rolled parser,
396+so ordinary parse/emit round-trips preserve comments and authoring shape while
397+resolved paths use the same map-key / sequence-index model as JSONC. The same
398+adapter handles `.yaml`, `.yml`, and `.lobster` files.
399+355400## Subcommand reference
356401357402### `resolve <oc-path>`
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。