patchwarden 1.1.0 → 1.5.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.
Files changed (258) hide show
  1. package/README.en.md +83 -8
  2. package/README.md +78 -10
  3. package/dist/assessments/agentAssessor.d.ts +1 -1
  4. package/dist/assessments/agentAssessor.js +3 -3
  5. package/dist/assessments/assessmentStore.d.ts +1 -1
  6. package/dist/assessments/assessmentStore.js +2 -2
  7. package/dist/assessments/confirmCli.js +5 -4
  8. package/dist/config.d.ts +7 -0
  9. package/dist/config.js +34 -0
  10. package/dist/control/middleware/auth.d.ts +10 -0
  11. package/dist/control/middleware/auth.js +8 -0
  12. package/dist/control/middleware/static.d.ts +3 -0
  13. package/dist/control/middleware/static.js +65 -0
  14. package/dist/control/routes/audit.d.ts +15 -0
  15. package/dist/control/routes/audit.js +277 -0
  16. package/dist/control/routes/evidence.d.ts +4 -0
  17. package/dist/control/routes/evidence.js +96 -0
  18. package/dist/control/routes/lineage.d.ts +3 -0
  19. package/dist/control/routes/lineage.js +71 -0
  20. package/dist/control/routes/policy.d.ts +3 -0
  21. package/dist/control/routes/policy.js +81 -0
  22. package/dist/control/routes/process.d.ts +5 -0
  23. package/dist/control/routes/process.js +200 -0
  24. package/dist/control/routes/sessions.d.ts +22 -0
  25. package/dist/control/routes/sessions.js +224 -0
  26. package/dist/control/routes/status.d.ts +6 -0
  27. package/dist/control/routes/status.js +250 -0
  28. package/dist/control/routes/taskActions.d.ts +21 -0
  29. package/dist/control/routes/taskActions.js +233 -0
  30. package/dist/control/routes/tasks.d.ts +20 -0
  31. package/dist/control/routes/tasks.js +310 -0
  32. package/dist/control/routes/workspace.d.ts +15 -0
  33. package/dist/control/routes/workspace.js +193 -0
  34. package/dist/control/runtime.d.ts +91 -0
  35. package/dist/control/runtime.js +392 -0
  36. package/dist/control/server.d.ts +13 -0
  37. package/dist/control/server.js +479 -0
  38. package/dist/control/shared.d.ts +35 -0
  39. package/dist/control/shared.js +288 -0
  40. package/dist/controlCenter.d.ts +6 -0
  41. package/dist/controlCenter.js +7 -2001
  42. package/dist/direct/directGuards.js +30 -8
  43. package/dist/direct/directSessionStore.d.ts +2 -0
  44. package/dist/direct/directVerification.js +7 -0
  45. package/dist/doctor.d.ts +18 -1
  46. package/dist/doctor.js +579 -348
  47. package/dist/goal/goalReport.d.ts +54 -0
  48. package/dist/goal/goalReport.js +204 -0
  49. package/dist/goal/goalStatus.d.ts +6 -0
  50. package/dist/goal/specKitImport.d.ts +63 -0
  51. package/dist/goal/specKitImport.js +220 -0
  52. package/dist/goal/subgoalSync.js +2 -1
  53. package/dist/httpServer.js +15 -12
  54. package/dist/index.js +7 -4
  55. package/dist/logging.d.ts +7 -1
  56. package/dist/logging.js +8 -0
  57. package/dist/policy/projectPolicy.d.ts +55 -0
  58. package/dist/policy/projectPolicy.js +286 -0
  59. package/dist/runner/changeCapture.d.ts +3 -3
  60. package/dist/runner/changeCapture.js +63 -39
  61. package/dist/runner/cli.js +7 -6
  62. package/dist/runner/postTaskCleanup.js +26 -2
  63. package/dist/runner/runTask.js +245 -221
  64. package/dist/runner/simpleProcess.js +4 -4
  65. package/dist/runner/watch.js +17 -14
  66. package/dist/security/contentRedaction.d.ts +6 -0
  67. package/dist/security/contentRedaction.js +22 -0
  68. package/dist/smoke-test.js +261 -255
  69. package/dist/test/unit/apply-patch.test.d.ts +1 -0
  70. package/dist/test/unit/apply-patch.test.js +225 -0
  71. package/dist/test/unit/create-task.test.d.ts +1 -0
  72. package/dist/test/unit/create-task.test.js +197 -0
  73. package/dist/test/unit/direct-guards.test.js +124 -9
  74. package/dist/test/unit/evidence-pack.test.d.ts +1 -0
  75. package/dist/test/unit/evidence-pack.test.js +224 -0
  76. package/dist/test/unit/get-task-status.test.d.ts +1 -0
  77. package/dist/test/unit/get-task-status.test.js +174 -0
  78. package/dist/test/unit/get-task-summary.test.d.ts +1 -0
  79. package/dist/test/unit/get-task-summary.test.js +146 -0
  80. package/dist/test/unit/goal-report.test.d.ts +1 -0
  81. package/dist/test/unit/goal-report.test.js +159 -0
  82. package/dist/test/unit/goal-subgoal-task.test.js +6 -6
  83. package/dist/test/unit/goal-tools-registry.test.js +6 -4
  84. package/dist/test/unit/path-guard.test.js +24 -0
  85. package/dist/test/unit/project-policy-release-mode.test.d.ts +1 -0
  86. package/dist/test/unit/project-policy-release-mode.test.js +125 -0
  87. package/dist/test/unit/run-task-loop.test.d.ts +1 -0
  88. package/dist/test/unit/run-task-loop.test.js +380 -0
  89. package/dist/test/unit/schema-drift-check.test.js +10 -9
  90. package/dist/test/unit/spec-kit-import.test.d.ts +1 -0
  91. package/dist/test/unit/spec-kit-import.test.js +341 -0
  92. package/dist/test/unit/wait-for-task.test.d.ts +1 -0
  93. package/dist/test/unit/wait-for-task.test.js +144 -0
  94. package/dist/tools/auditTask.d.ts +8 -63
  95. package/dist/tools/auditTask.js +12 -8
  96. package/dist/tools/createDirectSession.d.ts +1 -1
  97. package/dist/tools/createDirectSession.js +2 -2
  98. package/dist/tools/createTask.d.ts +2 -2
  99. package/dist/tools/createTask.js +4 -4
  100. package/dist/tools/dispatch/coreDispatch.d.ts +9 -0
  101. package/dist/tools/dispatch/coreDispatch.js +282 -0
  102. package/dist/tools/dispatch/diagnosticDispatch.d.ts +14 -0
  103. package/dist/tools/dispatch/diagnosticDispatch.js +78 -0
  104. package/dist/tools/dispatch/directDispatch.d.ts +8 -0
  105. package/dist/tools/dispatch/directDispatch.js +115 -0
  106. package/dist/tools/dispatch/goalDispatch.d.ts +8 -0
  107. package/dist/tools/dispatch/goalDispatch.js +91 -0
  108. package/dist/tools/dispatch/releaseDispatch.d.ts +8 -0
  109. package/dist/tools/dispatch/releaseDispatch.js +45 -0
  110. package/dist/tools/dispatch/types.d.ts +23 -0
  111. package/dist/tools/dispatch/types.js +15 -0
  112. package/dist/tools/evidencePack.d.ts +45 -0
  113. package/dist/tools/evidencePack.js +375 -0
  114. package/dist/tools/finalizeDirectSession.d.ts +1 -1
  115. package/dist/tools/finalizeDirectSession.js +3 -3
  116. package/dist/tools/goalSubgoalTask.d.ts +1 -1
  117. package/dist/tools/goalSubgoalTask.js +2 -2
  118. package/dist/tools/healthCheck.js +3 -3
  119. package/dist/tools/recommendAgentForTask.d.ts +19 -0
  120. package/dist/tools/recommendAgentForTask.js +56 -0
  121. package/dist/tools/registry.d.ts +3 -3
  122. package/dist/tools/registry.js +333 -402
  123. package/dist/tools/releaseMode.d.ts +50 -0
  124. package/dist/tools/releaseMode.js +370 -0
  125. package/dist/tools/retryTask.d.ts +2 -2
  126. package/dist/tools/retryTask.js +2 -2
  127. package/dist/tools/runDirectVerificationBundle.d.ts +26 -0
  128. package/dist/tools/runDirectVerificationBundle.js +64 -0
  129. package/dist/tools/runTaskLoop.d.ts +57 -0
  130. package/dist/tools/runTaskLoop.js +417 -0
  131. package/dist/tools/runVerification.d.ts +4 -0
  132. package/dist/tools/runVerification.js +4 -0
  133. package/dist/tools/safeViews.d.ts +8 -2
  134. package/dist/tools/safeViews.js +4 -2
  135. package/dist/tools/taskLineage.d.ts +91 -0
  136. package/dist/tools/taskLineage.js +175 -0
  137. package/dist/tools/toolCatalog.d.ts +2 -2
  138. package/dist/tools/toolCatalog.js +6 -0
  139. package/dist/tools/toolRegistry.js +132 -0
  140. package/dist/version.d.ts +2 -2
  141. package/dist/version.js +2 -2
  142. package/docs/CODE_WIKI.md +983 -0
  143. package/docs/agentseal-integration.md +150 -0
  144. package/docs/architecture.md +63 -0
  145. package/docs/assets/patchwarden-oss-demo.gif +0 -0
  146. package/docs/chatgpt-usage.md +31 -0
  147. package/docs/control-center/README.md +9 -0
  148. package/docs/dashboard-overview.md +86 -0
  149. package/docs/demo.md +8 -0
  150. package/docs/direct-session-workflow.md +98 -0
  151. package/docs/evidence-pack-schema.md +215 -0
  152. package/docs/execution-plan-2026-07-09.md +315 -0
  153. package/docs/lineage-evidence-pack-workflow.md +127 -0
  154. package/docs/mcp-inspector-testing.md +200 -0
  155. package/docs/open-source-application.md +162 -0
  156. package/docs/opencode-worker.md +151 -0
  157. package/docs/openhands-worker.md +181 -0
  158. package/docs/release-evidence.md +72 -0
  159. package/docs/roadmap-execution-and-acceptance.md +365 -0
  160. package/docs/spec-kit-integration.md +131 -0
  161. package/docs/task-safe-review-workflow.md +98 -0
  162. package/docs/threat-model.md +79 -0
  163. package/docs/user-feedback.md +40 -0
  164. package/docs/why-patchwarden.md +110 -0
  165. package/package.json +3 -3
  166. package/scripts/checks/control-center-smoke.js +443 -0
  167. package/scripts/checks/control-smoke.js +2 -2
  168. package/scripts/checks/lifecycle-smoke.js +29 -23
  169. package/scripts/checks/mcp-manifest-check.js +12 -0
  170. package/scripts/checks/mcp-smoke.js +33 -7
  171. package/scripts/checks/watcher-supervisor-smoke.js +1 -1
  172. package/scripts/generate-demo-gif.py +320 -0
  173. package/src/assessments/agentAssessor.ts +3 -3
  174. package/src/assessments/assessmentStore.ts +2 -2
  175. package/src/assessments/confirmCli.ts +5 -4
  176. package/src/config.ts +37 -0
  177. package/src/control/middleware/auth.ts +17 -0
  178. package/src/control/middleware/static.ts +71 -0
  179. package/src/control/routes/audit.ts +321 -0
  180. package/src/control/routes/evidence.ts +107 -0
  181. package/src/control/routes/lineage.ts +92 -0
  182. package/src/control/routes/policy.ts +81 -0
  183. package/src/control/routes/process.ts +204 -0
  184. package/src/control/routes/sessions.ts +251 -0
  185. package/src/control/routes/status.ts +325 -0
  186. package/src/control/routes/taskActions.ts +248 -0
  187. package/src/control/routes/tasks.ts +323 -0
  188. package/src/control/routes/workspace.ts +203 -0
  189. package/src/control/runtime.ts +472 -0
  190. package/src/control/server.ts +471 -0
  191. package/src/control/shared.ts +294 -0
  192. package/src/controlCenter.ts +7 -2150
  193. package/src/direct/directGuards.ts +28 -7
  194. package/src/direct/directSessionStore.ts +2 -0
  195. package/src/direct/directVerification.ts +7 -0
  196. package/src/doctor.ts +741 -481
  197. package/src/goal/goalReport.ts +271 -0
  198. package/src/goal/goalStatus.ts +6 -0
  199. package/src/goal/specKitImport.ts +355 -0
  200. package/src/goal/subgoalSync.ts +4 -2
  201. package/src/httpServer.ts +17 -14
  202. package/src/index.ts +7 -4
  203. package/src/logging.ts +10 -1
  204. package/src/policy/projectPolicy.ts +344 -0
  205. package/src/runner/changeCapture.ts +70 -42
  206. package/src/runner/cli.ts +7 -6
  207. package/src/runner/postTaskCleanup.ts +26 -2
  208. package/src/runner/runTask.ts +325 -223
  209. package/src/runner/simpleProcess.ts +4 -4
  210. package/src/runner/watch.ts +17 -14
  211. package/src/security/contentRedaction.ts +29 -0
  212. package/src/smoke-test.ts +254 -252
  213. package/src/test/unit/apply-patch.test.ts +293 -0
  214. package/src/test/unit/create-task.test.ts +255 -0
  215. package/src/test/unit/direct-guards.test.ts +178 -8
  216. package/src/test/unit/evidence-pack.test.ts +251 -0
  217. package/src/test/unit/get-task-status.test.ts +203 -0
  218. package/src/test/unit/get-task-summary.test.ts +173 -0
  219. package/src/test/unit/goal-report.test.ts +189 -0
  220. package/src/test/unit/goal-subgoal-task.test.ts +6 -6
  221. package/src/test/unit/goal-tools-registry.test.ts +7 -5
  222. package/src/test/unit/path-guard.test.ts +30 -0
  223. package/src/test/unit/project-policy-release-mode.test.ts +156 -0
  224. package/src/test/unit/run-task-loop.test.ts +425 -0
  225. package/src/test/unit/schema-drift-check.test.ts +11 -9
  226. package/src/test/unit/spec-kit-import.test.ts +429 -0
  227. package/src/test/unit/wait-for-task.test.ts +176 -0
  228. package/src/tools/auditTask.ts +99 -59
  229. package/src/tools/createDirectSession.ts +3 -3
  230. package/src/tools/createTask.ts +7 -7
  231. package/src/tools/dispatch/coreDispatch.ts +374 -0
  232. package/src/tools/dispatch/diagnosticDispatch.ts +101 -0
  233. package/src/tools/dispatch/directDispatch.ts +167 -0
  234. package/src/tools/dispatch/goalDispatch.ts +127 -0
  235. package/src/tools/dispatch/releaseDispatch.ts +65 -0
  236. package/src/tools/dispatch/types.ts +24 -0
  237. package/src/tools/evidencePack.ts +490 -0
  238. package/src/tools/finalizeDirectSession.ts +4 -4
  239. package/src/tools/goalSubgoalTask.ts +2 -2
  240. package/src/tools/healthCheck.ts +3 -3
  241. package/src/tools/listWorkspace.ts +71 -71
  242. package/src/tools/recommendAgentForTask.ts +79 -0
  243. package/src/tools/registry.ts +352 -509
  244. package/src/tools/releaseMode.ts +450 -0
  245. package/src/tools/retryTask.ts +2 -2
  246. package/src/tools/runDirectVerificationBundle.ts +98 -0
  247. package/src/tools/runTaskLoop.ts +526 -0
  248. package/src/tools/runVerification.ts +8 -0
  249. package/src/tools/safeViews.ts +4 -2
  250. package/src/tools/taskLineage.ts +300 -0
  251. package/src/tools/toolCatalog.ts +6 -0
  252. package/src/tools/toolRegistry.ts +132 -0
  253. package/src/version.ts +2 -2
  254. package/ui/pages/audit.html +192 -3
  255. package/ui/pages/dashboard.html +1070 -14
  256. package/ui/pages/direct-sessions.html +505 -53
  257. package/ui/pages/task-detail.html +456 -438
  258. package/ui/pages/tasks.html +598 -61
@@ -0,0 +1,175 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ import { getConfig } from "../config.js";
5
+ import { guardReadPath } from "../security/pathGuard.js";
6
+ import { redactSensitiveValue } from "../security/contentRedaction.js";
7
+ import { PatchWardenError } from "../errors.js";
8
+ export function createLineageId(now = new Date()) {
9
+ const stamp = now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
10
+ return `lineage_${stamp}_${randomBytes(4).toString("hex")}`;
11
+ }
12
+ export function writeTaskLineage(record) {
13
+ const config = getConfig();
14
+ const lineageDir = resolve(config.workspaceRoot, ".patchwarden", "lineages", record.lineage_id);
15
+ mkdirSync(lineageDir, { recursive: true });
16
+ const safeRecord = redactSensitiveValue(record).value;
17
+ writeFileSync(join(lineageDir, "lineage.json"), JSON.stringify(safeRecord, null, 2) + "\n", "utf-8");
18
+ writeFileSync(join(lineageDir, "SUMMARY.md"), buildSummaryMarkdown(safeRecord), "utf-8");
19
+ return toSafeTaskLineage(safeRecord);
20
+ }
21
+ export function getTaskLineage(lineageId, options = {}) {
22
+ const maxItems = normalizeMaxItems(options.max_items);
23
+ if (!/^[A-Za-z0-9_-]+$/.test(lineageId)) {
24
+ throw new PatchWardenError("invalid_lineage_id", "lineage_id may contain only letters, numbers, underscores, and hyphens.", "Pass a lineage_id returned by run_task_loop.", true, { lineage_id: lineageId });
25
+ }
26
+ const config = getConfig();
27
+ const lineageFile = resolve(config.workspaceRoot, ".patchwarden", "lineages", lineageId, "lineage.json");
28
+ guardReadPath(lineageFile, config.workspaceRoot, ".patchwarden/lineages");
29
+ if (!existsSync(lineageFile)) {
30
+ throw new PatchWardenError("lineage_not_found", `Task lineage not found: "${lineageId}".`, "Pass a lineage_id returned by run_task_loop.", true, { lineage_id: lineageId });
31
+ }
32
+ const raw = readFileSync(lineageFile, "utf-8").replace(/^\uFEFF/, "");
33
+ const record = JSON.parse(raw);
34
+ return toSafeTaskLineage(redactSensitiveValue(record).value, maxItems);
35
+ }
36
+ export function toSafeTaskLineage(record, maxItems = 8) {
37
+ const rounds = record.rounds.slice(0, maxItems);
38
+ const latest = record.rounds[record.rounds.length - 1];
39
+ const directSessions = normalizeDirectSessions(record.direct_sessions);
40
+ return {
41
+ lineage_id: record.lineage_id,
42
+ goal: record.goal,
43
+ repo_path: record.repo_path,
44
+ created_at: record.created_at,
45
+ updated_at: record.updated_at,
46
+ final_status: record.final_status,
47
+ stop_reason: record.stop_reason,
48
+ next_action: record.next_action,
49
+ tasks: {
50
+ main: record.main_task,
51
+ fix: record.fix_tasks.slice(0, maxItems),
52
+ cleanup: record.cleanup_tasks.slice(0, maxItems),
53
+ direct_sessions: directSessions.slice(0, maxItems),
54
+ },
55
+ worktree: normalizeWorktree(record.worktree),
56
+ agent_routing: record.agent_routing ? {
57
+ requested_agent: record.agent_routing.requested_agent,
58
+ selected_agent: truncate(String(record.agent_routing.selected_agent), 120),
59
+ reason: truncate(String(record.agent_routing.reason), 240),
60
+ fallback: Boolean(record.agent_routing.fallback),
61
+ } : null,
62
+ verification: {
63
+ latest_status: latest?.verification_status || "not_available",
64
+ passed: latest?.verification_status === "passed",
65
+ },
66
+ rounds,
67
+ warnings: record.warnings.slice(0, maxItems).map((value) => truncate(value, 240)),
68
+ errors: record.errors.slice(0, maxItems).map((value) => truncate(value, 240)),
69
+ truncated: record.rounds.length > maxItems ||
70
+ record.fix_tasks.length > maxItems ||
71
+ record.cleanup_tasks.length > maxItems ||
72
+ directSessions.length > maxItems ||
73
+ record.warnings.length > maxItems ||
74
+ record.errors.length > maxItems,
75
+ };
76
+ }
77
+ function buildSummaryMarkdown(record) {
78
+ const rounds = record.rounds.map((round) => `- ${round.role} ${round.task_id}: ${round.status}, verification=${round.verification_status}, audit=${round.audit_verdict}`);
79
+ return [
80
+ "# PatchWarden Task Lineage",
81
+ "",
82
+ `- Lineage: ${record.lineage_id}`,
83
+ `- Goal: ${record.goal}`,
84
+ `- Repo: ${record.repo_path}`,
85
+ `- Final status: ${record.final_status}`,
86
+ `- Stop reason: ${record.stop_reason}`,
87
+ `- Next action: ${record.next_action}`,
88
+ `- Isolation: ${normalizeWorktree(record.worktree).isolation_mode}`,
89
+ `- Worktree: ${formatWorktree(record.worktree)}`,
90
+ `- Agent routing: ${formatAgentRouting(record.agent_routing)}`,
91
+ "",
92
+ "## Tasks",
93
+ `- Main: ${record.main_task || "none"}`,
94
+ `- Fix tasks: ${record.fix_tasks.length > 0 ? record.fix_tasks.join(", ") : "none"}`,
95
+ `- Cleanup tasks: ${record.cleanup_tasks.length > 0 ? record.cleanup_tasks.join(", ") : "none"}`,
96
+ `- Direct sessions: ${formatDirectSessions(record.direct_sessions)}`,
97
+ "",
98
+ "## Rounds",
99
+ ...(rounds.length > 0 ? rounds : ["- None."]),
100
+ "",
101
+ ].join("\n");
102
+ }
103
+ function normalizeWorktree(value) {
104
+ if (!value) {
105
+ return {
106
+ isolation_mode: "current_repo",
107
+ cleanup: "keep",
108
+ status: "not_used",
109
+ next_action: "none",
110
+ };
111
+ }
112
+ return {
113
+ isolation_mode: value.isolation_mode === "worktree" ? "worktree" : "current_repo",
114
+ worktree_id: value.worktree_id ? truncate(String(value.worktree_id), 120) : undefined,
115
+ worktree_path: value.worktree_path ? truncate(String(value.worktree_path), 260) : undefined,
116
+ branch: value.branch ? truncate(String(value.branch), 160) : undefined,
117
+ requested_base_branch: value.requested_base_branch ? truncate(String(value.requested_base_branch), 160) : undefined,
118
+ cleanup: value.cleanup,
119
+ status: value.status,
120
+ next_action: truncate(String(value.next_action || "review_worktree"), 240),
121
+ };
122
+ }
123
+ function formatWorktree(value) {
124
+ const worktree = normalizeWorktree(value);
125
+ if (worktree.isolation_mode !== "worktree")
126
+ return "not used";
127
+ const id = worktree.worktree_id || "unknown";
128
+ const status = worktree.status || "unknown";
129
+ const branch = worktree.branch ? ` branch=${worktree.branch}` : "";
130
+ return `${id} status=${status}${branch}`;
131
+ }
132
+ function formatAgentRouting(value) {
133
+ if (!value)
134
+ return "not recorded";
135
+ const requested = value.requested_agent ? ` requested=${value.requested_agent}` : "";
136
+ return `${value.selected_agent}${requested} reason=${truncate(value.reason, 160)}`;
137
+ }
138
+ function normalizeDirectSessions(value) {
139
+ return value.map((entry) => {
140
+ if (typeof entry === "string")
141
+ return { session_id: entry };
142
+ return {
143
+ session_id: String(entry.session_id || ""),
144
+ status: entry.status,
145
+ command_count: entry.command_count,
146
+ passed_commands: entry.passed_commands,
147
+ failed_commands: entry.failed_commands,
148
+ timed_out_commands: entry.timed_out_commands,
149
+ audit_decision: entry.audit_decision,
150
+ changed_files_total: entry.changed_files_total,
151
+ next_action: entry.next_action ? truncate(String(entry.next_action), 240) : undefined,
152
+ };
153
+ }).filter((entry) => entry.session_id !== "");
154
+ }
155
+ function formatDirectSessions(value) {
156
+ const sessions = normalizeDirectSessions(value);
157
+ if (sessions.length === 0)
158
+ return "none";
159
+ return sessions.map((entry) => {
160
+ const status = entry.status ? ` status=${entry.status}` : "";
161
+ const audit = entry.audit_decision ? ` audit=${entry.audit_decision}` : "";
162
+ return `${entry.session_id}${status}${audit}`;
163
+ }).join(", ");
164
+ }
165
+ function normalizeMaxItems(value) {
166
+ if (value === undefined)
167
+ return 8;
168
+ if (!Number.isInteger(value) || value < 1 || value > 50) {
169
+ throw new Error("max_items must be an integer from 1 to 50.");
170
+ }
171
+ return value;
172
+ }
173
+ function truncate(value, maxChars) {
174
+ return value.length <= maxChars ? value : `${value.slice(0, maxChars)}...`;
175
+ }
@@ -12,8 +12,8 @@ export interface ToolCatalogSnapshot {
12
12
  tool_names: string[];
13
13
  tool_manifest_sha256: string;
14
14
  }
15
- export declare const CHATGPT_CORE_TOOL_NAMES: readonly ["health_check", "list_agents", "list_workspace", "read_workspace_file", "save_plan", "create_task", "wait_for_task", "get_task_summary", "get_diff", "get_result", "get_result_json", "get_test_log", "get_task_status", "list_tasks", "cancel_task", "audit_task", "safe_status", "safe_result", "safe_audit", "safe_test_summary", "safe_diff_summary"];
16
- export declare const CHATGPT_DIRECT_TOOL_NAMES: readonly ["health_check", "list_workspace", "create_direct_session", "search_workspace", "read_workspace_file", "apply_patch", "run_verification", "finalize_direct_session", "audit_session", "safe_direct_summary", "safe_finalize_direct_session", "safe_audit_direct_session", "sync_file"];
15
+ export declare const CHATGPT_CORE_TOOL_NAMES: readonly ["health_check", "list_agents", "list_workspace", "read_workspace_file", "save_plan", "create_task", "run_task_loop", "recommend_agent_for_task", "get_task_lineage", "export_task_evidence_pack", "get_project_policy", "wait_for_task", "get_task_summary", "get_diff", "get_result", "get_result_json", "get_test_log", "get_task_status", "list_tasks", "cancel_task", "audit_task", "safe_status", "safe_result", "safe_audit", "safe_test_summary", "safe_diff_summary"];
16
+ export declare const CHATGPT_DIRECT_TOOL_NAMES: readonly ["health_check", "list_workspace", "create_direct_session", "search_workspace", "read_workspace_file", "apply_patch", "run_verification", "run_direct_verification_bundle", "finalize_direct_session", "audit_session", "safe_direct_summary", "safe_finalize_direct_session", "safe_audit_direct_session", "sync_file"];
17
17
  export declare const CHATGPT_SEARCH_TOOL_NAMES: readonly ["health_check", "discover_tools", "explain_tool", "invoke_discovered_tool", "safe_status"];
18
18
  export declare function resolveToolProfile(configProfile?: string): ToolProfile;
19
19
  export declare function selectToolsForProfile<T extends CatalogTool>(tools: T[], profile: ToolProfile, enableDirectProfile?: boolean): T[];
@@ -7,6 +7,11 @@ export const CHATGPT_CORE_TOOL_NAMES = [
7
7
  "read_workspace_file",
8
8
  "save_plan",
9
9
  "create_task",
10
+ "run_task_loop",
11
+ "recommend_agent_for_task",
12
+ "get_task_lineage",
13
+ "export_task_evidence_pack",
14
+ "get_project_policy",
10
15
  "wait_for_task",
11
16
  "get_task_summary",
12
17
  "get_diff",
@@ -31,6 +36,7 @@ export const CHATGPT_DIRECT_TOOL_NAMES = [
31
36
  "read_workspace_file",
32
37
  "apply_patch",
33
38
  "run_verification",
39
+ "run_direct_verification_bundle",
34
40
  "finalize_direct_session",
35
41
  "audit_session",
36
42
  "safe_direct_summary",
@@ -350,6 +350,61 @@ const STATIC_TOOL_META = {
350
350
  requiresConfirmation: false,
351
351
  relatedTools: ["save_plan", "wait_for_task", "get_task_status"],
352
352
  },
353
+ run_task_loop: {
354
+ title: "Run Task Loop",
355
+ summary: "运行受保护的任务循环:创建任务、等待、验证、审计,并在低风险测试失败时创建 fix_tests 后续任务",
356
+ profiles: ["full", "chatgpt_core"],
357
+ modes: ["delegate", "audit"],
358
+ tags: ["loop", "task", "lineage", "verify", "audit", "fix"],
359
+ aliases: ["task_loop", "run_loop", "guarded_loop"],
360
+ risk: "workspace_write",
361
+ requiresConfirmation: false,
362
+ relatedTools: ["create_task", "wait_for_task", "safe_result", "safe_audit", "get_task_lineage"],
363
+ },
364
+ recommend_agent_for_task: {
365
+ title: "Recommend Agent For Task",
366
+ summary: "Return bounded agent routing guidance without starting an agent or creating a task",
367
+ profiles: ["full", "chatgpt_core"],
368
+ modes: ["delegate", "diagnostic"],
369
+ tags: ["agent", "routing", "recommend", "task", "safe"],
370
+ aliases: ["recommend_agent", "route_agent", "agent_routing"],
371
+ risk: "readonly",
372
+ requiresConfirmation: false,
373
+ relatedTools: ["list_agents", "create_task", "run_task_loop"],
374
+ },
375
+ get_task_lineage: {
376
+ title: "Get Task Lineage",
377
+ summary: "读取 run_task_loop 生成的任务链路安全摘要,不返回完整日志或 diff",
378
+ profiles: ["full", "chatgpt_core"],
379
+ modes: ["delegate", "audit", "diagnostic"],
380
+ tags: ["lineage", "loop", "summary", "task", "safe"],
381
+ aliases: ["lineage", "task_lineage"],
382
+ risk: "readonly",
383
+ requiresConfirmation: false,
384
+ relatedTools: ["run_task_loop", "safe_result", "safe_audit"],
385
+ },
386
+ export_task_evidence_pack: {
387
+ title: "Export Task Evidence Pack",
388
+ summary: "Export bounded lineage, verification, Direct, policy, and catalog evidence without logs or diffs",
389
+ profiles: ["full", "chatgpt_core"],
390
+ modes: ["delegate", "audit", "diagnostic"],
391
+ tags: ["evidence", "lineage", "summary", "release", "safe"],
392
+ aliases: ["evidence_pack", "export_evidence", "task_evidence"],
393
+ risk: "workspace_write",
394
+ requiresConfirmation: false,
395
+ relatedTools: ["get_task_lineage", "run_task_loop", "get_project_policy"],
396
+ },
397
+ get_project_policy: {
398
+ title: "Get Project Policy",
399
+ summary: "Read bounded project policy and release readiness without exposing secrets or expanding command permissions",
400
+ profiles: ["full", "chatgpt_core"],
401
+ modes: ["diagnostic", "release"],
402
+ tags: ["policy", "project", "release", "readiness", "safe"],
403
+ aliases: ["project_policy", "policy", "get_policy"],
404
+ risk: "readonly",
405
+ requiresConfirmation: false,
406
+ relatedTools: ["release_check", "release_prepare", "release_cleanup"],
407
+ },
353
408
  sync_file: {
354
409
  title: "Sync File",
355
410
  summary: "在 Direct 会话中同步文件(带 sha256 校验)",
@@ -461,6 +516,17 @@ const STATIC_TOOL_META = {
461
516
  requiresConfirmation: false,
462
517
  relatedTools: ["finalize_direct_session", "audit_session"],
463
518
  },
519
+ run_direct_verification_bundle: {
520
+ title: "Run Direct Verification Bundle",
521
+ summary: "Run multiple Direct allowlisted verification commands and return bounded status without stdout or stderr tails",
522
+ profiles: ["full", "chatgpt_direct"],
523
+ modes: ["direct", "audit"],
524
+ tags: ["direct", "verify", "verification", "bundle", "safe"],
525
+ aliases: ["direct_verify_bundle", "verification_bundle"],
526
+ risk: "command",
527
+ requiresConfirmation: false,
528
+ relatedTools: ["run_verification", "safe_finalize_direct_session", "safe_audit_direct_session"],
529
+ },
464
530
  safe_direct_summary: {
465
531
  title: "Safe Direct Summary",
466
532
  summary: "Direct 会话安全摘要(不含完整 diff 或验证 stdout/stderr)",
@@ -605,6 +671,28 @@ const STATIC_TOOL_META = {
605
671
  requiresConfirmation: false,
606
672
  relatedTools: ["summarize_goal_progress", "read_goal"],
607
673
  },
674
+ export_goal_report: {
675
+ title: "Export Goal Report",
676
+ summary: "Export a structured final report for a Goal session",
677
+ profiles: ["full"],
678
+ modes: ["delegate", "audit"],
679
+ tags: ["goal", "report", "export", "summary", "final"],
680
+ aliases: ["goal_report", "report"],
681
+ risk: "workspace_write",
682
+ requiresConfirmation: false,
683
+ relatedTools: ["summarize_goal_progress", "export_handoff"],
684
+ },
685
+ import_speckit_tasks: {
686
+ title: "Import Spec Kit Tasks",
687
+ summary: "Import Spec Kit tasks into a Goal session as subgoals",
688
+ profiles: ["full"],
689
+ modes: ["delegate", "audit"],
690
+ tags: ["goal", "speckit", "import", "tasks", "subgoal"],
691
+ aliases: ["speckit_import", "import_tasks"],
692
+ risk: "workspace_write",
693
+ requiresConfirmation: false,
694
+ relatedTools: ["create_subgoal_task", "export_goal_report"],
695
+ },
608
696
  invoke_discovered_tool: {
609
697
  title: "Invoke Discovered Tool",
610
698
  summary: "v0.8.1: 通过 token 调用 discover_tools 发现的动态工具",
@@ -639,6 +727,50 @@ const STATIC_TOOL_META = {
639
727
  requiresConfirmation: true,
640
728
  relatedTools: ["audit_task", "safe_status"],
641
729
  },
730
+ release_check: {
731
+ title: "Release Check",
732
+ summary: "Run bounded release readiness checks through the existing release gate without remote writes",
733
+ profiles: ["full"],
734
+ modes: ["release", "diagnostic"],
735
+ tags: ["release", "check", "gate", "readiness", "policy"],
736
+ aliases: ["release_check", "check_release"],
737
+ risk: "release",
738
+ requiresConfirmation: true,
739
+ relatedTools: ["check_release_gate", "get_project_policy", "release_prepare", "release_verify"],
740
+ },
741
+ release_prepare: {
742
+ title: "Release Prepare",
743
+ summary: "Run policy-approved local release preparation commands through the existing command guard",
744
+ profiles: ["full"],
745
+ modes: ["release"],
746
+ tags: ["release", "prepare", "build", "test", "policy"],
747
+ aliases: ["prepare_release", "release_ready"],
748
+ risk: "release",
749
+ requiresConfirmation: true,
750
+ relatedTools: ["get_project_policy", "release_check", "release_verify"],
751
+ },
752
+ release_verify: {
753
+ title: "Release Verify",
754
+ summary: "Verify npm, GitHub release, and CI facts with read-only remote checks",
755
+ profiles: ["full"],
756
+ modes: ["release", "diagnostic"],
757
+ tags: ["release", "verify", "npm", "github", "ci"],
758
+ aliases: ["verify_release", "release_remote_verify"],
759
+ risk: "release",
760
+ requiresConfirmation: true,
761
+ relatedTools: ["release_check", "check_release_gate"],
762
+ },
763
+ release_cleanup: {
764
+ title: "Release Cleanup",
765
+ summary: "Dry-run-first cleanup for low-risk release artifacts under project policy",
766
+ profiles: ["full"],
767
+ modes: ["release"],
768
+ tags: ["release", "cleanup", "artifacts", "policy"],
769
+ aliases: ["cleanup_release", "release_artifact_cleanup"],
770
+ risk: "workspace_write",
771
+ requiresConfirmation: true,
772
+ relatedTools: ["get_project_policy", "release_prepare"],
773
+ },
642
774
  merge_worktree: {
643
775
  title: "Merge Worktree",
644
776
  summary: "v1.0.0: 合并隔离 worktree 变更回主工作区",
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const PATCHWARDEN_VERSION = "1.1.0";
2
- export declare const TOOL_SCHEMA_EPOCH = "2026-06-27-v9";
1
+ export declare const PATCHWARDEN_VERSION = "1.5.1";
2
+ export declare const TOOL_SCHEMA_EPOCH = "2026-07-05-v13";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const PATCHWARDEN_VERSION = "1.1.0";
2
- export const TOOL_SCHEMA_EPOCH = "2026-06-27-v9";
1
+ export const PATCHWARDEN_VERSION = "1.5.1";
2
+ export const TOOL_SCHEMA_EPOCH = "2026-07-05-v13";