patchwarden 1.5.1 → 1.6.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.
Files changed (591) hide show
  1. package/PatchWarden.cmd +32 -2
  2. package/README.en.md +158 -26
  3. package/README.md +124 -24
  4. package/dist/assessments/agentAssessor.js +21 -12
  5. package/dist/assessments/assessmentDiagnostics.d.ts +29 -0
  6. package/dist/assessments/assessmentDiagnostics.js +132 -0
  7. package/dist/assessments/assessmentStore.d.ts +39 -0
  8. package/dist/assessments/assessmentStore.js +207 -45
  9. package/dist/assessments/securitySnapshot.d.ts +50 -0
  10. package/dist/assessments/securitySnapshot.js +158 -0
  11. package/dist/config.d.ts +15 -0
  12. package/dist/config.js +66 -13
  13. package/dist/control/fileManager.d.ts +2 -0
  14. package/dist/control/fileManager.js +39 -0
  15. package/dist/control/middleware/auth.d.ts +6 -0
  16. package/dist/control/middleware/auth.js +14 -5
  17. package/dist/control/middleware/static.js +16 -3
  18. package/dist/control/routeTable.d.ts +24 -0
  19. package/dist/control/routeTable.js +263 -0
  20. package/dist/control/routes/audit.js +17 -7
  21. package/dist/control/routes/evidence.js +1 -1
  22. package/dist/control/routes/lineage.js +1 -1
  23. package/dist/control/routes/process.d.ts +7 -0
  24. package/dist/control/routes/process.js +329 -42
  25. package/dist/control/routes/sessions.d.ts +9 -1
  26. package/dist/control/routes/sessions.js +84 -21
  27. package/dist/control/routes/status.d.ts +60 -1
  28. package/dist/control/routes/status.js +94 -15
  29. package/dist/control/routes/taskActions.js +24 -60
  30. package/dist/control/routes/tasks.d.ts +4 -0
  31. package/dist/control/routes/tasks.js +61 -62
  32. package/dist/control/routes/workspace.js +50 -23
  33. package/dist/control/runtime.d.ts +3 -2
  34. package/dist/control/runtime.js +65 -40
  35. package/dist/control/server.js +37 -365
  36. package/dist/control/shared.d.ts +25 -1
  37. package/dist/control/shared.js +64 -11
  38. package/dist/diagnostics/allowedTestCommandSafety.d.ts +1 -0
  39. package/dist/diagnostics/allowedTestCommandSafety.js +11 -0
  40. package/dist/direct/directAudit.js +234 -225
  41. package/dist/direct/directGuards.d.ts +2 -1
  42. package/dist/direct/directGuards.js +42 -29
  43. package/dist/direct/directPatch.d.ts +6 -1
  44. package/dist/direct/directPatch.js +55 -8
  45. package/dist/direct/directSessionStore.d.ts +16 -6
  46. package/dist/direct/directSessionStore.js +128 -35
  47. package/dist/direct/directVerification.js +8 -16
  48. package/dist/doctor.js +65 -57
  49. package/dist/goal/acceptanceEngine.d.ts +1 -1
  50. package/dist/goal/goalProgress.js +75 -69
  51. package/dist/goal/goalReport.js +5 -12
  52. package/dist/goal/goalStatus.d.ts +2 -0
  53. package/dist/goal/goalStatus.js +10 -3
  54. package/dist/goal/goalStore.d.ts +9 -2
  55. package/dist/goal/goalStore.js +152 -45
  56. package/dist/goal/handoffExport.js +6 -6
  57. package/dist/goal/specKitImport.js +97 -96
  58. package/dist/goal/subgoalSync.js +11 -9
  59. package/dist/goal/worktreeManager.d.ts +2 -0
  60. package/dist/goal/worktreeManager.js +209 -136
  61. package/dist/httpServer.js +111 -32
  62. package/dist/logging.js +5 -3
  63. package/dist/policy/projectPolicy.js +5 -2
  64. package/dist/release/releaseGate.d.ts +1 -1
  65. package/dist/release/releaseGate.js +78 -25
  66. package/dist/runner/agentInvocation.d.ts +14 -0
  67. package/dist/runner/agentInvocation.js +96 -4
  68. package/dist/runner/changeCapture.d.ts +13 -5
  69. package/dist/runner/changeCapture.js +243 -61
  70. package/dist/runner/postTaskCleanup.js +48 -19
  71. package/dist/runner/processSecurity.d.ts +56 -0
  72. package/dist/runner/processSecurity.js +373 -0
  73. package/dist/runner/runTask.d.ts +2 -1
  74. package/dist/runner/runTask.js +162 -93
  75. package/dist/runner/simpleProcess.d.ts +3 -0
  76. package/dist/runner/simpleProcess.js +50 -36
  77. package/dist/{taskProgress.d.ts → runner/taskProgress.d.ts} +1 -1
  78. package/dist/{taskProgress.js → runner/taskProgress.js} +2 -2
  79. package/dist/{taskRuntime.d.ts → runner/taskRuntime.d.ts} +3 -1
  80. package/dist/{taskRuntime.js → runner/taskRuntime.js} +3 -2
  81. package/dist/runner/taskStatusStore.d.ts +11 -0
  82. package/dist/runner/taskStatusStore.js +35 -0
  83. package/dist/runner/watch.d.ts +14 -1
  84. package/dist/runner/watch.js +320 -49
  85. package/dist/security/contentRedaction.js +2 -2
  86. package/dist/security/discoveryTokenStore.d.ts +3 -2
  87. package/dist/security/discoveryTokenStore.js +17 -2
  88. package/dist/security/loopbackHost.d.ts +2 -0
  89. package/dist/security/loopbackHost.js +16 -0
  90. package/dist/security/pathGuard.js +32 -17
  91. package/dist/security/planGuard.js +2 -1
  92. package/dist/security/runtimeGuard.js +9 -6
  93. package/dist/security/secretComparison.d.ts +3 -0
  94. package/dist/security/secretComparison.js +11 -0
  95. package/dist/security/sensitiveGuard.d.ts +5 -0
  96. package/dist/security/sensitiveGuard.js +27 -8
  97. package/dist/security/toolInvocationGuard.d.ts +2 -2
  98. package/dist/security/toolInvocationGuard.js +1 -1
  99. package/dist/security/workspaceRootGuard.d.ts +8 -0
  100. package/dist/security/workspaceRootGuard.js +47 -0
  101. package/dist/smoke-test.js +27 -26
  102. package/dist/tools/catalog/index.d.ts +4 -0
  103. package/dist/tools/catalog/index.js +4 -0
  104. package/dist/tools/{toolCatalog.js → catalog/toolCatalog.js} +3 -12
  105. package/dist/tools/{toolRegistry.d.ts → catalog/toolRegistry.d.ts} +3 -3
  106. package/dist/tools/{toolRegistry.js → catalog/toolRegistry.js} +6 -15
  107. package/dist/tools/definitions/toolDefs.d.ts +18 -0
  108. package/dist/tools/definitions/toolDefs.js +1177 -0
  109. package/dist/tools/{auditSession.d.ts → diagnostics/auditSession.d.ts} +1 -1
  110. package/dist/tools/{auditSession.js → diagnostics/auditSession.js} +2 -2
  111. package/dist/tools/{auditTask.d.ts → diagnostics/auditTask.d.ts} +2 -1
  112. package/dist/tools/{auditTask.js → diagnostics/auditTask.js} +134 -36
  113. package/dist/tools/{healthCheck.d.ts → diagnostics/healthCheck.d.ts} +18 -6
  114. package/dist/tools/{healthCheck.js → diagnostics/healthCheck.js} +36 -8
  115. package/dist/tools/diagnostics/index.d.ts +6 -0
  116. package/dist/tools/diagnostics/index.js +6 -0
  117. package/dist/tools/{safeStatus.d.ts → diagnostics/safeStatus.d.ts} +3 -3
  118. package/dist/tools/{safeStatus.js → diagnostics/safeStatus.js} +6 -6
  119. package/dist/tools/{safeViews.d.ts → diagnostics/safeViews.d.ts} +12 -8
  120. package/dist/tools/{safeViews.js → diagnostics/safeViews.js} +23 -13
  121. package/dist/tools/{schemaDriftCheck.d.ts → diagnostics/schemaDriftCheck.d.ts} +1 -1
  122. package/dist/tools/{schemaDriftCheck.js → diagnostics/schemaDriftCheck.js} +2 -2
  123. package/dist/tools/{createDirectSession.js → direct/createDirectSession.js} +6 -6
  124. package/dist/tools/{finalizeDirectSession.d.ts → direct/finalizeDirectSession.d.ts} +1 -1
  125. package/dist/tools/direct/finalizeDirectSession.js +86 -0
  126. package/dist/tools/direct/index.d.ts +3 -0
  127. package/dist/tools/direct/index.js +3 -0
  128. package/dist/tools/{runDirectVerificationBundle.js → direct/runDirectVerificationBundle.js} +2 -2
  129. package/dist/tools/{discoverTools.d.ts → discovery/discoverTools.d.ts} +2 -2
  130. package/dist/tools/{discoverTools.js → discovery/discoverTools.js} +5 -5
  131. package/dist/tools/{explainTool.d.ts → discovery/explainTool.d.ts} +2 -2
  132. package/dist/tools/{explainTool.js → discovery/explainTool.js} +2 -2
  133. package/dist/tools/discovery/index.d.ts +3 -0
  134. package/dist/tools/discovery/index.js +3 -0
  135. package/dist/tools/{invokeDiscoveredTool.d.ts → discovery/invokeDiscoveredTool.d.ts} +2 -2
  136. package/dist/tools/{invokeDiscoveredTool.js → discovery/invokeDiscoveredTool.js} +5 -5
  137. package/dist/tools/dispatch/coreDispatch.js +32 -31
  138. package/dist/tools/dispatch/diagnosticDispatch.d.ts +3 -5
  139. package/dist/tools/dispatch/diagnosticDispatch.js +70 -68
  140. package/dist/tools/dispatch/directDispatch.js +11 -10
  141. package/dist/tools/dispatch/goalDispatch.js +5 -4
  142. package/dist/tools/dispatch/releaseDispatch.js +3 -2
  143. package/dist/tools/dispatch/validation.d.ts +7 -0
  144. package/dist/tools/dispatch/validation.js +71 -0
  145. package/dist/tools/{getPlan.js → goals/getPlan.js} +4 -4
  146. package/dist/tools/{goalSubgoalTask.d.ts → goals/goalSubgoalTask.d.ts} +1 -1
  147. package/dist/tools/goals/goalSubgoalTask.js +118 -0
  148. package/dist/tools/goals/index.d.ts +3 -0
  149. package/dist/tools/goals/index.js +3 -0
  150. package/dist/tools/{savePlan.js → goals/savePlan.js} +28 -8
  151. package/dist/tools/registry.d.ts +7 -11
  152. package/dist/tools/registry.js +17 -1178
  153. package/dist/tools/{checkReleaseGate.d.ts → release/checkReleaseGate.d.ts} +1 -1
  154. package/dist/tools/{checkReleaseGate.js → release/checkReleaseGate.js} +3 -3
  155. package/dist/tools/release/index.d.ts +2 -0
  156. package/dist/tools/release/index.js +2 -0
  157. package/dist/tools/{releaseMode.d.ts → release/releaseMode.d.ts} +2 -2
  158. package/dist/tools/{releaseMode.js → release/releaseMode.js} +46 -26
  159. package/dist/tools/tasks/cancelTask.d.ts +11 -0
  160. package/dist/tools/tasks/cancelTask.js +86 -0
  161. package/dist/tools/{createTask.d.ts → tasks/createTask.d.ts} +12 -4
  162. package/dist/tools/{createTask.js → tasks/createTask.js} +110 -34
  163. package/dist/tools/{diagnoseTask.d.ts → tasks/diagnoseTask.d.ts} +1 -1
  164. package/dist/tools/{diagnoseTask.js → tasks/diagnoseTask.js} +12 -16
  165. package/dist/tools/{evidencePack.js → tasks/evidencePack.js} +34 -22
  166. package/dist/tools/{getTaskFile.js → tasks/getTaskFile.js} +4 -4
  167. package/dist/tools/{getTaskStatus.d.ts → tasks/getTaskStatus.d.ts} +6 -1
  168. package/dist/tools/{getTaskStatus.js → tasks/getTaskStatus.js} +11 -6
  169. package/dist/tools/{getTaskStdoutTail.js → tasks/getTaskStdoutTail.js} +13 -11
  170. package/dist/tools/{getTaskSummary.js → tasks/getTaskSummary.js} +35 -36
  171. package/dist/tools/tasks/index.d.ts +18 -0
  172. package/dist/tools/tasks/index.js +18 -0
  173. package/dist/tools/tasks/killTask.d.ts +1 -0
  174. package/dist/tools/{listTasks.d.ts → tasks/listTasks.d.ts} +1 -1
  175. package/dist/tools/{listTasks.js → tasks/listTasks.js} +5 -4
  176. package/dist/tools/{reconcileTasks.d.ts → tasks/reconcileTasks.d.ts} +3 -2
  177. package/dist/tools/tasks/reconcileTasks.js +496 -0
  178. package/dist/tools/tasks/retryTask.js +60 -0
  179. package/dist/tools/{runTaskLoop.d.ts → tasks/runTaskLoop.d.ts} +6 -6
  180. package/dist/tools/{runTaskLoop.js → tasks/runTaskLoop.js} +63 -41
  181. package/dist/tools/tasks/runVerification.js +38 -0
  182. package/dist/tools/{taskLineage.js → tasks/taskLineage.js} +8 -7
  183. package/dist/tools/{taskOutputs.d.ts → tasks/taskOutputs.d.ts} +2 -2
  184. package/dist/tools/{taskOutputs.js → tasks/taskOutputs.js} +17 -16
  185. package/dist/tools/tasks/taskStates.d.ts +6 -0
  186. package/dist/tools/tasks/taskStates.js +52 -0
  187. package/dist/tools/{waitForTask.js → tasks/waitForTask.js} +3 -11
  188. package/dist/tools/{androidDoctor.js → workspace/androidDoctor.js} +16 -10
  189. package/dist/tools/{applyPatch.d.ts → workspace/applyPatch.d.ts} +1 -1
  190. package/dist/tools/workspace/applyPatch.js +53 -0
  191. package/dist/tools/{discardWorktree.js → workspace/discardWorktree.js} +3 -3
  192. package/dist/tools/workspace/index.d.ts +10 -0
  193. package/dist/tools/workspace/index.js +10 -0
  194. package/dist/tools/workspace/listAgents.d.ts +23 -0
  195. package/dist/tools/workspace/listAgents.js +56 -0
  196. package/dist/tools/{listWorkspace.js → workspace/listWorkspace.js} +3 -3
  197. package/dist/tools/{mergeWorktree.js → workspace/mergeWorktree.js} +3 -3
  198. package/dist/tools/{readWorkspaceFile.js → workspace/readWorkspaceFile.js} +8 -8
  199. package/dist/tools/{recommendAgentForTask.js → workspace/recommendAgentForTask.js} +3 -3
  200. package/dist/tools/{searchWorkspace.js → workspace/searchWorkspace.js} +5 -5
  201. package/dist/tools/{syncFile.d.ts → workspace/syncFile.d.ts} +1 -1
  202. package/dist/tools/workspace/syncFile.js +134 -0
  203. package/dist/utils/atomicFile.d.ts +7 -0
  204. package/dist/utils/atomicFile.js +67 -0
  205. package/dist/utils/boundedFile.d.ts +8 -0
  206. package/dist/utils/boundedFile.js +93 -0
  207. package/dist/utils/lockedJsonFile.d.ts +15 -0
  208. package/dist/utils/lockedJsonFile.js +224 -0
  209. package/dist/utils/platform.d.ts +11 -0
  210. package/dist/utils/platform.js +26 -0
  211. package/dist/utils/stableJson.d.ts +2 -0
  212. package/dist/utils/stableJson.js +12 -0
  213. package/dist/version.d.ts +3 -2
  214. package/dist/version.js +3 -2
  215. package/dist/watcherStatus.d.ts +2 -2
  216. package/dist/watcherStatus.js +18 -0
  217. package/docs/CODE_WIKI.md +808 -143
  218. package/docs/architecture.md +15 -55
  219. package/docs/assets/patchwarden-desktop-onboarding.png +0 -0
  220. package/docs/control-center/README.md +4 -4
  221. package/docs/dashboard-overview.md +4 -4
  222. package/docs/desktop-app.md +175 -0
  223. package/docs/evidence-pack-schema.md +3 -3
  224. package/docs/open-source-application.md +16 -11
  225. package/docs/release-checklist.md +1 -1
  226. package/docs/release-evidence.md +35 -39
  227. package/docs/task-safe-review-workflow.md +5 -5
  228. package/docs/threat-model.md +19 -1
  229. package/examples/config.example.json +4 -2
  230. package/package.json +27 -10
  231. package/scripts/README.md +15 -6
  232. package/scripts/build.js +11 -0
  233. package/scripts/checks/brand-check.js +3 -0
  234. package/scripts/checks/build-output-check.js +37 -0
  235. package/scripts/checks/control-center-smoke.js +102 -10
  236. package/scripts/checks/control-smoke.js +19 -8
  237. package/scripts/checks/http-mcp-smoke.js +82 -4
  238. package/scripts/checks/lifecycle-smoke.js +15 -12
  239. package/scripts/checks/mcp-manifest-check.js +1 -1
  240. package/scripts/checks/mcp-smoke.js +58 -4
  241. package/scripts/checks/package-manifest-check.js +20 -7
  242. package/scripts/checks/unit-tests.js +3 -5
  243. package/scripts/checks/watcher-supervisor-smoke.js +38 -1
  244. package/scripts/control/get-patchwarden-health.ps1 +1 -1
  245. package/scripts/control/manage-patchwarden.ps1 +69 -4
  246. package/scripts/control/provision-patchwarden-tunnel.ps1 +127 -0
  247. package/scripts/control/run-background-supervisor.ps1 +41 -0
  248. package/scripts/control/start-patchwarden-tunnel.ps1 +191 -33
  249. package/scripts/e2e/demo-runtime.mjs +153 -0
  250. package/{PatchWarden-Control-Tray.cmd → scripts/launchers/PatchWarden-Control-Tray.cmd} +3 -3
  251. package/scripts/launchers/PatchWarden-Control.cmd +6 -0
  252. package/{PatchWarden-Desktop.cmd → scripts/launchers/PatchWarden-Desktop.cmd} +2 -2
  253. package/scripts/launchers/Restart-PatchWarden-Control.cmd +6 -0
  254. package/{Stop-PatchWarden.cmd → scripts/launchers/Stop-PatchWarden.cmd} +2 -2
  255. package/scripts/lib/clean-generated-output.js +11 -0
  256. package/scripts/lib/file-discovery.js +12 -0
  257. package/scripts/release/desktop-preflight.js +211 -0
  258. package/scripts/release/pack-clean.js +59 -14
  259. package/src/assessments/agentAssessor.ts +26 -12
  260. package/src/assessments/assessmentDiagnostics.ts +172 -0
  261. package/src/assessments/assessmentStore.ts +288 -51
  262. package/src/assessments/securitySnapshot.ts +231 -0
  263. package/src/config.ts +70 -13
  264. package/src/control/fileManager.ts +40 -0
  265. package/src/control/middleware/auth.ts +22 -4
  266. package/src/control/middleware/static.ts +16 -3
  267. package/src/control/routeTable.ts +301 -0
  268. package/src/control/routes/audit.ts +14 -6
  269. package/src/control/routes/evidence.ts +1 -1
  270. package/src/control/routes/lineage.ts +1 -1
  271. package/src/control/routes/process.ts +341 -40
  272. package/src/control/routes/sessions.ts +88 -25
  273. package/src/control/routes/status.ts +134 -17
  274. package/src/control/routes/taskActions.ts +24 -58
  275. package/src/control/routes/tasks.ts +66 -58
  276. package/src/control/routes/workspace.ts +56 -25
  277. package/src/control/runtime.ts +71 -43
  278. package/src/control/server.ts +37 -342
  279. package/src/control/shared.ts +77 -11
  280. package/src/diagnostics/allowedTestCommandSafety.ts +12 -0
  281. package/src/direct/directAudit.ts +17 -9
  282. package/src/direct/directGuards.ts +72 -44
  283. package/src/direct/directPatch.ts +95 -8
  284. package/src/direct/directSessionStore.ts +213 -55
  285. package/src/direct/directVerification.ts +9 -23
  286. package/src/doctor.ts +76 -64
  287. package/src/goal/acceptanceEngine.ts +1 -1
  288. package/src/goal/goalProgress.ts +17 -13
  289. package/src/goal/goalReport.ts +5 -13
  290. package/src/goal/goalStatus.ts +19 -3
  291. package/src/goal/goalStore.ts +241 -54
  292. package/src/goal/handoffExport.ts +6 -6
  293. package/src/goal/specKitImport.ts +12 -12
  294. package/src/goal/subgoalSync.ts +11 -8
  295. package/src/goal/worktreeManager.ts +139 -22
  296. package/src/httpServer.ts +113 -30
  297. package/src/logging.ts +10 -3
  298. package/src/policy/projectPolicy.ts +5 -2
  299. package/src/release/releaseGate.ts +74 -27
  300. package/src/runner/agentInvocation.ts +126 -4
  301. package/src/runner/changeCapture.ts +291 -57
  302. package/src/runner/postTaskCleanup.ts +41 -17
  303. package/src/runner/processSecurity.ts +433 -0
  304. package/src/runner/runTask.ts +197 -97
  305. package/src/runner/simpleProcess.ts +66 -31
  306. package/src/{taskProgress.ts → runner/taskProgress.ts} +3 -3
  307. package/src/{taskRuntime.ts → runner/taskRuntime.ts} +6 -3
  308. package/src/runner/taskStatusStore.ts +69 -0
  309. package/src/runner/watch.ts +348 -52
  310. package/src/security/contentRedaction.ts +2 -2
  311. package/src/security/discoveryTokenStore.ts +18 -4
  312. package/src/security/loopbackHost.ts +19 -0
  313. package/src/security/pathGuard.ts +35 -16
  314. package/src/security/planGuard.ts +2 -1
  315. package/src/security/runtimeGuard.ts +9 -6
  316. package/src/security/secretComparison.ts +13 -0
  317. package/src/security/sensitiveGuard.ts +27 -8
  318. package/src/security/toolInvocationGuard.ts +2 -2
  319. package/src/security/workspaceRootGuard.ts +53 -0
  320. package/src/smoke-test.ts +27 -26
  321. package/src/tools/catalog/index.ts +4 -0
  322. package/src/tools/{toolCatalog.ts → catalog/toolCatalog.ts} +3 -12
  323. package/src/tools/{toolRegistry.ts → catalog/toolRegistry.ts} +7 -16
  324. package/src/tools/definitions/toolDefs.ts +1264 -0
  325. package/src/tools/{auditSession.ts → diagnostics/auditSession.ts} +2 -2
  326. package/src/tools/{auditTask.ts → diagnostics/auditTask.ts} +136 -39
  327. package/src/tools/{healthCheck.ts → diagnostics/healthCheck.ts} +37 -9
  328. package/src/tools/diagnostics/index.ts +6 -0
  329. package/src/tools/{safeStatus.ts → diagnostics/safeStatus.ts} +7 -7
  330. package/src/tools/{safeViews.ts → diagnostics/safeViews.ts} +27 -17
  331. package/src/tools/{schemaDriftCheck.ts → diagnostics/schemaDriftCheck.ts} +3 -3
  332. package/src/tools/{createDirectSession.ts → direct/createDirectSession.ts} +6 -6
  333. package/src/tools/{finalizeDirectSession.ts → direct/finalizeDirectSession.ts} +7 -5
  334. package/src/tools/direct/index.ts +3 -0
  335. package/src/tools/{runDirectVerificationBundle.ts → direct/runDirectVerificationBundle.ts} +2 -2
  336. package/src/tools/{discoverTools.ts → discovery/discoverTools.ts} +6 -6
  337. package/src/tools/{explainTool.ts → discovery/explainTool.ts} +3 -3
  338. package/src/tools/discovery/index.ts +3 -0
  339. package/src/tools/{invokeDiscoveredTool.ts → discovery/invokeDiscoveredTool.ts} +7 -7
  340. package/src/tools/dispatch/coreDispatch.ts +36 -31
  341. package/src/tools/dispatch/diagnosticDispatch.ts +26 -21
  342. package/src/tools/dispatch/directDispatch.ts +11 -10
  343. package/src/tools/dispatch/goalDispatch.ts +5 -4
  344. package/src/tools/dispatch/releaseDispatch.ts +3 -2
  345. package/src/tools/dispatch/validation.ts +78 -0
  346. package/src/tools/{getPlan.ts → goals/getPlan.ts} +4 -4
  347. package/src/tools/{goalSubgoalTask.ts → goals/goalSubgoalTask.ts} +41 -26
  348. package/src/tools/goals/index.ts +3 -0
  349. package/src/tools/{savePlan.ts → goals/savePlan.ts} +38 -8
  350. package/src/tools/registry.ts +17 -1261
  351. package/src/tools/{checkReleaseGate.ts → release/checkReleaseGate.ts} +3 -3
  352. package/src/tools/release/index.ts +2 -0
  353. package/src/tools/{releaseMode.ts → release/releaseMode.ts} +42 -24
  354. package/src/tools/tasks/cancelTask.ts +110 -0
  355. package/src/tools/{createTask.ts → tasks/createTask.ts} +161 -33
  356. package/src/tools/{diagnoseTask.ts → tasks/diagnoseTask.ts} +12 -16
  357. package/src/tools/{evidencePack.ts → tasks/evidencePack.ts} +36 -22
  358. package/src/tools/{getTaskFile.ts → tasks/getTaskFile.ts} +4 -4
  359. package/src/tools/{getTaskStatus.ts → tasks/getTaskStatus.ts} +13 -6
  360. package/src/tools/{getTaskStdoutTail.ts → tasks/getTaskStdoutTail.ts} +13 -11
  361. package/src/tools/{getTaskSummary.ts → tasks/getTaskSummary.ts} +46 -44
  362. package/src/tools/tasks/index.ts +18 -0
  363. package/src/tools/{listTasks.ts → tasks/listTasks.ts} +6 -5
  364. package/src/tools/{reconcileTasks.ts → tasks/reconcileTasks.ts} +228 -77
  365. package/src/tools/tasks/retryTask.ts +69 -0
  366. package/src/tools/{runTaskLoop.ts → tasks/runTaskLoop.ts} +73 -46
  367. package/src/tools/{runVerification.ts → tasks/runVerification.ts} +6 -3
  368. package/src/tools/{taskLineage.ts → tasks/taskLineage.ts} +8 -7
  369. package/src/tools/{taskOutputs.ts → tasks/taskOutputs.ts} +27 -20
  370. package/src/tools/tasks/taskStates.ts +54 -0
  371. package/src/tools/{waitForTask.ts → tasks/waitForTask.ts} +3 -12
  372. package/src/tools/{androidDoctor.ts → workspace/androidDoctor.ts} +15 -10
  373. package/src/tools/{applyPatch.ts → workspace/applyPatch.ts} +38 -16
  374. package/src/tools/{discardWorktree.ts → workspace/discardWorktree.ts} +3 -3
  375. package/src/tools/workspace/index.ts +10 -0
  376. package/src/tools/workspace/listAgents.ts +75 -0
  377. package/src/tools/{listWorkspace.ts → workspace/listWorkspace.ts} +3 -3
  378. package/src/tools/{mergeWorktree.ts → workspace/mergeWorktree.ts} +3 -3
  379. package/src/tools/{readWorkspaceFile.ts → workspace/readWorkspaceFile.ts} +8 -8
  380. package/src/tools/{recommendAgentForTask.ts → workspace/recommendAgentForTask.ts} +3 -3
  381. package/src/tools/{searchWorkspace.ts → workspace/searchWorkspace.ts} +5 -5
  382. package/src/tools/workspace/syncFile.ts +292 -0
  383. package/src/utils/atomicFile.ts +74 -0
  384. package/src/utils/boundedFile.ts +116 -0
  385. package/src/utils/lockedJsonFile.ts +251 -0
  386. package/src/utils/platform.ts +31 -0
  387. package/src/utils/stableJson.ts +12 -0
  388. package/src/version.ts +3 -2
  389. package/src/watcherStatus.ts +19 -1
  390. package/ui/desktop-bootstrap.js +11 -0
  391. package/ui/desktop-bridge.js +36 -0
  392. package/ui/desktop.css +160 -0
  393. package/ui/getting-started.js +93 -0
  394. package/ui/i18n.js +484 -0
  395. package/ui/log-parser.js +30 -0
  396. package/ui/pages/audit.html +12 -0
  397. package/ui/pages/dashboard.html +94 -147
  398. package/ui/pages/direct-sessions.html +123 -26
  399. package/ui/pages/getting-started.html +43 -0
  400. package/ui/pages/logs.html +134 -22
  401. package/ui/pages/settings.html +101 -0
  402. package/ui/pages/task-detail.html +12 -0
  403. package/ui/pages/tasks.html +54 -8
  404. package/ui/pages/workspace.html +38 -1
  405. package/ui/settings.js +254 -0
  406. package/PatchWarden-Control.cmd +0 -6
  407. package/Restart-PatchWarden-Control.cmd +0 -6
  408. package/dist/test/unit/acceptance-engine.test.d.ts +0 -1
  409. package/dist/test/unit/acceptance-engine.test.js +0 -228
  410. package/dist/test/unit/agent-router.test.d.ts +0 -1
  411. package/dist/test/unit/agent-router.test.js +0 -287
  412. package/dist/test/unit/android-doctor.test.d.ts +0 -1
  413. package/dist/test/unit/android-doctor.test.js +0 -118
  414. package/dist/test/unit/apply-patch.test.d.ts +0 -1
  415. package/dist/test/unit/apply-patch.test.js +0 -225
  416. package/dist/test/unit/audit-checks.test.d.ts +0 -1
  417. package/dist/test/unit/audit-checks.test.js +0 -350
  418. package/dist/test/unit/chinese-path.test.d.ts +0 -1
  419. package/dist/test/unit/chinese-path.test.js +0 -91
  420. package/dist/test/unit/command-guard.test.d.ts +0 -1
  421. package/dist/test/unit/command-guard.test.js +0 -160
  422. package/dist/test/unit/create-task.test.d.ts +0 -1
  423. package/dist/test/unit/create-task.test.js +0 -197
  424. package/dist/test/unit/diagnose-task.test.d.ts +0 -1
  425. package/dist/test/unit/diagnose-task.test.js +0 -457
  426. package/dist/test/unit/direct-guards.test.d.ts +0 -1
  427. package/dist/test/unit/direct-guards.test.js +0 -328
  428. package/dist/test/unit/discovery-token-store.test.d.ts +0 -1
  429. package/dist/test/unit/discovery-token-store.test.js +0 -139
  430. package/dist/test/unit/evidence-pack.test.d.ts +0 -1
  431. package/dist/test/unit/evidence-pack.test.js +0 -224
  432. package/dist/test/unit/get-task-status.test.d.ts +0 -1
  433. package/dist/test/unit/get-task-status.test.js +0 -174
  434. package/dist/test/unit/get-task-summary.test.d.ts +0 -1
  435. package/dist/test/unit/get-task-summary.test.js +0 -146
  436. package/dist/test/unit/goal-graph.test.d.ts +0 -1
  437. package/dist/test/unit/goal-graph.test.js +0 -298
  438. package/dist/test/unit/goal-progress.test.d.ts +0 -1
  439. package/dist/test/unit/goal-progress.test.js +0 -381
  440. package/dist/test/unit/goal-report.test.d.ts +0 -1
  441. package/dist/test/unit/goal-report.test.js +0 -159
  442. package/dist/test/unit/goal-status.test.d.ts +0 -1
  443. package/dist/test/unit/goal-status.test.js +0 -215
  444. package/dist/test/unit/goal-store.test.d.ts +0 -1
  445. package/dist/test/unit/goal-store.test.js +0 -253
  446. package/dist/test/unit/goal-subgoal-task.test.d.ts +0 -1
  447. package/dist/test/unit/goal-subgoal-task.test.js +0 -55
  448. package/dist/test/unit/goal-tools-registry.test.d.ts +0 -1
  449. package/dist/test/unit/goal-tools-registry.test.js +0 -192
  450. package/dist/test/unit/handoff-export.test.d.ts +0 -1
  451. package/dist/test/unit/handoff-export.test.js +0 -263
  452. package/dist/test/unit/invoke-discovered-tool.test.d.ts +0 -1
  453. package/dist/test/unit/invoke-discovered-tool.test.js +0 -167
  454. package/dist/test/unit/logging.test.d.ts +0 -1
  455. package/dist/test/unit/logging.test.js +0 -397
  456. package/dist/test/unit/path-guard.test.d.ts +0 -1
  457. package/dist/test/unit/path-guard.test.js +0 -133
  458. package/dist/test/unit/post-task-cleanup.test.d.ts +0 -1
  459. package/dist/test/unit/post-task-cleanup.test.js +0 -48
  460. package/dist/test/unit/project-policy-release-mode.test.d.ts +0 -1
  461. package/dist/test/unit/project-policy-release-mode.test.js +0 -125
  462. package/dist/test/unit/reconcile-tasks.test.d.ts +0 -1
  463. package/dist/test/unit/reconcile-tasks.test.js +0 -456
  464. package/dist/test/unit/release-gate.test.d.ts +0 -1
  465. package/dist/test/unit/release-gate.test.js +0 -242
  466. package/dist/test/unit/run-task-loop.test.d.ts +0 -1
  467. package/dist/test/unit/run-task-loop.test.js +0 -380
  468. package/dist/test/unit/safe-status.test.d.ts +0 -1
  469. package/dist/test/unit/safe-status.test.js +0 -165
  470. package/dist/test/unit/safe-views.test.d.ts +0 -1
  471. package/dist/test/unit/safe-views.test.js +0 -171
  472. package/dist/test/unit/schema-drift-check.test.d.ts +0 -1
  473. package/dist/test/unit/schema-drift-check.test.js +0 -176
  474. package/dist/test/unit/sensitive-guard.test.d.ts +0 -1
  475. package/dist/test/unit/sensitive-guard.test.js +0 -104
  476. package/dist/test/unit/spec-kit-import.test.d.ts +0 -1
  477. package/dist/test/unit/spec-kit-import.test.js +0 -341
  478. package/dist/test/unit/subgoal-sync.test.d.ts +0 -1
  479. package/dist/test/unit/subgoal-sync.test.js +0 -183
  480. package/dist/test/unit/sync-file.test.d.ts +0 -1
  481. package/dist/test/unit/sync-file.test.js +0 -154
  482. package/dist/test/unit/tool-invocation-guard.test.d.ts +0 -1
  483. package/dist/test/unit/tool-invocation-guard.test.js +0 -432
  484. package/dist/test/unit/tool-usage-stats.test.d.ts +0 -1
  485. package/dist/test/unit/tool-usage-stats.test.js +0 -300
  486. package/dist/test/unit/toolSearch.test.d.ts +0 -1
  487. package/dist/test/unit/toolSearch.test.js +0 -571
  488. package/dist/test/unit/wait-for-task.test.d.ts +0 -1
  489. package/dist/test/unit/wait-for-task.test.js +0 -144
  490. package/dist/test/unit/watcher-status.test.d.ts +0 -1
  491. package/dist/test/unit/watcher-status.test.js +0 -169
  492. package/dist/test/unit/worktree-manager.test.d.ts +0 -1
  493. package/dist/test/unit/worktree-manager.test.js +0 -176
  494. package/dist/tools/applyPatch.js +0 -41
  495. package/dist/tools/cancelTask.d.ts +0 -30
  496. package/dist/tools/cancelTask.js +0 -64
  497. package/dist/tools/finalizeDirectSession.js +0 -84
  498. package/dist/tools/goalSubgoalTask.js +0 -110
  499. package/dist/tools/killTask.d.ts +0 -15
  500. package/dist/tools/listAgents.d.ts +0 -12
  501. package/dist/tools/listAgents.js +0 -42
  502. package/dist/tools/reconcileTasks.js +0 -352
  503. package/dist/tools/retryTask.js +0 -45
  504. package/dist/tools/runVerification.js +0 -36
  505. package/dist/tools/syncFile.js +0 -65
  506. package/docs/control-center/control-center-daily-driver.md +0 -211
  507. package/docs/control-center/control-center-mvp.md +0 -205
  508. package/docs/control-center/control-center-phase2.md +0 -159
  509. package/docs/execution-plan-2026-07-09.md +0 -315
  510. package/docs/release-v0.6.0.md +0 -71
  511. package/docs/release-v0.6.1.md +0 -75
  512. package/docs/release-v0.6.4.md +0 -45
  513. package/docs/roadmap-execution-and-acceptance.md +0 -365
  514. package/src/test/unit/acceptance-engine.test.ts +0 -261
  515. package/src/test/unit/agent-router.test.ts +0 -342
  516. package/src/test/unit/android-doctor.test.ts +0 -158
  517. package/src/test/unit/apply-patch.test.ts +0 -293
  518. package/src/test/unit/audit-checks.test.ts +0 -567
  519. package/src/test/unit/chinese-path.test.ts +0 -106
  520. package/src/test/unit/command-guard.test.ts +0 -221
  521. package/src/test/unit/create-task.test.ts +0 -255
  522. package/src/test/unit/diagnose-task.test.ts +0 -544
  523. package/src/test/unit/direct-guards.test.ts +0 -467
  524. package/src/test/unit/discovery-token-store.test.ts +0 -181
  525. package/src/test/unit/evidence-pack.test.ts +0 -251
  526. package/src/test/unit/get-task-status.test.ts +0 -203
  527. package/src/test/unit/get-task-summary.test.ts +0 -173
  528. package/src/test/unit/goal-graph.test.ts +0 -347
  529. package/src/test/unit/goal-progress.test.ts +0 -538
  530. package/src/test/unit/goal-report.test.ts +0 -189
  531. package/src/test/unit/goal-status.test.ts +0 -270
  532. package/src/test/unit/goal-store.test.ts +0 -318
  533. package/src/test/unit/goal-subgoal-task.test.ts +0 -72
  534. package/src/test/unit/goal-tools-registry.test.ts +0 -245
  535. package/src/test/unit/handoff-export.test.ts +0 -295
  536. package/src/test/unit/invoke-discovered-tool.test.ts +0 -216
  537. package/src/test/unit/logging.test.ts +0 -497
  538. package/src/test/unit/path-guard.test.ts +0 -180
  539. package/src/test/unit/post-task-cleanup.test.ts +0 -53
  540. package/src/test/unit/project-policy-release-mode.test.ts +0 -156
  541. package/src/test/unit/reconcile-tasks.test.ts +0 -551
  542. package/src/test/unit/release-gate.test.ts +0 -314
  543. package/src/test/unit/run-task-loop.test.ts +0 -425
  544. package/src/test/unit/safe-status.test.ts +0 -187
  545. package/src/test/unit/safe-views.test.ts +0 -184
  546. package/src/test/unit/schema-drift-check.test.ts +0 -260
  547. package/src/test/unit/sensitive-guard.test.ts +0 -124
  548. package/src/test/unit/spec-kit-import.test.ts +0 -429
  549. package/src/test/unit/subgoal-sync.test.ts +0 -236
  550. package/src/test/unit/sync-file.test.ts +0 -231
  551. package/src/test/unit/tool-invocation-guard.test.ts +0 -542
  552. package/src/test/unit/tool-usage-stats.test.ts +0 -384
  553. package/src/test/unit/toolSearch.test.ts +0 -756
  554. package/src/test/unit/wait-for-task.test.ts +0 -176
  555. package/src/test/unit/watcher-status.test.ts +0 -190
  556. package/src/test/unit/worktree-manager.test.ts +0 -247
  557. package/src/tools/cancelTask.ts +0 -70
  558. package/src/tools/listAgents.ts +0 -54
  559. package/src/tools/retryTask.ts +0 -53
  560. package/src/tools/syncFile.ts +0 -122
  561. /package/dist/tools/{toolCatalog.d.ts → catalog/toolCatalog.d.ts} +0 -0
  562. /package/dist/tools/{toolSearch.d.ts → catalog/toolSearch.d.ts} +0 -0
  563. /package/dist/tools/{toolSearch.js → catalog/toolSearch.js} +0 -0
  564. /package/dist/tools/{toolUsageStats.d.ts → catalog/toolUsageStats.d.ts} +0 -0
  565. /package/dist/tools/{toolUsageStats.js → catalog/toolUsageStats.js} +0 -0
  566. /package/dist/tools/{createDirectSession.d.ts → direct/createDirectSession.d.ts} +0 -0
  567. /package/dist/tools/{runDirectVerificationBundle.d.ts → direct/runDirectVerificationBundle.d.ts} +0 -0
  568. /package/dist/tools/{getPlan.d.ts → goals/getPlan.d.ts} +0 -0
  569. /package/dist/tools/{savePlan.d.ts → goals/savePlan.d.ts} +0 -0
  570. /package/dist/tools/{evidencePack.d.ts → tasks/evidencePack.d.ts} +0 -0
  571. /package/dist/tools/{getTaskFile.d.ts → tasks/getTaskFile.d.ts} +0 -0
  572. /package/dist/tools/{getTaskProgress.d.ts → tasks/getTaskProgress.d.ts} +0 -0
  573. /package/dist/tools/{getTaskProgress.js → tasks/getTaskProgress.js} +0 -0
  574. /package/dist/tools/{getTaskStdoutTail.d.ts → tasks/getTaskStdoutTail.d.ts} +0 -0
  575. /package/dist/tools/{getTaskSummary.d.ts → tasks/getTaskSummary.d.ts} +0 -0
  576. /package/dist/tools/{killTask.js → tasks/killTask.js} +0 -0
  577. /package/dist/tools/{retryTask.d.ts → tasks/retryTask.d.ts} +0 -0
  578. /package/dist/tools/{runVerification.d.ts → tasks/runVerification.d.ts} +0 -0
  579. /package/dist/tools/{taskLineage.d.ts → tasks/taskLineage.d.ts} +0 -0
  580. /package/dist/tools/{waitForTask.d.ts → tasks/waitForTask.d.ts} +0 -0
  581. /package/dist/tools/{androidDoctor.d.ts → workspace/androidDoctor.d.ts} +0 -0
  582. /package/dist/tools/{discardWorktree.d.ts → workspace/discardWorktree.d.ts} +0 -0
  583. /package/dist/tools/{listWorkspace.d.ts → workspace/listWorkspace.d.ts} +0 -0
  584. /package/dist/tools/{mergeWorktree.d.ts → workspace/mergeWorktree.d.ts} +0 -0
  585. /package/dist/tools/{readWorkspaceFile.d.ts → workspace/readWorkspaceFile.d.ts} +0 -0
  586. /package/dist/tools/{recommendAgentForTask.d.ts → workspace/recommendAgentForTask.d.ts} +0 -0
  587. /package/dist/tools/{searchWorkspace.d.ts → workspace/searchWorkspace.d.ts} +0 -0
  588. /package/src/tools/{toolSearch.ts → catalog/toolSearch.ts} +0 -0
  589. /package/src/tools/{toolUsageStats.ts → catalog/toolUsageStats.ts} +0 -0
  590. /package/src/tools/{getTaskProgress.ts → tasks/getTaskProgress.ts} +0 -0
  591. /package/src/tools/{killTask.ts → tasks/killTask.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import { type DirectSessionAuditOutput } from "../direct/directAudit.js";
1
+ import { type DirectSessionAuditOutput } from "../../direct/directAudit.js";
2
2
  export interface AuditSessionInput {
3
3
  session_id: string;
4
4
  }
@@ -1,5 +1,5 @@
1
- import { auditDirectSession, } from "../direct/directAudit.js";
2
- import { updateDirectSession } from "../direct/directSessionStore.js";
1
+ import { auditDirectSession, } from "../../direct/directAudit.js";
2
+ import { updateDirectSession } from "../../direct/directSessionStore.js";
3
3
  // ── Main function ──────────────────────────────────────────────────
4
4
  export function auditSession(input) {
5
5
  const { session_id } = input;
@@ -32,7 +32,8 @@ export interface AuditTaskOutput {
32
32
  manual_verification_items: string[];
33
33
  recommended_next_actions: string[];
34
34
  }
35
- import type { ChangedFile } from "../runner/changeCapture.js";
35
+ import type { ChangedFile } from "../../runner/changeCapture.js";
36
+ export declare function extractNpmRunScriptNames(content: string): string[];
36
37
  /**
37
38
  * Check 1: forbidden_scope_violation (fail level).
38
39
  * Returns null when no forbidden patterns are configured (skip).
@@ -1,10 +1,13 @@
1
- import { readFileSync, existsSync, writeFileSync, readdirSync, statSync } from "node:fs";
1
+ import { readFileSync, existsSync, opendirSync, statSync } from "node:fs";
2
2
  import { join, resolve, relative, basename, sep, isAbsolute } from "node:path";
3
- import { getTasksDir, getConfig } from "../config.js";
4
- import { guardReadPath, guardWorkspacePath } from "../security/pathGuard.js";
5
- import { guardSensitivePath, isSensitivePath } from "../security/sensitiveGuard.js";
6
- import { evaluateAcceptance } from "../goal/acceptanceEngine.js";
7
- import { renderAcceptanceMarkdown } from "../goal/acceptanceTemplate.js";
3
+ import { getTasksDir, getConfig } from "../../config.js";
4
+ import { guardReadPath, guardWorkspacePath } from "../../security/pathGuard.js";
5
+ import { guardSensitivePath, isSensitivePath } from "../../security/sensitiveGuard.js";
6
+ import { evaluateAcceptance } from "../../goal/acceptanceEngine.js";
7
+ import { renderAcceptanceMarkdown } from "../../goal/acceptanceTemplate.js";
8
+ import { atomicWriteFileSync } from "../../utils/atomicFile.js";
9
+ import { mutateTaskStatus } from "../../runner/taskStatusStore.js";
10
+ import { readTextFilePrefixSync, readTextFileTailLinesSync, } from "../../utils/boundedFile.js";
8
11
  // Release claim patterns — anything that claims remote publish/release/deploy
9
12
  const RELEASE_PATTERNS = [
10
13
  /npm\s+package\s+version\s+published/i,
@@ -16,6 +19,10 @@ const RELEASE_PATTERNS = [
16
19
  /npm\s+publish\s+completed/i,
17
20
  /deploy(ed|ment)?\s+(to|on)\s+(npm|registry|github)/i,
18
21
  ];
22
+ const MAX_AUDIT_DOC_FILES = 200;
23
+ const MAX_AUDIT_DOC_FILE_BYTES = 512 * 1024;
24
+ const MAX_AUDIT_DOC_TOTAL_BYTES = 4 * 1024 * 1024;
25
+ const MAX_AUDIT_EVIDENCE_BYTES = 1024 * 1024;
19
26
  function scanForReleaseClaims(text) {
20
27
  const found = [];
21
28
  for (const pattern of RELEASE_PATTERNS) {
@@ -25,24 +32,89 @@ function scanForReleaseClaims(text) {
25
32
  }
26
33
  return found;
27
34
  }
28
- function findMdFiles(dir, maxDepth = 3) {
35
+ function findMdFiles(dir, maxDepth = 3, maxFiles = MAX_AUDIT_DOC_FILES) {
29
36
  const results = [];
30
- if (!existsSync(dir) || maxDepth <= 0)
31
- return results;
32
- try {
33
- const entries = readdirSync(dir, { withFileTypes: true });
34
- for (const e of entries) {
35
- const full = join(dir, e.name);
36
- if (e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules") {
37
- results.push(...findMdFiles(full, maxDepth - 1));
37
+ const pending = [{ path: dir, depth: maxDepth }];
38
+ const maxDirectories = maxFiles * 4;
39
+ let visitedDirectories = 0;
40
+ let truncated = false;
41
+ while (pending.length > 0 && results.length < maxFiles && visitedDirectories < maxDirectories) {
42
+ const current = pending.pop();
43
+ if (!existsSync(current.path) || current.depth <= 0)
44
+ continue;
45
+ visitedDirectories += 1;
46
+ let handle;
47
+ try {
48
+ handle = opendirSync(current.path);
49
+ while (results.length < maxFiles) {
50
+ const entry = handle.readSync();
51
+ if (!entry)
52
+ break;
53
+ const full = join(current.path, entry.name);
54
+ if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
55
+ if (pending.length < maxDirectories)
56
+ pending.push({ path: full, depth: current.depth - 1 });
57
+ else
58
+ truncated = true;
59
+ }
60
+ else if (entry.isFile() && entry.name.toLowerCase().endsWith(".md")) {
61
+ results.push(full);
62
+ }
38
63
  }
39
- else if (e.isFile() && e.name.endsWith(".md")) {
40
- results.push(full);
64
+ }
65
+ catch { /* skip unreadable dirs */ }
66
+ finally {
67
+ try {
68
+ handle?.closeSync();
41
69
  }
70
+ catch { /* best effort */ }
42
71
  }
43
72
  }
44
- catch { /* skip unreadable dirs */ }
45
- return results;
73
+ truncated ||= pending.length > 0 || results.length >= maxFiles || visitedDirectories >= maxDirectories;
74
+ return { files: results, truncated };
75
+ }
76
+ export function extractNpmRunScriptNames(content) {
77
+ const names = new Set();
78
+ const collectCommands = (text) => {
79
+ const pattern = /\bnpm(?:\.cmd)?\s+run\s+([a-zA-Z0-9:_-]+)/gi;
80
+ let match;
81
+ while ((match = pattern.exec(text)) !== null) {
82
+ if (match[1])
83
+ names.add(match[1]);
84
+ }
85
+ };
86
+ // Markdown code blocks are explicit command-bearing regions. Keep their
87
+ // content separate from prose so token boundaries cannot be concatenated.
88
+ const withoutFences = content.replace(/(?:```|~~~)[^\r\n]*\r?\n([\s\S]*?)(?:```|~~~)/g, (_whole, body) => {
89
+ collectCommands(body);
90
+ return "\n";
91
+ });
92
+ // Inline code is also explicit. Remove it from the prose pass afterward to
93
+ // avoid double-counting and accidental cross-node matches.
94
+ const withoutInlineCode = withoutFences.replace(/`([^`\r\n]+)`/g, (_whole, body) => {
95
+ collectCommands(body);
96
+ return " ";
97
+ });
98
+ // In ordinary text, accept only a standalone command line (optionally a
99
+ // list item, shell prompt, or Run:/Command: label). Narrative mentions such
100
+ // as "this guide discusses npm run deploy" are not executable evidence.
101
+ const explicitPlainCommand = /^\s*(?:(?:[-*+]\s+|\d+[.)]\s+|>\s*|\$\s*|PS>\s*)|(?:(?:run|command|命令)\s*[::]\s*))?npm(?:\.cmd)?\s+run\s+[a-zA-Z0-9:_-]+(?:\s+(?:--[^\r\n#]*|#[^\r\n]*))?\s*$/i;
102
+ for (const line of withoutInlineCode.split(/\r?\n/)) {
103
+ if (explicitPlainCommand.test(line))
104
+ collectCommands(line);
105
+ }
106
+ return [...names];
107
+ }
108
+ function readAuditEvidence(path) {
109
+ const half = Math.floor(MAX_AUDIT_EVIDENCE_BYTES / 2);
110
+ const prefix = readTextFilePrefixSync(path, half);
111
+ if (!prefix.truncated)
112
+ return { content: prefix.content, truncated: false };
113
+ const tail = readTextFileTailLinesSync(path, 1000, half);
114
+ return {
115
+ content: `${prefix.content}\n[...audit evidence truncated...]\n${tail}`,
116
+ truncated: true,
117
+ };
46
118
  }
47
119
  // ── v0.7.2: New audit checks (exported for testing) ────────────────
48
120
  /**
@@ -426,7 +498,7 @@ export function auditTask(taskId) {
426
498
  };
427
499
  // ── 1. Task status ──
428
500
  const taskStatus = statusData.status || "unknown";
429
- const failedStatuses = new Set(["failed", "failed_verification", "failed_scope_violation", "failed_policy_violation", "canceled"]);
501
+ const failedStatuses = new Set(["failed", "failed_verification", "failed_scope_violation", "failed_policy_violation", "canceled", "timeout"]);
430
502
  const doneStatuses = new Set(["done", "done_by_agent"]);
431
503
  checks.push({
432
504
  name: "task_status",
@@ -606,36 +678,52 @@ export function auditTask(taskId) {
606
678
  if (existsSync(readmePath))
607
679
  docsToScan.push(readmePath);
608
680
  const docsDir = join(repoPathSafe, "docs");
681
+ let markdownEnumerationTruncated = false;
609
682
  if (existsSync(docsDir)) {
610
- docsToScan.push(...findMdFiles(docsDir));
683
+ const markdown = findMdFiles(docsDir);
684
+ docsToScan.push(...markdown.files);
685
+ markdownEnumerationTruncated = markdown.truncated;
611
686
  }
612
687
  // Collect all npm run references from all docs
613
688
  const allNpmRunRefs = new Set();
614
689
  const allReleaseClaims = [];
690
+ let remainingDocBytes = MAX_AUDIT_DOC_TOTAL_BYTES;
691
+ let documentScanTruncated = markdownEnumerationTruncated || docsToScan.length > MAX_AUDIT_DOC_FILES;
615
692
  for (const docPath of docsToScan) {
693
+ if (remainingDocBytes <= 0) {
694
+ documentScanTruncated = true;
695
+ break;
696
+ }
616
697
  let content;
617
698
  try {
618
699
  if (docPath !== resultFile) {
619
700
  guardReadPath(docPath, config.workspaceRoot);
620
701
  guardSensitivePath(docPath);
621
702
  }
622
- content = readFileSync(docPath, "utf-8");
703
+ const bounded = readTextFilePrefixSync(docPath, Math.min(MAX_AUDIT_DOC_FILE_BYTES, remainingDocBytes));
704
+ content = bounded.content;
705
+ remainingDocBytes -= Buffer.byteLength(content, "utf-8");
706
+ documentScanTruncated ||= bounded.truncated;
623
707
  }
624
708
  catch {
625
709
  continue;
626
710
  }
627
711
  // Extract npm run xxx
628
- const refs = content.match(/npm(?:\.cmd)?\s+run\s+([a-zA-Z0-9:_-]+)/gi) || [];
629
- for (const ref of refs) {
630
- const scriptName = ref.replace(/npm\s+run\s+/i, "").replace(/[^a-zA-Z0-9:_-]/g, "");
631
- if (scriptName)
632
- allNpmRunRefs.add(scriptName);
633
- }
712
+ for (const scriptName of extractNpmRunScriptNames(content))
713
+ allNpmRunRefs.add(scriptName);
634
714
  // Check release claims
635
715
  const claims = scanForReleaseClaims(content);
636
716
  for (const c of claims)
637
717
  allReleaseClaims.push(`[${relative(repoPathSafe, docPath) || docPath}] ${c}`);
638
718
  }
719
+ if (documentScanTruncated) {
720
+ checks.push({
721
+ name: "documentation_scan_bounded",
722
+ result: "warn",
723
+ detail: `Documentation scan reached its ${MAX_AUDIT_DOC_FILES}-file or ${MAX_AUDIT_DOC_TOTAL_BYTES}-byte safety budget.`,
724
+ });
725
+ addManualVerification("Review documentation omitted by the bounded audit scan.");
726
+ }
639
727
  // Cross-check npm run refs against package.json scripts
640
728
  for (const scriptName of allNpmRunRefs) {
641
729
  if (pkgScripts.length > 0 && !pkgScripts.includes(scriptName)) {
@@ -682,7 +770,10 @@ export function auditTask(taskId) {
682
770
  if (hasTestLog) {
683
771
  let logContent;
684
772
  try {
685
- logContent = readFileSync(testLogFile, "utf-8");
773
+ const evidence = readAuditEvidence(testLogFile);
774
+ logContent = evidence.content;
775
+ if (evidence.truncated)
776
+ addManualVerification("test.log exceeded the audit read budget; inspect the complete local artifact.");
686
777
  }
687
778
  catch {
688
779
  logContent = "";
@@ -720,7 +811,10 @@ export function auditTask(taskId) {
720
811
  let resultMdContent = null;
721
812
  if (hasResult) {
722
813
  try {
723
- resultMdContent = readFileSync(resultFile, "utf-8");
814
+ const evidence = readAuditEvidence(resultFile);
815
+ resultMdContent = evidence.content;
816
+ if (evidence.truncated)
817
+ addManualVerification("result.md exceeded the audit read budget; inspect the complete local artifact.");
724
818
  }
725
819
  catch {
726
820
  resultMdContent = null;
@@ -788,7 +882,7 @@ export function auditTask(taskId) {
788
882
  "## Recommended Actions",
789
883
  ...actions.map((a) => `- ${a}`),
790
884
  ].join("\n");
791
- writeFileSync(join(taskDir, "independent-review.md"), reviewMd, "utf-8");
885
+ atomicWriteFileSync(join(taskDir, "independent-review.md"), reviewMd);
792
886
  // ── v0.7.2: 集成 acceptanceEngine ──
793
887
  const releaseClaimsUnverified = allReleaseClaims.length > 0;
794
888
  const acceptanceEvidence = {
@@ -827,16 +921,20 @@ export function auditTask(taskId) {
827
921
  const acceptanceResult = evaluateAcceptance(acceptanceEvidence);
828
922
  // 回写 status.json 的 acceptance_status(仅对 done_by_agent 有意义)
829
923
  if (taskStatus === "done_by_agent") {
830
- const updatedStatus = {
831
- ...statusData,
924
+ const statusPatch = {
832
925
  acceptance_status: acceptanceResult.acceptance_status,
833
- updated_at: new Date().toISOString(),
834
926
  };
835
- writeFileSync(statusFile, JSON.stringify(updatedStatus, null, 2), "utf-8");
927
+ mutateTaskStatus(statusFile, (current) => {
928
+ if (current.status !== "done_by_agent") {
929
+ return { result: current };
930
+ }
931
+ const next = { ...current, ...statusPatch, updated_at: new Date().toISOString() };
932
+ return { next, result: next };
933
+ });
836
934
  }
837
935
  // 导出 ACCEPTANCE.md
838
936
  const acceptanceMd = renderAcceptanceMarkdown(taskId, acceptanceResult, acceptanceEvidence);
839
- writeFileSync(join(taskDir, "ACCEPTANCE.md"), acceptanceMd, "utf-8");
937
+ atomicWriteFileSync(join(taskDir, "ACCEPTANCE.md"), acceptanceMd);
840
938
  return {
841
939
  task_id: taskId,
842
940
  verdict,
@@ -1,4 +1,4 @@
1
- import type { ToolCatalogSnapshot } from "./toolCatalog.js";
1
+ import type { ToolCatalogSnapshot } from "../catalog/toolCatalog.js";
2
2
  export interface HealthCheckInput {
3
3
  detail?: "standard" | "self_diagnostic";
4
4
  }
@@ -14,11 +14,12 @@ export declare function healthCheck(catalog?: ToolCatalogSnapshot, input?: Healt
14
14
  recent_tasks_returned: number;
15
15
  recent_failures: {
16
16
  task_id: string;
17
- status: import("./createTask.js").TaskStatus;
18
- phase: import("./createTask.js").TaskPhase;
19
- pending_reason: import("../watcherStatus.js").PendingReason;
17
+ status: import("../tasks/createTask.js").TaskStatus;
18
+ phase: import("../tasks/createTask.js").TaskPhase;
19
+ pending_reason: import("../../watcherStatus.js").PendingReason;
20
20
  error: string | null;
21
21
  }[];
22
+ last_assessment_validation_failure: import("../../assessments/assessmentDiagnostics.js").AssessmentValidationFailureDiagnostic | null;
22
23
  } | undefined;
23
24
  connector_visibility: {
24
25
  status: string;
@@ -37,7 +38,7 @@ export declare function healthCheck(catalog?: ToolCatalogSnapshot, input?: Healt
37
38
  };
38
39
  watcher: {
39
40
  supervisor: Record<string, unknown>;
40
- status: import("../watcherStatus.js").WatcherState;
41
+ status: import("../../watcherStatus.js").WatcherState;
41
42
  available: boolean;
42
43
  stale_after_seconds: number;
43
44
  last_heartbeat_at: string | null;
@@ -65,10 +66,21 @@ export declare function healthCheck(catalog?: ToolCatalogSnapshot, input?: Healt
65
66
  tunnel: Record<string, unknown> & {
66
67
  last_error: string | null;
67
68
  };
68
- agents: import("./listAgents.js").AgentAvailability[];
69
+ config_path: string;
70
+ runtime_build_layout: string | null;
71
+ watcher_entry_path: string | null;
72
+ validator_module_path: string | null;
73
+ agents: import("../workspace/listAgents.js").AgentAvailability[];
69
74
  agent_status: {
70
75
  [k: string]: string;
71
76
  };
77
+ agent_readiness: {
78
+ [k: string]: {
79
+ executable_available: boolean;
80
+ provider_status: "not_checked";
81
+ availability_scope: "executable_only";
82
+ };
83
+ };
72
84
  search_tool_count?: 5 | undefined;
73
85
  direct_tool_count?: number | undefined;
74
86
  status: string;
@@ -1,13 +1,14 @@
1
1
  import { accessSync, constants, existsSync, readFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, join } from "node:path";
4
- import { getConfig, getTasksDir, getDirectSessionsDir, resolveWorkspaceRoot } from "../config.js";
5
- import { listAgents } from "./listAgents.js";
6
- import { redactSensitiveContent, redactSensitiveValue } from "../security/contentRedaction.js";
7
- import { PATCHWARDEN_VERSION, TOOL_SCHEMA_EPOCH } from "../version.js";
8
- import { CHATGPT_CORE_TOOL_NAMES, CHATGPT_DIRECT_TOOL_NAMES, CHATGPT_SEARCH_TOOL_NAMES, resolveToolProfile } from "./toolCatalog.js";
9
- import { readWatcherStatus } from "../watcherStatus.js";
10
- import { listTasks } from "./listTasks.js";
4
+ import { getConfig, getTasksDir, getDirectSessionsDir, resolveWorkspaceRoot } from "../../config.js";
5
+ import { listAgents } from "../workspace/listAgents.js";
6
+ import { redactSensitiveContent, redactSensitiveValue } from "../../security/contentRedaction.js";
7
+ import { PATCHWARDEN_VERSION, TOOL_SCHEMA_EPOCH } from "../../version.js";
8
+ import { CHATGPT_CORE_TOOL_NAMES, CHATGPT_DIRECT_TOOL_NAMES, CHATGPT_SEARCH_TOOL_NAMES, resolveToolProfile } from "../catalog/toolCatalog.js";
9
+ import { readWatcherStatus } from "../../watcherStatus.js";
10
+ import { listTasks } from "../tasks/listTasks.js";
11
+ import { readLastAssessmentValidationFailure } from "../../assessments/assessmentDiagnostics.js";
11
12
  const SERVER_STARTED_AT = Date.now();
12
13
  export function healthCheck(catalog, input = {}) {
13
14
  const config = getConfig();
@@ -120,8 +121,23 @@ export function healthCheck(catalog, input = {}) {
120
121
  workspace_root: workspace,
121
122
  tasks_dir: tasks,
122
123
  tunnel,
124
+ config_path: agents.config_path,
125
+ runtime_build_layout: typeof watcher.supervisor?.runtime_build_layout === "string"
126
+ ? watcher.supervisor.runtime_build_layout
127
+ : null,
128
+ watcher_entry_path: typeof watcher.supervisor?.watcher_entry_path === "string"
129
+ ? watcher.supervisor.watcher_entry_path
130
+ : null,
131
+ validator_module_path: typeof watcher.supervisor?.validator_module_path === "string"
132
+ ? watcher.supervisor.validator_module_path
133
+ : null,
123
134
  agents: agents.agents,
124
135
  agent_status: Object.fromEntries(agents.agents.map((agent) => [agent.name, agent.available ? "ok" : "missing"])),
136
+ agent_readiness: Object.fromEntries(agents.agents.map((agent) => [agent.name, {
137
+ executable_available: agent.available,
138
+ provider_status: agent.provider_status,
139
+ availability_scope: agent.availability_scope,
140
+ }])),
125
141
  ...(input.detail === "self_diagnostic" ? { self_diagnostic: buildSelfDiagnostic(config) } : {}),
126
142
  last_error: tunnel.last_error || (!watcher.available ? watcher.reason : null) || mismatchReport[0] || null,
127
143
  };
@@ -129,7 +145,7 @@ export function healthCheck(catalog, input = {}) {
129
145
  function buildSelfDiagnostic(config) {
130
146
  const recent = listTasks({ limit: 20 });
131
147
  const failures = recent.tasks
132
- .filter((task) => task.status.startsWith("failed") || task.status === "canceled")
148
+ .filter((task) => task.status.startsWith("failed") || task.status === "canceled" || task.status === "timeout")
133
149
  .slice(0, 10)
134
150
  .map((task) => ({
135
151
  task_id: task.task_id,
@@ -145,6 +161,7 @@ function buildSelfDiagnostic(config) {
145
161
  configured_agents: Object.keys(config.agents),
146
162
  recent_tasks_returned: recent.tasks.length,
147
163
  recent_failures: failures,
164
+ last_assessment_validation_failure: readLastAssessmentValidationFailure(),
148
165
  };
149
166
  const safe = redactSensitiveValue(diagnostic);
150
167
  return {
@@ -171,6 +188,11 @@ function readWatcherSupervisorStatus() {
171
188
  restart_attempts: Number.isInteger(Number(raw.restart_attempts)) ? Number(raw.restart_attempts) : 0,
172
189
  last_error: safeText(raw.last_error, 500) || null,
173
190
  checked_at: safeText(raw.checked_at, 80) || null,
191
+ project_root: safeText(raw.project_root, 500) || null,
192
+ config_path: safeText(raw.config_path, 500) || null,
193
+ watcher_entry_path: safeText(raw.watcher_entry_path, 500) || null,
194
+ validator_module_path: safeText(raw.validator_module_path, 500) || null,
195
+ runtime_build_layout: safeText(raw.runtime_build_layout, 80) || null,
174
196
  };
175
197
  }
176
198
  catch {
@@ -239,6 +261,12 @@ function readTunnelStatus() {
239
261
  : [],
240
262
  tool_manifest_sha256: safeText(raw.tool_manifest_sha256, 80) || null,
241
263
  core_tools_ready: Boolean(raw.core_tools_ready),
264
+ project_root: safeText(raw.project_root, 500) || null,
265
+ config_path: safeText(raw.config_path, 500) || null,
266
+ mcp_entry_path: safeText(raw.mcp_entry_path, 500) || null,
267
+ watcher_entry_path: safeText(raw.watcher_entry_path, 500) || null,
268
+ validator_module_path: safeText(raw.validator_module_path, 500) || null,
269
+ runtime_build_layout: safeText(raw.runtime_build_layout, 80) || null,
242
270
  };
243
271
  const redacted = redactSensitiveContent(JSON.stringify(allowed));
244
272
  return JSON.parse(redacted.content);
@@ -0,0 +1,6 @@
1
+ export * from "./auditSession.js";
2
+ export * from "./auditTask.js";
3
+ export * from "./healthCheck.js";
4
+ export * from "./safeStatus.js";
5
+ export * from "./safeViews.js";
6
+ export * from "./schemaDriftCheck.js";
@@ -0,0 +1,6 @@
1
+ export * from "./auditSession.js";
2
+ export * from "./auditTask.js";
3
+ export * from "./healthCheck.js";
4
+ export * from "./safeStatus.js";
5
+ export * from "./safeViews.js";
6
+ export * from "./schemaDriftCheck.js";
@@ -1,6 +1,6 @@
1
- import { type PatchWardenConfig } from "../config.js";
2
- import type { TaskStatus, TaskPhase, AcceptanceStatus } from "./createTask.js";
3
- import { type DiagnosisType, type DiagnosisConfidence } from "./diagnoseTask.js";
1
+ import { type PatchWardenConfig } from "../../config.js";
2
+ import type { TaskStatus, TaskPhase, AcceptanceStatus } from "../tasks/createTask.js";
3
+ import { type DiagnosisType, type DiagnosisConfidence } from "../tasks/diagnoseTask.js";
4
4
  export interface SafeStatusOutput {
5
5
  task_id: string;
6
6
  status: TaskStatus | "not_found";
@@ -1,11 +1,11 @@
1
1
  import { readFileSync, existsSync } from "node:fs";
2
2
  import { resolve, join } from "node:path";
3
- import { getTasksDir, getConfig } from "../config.js";
4
- import { guardReadPath } from "../security/pathGuard.js";
5
- import { guardSensitivePath } from "../security/sensitiveGuard.js";
6
- import { readTaskRuntime } from "../taskRuntime.js";
7
- import { readWatcherStatus } from "../watcherStatus.js";
8
- import { diagnoseTask } from "./diagnoseTask.js";
3
+ import { getTasksDir, getConfig } from "../../config.js";
4
+ import { guardReadPath } from "../../security/pathGuard.js";
5
+ import { guardSensitivePath } from "../../security/sensitiveGuard.js";
6
+ import { readTaskRuntime } from "../../runner/taskRuntime.js";
7
+ import { readWatcherStatus } from "../../watcherStatus.js";
8
+ import { diagnoseTask } from "../tasks/diagnoseTask.js";
9
9
  export function safeStatus(taskId, config) {
10
10
  const cfg = config || getConfig();
11
11
  const tasksDir = getTasksDir(cfg);
@@ -2,6 +2,7 @@ export interface SafeViewOptions {
2
2
  max_items?: number;
3
3
  }
4
4
  export declare function safeResult(taskId: string, options?: SafeViewOptions): {
5
+ schema_version: string;
5
6
  task_id: string;
6
7
  status: string;
7
8
  terminal: boolean;
@@ -32,6 +33,7 @@ export declare function safeResult(taskId: string, options?: SafeViewOptions): {
32
33
  redaction_categories: string[];
33
34
  };
34
35
  export declare function safeTestSummary(taskId: string): {
36
+ schema_version: string;
35
37
  task_id: string;
36
38
  status: string;
37
39
  command_count: number;
@@ -41,19 +43,20 @@ export declare function safeTestSummary(taskId: string): {
41
43
  commands: {
42
44
  command: string;
43
45
  status: string;
44
- exit_code: any;
46
+ exit_code: {} | null;
45
47
  duration_ms: number;
46
48
  }[];
47
49
  headline: string;
48
50
  };
49
51
  export declare function safeDiffSummary(taskId: string, options?: SafeViewOptions): {
52
+ schema_version: string;
50
53
  task_id: string;
51
54
  changed_files_total: number;
52
55
  additions: number;
53
56
  deletions: number;
54
57
  diff_available: boolean;
55
58
  diff_truncated: boolean;
56
- patch_mode: any;
59
+ patch_mode: {} | null;
57
60
  files: {
58
61
  path: string;
59
62
  old_path: string | null;
@@ -62,13 +65,14 @@ export declare function safeDiffSummary(taskId: string, options?: SafeViewOption
62
65
  tracked: boolean;
63
66
  ignored: boolean;
64
67
  }[];
65
- artifact_hygiene_counts: Record<string, any>;
68
+ artifact_hygiene_counts: Record<string, unknown>;
66
69
  large_diff_omitted: boolean;
67
70
  truncated: boolean;
68
71
  };
69
72
  export declare function safeAudit(taskId: string, options?: SafeViewOptions): {
73
+ schema_version: string;
70
74
  task_id: string;
71
- verdict: "pass" | "warn" | "fail";
75
+ verdict: "warn" | "pass" | "fail";
72
76
  acceptance: {
73
77
  verdict: string;
74
78
  status: string;
@@ -84,17 +88,17 @@ export declare function safeAudit(taskId: string, options?: SafeViewOptions): {
84
88
  };
85
89
  checks: {
86
90
  name: string;
87
- result: "pass" | "warn" | "fail";
91
+ result: "warn" | "pass" | "fail";
88
92
  detail: string;
89
93
  }[];
90
94
  fail_checks: {
91
95
  name: string;
92
- result: "pass" | "warn" | "fail";
96
+ result: "warn" | "pass" | "fail";
93
97
  detail: string;
94
98
  }[];
95
99
  warn_checks: {
96
100
  name: string;
97
- result: "pass" | "warn" | "fail";
101
+ result: "warn" | "pass" | "fail";
98
102
  detail: string;
99
103
  }[];
100
104
  possible_false_positives: {
@@ -238,7 +242,7 @@ export declare function safeFinalizeDirectSession(sessionId: string, options?: S
238
242
  }>;
239
243
  export declare function safeAuditDirectSession(sessionId: string, options?: SafeViewOptions): {
240
244
  session_id: string;
241
- decision: "pass" | "warn" | "fail";
245
+ decision: "warn" | "pass" | "fail";
242
246
  reason_codes: string[];
243
247
  blocking_findings: string[];
244
248
  warnings: string[];
@@ -1,17 +1,19 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
- import { getConfig, getTasksDir } from "../config.js";
3
+ import { getConfig, getTasksDir } from "../../config.js";
4
4
  import { auditSession } from "./auditSession.js";
5
5
  import { auditTask } from "./auditTask.js";
6
- import { finalizeDirectSession } from "./finalizeDirectSession.js";
7
- import { getTaskSummary } from "./getTaskSummary.js";
8
- import { guardReadPath } from "../security/pathGuard.js";
9
- import { redactSensitiveValue } from "../security/contentRedaction.js";
10
- import { readDirectSession } from "../direct/directSessionStore.js";
6
+ import { finalizeDirectSession } from "../direct/finalizeDirectSession.js";
7
+ import { getTaskSummary } from "../tasks/getTaskSummary.js";
8
+ import { guardReadPath } from "../../security/pathGuard.js";
9
+ import { redactSensitiveValue } from "../../security/contentRedaction.js";
10
+ import { readDirectSession } from "../../direct/directSessionStore.js";
11
+ import { ARTIFACT_SCHEMA_VERSION } from "../../version.js";
11
12
  export function safeResult(taskId, options = {}) {
12
13
  const maxItems = normalizeMaxItems(options.max_items);
13
14
  const summary = getTaskSummary(taskId, { view: "compact", max_items: maxItems });
14
15
  return redact({
16
+ schema_version: ARTIFACT_SCHEMA_VERSION,
15
17
  task_id: summary.task_id,
16
18
  status: summary.status,
17
19
  terminal: summary.terminal,
@@ -39,13 +41,17 @@ export function safeTestSummary(taskId) {
39
41
  const { taskDir, config } = getTaskDir(taskId);
40
42
  const verify = readJson(join(taskDir, "verify.json"), config);
41
43
  const summary = getTaskSummary(taskId, { view: "compact", max_items: 8 });
42
- const commands = asArray(verify.commands).map((entry) => ({
43
- command: String(entry.command || ""),
44
- status: String(entry.status || "unknown"),
45
- exit_code: entry.exit_code ?? null,
46
- duration_ms: Number(entry.duration_ms || 0),
47
- }));
44
+ const commands = asArray(verify.commands).map((entry) => {
45
+ const command = asRecord(entry);
46
+ return {
47
+ command: String(command.command || ""),
48
+ status: String(command.status || "unknown"),
49
+ exit_code: command.exit_code ?? null,
50
+ duration_ms: Number(command.duration_ms || 0),
51
+ };
52
+ });
48
53
  return redact({
54
+ schema_version: ARTIFACT_SCHEMA_VERSION,
49
55
  task_id: taskId,
50
56
  status: String(verify.status || summary.verification_summary.status || "not_available"),
51
57
  command_count: commands.length,
@@ -63,6 +69,7 @@ export function safeDiffSummary(taskId, options = {}) {
63
69
  const changedFiles = asArray(changes.changed_files);
64
70
  const hygiene = asRecord(changes.artifact_hygiene);
65
71
  return redact({
72
+ schema_version: ARTIFACT_SCHEMA_VERSION,
66
73
  task_id: taskId,
67
74
  changed_files_total: changedFiles.length,
68
75
  additions: Number(changes.additions || 0),
@@ -128,6 +135,7 @@ function auditToSafe(audit, maxItems) {
128
135
  detail: truncate(check.detail, 240),
129
136
  }));
130
137
  return redact({
138
+ schema_version: ARTIFACT_SCHEMA_VERSION,
131
139
  task_id: audit.task_id,
132
140
  verdict: audit.verdict,
133
141
  acceptance: {
@@ -239,7 +247,9 @@ function asArray(value) {
239
247
  return Array.isArray(value) ? value : [];
240
248
  }
241
249
  function asRecord(value) {
242
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
250
+ return value && typeof value === "object" && !Array.isArray(value)
251
+ ? value
252
+ : {};
243
253
  }
244
254
  function limitStrings(values, maxItems) {
245
255
  return values.slice(0, maxItems).map((value) => truncate(value, 240));
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * 本模块只做检测和报告,不做运行时阻断。
8
8
  */
9
- import type { PatchWardenToolMeta } from "./toolRegistry.js";
9
+ import type { PatchWardenToolMeta } from "../catalog/toolRegistry.js";
10
10
  export interface SchemaDriftResult {
11
11
  /** true 表示无 drift,false 表示有 drift */
12
12
  ok: boolean;