☰
OpenClaw `oc-path` 插件:用 `oc://` 统一寻址 markdown / JSONC / JSONL / YAML 工作区文件
2026/10/3 17:39:36 网站建设 项目流程

OpenClawoc-path插件:用oc://统一寻址 markdown / JSONC / JSONL / YAML 工作区文件

【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 🦞项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw

oc-path是 OpenClaw 内置(bundled)但默认不激活(opt-in)的 CLI 插件,它为oc://工作区文件寻址方案提供openclaw path命令,让你在终端里用一套稳定、与文件类型无关(kind-agnostic)的地址语法,精确读取或改写 markdown、JSONC、JSONL、YAML/.lobster文件中的单个叶子节点。读完本文,你将掌握oc://地址的完整语法、五个子命令(resolve/find/set/validate/emit)的用法与退出码约定、逐文件类型的寻址与改写语义,以及插件背后的源码实现原理(解析器、哨兵守卫、字节保真契约)。

插件定位:窄寻址层,不做高层语义

oc-path插件的元数据声明在extensions/oc-path/openclaw.plugin.json,它只做一件事:把openclaw pathCLI 接入 CLI 体系。

{ "id": "oc-path", "name": "OC Path", "description": "Adds the openclaw path CLI for oc:// workspace file addressing.", "cliCommands": [ { "name": "path", "description": "Inspect and edit workspace files via oc:// paths", "hasSubcommands": true } ], "activation": { "onStartup": false, "onCommands": ["path"] }, "commandAliases": [ { "name": "path", "kind": "cli" } ], "configSchema": { "type": "object", "additionalProperties": false, "properties": {} } }

插件入口extensions/oc-path/index.ts通过definePluginEntry注册,register(api)中调用registerOcPathCli(api)完成 CLI 接线。registerOcPathCli位于extensions/oc-path/cli-registration.ts,它做两件关键事:

  • 懒加载:真正的子命令实现通过动态import("./src/cli.js")引入,CLI 在首次执行openclaw path …时才加载插件代码;
  • 机器输出判定:isPathMachineOutput决定默认输出模式——显式传--json时输出 JSON;否则当 stdout 不是 TTY(被管道/重定向)时也输出 JSON;只有交互式终端且未传--json/--human时才默认人类可读输出。

onStartup: false保证插件不进 Gateway 启动路径,commandAliases与activation.onCommands配合让 CLI 在第一次运行path动词时按需加载——从未用过该动词的安装不付出任何加载成本。

为什么启用它

脚本、hooks 或本地 Agent 工具需要指向工作区状态的精确片段、又不愿为每种文件形状维护一套专属解析器时,就该启用oc-path。一个oc://地址可以命名 markdown frontmatter 键、章节条目、JSONC 配置叶子、JSONL 事件字段或 YAML 工作流步骤。常见动机:

  • 本地自动化:shell 脚本用openclaw path … --json解析或更新一个工作区值,免去分别维护 markdown、JSONC、JSONL、YAML 解析代码;
  • Agent 可见的编辑:Agent 写入前先对一个被寻址的叶子展示 dry-run diff,比自由格式的文件重写更容易审查;
  • 编辑器集成:编辑器把oc://AGENTS.md/tools/gh映射到精确的 markdown 节点和行号,无需靠标题文本猜测;
  • 诊断:emit把文件完整走一遍解析器 + 发射器,在依赖自动化编辑前先确认某类文件是否字节稳定(byte-stable)。
# 该配置中 GitHub 插件是否启用? openclaw path resolve 'oc://config.jsonc/plugins/github/enabled' --json # 这段会话日志里出现了哪些工具调用名? openclaw path find 'oc://session.jsonl/[event=tool_call]/name' --json # 这次微小的配置编辑会写出什么字节? openclaw path set 'oc://config.jsonc/plugins/github/enabled' 'true' --dry-run

边界声明:oc-path有意不拥有更高层语义。内存写入归 memory 插件,完整配置管理归 config 命令,last-known-good(LKG)配置恢复归其自身的恢复/提升流程。oc-path是那些高层工具可以构建其上的窄寻址 + 字节保真文件操作层。

它运行在哪里

插件在调用命令的宿主机上、openclawCLI 进程内运行。它不需要正在运行的 Gateway,不打开任何网络 socket——每个动词都是对指向文件的纯变换(pure transform)。

启用与停用

openclaw plugins enable oc-path

启用后,如果运行 Gateway,重启它以便 manifest 快照拾取新状态。裸的openclaw path调用在同一宿主机上立即生效——CLI 按需加载插件。停用:

openclaw plugins disable oc-path

启用oc-path不会给核心运行时拉入新包:所有解析依赖都是插件局部的(见extensions/oc-path/package.json)。依赖清单如下:

依赖用途
commanderresolve、find、set、validate、emit的子命令接线。
jsonc-parserJSONC 解析与叶子编辑,保留注释与尾逗号。
markdown-itmarkdown 分词,支撑 section / item / field 模型。
yamlYAMLDocument的 parse / emit / edit,保留注释与 flow 风格。
diffset --dry-run --diff的统一 diff 输出(源码cli.ts引用structuredPatch/formatPatch)。

JSONL 保持手写实现:面向行的解析比任何依赖都简单,且逐行解析本身已经过jsonc-parser。

插件提供的能力清单

表面提供方
openclaw pathCLIextensions/oc-path/cli-registration.ts(注册)、extensions/oc-path/src/cli.ts(子命令实现)
oc://解析器 / 格式化器extensions/oc-path/src/oc-path/oc-path.ts
逐类型 parse / emit / editextensions/oc-path/src/oc-path/{md,jsonc,jsonl,yaml}
通用 resolve / find / setextensions/oc-path/src/oc-path/{resolve,find,edit,universal}.ts
红action 哨兵守卫extensions/oc-path/src/oc-path/sentinel.ts

目前 CLI 是唯一公开表面。底层的 substrate 动词(parseOcPath、resolveOcPath、setOcPath、findOcPaths、各类emit*等)对插件私有,消费者通过 CLI 使用,或基于 SDK 构建自己的插件。extensions/oc-path/src/oc-path/index.ts这个 barrel 文件明确注释:“Keep this barrel limited to CLI imports”,印证了内部面仅为 CLI 服务的定位。

oc://地址语法

oc://FILE/SECTION/ITEM/FIELD?session=SCOPE

槽位规则:field依赖item,item依赖section。跨全部四个槽位的语法要素:

  • 引号段(Quoted segments):"a/b.c"内的/和.作为字面内容保留。引号内按字节原样解释,且不允许包含"与\。文件槽也感知引号:oc://"skills/email-drafter"/Tools/$last把skills/email-drafter当作单一文件路径。
  • 谓词(Predicates):[k=v]、[k!=v]、[k<v]、[k<=v]、[k>v]、[k>=v]。数值运算符要求两侧都能转成有限数值。
  • 联合(Unions):{a,b,c}匹配任意一个候选项。
  • 通配符(Wildcards):*匹配单个子段,**匹配零个或多个(递归)。find接受它们;resolve与set拒绝并把它们视为有歧义。
  • 位置(Positional):$first/$last解析为第一个 / 最后一个索引或声明键。
  • 序数(Ordinal):#N按文档顺序取第 N 个匹配。
  • 插入标记(Insertion markers):+、+key、+nnn分别用于键控 / 索引插入(配合set使用)。
  • 会话作用域(Session scope):?session=cron-daily等,与槽位嵌套正交。会话值按原始文本处理、不做百分号解码,且不得包含控制字符或保留查询分隔符(?、&、%)。

保留字符(?、&、%)在引号、谓词或联合段之外会被拒绝。控制字符(U+0000–U+001F、U+007F)在任何位置都被拒绝,包括session查询值。

规范化往返契约:formatOcPath(parseOcPath(path)) === path对规范化路径成立。非规范的查询参数会被忽略,只取第一个非空session=值。

硬上限(源码oc-path.ts中的常量):路径上限 4096 字节;最多 4 个槽位(file/section/item/field);每个槽位最多 64 个点分(dotted)子段;深层 JSON 路径最多 256 层嵌套遍历。另外,任何会加载文件的动词,超过 16 MiB 的输入文件在解析前一律拒绝——JSONC/JSON 报OC_JSONC_INPUT_TOO_LARGE,其他文件类型报OC_PATH_INPUT_TOO_LARGE(CLI 侧cli.ts中MAX_OC_PATH_INPUT_BYTES = MAX_JSONC_INPUT_BYTES,即所有解析器共用同一输入上限)。

源码中的安全校验

parseOcPath在入口处层层设防(validateFileSlot):

  • 拒绝绝对路径(/、\开头或盘符:前缀),错误码OC_PATH_ABSOLUTE_FILE——oc://路径是工作区相对的;
  • 拒绝..父目录逃逸段,错误码OC_PATH_PARENT_TRAVERSAL;
  • 拒绝控制字符,错误码OC_PATH_CONTROL_CHAR。

路径先做 NFC 规范化(兼容 macOS HFS+ 的 NFD 与 Unix/Windows 的 NFC),并容忍 BOM 前缀;因为 NFC 可能使字符串变长,规范化后会重新检查 4096 字节上限。formatOcPath还会做防御性检查:格式化结果若包含红action 哨兵则直接抛OcEmitSentinelError(见下文安全节),防止哨兵经遥测/审计/错误消息流出。

子命令一览

子命令用途
resolve <oc-path>打印路径处的具体匹配(或 “not found”)。
find <pattern>枚举通配符 / 联合 / 谓词路径的所有匹配。
set <oc-path> <value>在具体路径写入一个叶子或插入目标,支持--dry-run。
validate <oc-path>仅解析;打印结构拆解(file / section / item / field)。
emit <file>把文件完整跑一遍 parse + emit(字节保真诊断)。

全局标志

标志适用命令用途
--cwd <dir>resolve、find、set、emit相对该目录解析文件槽(默认:process.cwd())。
--file <path>resolve、find、set、emit覆盖文件槽解析出的路径(绝对访问)。
--json全部强制 JSON 输出(stdout 非 TTY 时默认)。
--human全部强制人类可读输出(stdout 为 TTY 时默认)。
--value-jsonset对 JSON/JSONC/JSONL 叶子替换,把<value>当作 JSON 解析。
--dry-runset只打印将要写入的字节,不实际写入。
--diffset(需配合--dry-run)打印统一 diff 而非完整字节。

validate只接受--json/--human;它不做任何文件系统访问,因此--cwd与--file不适用。

退出码约定

码含义
0成功(resolve/find:至少一个匹配;set:写入成功)。
1无匹配,或set被 substrate 拒绝(如哨兵守卫命中,非系统级错误)。
2参数或解析错误。

输出模式

openclaw path是 TTY 感知的:终端上输出人类可读文本,stdout 被管道或重定向时输出 JSON。--json与--human覆盖自动检测。此外 CLI 在输出前会把哨兵字面量替换为[REDACTED](cli.ts的scrubSentinel),保证终端捕获与管道不会泄漏标记。

逐文件类型的寻址模型

类型文件扩展名寻址模型
Markdown.md按 slug 定位 H2 章节,按 slug 或#N定位条目,通过[frontmatter]访问 frontmatter。
JSONC/JSON.jsonc、.json对象键与数组索引;点号拆分嵌套子段(引号内除外)。
JSONL.jsonl、.ndjson顶层行地址(L1、L2、$first、$last),行内再按 JSONC 风格向下走。
YAML/.lobster.yaml、.yml、.lobster映射键与序列索引;注释与 flow 风格由 YAML document API 处理。

resolve返回结构化匹配:root、node、leaf或insertion-point,附 1 起始行号。叶子值以文本 +leafType形式呈现,让插件作者无需依赖各类型 AST 形状即可渲染预览。

改写契约(Mutation contract)

set只写一个具体目标:

  • Markdown:frontmatter 值与- key: value条目字段是字符串叶子。值按字面写入(包括$1、$&、$$)。Markdown 插入会追加章节、frontmatter 键或章节条目,并为变更后的文件渲染规范的 Markdown 形状。章节正文不能整体通过set写入。
  • JSONC:叶子写入把字符串值强制转换为既有叶子类型(string、有限number、true/false或null)。当 JSONC/JSON/JSONL 叶子替换需要把<value>当 JSON 解析、可能改变形状时(例如把字符串密钥引用简写替换为对象),使用--value-json。JSONC 对象与数组插入把<value>当 JSON 解析,普通叶子写入走jsonc-parser编辑路径,保留注释与周边格式。
  • JSONL:行内叶子写入的强制转换规则与 JSONC 一致。整行替换与追加把<value>当 JSON 解析。渲染时保留文件的主导 LF/CRLF 换行约定(对文件内换行做多数投票,所以以 CRLF 为主的文件即便混有零星 LF 也保持 CRLF)。
  • YAML:叶子写入强制转换到既有标量类型(string、有限number、true/false或null)。YAML 插入使用内置yaml包的 document API 做 map/sequence 更新。带解析错误的畸形 YAML 文档在变更前即以parse-error拒绝。

在字节精确重要的场景,先跑--dry-run。JSONC 与 YAML 编辑是修补既有文档(经jsonc-parser或 YAML document API),未触及的字节通常原样存活;markdown 则在任何编辑时都会按解析出的结构重建文件,可能规范化变更叶子之外的偶然格式。想要聚焦的前后补丁而非完整渲染文件时,加--diff——补丁会记录换行变化与缺失的结尾换行,应用它产生的字节与真实写入完全一致。

逐类型实战示例

Markdown(--human输出):

<!-- frontmatter.md --> --- name: drafter description: email drafting agent tier: core --- ## Tools - gh: GitHub CLI - curl: HTTP client - send_email: enabled
$ openclaw path resolve 'oc://x.md/[frontmatter]/tier' --file frontmatter.md --human leaf @ L4: "core" (string) $ openclaw path resolve 'oc://x.md/tools/gh/gh' --file frontmatter.md --human leaf @ L9: "GitHub CLI" (string) $ openclaw path find 'oc://x.md/tools/*' --file frontmatter.md --human 3 matches for oc://x.md/tools/*: oc://x.md/tools/gh → node @ L9 [md-item] oc://x.md/tools/curl → node @ L10 [md-item] oc://x.md/tools/send-email → node @ L11 [md-item]

[frontmatter]谓词寻址 YAML frontmatter 块;tools通过 slug 匹配## Tools标题;条目叶子保持 slug 形式,即使源文件用下划线(send_email变成send-email)。

JSONC:

// config.jsonc { "plugins": { "github": {"enabled": true, "role": "vcs"}, "slack": {"enabled": false, "role": "chat"} } }
$ openclaw path resolve 'oc://config.jsonc/plugins/github/enabled' --file config.jsonc --human leaf @ L4: "true" (boolean) $ openclaw path set 'oc://config.jsonc/plugins/slack/enabled' 'true' --file config.jsonc --dry-run --dry-run: would write 142 bytes to /…/config.jsonc { "plugins": { "github": {"enabled": true, "role": "vcs"}, "slack": {"enabled": true, "role": "chat"} } }

JSONC 编辑走jsonc-parser,注释与空白在set后存活。.json文件使用与.jsonc相同的适配器与编辑路径。

JSONL:

{"event":"start","userId":"u1","ts":1} {"event":"action","userId":"u1","ts":2} {"event":"end","userId":"u1","ts":3}
$ openclaw path find 'oc://session.jsonl/[event=action]/userId' --file session.jsonl --human 1 match for oc://session.jsonl/[event=action]/userId: oc://session.jsonl/L2/userId → leaf @ L2: "u1" (string) $ openclaw path resolve 'oc://session.jsonl/L2/ts' --file session.jsonl --human leaf @ L2: "2" (number)

每行是一条记录。不知道行号时用谓词([event=action])寻址,知道行号时用规范化的LN段。.ndjson文件与.jsonl使用同一适配器。

YAML:

# workflow.yaml name: inbox-triage steps: - id: fetch command: gmail.search - id: classify command: openclaw.invoke
$ openclaw path resolve 'oc://workflow.yaml/steps/0/id' --file workflow.yaml --human leaf @ L3: "fetch" (string) $ openclaw path set 'oc://workflow.yaml/steps/$last/id' 'classify-renamed' --file workflow.yaml --dry-run --dry-run: would write 99 bytes to /…/workflow.yaml name: inbox-triage steps: - id: fetch command: gmail.search - id: classify-renamed command: openclaw.invoke

YAML 用yaml包的DocumentAPI 而非手写解析器,普通 parse/emit 往返保留注释与编写形状,而解析出的路径与 JSONC 使用同一套 map-key / sequence-index 模型。同一适配器处理.yaml、.yml与.lobster。

子命令参考

resolve <oc-path>

读取单个叶子或节点。通配符被拒绝——这类查询用find。匹配时退出0,干净未命中退出1,解析错误或模式被拒退出2。

openclaw path resolve 'oc://AGENTS.md/tools/gh/risk' --human openclaw path resolve 'oc://gateway.jsonc/server/port' --json

find <pattern>

枚举通配符 / 谓词 / 联合模式的每一个匹配。至少一个匹配时退出0,零匹配退出1。文件槽的通配符以OC_PATH_FILE_WILDCARD_UNSUPPORTED拒绝——必须传具体文件(多文件 glob 属于后续功能)。

openclaw path find 'oc://AGENTS.md/tools/**/risk' openclaw path find 'oc://session.jsonl/[event=action]/userId' openclaw path find 'oc://config.jsonc/plugins/{github,slack}/enabled'

set <oc-path> <value>

写入一个叶子。配合--dry-run预览将要写入的字节而不碰文件;加--diff得到统一 diff 预览。写入成功退出0,substrate 拒绝(如哨兵守卫命中)退出1,解析错误退出2。

openclaw path set 'oc://gateway.jsonc/version' '2.0' --dry-run openclaw path set 'oc://gateway.jsonc/version' '2.0' --dry-run --diff openclaw path set 'oc://gateway.jsonc/version' '2.0' openclaw path set 'oc://AGENTS.md/Tools/+gh/risk' 'low'

+key插入标记会在命名子节点不存在时创建它;+nnn与裸+分别用于索引插入与追加插入。

validate <oc-path>

纯解析检查,不做文件系统访问。适合在替换变量前确认模板路径格式正确,或调试时查看结构拆解:

$ openclaw path validate 'oc://AGENTS.md/tools/gh' --human valid: oc://AGENTS.md/tools/gh file: AGENTS.md section: tools item: gh

合法退出0,非法退出1(带结构化code与message),参数错误退出2。

emit <file>

把文件完整走一遍对应类型的解析器与发射器。对健全文件输出应与输入逐字节一致;出现差异说明解析器 bug 或哨兵命中。适合在真实输入上调试 substrate 行为。

openclaw path emit ./AGENTS.md openclaw path emit ./gateway.jsonc --json

安全:红action 哨兵守卫

set通过 substrate 的 emit 路径写原始字节,emit 路径自动应用红action 哨兵守卫(extensions/oc-path/src/oc-path/sentinel.ts)。携带__OPENCLAW_REDACTED__(逐字或作为子串出现)的叶子在写入时以OC_EMIT_SENTINEL拒绝——注意是子串匹配而非相等匹配,prefix__OPENCLAW_REDACTED__suffix仍然泄漏标记,所以同样拦截。哨兵检测对所有字符串值生效,包括 markdown frontmatter、条目与标题的插入值;既有的无关标记文本在普通编辑中原样保留。

守卫采用**失败关闭(fail-closed)**策略:与其静默剥离标记(那会悄然损坏文件),不如拒绝写入。guardSentinel在 emit 边界抛出OcEmitSentinelError,让每一条写入路径都被覆盖,而不只是被审计的消费者。CLI 侧(cli.ts的emit/emitError/scrubSentinel)还会在打印任何人类可读或 JSON 输出前把哨兵字面量替换成[REDACTED],终端捕获与管道永远不会泄漏该标记。

与其他插件的关系

  • memory-*:内存写入走 memory 插件,不经过oc-path。oc-path是通用文件 substrate;memory 插件在其上叠加自己的语义。
  • LKG:path不感知 last-known-good 配置恢复。如果你通过path编辑的文件同时被 LKG 跟踪,下一次配置 observe 周期会决定提升还是恢复它——把path编辑视同对该文件的任何其他直接写入。

实用速查:组合语法示例

# 校验一个路径(不做文件系统访问) openclaw path validate 'oc://AGENTS.md/Tools/$last/risk' # 读取一个叶子 openclaw path resolve 'oc://gateway.jsonc/version' # 通配符搜索 openclaw path find 'oc://session.jsonl/*/event' --file ./logs/session.jsonl # 干跑一次写入 openclaw path set 'oc://gateway.jsonc/version' '2.0' --dry-run # 干跑并以统一 diff 预览 openclaw path set 'oc://gateway.jsonc/version' '2.0' --dry-run --diff # 应用写入 openclaw path set 'oc://gateway.jsonc/version' '2.0' # 字节保真往返(诊断) openclaw path emit ./AGENTS.md

更完整的语法示例:

# 引号键,容纳包含 / 或 . 的键 openclaw path resolve 'oc://config.jsonc/agents.defaults.models/"anthropic/claude-opus-4-7"/alias' # 深层 JSON/JSONC 路径可用斜杠分段;它们归一化为点分子段 openclaw path set 'oc://openclaw.json/agents/list/0/tools/exec/security' 'allowlist' --dry-run # 把 JSONC 叶子替换为解析后的对象 openclaw path set 'oc://openclaw.json/gateway/auth/token' '{"source":"file","provider":"secrets","id":"/test"}' --value-json --dry-run # 在 JSONC 子节点上做谓词搜索 openclaw path find 'oc://config.jsonc/plugins/[enabled=true]/id' # 插入 JSONC 数组元素 openclaw path set 'oc://config.jsonc/items/+1' '{"id":"new","enabled":true}' --dry-run # 插入 JSONC 对象键 openclaw path set 'oc://config.jsonc/plugins/+github' '{"enabled":true}' --dry-run # 追加 JSONL 事件 openclaw path set 'oc://session.jsonl/+' '{"event":"checkpoint","ok":true}' --file ./logs/session.jsonl # 解析最后一行 JSONL 值 openclaw path resolve 'oc://session.jsonl/$last/event' --file ./logs/session.jsonl # 解析 YAML 工作流步骤 openclaw path resolve 'oc://workflow.yaml/steps/0/id' # 更新 YAML 标量 openclaw path set 'oc://workflow.yaml/steps/$last/id' 'classify-renamed' --dry-run # 寻址 markdown frontmatter openclaw path resolve 'oc://AGENTS.md/[frontmatter]/name' # 插入 markdown frontmatter openclaw path set 'oc://AGENTS.md/[frontmatter]/+description' 'Agent instructions' --dry-run # 查找 markdown 条目字段 openclaw path find 'oc://SKILL.md/Tools/*/send_email' # 校验一个带会话作用域的路径 openclaw path validate 'oc://AGENTS.md/Tools/$last/risk?session=cron-daily'

使用边界与注意事项

  • set在写入或干跑预览前,拒绝包含__OPENCLAW_REDACTED__(逐字或子串)的字符串叶子值。
  • JSONC 解析与叶子编辑使用插件局部的jsonc-parser依赖,普通叶子写入保留注释与格式,而不是走手写解析/重渲染路径。
  • path不感知 LKG 配置跟踪或恢复——该生命周期由其他模块所有。通过path编辑的 LKG 跟踪文件,下一次配置读取决定提升或恢复,视同任何其他直接写入。
  • resolve/set只接受具体路径;通配符、联合、谓词等模式在写入前被拒绝,探索性匹配请用find。

进一步阅读

  • openclaw pathCLI 参考(完整语法、逐动词标志清单与逐文件类型工作示例)
  • 管理插件
  • 构建插件
  • 插件源码与测试:extensions/oc-path/,其中src/oc-path/tests/scenarios/下的byte-fidelity、sentinel-guard、roundtrip-property等测试用例覆盖了本文所述的关键契约

【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 🦞项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询