plan-governance-cli 1.0.0 → 1.0.1

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/README.md CHANGED
@@ -209,6 +209,14 @@ plan-governance-cli graph code impact --repo modelpad --file Sources/ModelPadCor
209
209
 
210
210
  [验证规范](resources/skill/references/verification.md)统一维护风险分流、证据复用、失败重审与用户验收;其他会话从同一 skill 读取。需要独立复核且授权明确时自动安排只读 subagent,不为普通小改逐次派发;技术完成待用户验收的适用功能计划仍保持实施中。
211
211
 
212
+ 1.0.1 起支持可选的最近记录窗口:
213
+
214
+ ```bash
215
+ plan-governance-cli workset . --json --evidence-limit 3
216
+ ```
217
+
218
+ 每个计划保留末尾三条记录,并给出省略数量和原文位置;默认完整输出和门禁判断保持。窗口用于恢复阅读,必要时去掉参数回查完整记录,详见 [CLI 参考](resources/skill/references/cli.md#当前工作集)。已发布的 1.0.0 尚不支持此参数。
219
+
212
220
  ## 按需读取规则
213
221
 
214
222
  ```bash
@@ -225,7 +233,7 @@ SKILL 保留任务分流和执行底线,三份 references 按需读取并随 m
225
233
  也可以不全局安装,直接使用锁定版本:
226
234
 
227
235
  ```bash
228
- npx --yes --package plan-governance-cli@1.0.0 plan-governance-cli check . --strict-readiness
236
+ npx --yes --package plan-governance-cli@1.0.1 plan-governance-cli check . --strict-readiness
229
237
  ```
230
238
 
231
239
  npm 包内部仍使用版本化的 Python 检查器,但用户不需要直接调用或复制该脚本。旧项目已有本地脚本时仍可保留作为兼容或回滚路径。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plan-governance-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "统一入口的计划治理检查 CLI",
5
5
  "private": false,
6
6
  "type": "module",
@@ -10,6 +10,10 @@
10
10
 
11
11
  `plan-governance-cli workset . --json` 派生当前计划、阶段、阻塞、下一动作、并行提示和最近证据;加 `--strict-readiness` 对活跃计划的机械缺陷返回非零。它不写计划、不自动执行动作、不替代授权或业务验收,也不自动核对快照和环境漂移。恢复先读工作集与相关当前记录,必要时再展开原计划。
12
12
 
13
+ 1.0.1 起,恢复阅读可显式用 `workset . --json --evidence-limit 3`,按原追加顺序显示每个计划末尾三条记录。N 必须为正整数且仅适用于 workset JSON;默认仍返回完整记录。限量模式的 `recent_evidence_window` 提供 `total`、`omitted` 和原文 `source`(实际 `path`/`section`;无法确认时为 null),不改变完整数据派生的阻塞、动作、诊断或退出码。没有记录章节时 section 为 null。
14
+
15
+ 限量窗口不等于完整验收证据;有阻塞、缺关键上下文或需要复核结论时,按 source 回查,或去掉 `--evidence-limit` 读取完整记录。`--include-history` 仍只控制是否纳入历史计划。普通文本不显示记录表,不需要此参数;旧 CLI(包括 1.0.0)不支持限量时,继续用完整输出,按已获授权更新版本。
16
+
13
17
  ## 分发与资源
14
18
 
15
19
  SKILL、三个 references、agents 元数据与 assets 由同一 npm 包的 manifest 分发。`plan-governance-cli setup --target codex|claude|all --dry-run` 查看同步差异;实际覆盖需既有用户授权并按 setup 冲突提示处理,不自动清理用户目录残留。项目升级不迁移旧计划,受管块外内容必须保持。
@@ -2208,9 +2208,50 @@ def print_workset_text(payload, strict=False):
2208
2208
  print(f"{level}: {warning}")
2209
2209
 
2210
2210
 
2211
- def run_workset(root, as_json=False, include_history=False, strict=False):
2211
+ def limit_workset_evidence(root, payload, limit):
2212
+ """裁剪 JSON 阅读窗口;完整 payload 和门禁结果保持不变。"""
2213
+ result = {**payload, "plans": []}
2214
+ if not payload["plans"]:
2215
+ return result
2216
+ source_errors = []
2217
+ _, _, records = load_plan_records(root, source_errors)
2218
+ if source_errors:
2219
+ records = {}
2220
+ for item in payload["plans"]:
2221
+ rows = item["recent_evidence"]
2222
+ source = None
2223
+ record = records.get(item["plan"])
2224
+ if record and record["phase"] == item["phase"]:
2225
+ errors = []
2226
+ text = read_utf8(record["path"], errors)
2227
+ # 来源只辅助回查;再次读取失败或内容变化不能伪造定位。
2228
+ if not errors and recent_evidence(text, item["phase"]) == rows:
2229
+ current = top_level_section(text, "当前阶段") or ""
2230
+ titles = ["最近实施/验证记录"]
2231
+ if item["phase"]:
2232
+ titles.extend([f"{item['phase']} 最近验证记录", f"{item['phase']} 最近实施/验证记录"])
2233
+ section = next((title for title in titles if fixed_section(current, title) is not None), None)
2234
+ try:
2235
+ path = record["path"].relative_to(root).as_posix()
2236
+ except ValueError:
2237
+ path = record["path"].as_posix()
2238
+ source = {"path": path, "section": section}
2239
+ shown = rows[-limit:]
2240
+ result["plans"].append({
2241
+ **item,
2242
+ "recent_evidence": shown,
2243
+ "recent_evidence_window": {
2244
+ "total": len(rows), "omitted": len(rows) - len(shown), "source": source,
2245
+ },
2246
+ })
2247
+ return result
2248
+
2249
+
2250
+ def run_workset(root, as_json=False, include_history=False, strict=False, evidence_limit=None):
2212
2251
  payload, status = workset_payload(root, include_history=include_history, strict=strict)
2213
2252
  if as_json:
2253
+ if evidence_limit is not None:
2254
+ payload = limit_workset_evidence(root, payload, evidence_limit)
2214
2255
  print(json.dumps(payload, ensure_ascii=False, indent=2))
2215
2256
  else:
2216
2257
  print_workset_text(payload, strict=strict)
@@ -2223,6 +2264,8 @@ def parse_args(argv):
2223
2264
  parser.add_argument("--workset", action="store_true", help="输出只读当前工作集。")
2224
2265
  parser.add_argument("--json", action="store_true", help="以 JSON 输出工作集。")
2225
2266
  parser.add_argument("--include-history", action="store_true", help="工作集包含历史计划。")
2267
+ parser.add_argument("--evidence-limit", type=int, metavar="N",
2268
+ help="仅工作集 JSON:每个计划显示末尾 N 条记录(正整数),省略时返回全部。")
2226
2269
  parser.add_argument("--root", dest="mode_root", help="工作集的仓库根目录。")
2227
2270
  parser.add_argument("--drift", action="store_true", help="检查工作区变更是否被活跃计划影响范围覆盖。")
2228
2271
  parser.add_argument("--pre-commit", action="store_true", help="检查 staged 变更是否被活跃计划影响范围覆盖。")
@@ -2255,7 +2298,13 @@ def parse_args(argv):
2255
2298
  default=None,
2256
2299
  help="检查活跃计划是否超过 N 天未更新;省略 N 时默认 10 天。",
2257
2300
  )
2258
- return parser.parse_args(argv)
2301
+ args = parser.parse_args(argv)
2302
+ if args.evidence_limit is not None:
2303
+ if args.evidence_limit <= 0:
2304
+ parser.error("--evidence-limit 必须为正整数")
2305
+ if not args.workset or not args.json:
2306
+ parser.error("--evidence-limit 只能与 --workset 和 --json 一起使用")
2307
+ return args
2259
2308
 
2260
2309
 
2261
2310
  def main(argv=None):
@@ -2269,6 +2318,7 @@ def main(argv=None):
2269
2318
  as_json=args.json,
2270
2319
  include_history=args.include_history,
2271
2320
  strict=args.strict_readiness,
2321
+ evidence_limit=args.evidence_limit,
2272
2322
  )
2273
2323
  root = Path(args.root)
2274
2324
  docs = root / "docs"