ygl-trees 0.68.0 → 0.70.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/apps/cli/src/bin.js +134 -126
- package/dist/bundle/bin.cjs +120 -88
- package/dist/bundle/mcp-C27lIHd1.cjs +276 -0
- package/dist/bundle/rolldown-runtime-C96Ew50Q.cjs +64 -0
- package/dist/packages/ops/tools/src/agent-cmds.js +72 -0
- package/dist/packages/ops/tools/src/index.js +4 -1
- package/dist/packages/ops/tools/src/mcp.js +233 -0
- package/llms.txt +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.70.0(2026-10-17)`agent metrics`——从 R11 手动测量到自动化指标
|
|
4
|
+
- **`ygl-trees agent metrics`**:一条命令输出工作台全量量化指标——冷启动(brief 耗时/next actions/可用技能)、知识(总量/7日增长/增长率)、研究(来源/证据/断言/验证率/证据密度)、技能(总数/命中/均命中)、科技树(棵数/节点/解锁率)、活动(7 日 events)
|
|
5
|
+
- **来源**:R11 冷启动量化研究的手动测量 → 自动化——从 `time agent brief` + 手动 grep 统计变为一键输出
|
|
6
|
+
- 135 单测全绿
|
|
7
|
+
|
|
8
|
+
## 0.69.0(2026-10-17)MCP Server——R8 研究设计的工程落地
|
|
9
|
+
- **`ygl-trees mcp`**:启动 stdio MCP 服务器(JSON-RPC 2.0),Claude Desktop / Cursor / VS Code 等 IDE Agent 可直接连接
|
|
10
|
+
- **8 工具面**(三支柱理论驱动):agent_brief · agent_match · kb_search · claim_evaluate · tree_state · produce_report · doctor · task_advance
|
|
11
|
+
- **每个工具继承 CLI 冻结契约**(幂等写入、JSON 纯净、snake_case)——Agent 调用工具不需要解析命令行
|
|
12
|
+
- **实现**:`packages/ops/tools/src/mcp.ts`——readline stdio + JSON-RPC 路由 + `cliJson()` 子进程调用(`process.argv[1]` 自引用,bundle/源码双兼容)
|
|
13
|
+
- 实测:initialize ✓ · tools/list(8) ✓ · agent_brief(project) ✓ · kb_search(CJK 命中) ✓ · doctor(9 项) ✓
|
|
14
|
+
|
|
3
15
|
## 0.68.0(2026-10-17)锁设计修复——serve/CLI 共存 + PID 活锁检测 + JSON 纯净 + v9 时间纪律
|
|
4
16
|
- **F1(P0):webui serve 不再持排他锁**——原实现进程级锁让 serve 生命周期内挡掉一切 CLI 命令;现 serve 跳过锁(`YGL_SERVE=1` 旁路),SQLite WAL 天然支持并发读 + 序列化写;CLI 短命令仍锁(单写者保护写窗口)
|
|
5
17
|
- **P1(用户反馈):PID 活锁检测替代 15 分钟 mtime**——Windows 上 `process.on("exit")` 的 rmSync 句柄未释放时静默失败→锁残留→下进程撞白锁;现用 `process.kill(pid, 0)` 探测持有者是否存活(EPERM=活/ESRCH=死),死 PID **立即清锁**(不看 mtime),活 PID **如实报告**(不误报 stale)
|
package/dist/apps/cli/src/bin.js
CHANGED
|
@@ -116,132 +116,132 @@ function appVersion() {
|
|
|
116
116
|
}
|
|
117
117
|
// ── Usage text ──
|
|
118
118
|
// (kept in apps/cli because it's presentation, not domain logic)
|
|
119
|
-
const USAGE = `
|
|
120
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "ygl-trees", true)} 猿光 · 科技树
|
|
121
|
-
${(0, fmt_1.paint)(fmt_1.C.dim, "database-centric CLI: research → production → knowledge reuse", true)}
|
|
122
|
-
|
|
123
|
-
ygl-trees <group> <action> [args] [options] add --json for machine output
|
|
124
|
-
|
|
125
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "config", true)} user-tunable settings (registry defaults + overrides)
|
|
126
|
-
list all keys: value + default + note
|
|
127
|
-
get <key> resolved value (config table > default)
|
|
128
|
-
set <key> <value> validated against registry (type/range); events logged
|
|
129
|
-
reset <key> drop override → back to default
|
|
130
|
-
|
|
131
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "db", true)}
|
|
132
|
-
init create the workspace + schema
|
|
133
|
-
stats row counts per table
|
|
134
|
-
path print the database file path
|
|
135
|
-
export <file.sql> [--lean] dump ALL data tables (+ summary); --lean skips derived
|
|
136
|
-
sync pg <url> one-way full mirror to PostgreSQL (L1, see docs/pg-compat.md)
|
|
137
|
-
migrate pg <url> [--fresh] one-time full-fidelity graduation (constraints + data, atomic)
|
|
138
|
-
dups list duplicate-content rows
|
|
139
|
-
reset delete the database (asks nothing, be careful)
|
|
140
|
-
sql "<sql>" ad-hoc statement (can mutate — power tool, no guardrails)
|
|
141
|
-
|
|
142
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "skill", true)} L1 description / L2 body / L3 references
|
|
143
|
-
import <file.md> import a SKILL.md (frontmatter = L1, body = L2)
|
|
144
|
-
add --name --description --body [-f file.md]
|
|
145
|
-
list | show <name> | rm <name> | enable <name> | disable <name>
|
|
146
|
-
match "<query>" full-text match, prints L1 candidates for an agent
|
|
147
|
-
refs add <skill> <path> --body ...
|
|
148
|
-
|
|
149
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "project", true)}
|
|
150
|
-
new <name> -q "<question>" create + select
|
|
151
|
-
list | use <name> | show
|
|
152
|
-
|
|
153
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "research", true)} collect → screen → extract → claim
|
|
154
|
-
query add "<text>" register a search query
|
|
155
|
-
query attach <qid> <sid> link source to query (recalled count)
|
|
156
|
-
query list
|
|
157
|
-
source add --title --url [--abstract --content --relevance --confidence --query]
|
|
158
|
-
source fetch <url> fetch page, extract title/meta/text (zero side-effect on failure)
|
|
159
|
-
source list | search "<q>" | show <id> | rm <id>
|
|
160
|
-
evidence add <sourceId> --quote "..." [--note --locator]
|
|
161
|
-
evidence list
|
|
162
|
-
claim add "<text>" [--confidence A|B|C]
|
|
163
|
-
claim link <claimId> <evidenceId> [--stance supports|refutes]
|
|
164
|
-
claim resolve <claimId> --as supported|refuted|contested [--note]
|
|
165
|
-
claim list
|
|
166
|
-
|
|
167
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "produce", true)} outline → section → report · spec/design(工程产出)
|
|
168
|
-
outline auto-outline from claims
|
|
169
|
-
section <title> --body|-f add a section artifact
|
|
170
|
-
report assemble claims+evidence+sections into a report
|
|
171
|
-
spec <title> --body|-f requirements spec artifact (R12)
|
|
172
|
-
design <title> --body|-f design artifact (R12) --design-type ui-ux|arch|decision
|
|
173
|
-
list | show <id> | export <id> <file>
|
|
174
|
-
|
|
175
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "task", true)} 任务清单(todo|doing|done 状态机,R12)
|
|
176
|
-
add "<title>" [--note ...] create a task (status todo)
|
|
177
|
-
list [--status todo|doing|done]
|
|
178
|
-
doing|done <id> move along the state machine(勾销全程留痕)
|
|
179
|
-
|
|
180
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "kb", true)} long-term knowledge
|
|
181
|
-
add --title --body|-f [--tags --confidence]
|
|
182
|
-
import <dir|file.md> batch markdown (frontmatter, idempotent, single tx)
|
|
183
|
-
search "<q>" | list | show <id>
|
|
184
|
-
link <a> <b> [--rel]
|
|
185
|
-
ingest <artifactId> import a finished artifact
|
|
186
|
-
promote <noteId> [--name] turn a note into a reusable skill
|
|
187
|
-
|
|
188
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "job", true)} batch + schedule (drive with cron: job tick)
|
|
189
|
-
add <title> -- <command> [--every <min>] [--at "YYYY-MM-DD HH:MM"]
|
|
190
|
-
list | run <id> | tick | enable <id> | disable <id> | logs
|
|
191
|
-
|
|
192
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "tree / node", true)} tech-tree node model
|
|
193
|
-
tree new <name> [--project p] create a tree (nodes live in it)
|
|
194
|
-
tree list | tree use <name>
|
|
195
|
-
|
|
196
|
-
node add <key> [--name --kind --tier --cost --tags --payload]
|
|
197
|
-
node link <parent> <child> [--rel prereq|unlock|excludes|enables]
|
|
198
|
-
[--mode AND|OR|XOR|NOT] [--optional]
|
|
199
|
-
[--min-level n] [--weight n]
|
|
200
|
-
node unlink <parent> <child> [--rel prereq]
|
|
201
|
-
node cond <key> --name <c> [--kind flag|resource|level|quest|time|expr]
|
|
202
|
-
[--op >=|==|<=|!=|has] [--value v] [--optional]
|
|
203
|
-
[--op eval --value "<布尔问题>"]
|
|
204
|
-
[--op eval-choice --value "<问题>" --options "k=desc,..." --answer k]
|
|
205
|
-
[--op eval-score --value "<问题>" --levels "级0,..." --min-score n]
|
|
206
|
-
[--effect gate|cost_mul] [--weight n]
|
|
207
|
-
node index rebuild closure + topo order
|
|
208
|
-
node can <key> [--state k=v] evaluate required vs optional gates
|
|
209
|
-
(--eval: eval 题型经决策模型判定;
|
|
210
|
-
boolean P / choice P(期望答案) / score ±1 灰带)
|
|
211
|
-
node ready [--state k=v] [--eval] currently unlockable set
|
|
212
|
-
node path <key> dependency-order path to target (all locked ancestors; OR branches not optimized)
|
|
213
|
-
node parents|children <key> direct relations
|
|
214
|
-
node ancestors|descendants <key> transitive, via closure index
|
|
215
|
-
node list | show <key> | search "<q>" | unlock|lock <key>
|
|
216
|
-
node validate cycles, dangling edges, dirty index
|
|
217
|
-
node export [--out file.json] portable JSON
|
|
218
|
-
node import --file <file.json> [--tree name] [--merge] — strict, transactional
|
|
219
|
-
|
|
220
|
-
Writes are idempotent (claim/evidence/query/kb/job dedupe by content
|
|
221
|
-
hash); pass --force to keep a deliberate duplicate.
|
|
222
|
-
|
|
223
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "webui", true)} dashboard (zero-dependency)
|
|
224
|
-
export [--out <file>] single-file dashboard.html (open in browser)
|
|
225
|
-
serve [--port N] live dashboard at http://127.0.0.1:N/ (Ctrl+C to stop)
|
|
226
|
-
|
|
227
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "rel", true)} 关联织物(spec R9:任意两类实体互相挂接)
|
|
228
|
-
add <src> <dst> [--rel t] link two refs: node:key claim:id kb:id artifact:id
|
|
229
|
-
skill:name evidence:id source:id query:id
|
|
230
|
-
rm <src> <dst> [--rel t] unlink
|
|
231
|
-
list [--src r] [--dst r] browse (either side filter, resolves displays)
|
|
232
|
-
|
|
233
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "plugin", true)} 用户层插件分发(spec R14 L3,业务域扩展位)
|
|
234
|
-
init create $YGL_HOME/plugins profile
|
|
235
|
-
install <spec> npm package / git url / local dir (auto link:)
|
|
236
|
-
remove <name> | list manage the user layer ($YGL_HOME/ygl.user.bundle.json)
|
|
237
|
-
插件契约:export apply(ctx,config) + 可选 commands 贡献 CLI 命令组
|
|
238
|
-
|
|
239
|
-
${(0, fmt_1.paint)(fmt_1.C.bold, "agent", true)} agent-facing views
|
|
240
|
-
brief current project state + next actions (start here)
|
|
241
|
-
match "<task>" which skill should handle this task
|
|
242
|
-
log recent events
|
|
243
|
-
|
|
244
|
-
Global: --json --no-color --db <file> --home <dir>
|
|
119
|
+
const USAGE = `
|
|
120
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "ygl-trees", true)} 猿光 · 科技树
|
|
121
|
+
${(0, fmt_1.paint)(fmt_1.C.dim, "database-centric CLI: research → production → knowledge reuse", true)}
|
|
122
|
+
|
|
123
|
+
ygl-trees <group> <action> [args] [options] add --json for machine output
|
|
124
|
+
|
|
125
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "config", true)} user-tunable settings (registry defaults + overrides)
|
|
126
|
+
list all keys: value + default + note
|
|
127
|
+
get <key> resolved value (config table > default)
|
|
128
|
+
set <key> <value> validated against registry (type/range); events logged
|
|
129
|
+
reset <key> drop override → back to default
|
|
130
|
+
|
|
131
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "db", true)}
|
|
132
|
+
init create the workspace + schema
|
|
133
|
+
stats row counts per table
|
|
134
|
+
path print the database file path
|
|
135
|
+
export <file.sql> [--lean] dump ALL data tables (+ summary); --lean skips derived
|
|
136
|
+
sync pg <url> one-way full mirror to PostgreSQL (L1, see docs/pg-compat.md)
|
|
137
|
+
migrate pg <url> [--fresh] one-time full-fidelity graduation (constraints + data, atomic)
|
|
138
|
+
dups list duplicate-content rows
|
|
139
|
+
reset delete the database (asks nothing, be careful)
|
|
140
|
+
sql "<sql>" ad-hoc statement (can mutate — power tool, no guardrails)
|
|
141
|
+
|
|
142
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "skill", true)} L1 description / L2 body / L3 references
|
|
143
|
+
import <file.md> import a SKILL.md (frontmatter = L1, body = L2)
|
|
144
|
+
add --name --description --body [-f file.md]
|
|
145
|
+
list | show <name> | rm <name> | enable <name> | disable <name>
|
|
146
|
+
match "<query>" full-text match, prints L1 candidates for an agent
|
|
147
|
+
refs add <skill> <path> --body ...
|
|
148
|
+
|
|
149
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "project", true)}
|
|
150
|
+
new <name> -q "<question>" create + select
|
|
151
|
+
list | use <name> | show
|
|
152
|
+
|
|
153
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "research", true)} collect → screen → extract → claim
|
|
154
|
+
query add "<text>" register a search query
|
|
155
|
+
query attach <qid> <sid> link source to query (recalled count)
|
|
156
|
+
query list
|
|
157
|
+
source add --title --url [--abstract --content --relevance --confidence --query]
|
|
158
|
+
source fetch <url> fetch page, extract title/meta/text (zero side-effect on failure)
|
|
159
|
+
source list | search "<q>" | show <id> | rm <id>
|
|
160
|
+
evidence add <sourceId> --quote "..." [--note --locator]
|
|
161
|
+
evidence list
|
|
162
|
+
claim add "<text>" [--confidence A|B|C]
|
|
163
|
+
claim link <claimId> <evidenceId> [--stance supports|refutes]
|
|
164
|
+
claim resolve <claimId> --as supported|refuted|contested [--note]
|
|
165
|
+
claim list
|
|
166
|
+
|
|
167
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "produce", true)} outline → section → report · spec/design(工程产出)
|
|
168
|
+
outline auto-outline from claims
|
|
169
|
+
section <title> --body|-f add a section artifact
|
|
170
|
+
report assemble claims+evidence+sections into a report
|
|
171
|
+
spec <title> --body|-f requirements spec artifact (R12)
|
|
172
|
+
design <title> --body|-f design artifact (R12) --design-type ui-ux|arch|decision
|
|
173
|
+
list | show <id> | export <id> <file>
|
|
174
|
+
|
|
175
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "task", true)} 任务清单(todo|doing|done 状态机,R12)
|
|
176
|
+
add "<title>" [--note ...] create a task (status todo)
|
|
177
|
+
list [--status todo|doing|done]
|
|
178
|
+
doing|done <id> move along the state machine(勾销全程留痕)
|
|
179
|
+
|
|
180
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "kb", true)} long-term knowledge
|
|
181
|
+
add --title --body|-f [--tags --confidence]
|
|
182
|
+
import <dir|file.md> batch markdown (frontmatter, idempotent, single tx)
|
|
183
|
+
search "<q>" | list | show <id>
|
|
184
|
+
link <a> <b> [--rel]
|
|
185
|
+
ingest <artifactId> import a finished artifact
|
|
186
|
+
promote <noteId> [--name] turn a note into a reusable skill
|
|
187
|
+
|
|
188
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "job", true)} batch + schedule (drive with cron: job tick)
|
|
189
|
+
add <title> -- <command> [--every <min>] [--at "YYYY-MM-DD HH:MM"]
|
|
190
|
+
list | run <id> | tick | enable <id> | disable <id> | logs
|
|
191
|
+
|
|
192
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "tree / node", true)} tech-tree node model
|
|
193
|
+
tree new <name> [--project p] create a tree (nodes live in it)
|
|
194
|
+
tree list | tree use <name>
|
|
195
|
+
|
|
196
|
+
node add <key> [--name --kind --tier --cost --tags --payload]
|
|
197
|
+
node link <parent> <child> [--rel prereq|unlock|excludes|enables]
|
|
198
|
+
[--mode AND|OR|XOR|NOT] [--optional]
|
|
199
|
+
[--min-level n] [--weight n]
|
|
200
|
+
node unlink <parent> <child> [--rel prereq]
|
|
201
|
+
node cond <key> --name <c> [--kind flag|resource|level|quest|time|expr]
|
|
202
|
+
[--op >=|==|<=|!=|has] [--value v] [--optional]
|
|
203
|
+
[--op eval --value "<布尔问题>"]
|
|
204
|
+
[--op eval-choice --value "<问题>" --options "k=desc,..." --answer k]
|
|
205
|
+
[--op eval-score --value "<问题>" --levels "级0,..." --min-score n]
|
|
206
|
+
[--effect gate|cost_mul] [--weight n]
|
|
207
|
+
node index rebuild closure + topo order
|
|
208
|
+
node can <key> [--state k=v] evaluate required vs optional gates
|
|
209
|
+
(--eval: eval 题型经决策模型判定;
|
|
210
|
+
boolean P / choice P(期望答案) / score ±1 灰带)
|
|
211
|
+
node ready [--state k=v] [--eval] currently unlockable set
|
|
212
|
+
node path <key> dependency-order path to target (all locked ancestors; OR branches not optimized)
|
|
213
|
+
node parents|children <key> direct relations
|
|
214
|
+
node ancestors|descendants <key> transitive, via closure index
|
|
215
|
+
node list | show <key> | search "<q>" | unlock|lock <key>
|
|
216
|
+
node validate cycles, dangling edges, dirty index
|
|
217
|
+
node export [--out file.json] portable JSON
|
|
218
|
+
node import --file <file.json> [--tree name] [--merge] — strict, transactional
|
|
219
|
+
|
|
220
|
+
Writes are idempotent (claim/evidence/query/kb/job dedupe by content
|
|
221
|
+
hash); pass --force to keep a deliberate duplicate.
|
|
222
|
+
|
|
223
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "webui", true)} dashboard (zero-dependency)
|
|
224
|
+
export [--out <file>] single-file dashboard.html (open in browser)
|
|
225
|
+
serve [--port N] live dashboard at http://127.0.0.1:N/ (Ctrl+C to stop)
|
|
226
|
+
|
|
227
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "rel", true)} 关联织物(spec R9:任意两类实体互相挂接)
|
|
228
|
+
add <src> <dst> [--rel t] link two refs: node:key claim:id kb:id artifact:id
|
|
229
|
+
skill:name evidence:id source:id query:id
|
|
230
|
+
rm <src> <dst> [--rel t] unlink
|
|
231
|
+
list [--src r] [--dst r] browse (either side filter, resolves displays)
|
|
232
|
+
|
|
233
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "plugin", true)} 用户层插件分发(spec R14 L3,业务域扩展位)
|
|
234
|
+
init create $YGL_HOME/plugins profile
|
|
235
|
+
install <spec> npm package / git url / local dir (auto link:)
|
|
236
|
+
remove <name> | list manage the user layer ($YGL_HOME/ygl.user.bundle.json)
|
|
237
|
+
插件契约:export apply(ctx,config) + 可选 commands 贡献 CLI 命令组
|
|
238
|
+
|
|
239
|
+
${(0, fmt_1.paint)(fmt_1.C.bold, "agent", true)} agent-facing views
|
|
240
|
+
brief current project state + next actions (start here)
|
|
241
|
+
match "<task>" which skill should handle this task
|
|
242
|
+
log recent events
|
|
243
|
+
|
|
244
|
+
Global: --json --no-color --db <file> --home <dir>
|
|
245
245
|
`;
|
|
246
246
|
function usage() {
|
|
247
247
|
return USAGE;
|
|
@@ -276,6 +276,14 @@ async function main(argv) {
|
|
|
276
276
|
(0, fmt_1.out)(ctx, generateLlmsManifest());
|
|
277
277
|
return 0;
|
|
278
278
|
}
|
|
279
|
+
// MCP: Model Context Protocol server (stdio) — 8-tool surface.
|
|
280
|
+
// Designed by the unified three-pillar theory (R8 research); each tool
|
|
281
|
+
// routes to CLI --json, inheriting frozen contracts.
|
|
282
|
+
if (group === "mcp") {
|
|
283
|
+
const { serveMcp } = await Promise.resolve().then(() => __importStar(require("../../../packages/ops/tools/src/mcp")));
|
|
284
|
+
serveMcp();
|
|
285
|
+
return new Promise(() => { });
|
|
286
|
+
}
|
|
279
287
|
if (!group || group === "help" || group === "-h" || group === "--help") {
|
|
280
288
|
if (!ctx.json)
|
|
281
289
|
(0, fmt_1.out)(ctx, usage());
|