plan-governance-cli 0.3.0 → 0.3.2
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 +29 -3
- package/bin/plan-governance-cli.mjs +7 -0
- package/package.json +1 -1
- package/resources/manifest.json +1 -1
- package/resources/skill/SKILL.md +25 -4
- package/resources/skill/agents/openai.yaml +1 -1
- package/resources/skill/assets/PLAN_MAP.template.md +2 -0
- package/resources/skill/assets/plan.template.md +33 -0
- package/scripts/check_plan_governance.py +1402 -18
- package/scripts/plan_governance_hook.py +30 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
import argparse
|
|
3
|
+
import importlib.util
|
|
3
4
|
import re
|
|
4
5
|
import subprocess
|
|
5
6
|
import sys
|
|
@@ -134,6 +135,16 @@ def active_plans(root):
|
|
|
134
135
|
return [plan for plan in plans if plan["status"] in ACTIVE_STATUSES], blockers
|
|
135
136
|
|
|
136
137
|
|
|
138
|
+
def load_next_checker():
|
|
139
|
+
checker_path = Path(__file__).with_name("check_plan_governance.py")
|
|
140
|
+
spec = importlib.util.spec_from_file_location("plan_governance_next_checker", checker_path)
|
|
141
|
+
if spec is None or spec.loader is None:
|
|
142
|
+
return None
|
|
143
|
+
module = importlib.util.module_from_spec(spec)
|
|
144
|
+
spec.loader.exec_module(module)
|
|
145
|
+
return module
|
|
146
|
+
|
|
147
|
+
|
|
137
148
|
def target_matches_path(target, path):
|
|
138
149
|
normalized_target = normalize_scope_path(target)
|
|
139
150
|
normalized_path = normalize_scope_path(path)
|
|
@@ -178,7 +189,25 @@ def print_session_start(root):
|
|
|
178
189
|
print(f"- {row[0]}: {row[4]}")
|
|
179
190
|
else:
|
|
180
191
|
print("[plan-governance] 当前阻塞项:无。")
|
|
181
|
-
|
|
192
|
+
|
|
193
|
+
checker = load_next_checker()
|
|
194
|
+
if checker is None:
|
|
195
|
+
return 0
|
|
196
|
+
hook_status = 0
|
|
197
|
+
for plan in active:
|
|
198
|
+
payload, status = checker.plan_next_payload(root, plan["name"])
|
|
199
|
+
if payload["status"] == "not_enabled":
|
|
200
|
+
continue
|
|
201
|
+
ready = ",".join(item["id"] for item in payload.get("ready_steps", [])) or "-"
|
|
202
|
+
blocked = ",".join(item["id"] for item in payload.get("blocked_steps", [])) or "-"
|
|
203
|
+
action = payload["next_action"]
|
|
204
|
+
print(
|
|
205
|
+
f"[plan-governance] autonomous next: {plan['name']} | "
|
|
206
|
+
f"{payload['status']} | ready={ready} | blocked={blocked} | "
|
|
207
|
+
f"next={action['kind']}:{action['reason']}"
|
|
208
|
+
)
|
|
209
|
+
hook_status = max(hook_status, status)
|
|
210
|
+
return hook_status
|
|
182
211
|
|
|
183
212
|
|
|
184
213
|
def print_pre_write(root, paths):
|