patchwarden 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PatchWarden.cmd +32 -2
- package/README.en.md +194 -26
- package/README.md +160 -22
- package/dist/assessments/agentAssessor.d.ts +1 -1
- package/dist/assessments/agentAssessor.js +24 -15
- package/dist/assessments/assessmentStore.d.ts +1 -1
- package/dist/assessments/assessmentStore.js +44 -36
- package/dist/assessments/confirmCli.js +5 -4
- package/dist/config.d.ts +22 -0
- package/dist/config.js +98 -11
- package/dist/control/fileManager.d.ts +2 -0
- package/dist/control/fileManager.js +39 -0
- package/dist/control/middleware/auth.d.ts +16 -0
- package/dist/control/middleware/auth.js +17 -0
- package/dist/control/middleware/static.d.ts +3 -0
- package/dist/control/middleware/static.js +78 -0
- package/dist/control/routeTable.d.ts +24 -0
- package/dist/control/routeTable.js +263 -0
- package/dist/control/routes/audit.d.ts +15 -0
- package/dist/control/routes/audit.js +287 -0
- package/dist/control/routes/evidence.d.ts +4 -0
- package/dist/control/routes/evidence.js +96 -0
- package/dist/control/routes/lineage.d.ts +3 -0
- package/dist/control/routes/lineage.js +71 -0
- package/dist/control/routes/policy.d.ts +3 -0
- package/dist/control/routes/policy.js +81 -0
- package/dist/control/routes/process.d.ts +12 -0
- package/dist/control/routes/process.js +487 -0
- package/dist/control/routes/sessions.d.ts +30 -0
- package/dist/control/routes/sessions.js +287 -0
- package/dist/control/routes/status.d.ts +51 -0
- package/dist/control/routes/status.js +307 -0
- package/dist/control/routes/taskActions.d.ts +21 -0
- package/dist/control/routes/taskActions.js +197 -0
- package/dist/control/routes/tasks.d.ts +24 -0
- package/dist/control/routes/tasks.js +309 -0
- package/dist/control/routes/workspace.d.ts +15 -0
- package/dist/control/routes/workspace.js +220 -0
- package/dist/control/runtime.d.ts +92 -0
- package/dist/control/runtime.js +425 -0
- package/dist/control/server.d.ts +13 -0
- package/dist/control/server.js +150 -0
- package/dist/control/shared.d.ts +59 -0
- package/dist/control/shared.js +341 -0
- package/dist/controlCenter.d.ts +6 -0
- package/dist/controlCenter.js +7 -2197
- package/dist/direct/directAudit.js +234 -225
- package/dist/direct/directGuards.d.ts +2 -1
- package/dist/direct/directGuards.js +72 -37
- package/dist/direct/directPatch.d.ts +6 -1
- package/dist/direct/directPatch.js +55 -8
- package/dist/direct/directSessionStore.d.ts +16 -6
- package/dist/direct/directSessionStore.js +127 -35
- package/dist/direct/directVerification.js +8 -16
- package/dist/doctor.d.ts +18 -1
- package/dist/doctor.js +614 -373
- package/dist/goal/acceptanceEngine.d.ts +1 -1
- package/dist/goal/goalProgress.js +75 -69
- package/dist/goal/goalReport.d.ts +54 -0
- package/dist/goal/goalReport.js +197 -0
- package/dist/goal/goalStatus.d.ts +8 -0
- package/dist/goal/goalStatus.js +10 -3
- package/dist/goal/goalStore.d.ts +9 -2
- package/dist/goal/goalStore.js +152 -45
- package/dist/goal/handoffExport.js +6 -6
- package/dist/goal/specKitImport.d.ts +63 -0
- package/dist/goal/specKitImport.js +221 -0
- package/dist/goal/subgoalSync.js +13 -10
- package/dist/goal/worktreeManager.d.ts +2 -0
- package/dist/goal/worktreeManager.js +209 -136
- package/dist/httpServer.js +126 -44
- package/dist/index.js +7 -4
- package/dist/logging.d.ts +7 -1
- package/dist/logging.js +13 -3
- package/dist/policy/projectPolicy.js +5 -2
- package/dist/release/releaseGate.d.ts +1 -1
- package/dist/release/releaseGate.js +78 -25
- package/dist/runner/agentInvocation.d.ts +14 -0
- package/dist/runner/agentInvocation.js +96 -4
- package/dist/runner/changeCapture.d.ts +14 -6
- package/dist/runner/changeCapture.js +287 -81
- package/dist/runner/cli.js +7 -6
- package/dist/runner/postTaskCleanup.js +60 -7
- package/dist/runner/processSecurity.d.ts +56 -0
- package/dist/runner/processSecurity.js +373 -0
- package/dist/runner/runTask.d.ts +1 -1
- package/dist/runner/runTask.js +339 -287
- package/dist/runner/simpleProcess.d.ts +3 -0
- package/dist/runner/simpleProcess.js +52 -38
- package/dist/{taskProgress.d.ts → runner/taskProgress.d.ts} +1 -1
- package/dist/{taskProgress.js → runner/taskProgress.js} +2 -2
- package/dist/{taskRuntime.d.ts → runner/taskRuntime.d.ts} +1 -1
- package/dist/{taskRuntime.js → runner/taskRuntime.js} +3 -2
- package/dist/runner/taskStatusStore.d.ts +11 -0
- package/dist/runner/taskStatusStore.js +24 -0
- package/dist/runner/watch.d.ts +14 -1
- package/dist/runner/watch.js +265 -54
- package/dist/security/contentRedaction.d.ts +6 -0
- package/dist/security/contentRedaction.js +24 -2
- package/dist/security/discoveryTokenStore.d.ts +3 -2
- package/dist/security/discoveryTokenStore.js +17 -2
- package/dist/security/loopbackHost.d.ts +2 -0
- package/dist/security/loopbackHost.js +16 -0
- package/dist/security/pathGuard.js +32 -17
- package/dist/security/planGuard.js +2 -1
- package/dist/security/runtimeGuard.js +9 -6
- package/dist/security/secretComparison.d.ts +3 -0
- package/dist/security/secretComparison.js +11 -0
- package/dist/security/sensitiveGuard.d.ts +5 -0
- package/dist/security/sensitiveGuard.js +27 -8
- package/dist/security/toolInvocationGuard.d.ts +2 -2
- package/dist/security/toolInvocationGuard.js +1 -1
- package/dist/security/workspaceRootGuard.d.ts +8 -0
- package/dist/security/workspaceRootGuard.js +47 -0
- package/dist/smoke-test.js +280 -273
- package/dist/tools/catalog/index.d.ts +4 -0
- package/dist/tools/catalog/index.js +4 -0
- package/dist/tools/{toolCatalog.js → catalog/toolCatalog.js} +3 -12
- package/dist/tools/{toolRegistry.d.ts → catalog/toolRegistry.d.ts} +3 -3
- package/dist/tools/{toolRegistry.js → catalog/toolRegistry.js} +28 -15
- package/dist/tools/definitions/toolDefs.d.ts +18 -0
- package/dist/tools/definitions/toolDefs.js +1177 -0
- package/dist/tools/{auditSession.d.ts → diagnostics/auditSession.d.ts} +1 -1
- package/dist/tools/{auditSession.js → diagnostics/auditSession.js} +2 -2
- package/dist/tools/{auditTask.d.ts → diagnostics/auditTask.d.ts} +8 -63
- package/dist/tools/{auditTask.js → diagnostics/auditTask.js} +111 -37
- package/dist/tools/{healthCheck.d.ts → diagnostics/healthCheck.d.ts} +6 -6
- package/dist/tools/{healthCheck.js → diagnostics/healthCheck.js} +10 -10
- package/dist/tools/diagnostics/index.d.ts +6 -0
- package/dist/tools/diagnostics/index.js +6 -0
- package/dist/tools/{safeStatus.d.ts → diagnostics/safeStatus.d.ts} +3 -3
- package/dist/tools/{safeStatus.js → diagnostics/safeStatus.js} +6 -6
- package/dist/tools/{safeViews.d.ts → diagnostics/safeViews.d.ts} +14 -10
- package/dist/tools/{safeViews.js → diagnostics/safeViews.js} +25 -15
- package/dist/tools/{schemaDriftCheck.d.ts → diagnostics/schemaDriftCheck.d.ts} +1 -1
- package/dist/tools/{schemaDriftCheck.js → diagnostics/schemaDriftCheck.js} +2 -2
- package/dist/tools/{createDirectSession.d.ts → direct/createDirectSession.d.ts} +1 -1
- package/dist/tools/{createDirectSession.js → direct/createDirectSession.js} +8 -8
- package/dist/tools/{finalizeDirectSession.d.ts → direct/finalizeDirectSession.d.ts} +2 -2
- package/dist/tools/direct/finalizeDirectSession.js +86 -0
- package/dist/tools/direct/index.d.ts +3 -0
- package/dist/tools/direct/index.js +3 -0
- package/dist/tools/{runDirectVerificationBundle.js → direct/runDirectVerificationBundle.js} +2 -2
- package/dist/tools/{discoverTools.d.ts → discovery/discoverTools.d.ts} +2 -2
- package/dist/tools/{discoverTools.js → discovery/discoverTools.js} +5 -5
- package/dist/tools/{explainTool.d.ts → discovery/explainTool.d.ts} +2 -2
- package/dist/tools/{explainTool.js → discovery/explainTool.js} +2 -2
- package/dist/tools/discovery/index.d.ts +3 -0
- package/dist/tools/discovery/index.js +3 -0
- package/dist/tools/{invokeDiscoveredTool.d.ts → discovery/invokeDiscoveredTool.d.ts} +2 -2
- package/dist/tools/{invokeDiscoveredTool.js → discovery/invokeDiscoveredTool.js} +5 -5
- package/dist/tools/dispatch/coreDispatch.d.ts +9 -0
- package/dist/tools/dispatch/coreDispatch.js +283 -0
- package/dist/tools/dispatch/diagnosticDispatch.d.ts +12 -0
- package/dist/tools/dispatch/diagnosticDispatch.js +80 -0
- package/dist/tools/dispatch/directDispatch.d.ts +8 -0
- package/dist/tools/dispatch/directDispatch.js +116 -0
- package/dist/tools/dispatch/goalDispatch.d.ts +8 -0
- package/dist/tools/dispatch/goalDispatch.js +92 -0
- package/dist/tools/dispatch/releaseDispatch.d.ts +8 -0
- package/dist/tools/dispatch/releaseDispatch.js +46 -0
- package/dist/tools/dispatch/types.d.ts +23 -0
- package/dist/tools/dispatch/types.js +15 -0
- package/dist/tools/dispatch/validation.d.ts +7 -0
- package/dist/tools/dispatch/validation.js +71 -0
- package/dist/tools/{getPlan.js → goals/getPlan.js} +4 -4
- package/dist/tools/{goalSubgoalTask.d.ts → goals/goalSubgoalTask.d.ts} +2 -2
- package/dist/tools/goals/goalSubgoalTask.js +118 -0
- package/dist/tools/goals/index.d.ts +3 -0
- package/dist/tools/goals/index.js +3 -0
- package/dist/tools/{savePlan.js → goals/savePlan.js} +28 -8
- package/dist/tools/registry.d.ts +10 -14
- package/dist/tools/registry.js +47 -1651
- package/dist/tools/{checkReleaseGate.d.ts → release/checkReleaseGate.d.ts} +1 -1
- package/dist/tools/{checkReleaseGate.js → release/checkReleaseGate.js} +3 -3
- package/dist/tools/release/index.d.ts +2 -0
- package/dist/tools/release/index.js +2 -0
- package/dist/tools/{releaseMode.d.ts → release/releaseMode.d.ts} +2 -2
- package/dist/tools/{releaseMode.js → release/releaseMode.js} +46 -26
- package/dist/tools/tasks/cancelTask.d.ts +11 -0
- package/dist/tools/tasks/cancelTask.js +85 -0
- package/dist/tools/{createTask.d.ts → tasks/createTask.d.ts} +12 -4
- package/dist/tools/{createTask.js → tasks/createTask.js} +46 -31
- package/dist/tools/{diagnoseTask.d.ts → tasks/diagnoseTask.d.ts} +1 -1
- package/dist/tools/{diagnoseTask.js → tasks/diagnoseTask.js} +8 -8
- package/dist/tools/{evidencePack.d.ts → tasks/evidencePack.d.ts} +6 -0
- package/dist/tools/tasks/evidencePack.js +387 -0
- package/dist/tools/{getTaskFile.js → tasks/getTaskFile.js} +4 -4
- package/dist/tools/{getTaskStatus.d.ts → tasks/getTaskStatus.d.ts} +6 -1
- package/dist/tools/{getTaskStatus.js → tasks/getTaskStatus.js} +5 -5
- package/dist/tools/{getTaskStdoutTail.js → tasks/getTaskStdoutTail.js} +13 -11
- package/dist/tools/{getTaskSummary.js → tasks/getTaskSummary.js} +33 -26
- package/dist/tools/tasks/index.d.ts +18 -0
- package/dist/tools/tasks/index.js +18 -0
- package/dist/tools/tasks/killTask.d.ts +1 -0
- package/dist/tools/{listTasks.d.ts → tasks/listTasks.d.ts} +1 -1
- package/dist/tools/{listTasks.js → tasks/listTasks.js} +3 -3
- package/dist/tools/{reconcileTasks.d.ts → tasks/reconcileTasks.d.ts} +1 -1
- package/dist/tools/{reconcileTasks.js → tasks/reconcileTasks.js} +64 -66
- package/dist/tools/{retryTask.d.ts → tasks/retryTask.d.ts} +2 -2
- package/dist/tools/tasks/retryTask.js +60 -0
- package/dist/tools/{runTaskLoop.d.ts → tasks/runTaskLoop.d.ts} +6 -6
- package/dist/tools/{runTaskLoop.js → tasks/runTaskLoop.js} +59 -31
- package/dist/tools/tasks/runVerification.js +38 -0
- package/dist/tools/{taskLineage.js → tasks/taskLineage.js} +8 -7
- package/dist/tools/{taskOutputs.js → tasks/taskOutputs.js} +17 -16
- package/dist/tools/{androidDoctor.js → workspace/androidDoctor.js} +16 -10
- package/dist/tools/{applyPatch.d.ts → workspace/applyPatch.d.ts} +1 -1
- package/dist/tools/workspace/applyPatch.js +53 -0
- package/dist/tools/{discardWorktree.js → workspace/discardWorktree.js} +3 -3
- package/dist/tools/workspace/index.d.ts +10 -0
- package/dist/tools/workspace/index.js +10 -0
- package/dist/tools/{listAgents.d.ts → workspace/listAgents.d.ts} +5 -0
- package/dist/tools/{listAgents.js → workspace/listAgents.js} +8 -4
- package/dist/tools/{listWorkspace.js → workspace/listWorkspace.js} +3 -3
- package/dist/tools/{mergeWorktree.js → workspace/mergeWorktree.js} +3 -3
- package/dist/tools/{readWorkspaceFile.js → workspace/readWorkspaceFile.js} +8 -8
- package/dist/tools/{recommendAgentForTask.js → workspace/recommendAgentForTask.js} +3 -3
- package/dist/tools/{searchWorkspace.js → workspace/searchWorkspace.js} +5 -5
- package/dist/tools/{syncFile.d.ts → workspace/syncFile.d.ts} +1 -1
- package/dist/tools/workspace/syncFile.js +134 -0
- package/dist/utils/atomicFile.d.ts +7 -0
- package/dist/utils/atomicFile.js +48 -0
- package/dist/utils/boundedFile.d.ts +8 -0
- package/dist/utils/boundedFile.js +93 -0
- package/dist/utils/lockedJsonFile.d.ts +15 -0
- package/dist/utils/lockedJsonFile.js +224 -0
- package/dist/utils/platform.d.ts +11 -0
- package/dist/utils/platform.js +26 -0
- package/dist/utils/stableJson.d.ts +2 -0
- package/dist/utils/stableJson.js +12 -0
- package/dist/version.d.ts +3 -2
- package/dist/version.js +3 -2
- package/dist/watcherStatus.d.ts +2 -2
- package/dist/watcherStatus.js +18 -0
- package/docs/CODE_WIKI.md +1648 -0
- package/docs/agentseal-integration.md +150 -0
- package/docs/architecture.md +23 -0
- package/docs/assets/patchwarden-desktop-onboarding.png +0 -0
- package/docs/assets/patchwarden-oss-demo.gif +0 -0
- package/docs/control-center/README.md +4 -4
- package/docs/dashboard-overview.md +86 -0
- package/docs/demo.md +8 -0
- package/docs/desktop-app.md +175 -0
- package/docs/direct-session-workflow.md +98 -0
- package/docs/evidence-pack-schema.md +215 -0
- package/docs/lineage-evidence-pack-workflow.md +127 -0
- package/docs/mcp-inspector-testing.md +200 -0
- package/docs/open-source-application.md +168 -0
- package/docs/opencode-worker.md +151 -0
- package/docs/openhands-worker.md +181 -0
- package/docs/release-checklist.md +1 -1
- package/docs/release-evidence.md +82 -0
- package/docs/spec-kit-integration.md +131 -0
- package/docs/task-safe-review-workflow.md +98 -0
- package/docs/threat-model.md +97 -0
- package/docs/user-feedback.md +40 -0
- package/docs/why-patchwarden.md +110 -0
- package/examples/config.example.json +4 -2
- package/package.json +28 -11
- package/scripts/README.md +15 -6
- package/scripts/build.js +11 -0
- package/scripts/checks/brand-check.js +3 -0
- package/scripts/checks/build-output-check.js +37 -0
- package/scripts/checks/control-center-smoke.js +447 -6
- package/scripts/checks/control-smoke.js +19 -8
- package/scripts/checks/http-mcp-smoke.js +82 -4
- package/scripts/checks/lifecycle-smoke.js +39 -33
- package/scripts/checks/mcp-manifest-check.js +1 -1
- package/scripts/checks/mcp-smoke.js +30 -4
- package/scripts/checks/package-manifest-check.js +20 -7
- package/scripts/checks/unit-tests.js +3 -5
- package/scripts/checks/watcher-supervisor-smoke.js +9 -0
- package/scripts/control/get-patchwarden-health.ps1 +1 -1
- package/scripts/control/manage-patchwarden.ps1 +69 -4
- package/scripts/control/provision-patchwarden-tunnel.ps1 +127 -0
- package/scripts/control/run-background-supervisor.ps1 +41 -0
- package/scripts/control/start-patchwarden-tunnel.ps1 +126 -32
- package/scripts/generate-demo-gif.py +320 -0
- package/{PatchWarden-Control-Tray.cmd → scripts/launchers/PatchWarden-Control-Tray.cmd} +3 -3
- package/scripts/launchers/PatchWarden-Control.cmd +6 -0
- package/{PatchWarden-Desktop.cmd → scripts/launchers/PatchWarden-Desktop.cmd} +2 -2
- package/scripts/launchers/Restart-PatchWarden-Control.cmd +6 -0
- package/{Stop-PatchWarden.cmd → scripts/launchers/Stop-PatchWarden.cmd} +2 -2
- package/scripts/lib/clean-generated-output.js +11 -0
- package/scripts/lib/file-discovery.js +12 -0
- package/scripts/release/desktop-preflight.js +211 -0
- package/scripts/release/pack-clean.js +59 -14
- package/src/assessments/agentAssessor.ts +29 -15
- package/src/assessments/assessmentStore.ts +55 -43
- package/src/assessments/confirmCli.ts +5 -4
- package/src/config.ts +105 -11
- package/src/control/fileManager.ts +40 -0
- package/src/control/middleware/auth.ts +35 -0
- package/src/control/middleware/static.ts +84 -0
- package/src/control/routeTable.ts +301 -0
- package/src/control/routes/audit.ts +329 -0
- package/src/control/routes/evidence.ts +107 -0
- package/src/control/routes/lineage.ts +92 -0
- package/src/control/routes/policy.ts +81 -0
- package/src/control/routes/process.ts +505 -0
- package/src/control/routes/sessions.ts +314 -0
- package/src/control/routes/status.ts +405 -0
- package/src/control/routes/taskActions.ts +214 -0
- package/src/control/routes/tasks.ts +331 -0
- package/src/control/routes/workspace.ts +234 -0
- package/src/control/runtime.ts +508 -0
- package/src/control/server.ts +165 -0
- package/src/control/shared.ts +360 -0
- package/src/controlCenter.ts +7 -2347
- package/src/direct/directAudit.ts +17 -9
- package/src/direct/directGuards.ts +100 -51
- package/src/direct/directPatch.ts +95 -8
- package/src/direct/directSessionStore.ts +211 -55
- package/src/direct/directVerification.ts +9 -23
- package/src/doctor.ts +766 -492
- package/src/goal/acceptanceEngine.ts +1 -1
- package/src/goal/goalProgress.ts +17 -13
- package/src/goal/goalReport.ts +263 -0
- package/src/goal/goalStatus.ts +25 -3
- package/src/goal/goalStore.ts +241 -54
- package/src/goal/handoffExport.ts +6 -6
- package/src/goal/specKitImport.ts +355 -0
- package/src/goal/subgoalSync.ts +15 -10
- package/src/goal/worktreeManager.ts +139 -22
- package/src/httpServer.ts +130 -44
- package/src/index.ts +7 -4
- package/src/logging.ts +20 -4
- package/src/policy/projectPolicy.ts +5 -2
- package/src/release/releaseGate.ts +74 -27
- package/src/runner/agentInvocation.ts +126 -4
- package/src/runner/changeCapture.ts +342 -80
- package/src/runner/cli.ts +7 -6
- package/src/runner/postTaskCleanup.ts +55 -7
- package/src/runner/processSecurity.ts +433 -0
- package/src/runner/runTask.ts +441 -292
- package/src/runner/simpleProcess.ts +68 -33
- package/src/{taskProgress.ts → runner/taskProgress.ts} +3 -3
- package/src/{taskRuntime.ts → runner/taskRuntime.ts} +4 -3
- package/src/runner/taskStatusStore.ts +54 -0
- package/src/runner/watch.ts +290 -57
- package/src/security/contentRedaction.ts +31 -2
- package/src/security/discoveryTokenStore.ts +18 -4
- package/src/security/loopbackHost.ts +19 -0
- package/src/security/pathGuard.ts +35 -16
- package/src/security/planGuard.ts +2 -1
- package/src/security/runtimeGuard.ts +9 -6
- package/src/security/secretComparison.ts +13 -0
- package/src/security/sensitiveGuard.ts +27 -8
- package/src/security/toolInvocationGuard.ts +2 -2
- package/src/security/workspaceRootGuard.ts +53 -0
- package/src/smoke-test.ts +276 -273
- package/src/tools/catalog/index.ts +4 -0
- package/src/tools/{toolCatalog.ts → catalog/toolCatalog.ts} +3 -12
- package/src/tools/{toolRegistry.ts → catalog/toolRegistry.ts} +29 -16
- package/src/tools/definitions/toolDefs.ts +1264 -0
- package/src/tools/{auditSession.ts → diagnostics/auditSession.ts} +2 -2
- package/src/tools/{auditTask.ts → diagnostics/auditTask.ts} +196 -89
- package/src/tools/{healthCheck.ts → diagnostics/healthCheck.ts} +11 -11
- package/src/tools/diagnostics/index.ts +6 -0
- package/src/tools/{safeStatus.ts → diagnostics/safeStatus.ts} +7 -7
- package/src/tools/{safeViews.ts → diagnostics/safeViews.ts} +29 -19
- package/src/tools/{schemaDriftCheck.ts → diagnostics/schemaDriftCheck.ts} +3 -3
- package/src/tools/{createDirectSession.ts → direct/createDirectSession.ts} +9 -9
- package/src/tools/{finalizeDirectSession.ts → direct/finalizeDirectSession.ts} +11 -9
- package/src/tools/direct/index.ts +3 -0
- package/src/tools/{runDirectVerificationBundle.ts → direct/runDirectVerificationBundle.ts} +2 -2
- package/src/tools/{discoverTools.ts → discovery/discoverTools.ts} +6 -6
- package/src/tools/{explainTool.ts → discovery/explainTool.ts} +3 -3
- package/src/tools/discovery/index.ts +3 -0
- package/src/tools/{invokeDiscoveredTool.ts → discovery/invokeDiscoveredTool.ts} +7 -7
- package/src/tools/dispatch/coreDispatch.ts +379 -0
- package/src/tools/dispatch/diagnosticDispatch.ts +106 -0
- package/src/tools/dispatch/directDispatch.ts +168 -0
- package/src/tools/dispatch/goalDispatch.ts +128 -0
- package/src/tools/dispatch/releaseDispatch.ts +66 -0
- package/src/tools/dispatch/types.ts +24 -0
- package/src/tools/dispatch/validation.ts +78 -0
- package/src/tools/{getPlan.ts → goals/getPlan.ts} +4 -4
- package/src/tools/{goalSubgoalTask.ts → goals/goalSubgoalTask.ts} +43 -28
- package/src/tools/goals/index.ts +3 -0
- package/src/tools/{savePlan.ts → goals/savePlan.ts} +38 -8
- package/src/tools/registry.ts +54 -1858
- package/src/tools/{checkReleaseGate.ts → release/checkReleaseGate.ts} +3 -3
- package/src/tools/release/index.ts +2 -0
- package/src/tools/{releaseMode.ts → release/releaseMode.ts} +42 -24
- package/src/tools/tasks/cancelTask.ts +109 -0
- package/src/tools/{createTask.ts → tasks/createTask.ts} +56 -33
- package/src/tools/{diagnoseTask.ts → tasks/diagnoseTask.ts} +8 -8
- package/src/tools/tasks/evidencePack.ts +504 -0
- package/src/tools/{getTaskFile.ts → tasks/getTaskFile.ts} +4 -4
- package/src/tools/{getTaskStatus.ts → tasks/getTaskStatus.ts} +7 -5
- package/src/tools/{getTaskStdoutTail.ts → tasks/getTaskStdoutTail.ts} +13 -11
- package/src/tools/{getTaskSummary.ts → tasks/getTaskSummary.ts} +44 -33
- package/src/tools/tasks/index.ts +18 -0
- package/src/tools/{listTasks.ts → tasks/listTasks.ts} +4 -4
- package/src/tools/{reconcileTasks.ts → tasks/reconcileTasks.ts} +68 -66
- package/src/tools/tasks/retryTask.ts +69 -0
- package/src/tools/{runTaskLoop.ts → tasks/runTaskLoop.ts} +70 -35
- package/src/tools/{runVerification.ts → tasks/runVerification.ts} +6 -3
- package/src/tools/{taskLineage.ts → tasks/taskLineage.ts} +8 -7
- package/src/tools/{taskOutputs.ts → tasks/taskOutputs.ts} +27 -20
- package/src/tools/{androidDoctor.ts → workspace/androidDoctor.ts} +15 -10
- package/src/tools/{applyPatch.ts → workspace/applyPatch.ts} +38 -16
- package/src/tools/{discardWorktree.ts → workspace/discardWorktree.ts} +3 -3
- package/src/tools/workspace/index.ts +10 -0
- package/src/tools/{listAgents.ts → workspace/listAgents.ts} +11 -4
- package/src/tools/{listWorkspace.ts → workspace/listWorkspace.ts} +3 -3
- package/src/tools/{mergeWorktree.ts → workspace/mergeWorktree.ts} +3 -3
- package/src/tools/{readWorkspaceFile.ts → workspace/readWorkspaceFile.ts} +8 -8
- package/src/tools/{recommendAgentForTask.ts → workspace/recommendAgentForTask.ts} +3 -3
- package/src/tools/{searchWorkspace.ts → workspace/searchWorkspace.ts} +5 -5
- package/src/tools/workspace/syncFile.ts +292 -0
- package/src/utils/atomicFile.ts +58 -0
- package/src/utils/boundedFile.ts +116 -0
- package/src/utils/lockedJsonFile.ts +251 -0
- package/src/utils/platform.ts +31 -0
- package/src/utils/stableJson.ts +12 -0
- package/src/version.ts +3 -2
- package/src/watcherStatus.ts +19 -1
- package/ui/desktop-bootstrap.js +11 -0
- package/ui/desktop-bridge.js +36 -0
- package/ui/desktop.css +160 -0
- package/ui/getting-started.js +93 -0
- package/ui/i18n.js +484 -0
- package/ui/log-parser.js +30 -0
- package/ui/pages/audit.html +204 -3
- package/ui/pages/dashboard.html +937 -79
- package/ui/pages/direct-sessions.html +609 -60
- package/ui/pages/getting-started.html +43 -0
- package/ui/pages/logs.html +105 -22
- package/ui/pages/settings.html +101 -0
- package/ui/pages/task-detail.html +468 -438
- package/ui/pages/tasks.html +648 -65
- package/ui/pages/workspace.html +38 -1
- package/ui/settings.js +245 -0
- package/PatchWarden-Control.cmd +0 -6
- package/Restart-PatchWarden-Control.cmd +0 -6
- package/dist/test/unit/acceptance-engine.test.d.ts +0 -1
- package/dist/test/unit/acceptance-engine.test.js +0 -228
- package/dist/test/unit/agent-router.test.d.ts +0 -1
- package/dist/test/unit/agent-router.test.js +0 -287
- package/dist/test/unit/android-doctor.test.d.ts +0 -1
- package/dist/test/unit/android-doctor.test.js +0 -118
- package/dist/test/unit/audit-checks.test.d.ts +0 -1
- package/dist/test/unit/audit-checks.test.js +0 -350
- package/dist/test/unit/chinese-path.test.d.ts +0 -1
- package/dist/test/unit/chinese-path.test.js +0 -91
- package/dist/test/unit/command-guard.test.d.ts +0 -1
- package/dist/test/unit/command-guard.test.js +0 -160
- package/dist/test/unit/diagnose-task.test.d.ts +0 -1
- package/dist/test/unit/diagnose-task.test.js +0 -457
- package/dist/test/unit/direct-guards.test.d.ts +0 -1
- package/dist/test/unit/direct-guards.test.js +0 -213
- package/dist/test/unit/discovery-token-store.test.d.ts +0 -1
- package/dist/test/unit/discovery-token-store.test.js +0 -139
- package/dist/test/unit/evidence-pack.test.d.ts +0 -1
- package/dist/test/unit/evidence-pack.test.js +0 -130
- package/dist/test/unit/goal-graph.test.d.ts +0 -1
- package/dist/test/unit/goal-graph.test.js +0 -298
- package/dist/test/unit/goal-progress.test.d.ts +0 -1
- package/dist/test/unit/goal-progress.test.js +0 -381
- package/dist/test/unit/goal-status.test.d.ts +0 -1
- package/dist/test/unit/goal-status.test.js +0 -215
- package/dist/test/unit/goal-store.test.d.ts +0 -1
- package/dist/test/unit/goal-store.test.js +0 -253
- package/dist/test/unit/goal-subgoal-task.test.d.ts +0 -1
- package/dist/test/unit/goal-subgoal-task.test.js +0 -55
- package/dist/test/unit/goal-tools-registry.test.d.ts +0 -1
- package/dist/test/unit/goal-tools-registry.test.js +0 -190
- package/dist/test/unit/handoff-export.test.d.ts +0 -1
- package/dist/test/unit/handoff-export.test.js +0 -263
- package/dist/test/unit/invoke-discovered-tool.test.d.ts +0 -1
- package/dist/test/unit/invoke-discovered-tool.test.js +0 -167
- package/dist/test/unit/logging.test.d.ts +0 -1
- package/dist/test/unit/logging.test.js +0 -397
- package/dist/test/unit/path-guard.test.d.ts +0 -1
- package/dist/test/unit/path-guard.test.js +0 -109
- package/dist/test/unit/post-task-cleanup.test.d.ts +0 -1
- package/dist/test/unit/post-task-cleanup.test.js +0 -48
- package/dist/test/unit/project-policy-release-mode.test.d.ts +0 -1
- package/dist/test/unit/project-policy-release-mode.test.js +0 -125
- package/dist/test/unit/reconcile-tasks.test.d.ts +0 -1
- package/dist/test/unit/reconcile-tasks.test.js +0 -456
- package/dist/test/unit/release-gate.test.d.ts +0 -1
- package/dist/test/unit/release-gate.test.js +0 -242
- package/dist/test/unit/run-task-loop.test.d.ts +0 -1
- package/dist/test/unit/run-task-loop.test.js +0 -380
- package/dist/test/unit/safe-status.test.d.ts +0 -1
- package/dist/test/unit/safe-status.test.js +0 -165
- package/dist/test/unit/safe-views.test.d.ts +0 -1
- package/dist/test/unit/safe-views.test.js +0 -171
- package/dist/test/unit/schema-drift-check.test.d.ts +0 -1
- package/dist/test/unit/schema-drift-check.test.js +0 -176
- package/dist/test/unit/sensitive-guard.test.d.ts +0 -1
- package/dist/test/unit/sensitive-guard.test.js +0 -104
- package/dist/test/unit/subgoal-sync.test.d.ts +0 -1
- package/dist/test/unit/subgoal-sync.test.js +0 -183
- package/dist/test/unit/sync-file.test.d.ts +0 -1
- package/dist/test/unit/sync-file.test.js +0 -154
- package/dist/test/unit/tool-invocation-guard.test.d.ts +0 -1
- package/dist/test/unit/tool-invocation-guard.test.js +0 -432
- package/dist/test/unit/tool-usage-stats.test.d.ts +0 -1
- package/dist/test/unit/tool-usage-stats.test.js +0 -300
- package/dist/test/unit/toolSearch.test.d.ts +0 -1
- package/dist/test/unit/toolSearch.test.js +0 -571
- package/dist/test/unit/watcher-status.test.d.ts +0 -1
- package/dist/test/unit/watcher-status.test.js +0 -169
- package/dist/test/unit/worktree-manager.test.d.ts +0 -1
- package/dist/test/unit/worktree-manager.test.js +0 -176
- package/dist/tools/applyPatch.js +0 -41
- package/dist/tools/cancelTask.d.ts +0 -30
- package/dist/tools/cancelTask.js +0 -64
- package/dist/tools/evidencePack.js +0 -168
- package/dist/tools/finalizeDirectSession.js +0 -84
- package/dist/tools/goalSubgoalTask.js +0 -110
- package/dist/tools/killTask.d.ts +0 -15
- package/dist/tools/retryTask.js +0 -45
- package/dist/tools/runVerification.js +0 -36
- package/dist/tools/syncFile.js +0 -65
- package/docs/control-center/control-center-daily-driver.md +0 -211
- package/docs/control-center/control-center-mvp.md +0 -205
- package/docs/control-center/control-center-phase2.md +0 -159
- package/docs/release-v0.6.0.md +0 -71
- package/docs/release-v0.6.1.md +0 -75
- package/docs/release-v0.6.4.md +0 -45
- package/src/test/unit/acceptance-engine.test.ts +0 -261
- package/src/test/unit/agent-router.test.ts +0 -342
- package/src/test/unit/android-doctor.test.ts +0 -158
- package/src/test/unit/audit-checks.test.ts +0 -567
- package/src/test/unit/chinese-path.test.ts +0 -106
- package/src/test/unit/command-guard.test.ts +0 -221
- package/src/test/unit/diagnose-task.test.ts +0 -544
- package/src/test/unit/direct-guards.test.ts +0 -297
- package/src/test/unit/discovery-token-store.test.ts +0 -181
- package/src/test/unit/evidence-pack.test.ts +0 -142
- package/src/test/unit/goal-graph.test.ts +0 -347
- package/src/test/unit/goal-progress.test.ts +0 -538
- package/src/test/unit/goal-status.test.ts +0 -270
- package/src/test/unit/goal-store.test.ts +0 -318
- package/src/test/unit/goal-subgoal-task.test.ts +0 -72
- package/src/test/unit/goal-tools-registry.test.ts +0 -243
- package/src/test/unit/handoff-export.test.ts +0 -295
- package/src/test/unit/invoke-discovered-tool.test.ts +0 -216
- package/src/test/unit/logging.test.ts +0 -497
- package/src/test/unit/path-guard.test.ts +0 -150
- package/src/test/unit/post-task-cleanup.test.ts +0 -53
- package/src/test/unit/project-policy-release-mode.test.ts +0 -156
- package/src/test/unit/reconcile-tasks.test.ts +0 -551
- package/src/test/unit/release-gate.test.ts +0 -314
- package/src/test/unit/run-task-loop.test.ts +0 -425
- package/src/test/unit/safe-status.test.ts +0 -187
- package/src/test/unit/safe-views.test.ts +0 -184
- package/src/test/unit/schema-drift-check.test.ts +0 -260
- package/src/test/unit/sensitive-guard.test.ts +0 -124
- package/src/test/unit/subgoal-sync.test.ts +0 -236
- package/src/test/unit/sync-file.test.ts +0 -231
- package/src/test/unit/tool-invocation-guard.test.ts +0 -542
- package/src/test/unit/tool-usage-stats.test.ts +0 -384
- package/src/test/unit/toolSearch.test.ts +0 -756
- package/src/test/unit/watcher-status.test.ts +0 -190
- package/src/test/unit/worktree-manager.test.ts +0 -247
- package/src/tools/cancelTask.ts +0 -70
- package/src/tools/evidencePack.ts +0 -205
- package/src/tools/retryTask.ts +0 -53
- package/src/tools/syncFile.ts +0 -122
- /package/dist/tools/{toolCatalog.d.ts → catalog/toolCatalog.d.ts} +0 -0
- /package/dist/tools/{toolSearch.d.ts → catalog/toolSearch.d.ts} +0 -0
- /package/dist/tools/{toolSearch.js → catalog/toolSearch.js} +0 -0
- /package/dist/tools/{toolUsageStats.d.ts → catalog/toolUsageStats.d.ts} +0 -0
- /package/dist/tools/{toolUsageStats.js → catalog/toolUsageStats.js} +0 -0
- /package/dist/tools/{runDirectVerificationBundle.d.ts → direct/runDirectVerificationBundle.d.ts} +0 -0
- /package/dist/tools/{getPlan.d.ts → goals/getPlan.d.ts} +0 -0
- /package/dist/tools/{savePlan.d.ts → goals/savePlan.d.ts} +0 -0
- /package/dist/tools/{getTaskFile.d.ts → tasks/getTaskFile.d.ts} +0 -0
- /package/dist/tools/{getTaskProgress.d.ts → tasks/getTaskProgress.d.ts} +0 -0
- /package/dist/tools/{getTaskProgress.js → tasks/getTaskProgress.js} +0 -0
- /package/dist/tools/{getTaskStdoutTail.d.ts → tasks/getTaskStdoutTail.d.ts} +0 -0
- /package/dist/tools/{getTaskSummary.d.ts → tasks/getTaskSummary.d.ts} +0 -0
- /package/dist/tools/{killTask.js → tasks/killTask.js} +0 -0
- /package/dist/tools/{runVerification.d.ts → tasks/runVerification.d.ts} +0 -0
- /package/dist/tools/{taskLineage.d.ts → tasks/taskLineage.d.ts} +0 -0
- /package/dist/tools/{taskOutputs.d.ts → tasks/taskOutputs.d.ts} +0 -0
- /package/dist/tools/{waitForTask.d.ts → tasks/waitForTask.d.ts} +0 -0
- /package/dist/tools/{waitForTask.js → tasks/waitForTask.js} +0 -0
- /package/dist/tools/{androidDoctor.d.ts → workspace/androidDoctor.d.ts} +0 -0
- /package/dist/tools/{discardWorktree.d.ts → workspace/discardWorktree.d.ts} +0 -0
- /package/dist/tools/{listWorkspace.d.ts → workspace/listWorkspace.d.ts} +0 -0
- /package/dist/tools/{mergeWorktree.d.ts → workspace/mergeWorktree.d.ts} +0 -0
- /package/dist/tools/{readWorkspaceFile.d.ts → workspace/readWorkspaceFile.d.ts} +0 -0
- /package/dist/tools/{recommendAgentForTask.d.ts → workspace/recommendAgentForTask.d.ts} +0 -0
- /package/dist/tools/{searchWorkspace.d.ts → workspace/searchWorkspace.d.ts} +0 -0
- /package/src/tools/{toolSearch.ts → catalog/toolSearch.ts} +0 -0
- /package/src/tools/{toolUsageStats.ts → catalog/toolUsageStats.ts} +0 -0
- /package/src/tools/{getTaskProgress.ts → tasks/getTaskProgress.ts} +0 -0
- /package/src/tools/{killTask.ts → tasks/killTask.ts} +0 -0
- /package/src/tools/{waitForTask.ts → tasks/waitForTask.ts} +0 -0
|
@@ -135,6 +135,8 @@ html.dark {
|
|
|
135
135
|
.pw-spin { animation: pw-spin 1s linear infinite; }
|
|
136
136
|
@keyframes pw-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
|
137
137
|
</style>
|
|
138
|
+
<script src="/desktop-bootstrap.js"></script>
|
|
139
|
+
<link rel="stylesheet" href="/desktop.css">
|
|
138
140
|
</head>
|
|
139
141
|
<body class="flex h-screen overflow-hidden">
|
|
140
142
|
|
|
@@ -152,6 +154,10 @@ html.dark {
|
|
|
152
154
|
|
|
153
155
|
<!-- Navigation -->
|
|
154
156
|
<nav class="flex-1 flex flex-col gap-1 px-3 pt-4 overflow-y-auto">
|
|
157
|
+
<a href="/pages/getting-started.html" data-nav-key="getting-started" class="desktop-only-nav flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors truncate" style="color: var(--pw-text-secondary); font-family: var(--pw-font-sans);">
|
|
158
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.87 12.87 0 0 1 22 2c0 2.72-.78 7.5-6.05 11a22.35 22.35 0 0 1-3.95 2z"/></svg>
|
|
159
|
+
<span class="truncate" data-i18n="nav.gettingStarted">开始使用</span>
|
|
160
|
+
</a>
|
|
155
161
|
|
|
156
162
|
<a href="/pages/dashboard.html" data-nav-key="dashboard" data-dom-id="nav-dashboard" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors truncate" style="color: var(--pw-text-secondary); font-family: var(--pw-font-sans);">
|
|
157
163
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="shrink-0">
|
|
@@ -207,6 +213,10 @@ html.dark {
|
|
|
207
213
|
<span class="truncate" data-zh="日志" data-en="Logs">日志</span>
|
|
208
214
|
</a>
|
|
209
215
|
|
|
216
|
+
<a href="/pages/settings.html" data-nav-key="settings" class="desktop-only-nav flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors truncate" style="color: var(--pw-text-secondary); font-family: var(--pw-font-sans);">
|
|
217
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="shrink-0"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H2.8v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1A1.7 1.7 0 0 0 9 4.6 1.7 1.7 0 0 0 10 3V2.8h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9A1.7 1.7 0 0 0 21 10h.2v4H21a1.7 1.7 0 0 0-1.6 1z"/></svg>
|
|
218
|
+
<span class="truncate" data-i18n="nav.settings">设置</span>
|
|
219
|
+
</a>
|
|
210
220
|
</nav>
|
|
211
221
|
|
|
212
222
|
<!-- Bottom Section -->
|
|
@@ -372,176 +382,192 @@ html.dark {
|
|
|
372
382
|
</div>
|
|
373
383
|
</section>
|
|
374
384
|
|
|
375
|
-
<!--
|
|
376
|
-
<
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
<div class="flex flex-col gap-0.5 min-w-0">
|
|
386
|
-
<span class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);" data-zh="运行阶段" data-en="Runtime Phase">运行阶段</span>
|
|
387
|
-
<span id="rtPhase" class="truncate" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</span>
|
|
388
|
-
</div>
|
|
389
|
-
<div class="flex flex-col gap-0.5 min-w-0">
|
|
390
|
-
<span class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);" data-zh="最近心跳" data-en="Last Heartbeat">最近心跳</span>
|
|
391
|
-
<span id="rtHeartbeat" class="truncate" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</span>
|
|
392
|
-
</div>
|
|
393
|
-
<div class="flex flex-col gap-0.5 min-w-0">
|
|
394
|
-
<span class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);" data-zh="当前命令" data-en="Current Command">当前命令</span>
|
|
395
|
-
<span id="rtCurrentCmd" class="truncate" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</span>
|
|
396
|
-
</div>
|
|
397
|
-
</div>
|
|
398
|
-
</section>
|
|
385
|
+
<!-- ===== Safe Summary Section (DEFAULT visible, loaded from 4 safe endpoints) ===== -->
|
|
386
|
+
<section class="rounded-lg p-5" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
387
|
+
<div class="flex items-center gap-2 mb-1">
|
|
388
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--pw-accent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
|
389
|
+
<h2 class="text-base font-semibold" data-zh="安全摘要" data-en="Safe Summary" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">安全摘要</h2>
|
|
390
|
+
<span class="text-xs px-2 py-0.5 rounded-md whitespace-nowrap" style="color: var(--pw-accent); background-color: var(--pw-accent-subtle); font-family: var(--pw-font-mono);">safe-first</span>
|
|
391
|
+
</div>
|
|
392
|
+
<p class="text-xs mb-5" style="color: var(--pw-text-tertiary); font-family: var(--pw-font-sans);" data-zh="默认仅展示脱敏后的安全摘要。完整结果、diff、测试日志请见下方「高级」区域。" data-en="Shows redacted safe summaries by default. Full result/diff/test log are in the Advanced section below.">默认仅展示脱敏后的安全摘要。完整结果、diff、测试日志请见下方「高级」区域。</p>
|
|
393
|
+
|
|
394
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5">
|
|
399
395
|
|
|
400
|
-
<!--
|
|
401
|
-
<
|
|
402
|
-
<div class="flex items-center
|
|
403
|
-
<
|
|
404
|
-
<
|
|
396
|
+
<!-- Safe Result Overview -->
|
|
397
|
+
<div class="rounded-lg p-4 flex flex-col gap-3" style="background-color: var(--pw-bg); border: 1px solid var(--pw-border-subtle);">
|
|
398
|
+
<div class="flex items-center justify-between">
|
|
399
|
+
<h3 class="text-sm font-semibold" data-zh="结果概览" data-en="Safe Result" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">结果概览 (safe_result)</h3>
|
|
400
|
+
<span id="srStatusBadge" class="text-xs px-2 py-0.5 rounded-md whitespace-nowrap" style="color: var(--pw-text-tertiary); background-color: var(--pw-bg-hover); font-family: var(--pw-font-mono);">—</span>
|
|
405
401
|
</div>
|
|
406
|
-
<
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
<div class="flex
|
|
413
|
-
<
|
|
414
|
-
|
|
415
|
-
<h2 class="text-base font-semibold" data-zh="变更文件" data-en="Changed Files" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">变更文件</h2>
|
|
416
|
-
</div>
|
|
417
|
-
<span id="cfCountBadge" class="hidden text-xs px-2 py-0.5 rounded-md whitespace-nowrap" style="color: var(--pw-text-tertiary); background-color: var(--pw-bg-hover); font-family: var(--pw-font-mono);">—</span>
|
|
402
|
+
<dl class="grid grid-cols-2 gap-x-4 gap-y-2 text-xs">
|
|
403
|
+
<div class="flex flex-col gap-0.5 min-w-0"><dt style="color: var(--pw-text-tertiary);">terminal</dt><dd id="srTerminal" class="truncate" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</dd></div>
|
|
404
|
+
<div class="flex flex-col gap-0.5 min-w-0"><dt style="color: var(--pw-text-tertiary);">acceptance_status</dt><dd id="srAcceptance" class="truncate" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</dd></div>
|
|
405
|
+
<div class="flex flex-col gap-0.5 min-w-0"><dt style="color: var(--pw-text-tertiary);">changed_files_total</dt><dd id="srChangedTotal" class="truncate" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</dd></div>
|
|
406
|
+
<div class="flex flex-col gap-0.5 min-w-0"><dt style="color: var(--pw-text-tertiary);">out_of_scope_changes_total</dt><dd id="srOosTotal" class="truncate" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</dd></div>
|
|
407
|
+
</dl>
|
|
408
|
+
<div class="flex flex-col gap-0.5 min-w-0">
|
|
409
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">verification.headline</span>
|
|
410
|
+
<span id="srVerifyHeadline" class="text-xs break-words" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</span>
|
|
418
411
|
</div>
|
|
419
|
-
<div id="
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
<div id="cfStatsRow" class="hidden grid grid-cols-2 sm:grid-cols-4 gap-2 text-xs"></div>
|
|
423
|
-
<!-- changed files list (truncated) -->
|
|
424
|
-
<div id="cfList" class="rounded-md p-2 text-xs leading-relaxed overflow-auto" style="background-color: #0d1117; color: var(--pw-text-secondary); font-family: var(--pw-font-mono); max-height: 320px;"></div>
|
|
412
|
+
<div id="srFailureBlock" class="hidden flex flex-col gap-1">
|
|
413
|
+
<div class="flex flex-col gap-0.5 min-w-0"><span class="text-xs" style="color: var(--pw-state-error);">failure_reason</span><span id="srFailureReason" class="text-xs break-words" style="color: var(--pw-state-error); font-family: var(--pw-font-mono);">—</span></div>
|
|
414
|
+
<div class="flex flex-col gap-0.5 min-w-0"><span class="text-xs" style="color: var(--pw-state-error);">failed_command</span><span id="srFailedCommand" class="text-xs break-all" style="color: var(--pw-state-error); font-family: var(--pw-font-mono);">—</span></div>
|
|
425
415
|
</div>
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
<div class="flex
|
|
431
|
-
<
|
|
432
|
-
<
|
|
416
|
+
<div class="flex flex-col gap-0.5 min-w-0">
|
|
417
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">next_action</span>
|
|
418
|
+
<span id="srNextAction" class="text-xs break-words" style="color: var(--pw-accent); font-family: var(--pw-font-mono);">—</span>
|
|
419
|
+
</div>
|
|
420
|
+
<div id="srBlockedBlock" class="hidden flex flex-col gap-0.5 min-w-0">
|
|
421
|
+
<span class="text-xs" style="color: var(--pw-state-warning);">execution_blocked / pending_reason</span>
|
|
422
|
+
<span id="srPendingReason" class="text-xs break-words" style="color: var(--pw-state-warning); font-family: var(--pw-font-mono);">—</span>
|
|
433
423
|
</div>
|
|
434
|
-
<div id="
|
|
435
|
-
|
|
436
|
-
|
|
424
|
+
<div id="srWarningsBlock" class="hidden flex flex-col gap-1 min-w-0">
|
|
425
|
+
<span class="text-xs font-medium" style="color: var(--pw-state-warning);">warnings</span>
|
|
426
|
+
<pre id="srWarnings" class="rounded-md p-2 text-xs leading-relaxed whitespace-pre-wrap break-all" style="background-color: var(--pw-state-warning-bg); color: var(--pw-state-warning); font-family: var(--pw-font-mono); max-height: 160px; overflow-y: auto;"></pre>
|
|
427
|
+
</div>
|
|
428
|
+
</div>
|
|
437
429
|
|
|
438
|
-
|
|
430
|
+
<!-- Safe Test Summary -->
|
|
431
|
+
<div class="rounded-lg p-4 flex flex-col gap-3" style="background-color: var(--pw-bg); border: 1px solid var(--pw-border-subtle);">
|
|
432
|
+
<div class="flex items-center justify-between">
|
|
433
|
+
<h3 class="text-sm font-semibold" data-zh="测试摘要" data-en="Safe Test Summary" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">测试摘要 (safe_test_summary)</h3>
|
|
434
|
+
<span id="stStatusBadge" class="text-xs px-2 py-0.5 rounded-md whitespace-nowrap" style="color: var(--pw-text-tertiary); background-color: var(--pw-bg-hover); font-family: var(--pw-font-mono);">—</span>
|
|
435
|
+
</div>
|
|
436
|
+
<dl class="grid grid-cols-4 gap-x-3 gap-y-2 text-xs">
|
|
437
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">commands</dt><dd id="stCmdCount" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</dd></div>
|
|
438
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">passed</dt><dd id="stPassed" style="color: var(--pw-state-success); font-family: var(--pw-font-mono);">—</dd></div>
|
|
439
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">failed</dt><dd id="stFailed" style="color: var(--pw-state-error); font-family: var(--pw-font-mono);">—</dd></div>
|
|
440
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">skipped</dt><dd id="stSkipped" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</dd></div>
|
|
441
|
+
</dl>
|
|
442
|
+
<div class="flex flex-col gap-0.5 min-w-0">
|
|
443
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">headline</span>
|
|
444
|
+
<span id="stHeadline" class="text-xs break-words" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</span>
|
|
445
|
+
</div>
|
|
446
|
+
<div class="flex flex-col gap-1 min-w-0">
|
|
447
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">commands</span>
|
|
448
|
+
<div id="stCommandsBody" class="rounded-md p-2 text-xs leading-relaxed overflow-auto" style="background-color: #0d1117; color: var(--pw-text-secondary); font-family: var(--pw-font-mono); max-height: 220px;"></div>
|
|
449
|
+
</div>
|
|
450
|
+
</div>
|
|
439
451
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
<
|
|
447
|
-
<div class="flex
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
</div>
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
</
|
|
455
|
-
<div id="
|
|
456
|
-
|
|
457
|
-
|
|
452
|
+
<!-- Safe Diff Summary -->
|
|
453
|
+
<div class="rounded-lg p-4 flex flex-col gap-3" style="background-color: var(--pw-bg); border: 1px solid var(--pw-border-subtle);">
|
|
454
|
+
<div class="flex items-center justify-between">
|
|
455
|
+
<h3 class="text-sm font-semibold" data-zh="变更摘要" data-en="Safe Diff Summary" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">变更摘要 (safe_diff_summary)</h3>
|
|
456
|
+
<span id="sdPatchMode" class="text-xs px-2 py-0.5 rounded-md whitespace-nowrap" style="color: var(--pw-text-tertiary); background-color: var(--pw-bg-hover); font-family: var(--pw-font-mono);">—</span>
|
|
457
|
+
</div>
|
|
458
|
+
<dl class="grid grid-cols-4 gap-x-3 gap-y-2 text-xs">
|
|
459
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">files</dt><dd id="sdChangedTotal" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</dd></div>
|
|
460
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">additions</dt><dd id="sdAdditions" style="color: var(--pw-state-success); font-family: var(--pw-font-mono);">—</dd></div>
|
|
461
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">deletions</dt><dd id="sdDeletions" style="color: var(--pw-state-error); font-family: var(--pw-font-mono);">—</dd></div>
|
|
462
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">diff_available</dt><dd id="sdDiffAvailable" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</dd></div>
|
|
463
|
+
</dl>
|
|
464
|
+
<div id="sdTruncatedBlock" class="hidden text-xs" style="color: var(--pw-state-warning); font-family: var(--pw-font-mono);">⚠ diff_truncated / large_diff_omitted</div>
|
|
465
|
+
<div class="flex flex-col gap-1 min-w-0">
|
|
466
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">files (path · change · kind)</span>
|
|
467
|
+
<div id="sdFilesBody" class="rounded-md p-2 text-xs leading-relaxed overflow-auto" style="background-color: #0d1117; color: var(--pw-text-secondary); font-family: var(--pw-font-mono); max-height: 220px;"></div>
|
|
468
|
+
</div>
|
|
469
|
+
<div id="sdHygieneBlock" class="hidden flex flex-col gap-0.5 min-w-0">
|
|
470
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">artifact_hygiene_counts</span>
|
|
471
|
+
<pre id="sdHygiene" class="text-xs whitespace-pre-wrap break-all" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);"></pre>
|
|
458
472
|
</div>
|
|
459
|
-
</
|
|
473
|
+
</div>
|
|
460
474
|
|
|
461
|
-
<!-- Audit
|
|
462
|
-
<
|
|
463
|
-
<div class="flex items-center justify-between
|
|
464
|
-
<
|
|
465
|
-
<span id="
|
|
475
|
+
<!-- Safe Audit -->
|
|
476
|
+
<div class="rounded-lg p-4 flex flex-col gap-3" style="background-color: var(--pw-bg); border: 1px solid var(--pw-border-subtle);">
|
|
477
|
+
<div class="flex items-center justify-between">
|
|
478
|
+
<h3 class="text-sm font-semibold" data-zh="审计结论" data-en="Safe Audit" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">审计结论 (safe_audit)</h3>
|
|
479
|
+
<span id="saVerdictBadge" class="text-xs px-2 py-0.5 rounded-md whitespace-nowrap" style="color: var(--pw-text-tertiary); background-color: var(--pw-bg-hover); font-family: var(--pw-font-mono);">—</span>
|
|
480
|
+
</div>
|
|
481
|
+
<dl class="grid grid-cols-3 gap-x-3 gap-y-2 text-xs">
|
|
482
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">pass</dt><dd id="saCountsPass" style="color: var(--pw-state-success); font-family: var(--pw-font-mono);">—</dd></div>
|
|
483
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">warn</dt><dd id="saCountsWarn" style="color: var(--pw-state-warning); font-family: var(--pw-font-mono);">—</dd></div>
|
|
484
|
+
<div class="flex flex-col gap-0.5"><dt style="color: var(--pw-text-tertiary);">fail</dt><dd id="saCountsFail" style="color: var(--pw-state-error); font-family: var(--pw-font-mono);">—</dd></div>
|
|
485
|
+
</dl>
|
|
486
|
+
<div class="flex flex-col gap-0.5 min-w-0">
|
|
487
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">acceptance.verdict / status</span>
|
|
488
|
+
<span id="saAccVerdict" class="text-xs break-words" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</span>
|
|
489
|
+
</div>
|
|
490
|
+
<div class="flex flex-col gap-0.5 min-w-0">
|
|
491
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">acceptance.reason</span>
|
|
492
|
+
<span id="saAccReason" class="text-xs break-words" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</span>
|
|
466
493
|
</div>
|
|
467
|
-
<div class="flex flex-col gap-
|
|
468
|
-
<
|
|
469
|
-
|
|
470
|
-
<span id="auditScope" class="font-semibold" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</span>
|
|
471
|
-
</div>
|
|
472
|
-
<div class="flex items-center justify-between text-sm">
|
|
473
|
-
<span style="color: var(--pw-text-secondary);" data-zh="检查时间" data-en="Checked At">检查时间</span>
|
|
474
|
-
<span id="auditCheckedAt" class="truncate" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</span>
|
|
475
|
-
</div>
|
|
476
|
-
<div id="auditEmptyHint" class="text-xs" style="color: var(--pw-text-tertiary); font-family: var(--pw-font-sans);" data-zh="暂无审计记录" data-en="No audit record yet">暂无审计记录</div>
|
|
494
|
+
<div class="flex flex-col gap-0.5 min-w-0">
|
|
495
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">next_suggested_task</span>
|
|
496
|
+
<span id="saAccNextTask" class="text-xs break-words" style="color: var(--pw-accent); font-family: var(--pw-font-mono);">—</span>
|
|
477
497
|
</div>
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
<section class="rounded-lg overflow-hidden" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
482
|
-
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
483
|
-
<div class="flex items-center gap-2">
|
|
484
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--pw-text-secondary)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
|
485
|
-
<h2 class="text-base font-semibold" data-zh="独立审计报告" data-en="Independent Review" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">独立审计报告</h2>
|
|
486
|
-
</div>
|
|
487
|
-
<span id="reviewVerdictBadge" class="text-xs px-2 py-0.5 rounded-md whitespace-nowrap" style="color: var(--pw-text-tertiary); background-color: var(--pw-bg-hover); font-family: var(--pw-font-mono);">—</span>
|
|
498
|
+
<div id="saFailChecksBlock" class="hidden flex flex-col gap-0.5 min-w-0">
|
|
499
|
+
<span class="text-xs" style="color: var(--pw-state-error);">fail_checks</span>
|
|
500
|
+
<pre id="saFailChecks" class="rounded-md p-2 text-xs whitespace-pre-wrap break-all" style="background-color: var(--pw-state-error-bg); color: var(--pw-state-error); font-family: var(--pw-font-mono); max-height: 120px; overflow-y: auto;"></pre>
|
|
488
501
|
</div>
|
|
489
|
-
<div id="
|
|
490
|
-
<
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
<!-- Verification Summary Card -->
|
|
494
|
-
<section class="rounded-lg p-5" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
495
|
-
<h2 class="text-base font-semibold mb-4" data-zh="验证摘要" data-en="Verification Summary" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">验证摘要</h2>
|
|
496
|
-
<div class="flex flex-col gap-3">
|
|
497
|
-
<div class="flex items-center justify-between text-sm">
|
|
498
|
-
<span style="color: var(--pw-text-secondary);" data-zh="验证状态" data-en="Status">验证状态</span>
|
|
499
|
-
<span id="vsStatus" class="font-semibold" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">—</span>
|
|
500
|
-
</div>
|
|
501
|
-
<div class="flex items-center justify-between text-sm">
|
|
502
|
-
<span style="color: var(--pw-text-secondary);" data-zh="检查时间" data-en="Checked At">检查时间</span>
|
|
503
|
-
<span id="vsCheckedAt" class="truncate" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">—</span>
|
|
504
|
-
</div>
|
|
505
|
-
<div id="vsCommandsBlock" class="hidden rounded-md p-2 text-xs leading-relaxed" style="background-color: var(--pw-bg); border: 1px solid var(--pw-border-subtle); color: var(--pw-text-secondary); font-family: var(--pw-font-mono);">
|
|
506
|
-
<div class="text-xs mb-1" style="color: var(--pw-text-tertiary);" data-zh="验证命令" data-en="Commands">验证命令</div>
|
|
507
|
-
<pre id="vsCommands" class="whitespace-pre-wrap break-all"></pre>
|
|
508
|
-
</div>
|
|
509
|
-
<div id="vsEmptyHint" class="text-xs" style="color: var(--pw-text-tertiary); font-family: var(--pw-font-sans);" data-zh="暂无验证摘要" data-en="No verification summary">暂无验证摘要</div>
|
|
502
|
+
<div id="saManualBlock" class="hidden text-xs" style="color: var(--pw-state-warning); font-family: var(--pw-font-mono);">⚠ manual_verification_required</div>
|
|
503
|
+
<div id="saActionsBlock" class="hidden flex flex-col gap-0.5 min-w-0">
|
|
504
|
+
<span class="text-xs" style="color: var(--pw-text-tertiary);">recommended_next_actions</span>
|
|
505
|
+
<pre id="saActions" class="text-xs whitespace-pre-wrap break-all" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);"></pre>
|
|
510
506
|
</div>
|
|
511
|
-
</
|
|
507
|
+
</div>
|
|
508
|
+
|
|
509
|
+
</div>
|
|
510
|
+
</section>
|
|
512
511
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
512
|
+
<!-- ===== Advanced Section (collapsed by default; full content loaded ON DEMAND) ===== -->
|
|
513
|
+
<details class="rounded-lg overflow-hidden" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
514
|
+
<summary class="flex items-center gap-2 px-5 py-4 cursor-pointer select-none" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">
|
|
515
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--pw-text-secondary)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>
|
|
516
|
+
<span class="text-base font-semibold" data-zh="高级" data-en="Advanced">高级</span>
|
|
517
|
+
<span class="text-xs px-2 py-0.5 rounded-md whitespace-nowrap" style="color: var(--pw-state-warning); background-color: var(--pw-state-warning-bg); font-family: var(--pw-font-mono);">⚠️ may contain large output</span>
|
|
518
|
+
</summary>
|
|
519
|
+
<div class="flex flex-col gap-4 px-5 pb-5">
|
|
520
|
+
<p class="text-xs" style="color: var(--pw-text-tertiary); font-family: var(--pw-font-sans);" data-zh="以下内容仅在点击时按需加载,可能包含完整 stdout/stderr/diff 等较大输出。" data-en="The following content is loaded on demand only and may contain full stdout/stderr/diff.">以下内容仅在点击时按需加载,可能包含完整 stdout/stderr/diff 等较大输出。</p>
|
|
521
|
+
|
|
522
|
+
<!-- Advanced: full result -->
|
|
523
|
+
<div class="flex flex-col gap-2">
|
|
524
|
+
<div class="flex items-center gap-2 flex-wrap">
|
|
525
|
+
<button id="advBtnResult" class="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors" style="background-color: var(--pw-bg-hover); color: var(--pw-text-primary); border: 1px solid var(--pw-border-subtle); font-family: var(--pw-font-sans);">
|
|
526
|
+
<svg id="advSpinnerResult" class="hidden pw-spin" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="2" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/><line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/><line x1="2" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="22" y2="12"/><line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/><line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/></svg>
|
|
527
|
+
<span data-zh="加载完整结果 (get_result)" data-en="Load full result (get_result)">加载完整结果 (get_result)</span>
|
|
528
|
+
</button>
|
|
529
|
+
<span class="text-xs" style="color: var(--pw-state-warning); font-family: var(--pw-font-mono);">⚠️ Advanced view: may contain large output</span>
|
|
518
530
|
</div>
|
|
519
|
-
<
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
<
|
|
526
|
-
<
|
|
527
|
-
<
|
|
528
|
-
</
|
|
531
|
+
<pre id="advPreResult" class="hidden px-4 py-3 text-xs leading-relaxed overflow-x-auto whitespace-pre-wrap break-all" style="background-color: #0d1117; color: var(--pw-text-secondary); font-family: var(--pw-font-mono); max-height: 520px; overflow-y: auto;"></pre>
|
|
532
|
+
</div>
|
|
533
|
+
|
|
534
|
+
<!-- Advanced: full test log -->
|
|
535
|
+
<div class="flex flex-col gap-2">
|
|
536
|
+
<div class="flex items-center gap-2 flex-wrap">
|
|
537
|
+
<button id="advBtnTestLog" class="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors" style="background-color: var(--pw-bg-hover); color: var(--pw-text-primary); border: 1px solid var(--pw-border-subtle); font-family: var(--pw-font-sans);">
|
|
538
|
+
<svg id="advSpinnerTestLog" class="hidden pw-spin" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="2" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/><line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/><line x1="2" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="22" y2="12"/><line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/><line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/></svg>
|
|
539
|
+
<span data-zh="加载完整测试日志 (get_test_log)" data-en="Load full test log (get_test_log)">加载完整测试日志 (get_test_log)</span>
|
|
540
|
+
</button>
|
|
541
|
+
<span class="text-xs" style="color: var(--pw-state-warning); font-family: var(--pw-font-mono);">⚠️ Advanced view: may contain large output</span>
|
|
529
542
|
</div>
|
|
530
|
-
|
|
543
|
+
<pre id="advPreTestLog" class="hidden px-4 py-3 text-xs leading-relaxed overflow-x-auto whitespace-pre-wrap break-all" style="background-color: #0d1117; color: var(--pw-text-secondary); font-family: var(--pw-font-mono); max-height: 520px; overflow-y: auto;"></pre>
|
|
544
|
+
</div>
|
|
531
545
|
|
|
532
|
-
<!--
|
|
533
|
-
<
|
|
534
|
-
<div class="flex items-center gap-2
|
|
535
|
-
<
|
|
536
|
-
|
|
546
|
+
<!-- Advanced: full diff -->
|
|
547
|
+
<div class="flex flex-col gap-2">
|
|
548
|
+
<div class="flex items-center gap-2 flex-wrap">
|
|
549
|
+
<button id="advBtnDiff" class="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors" style="background-color: var(--pw-bg-hover); color: var(--pw-text-primary); border: 1px solid var(--pw-border-subtle); font-family: var(--pw-font-sans);">
|
|
550
|
+
<svg id="advSpinnerDiff" class="hidden pw-spin" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="2" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/><line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/><line x1="2" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="22" y2="12"/><line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/><line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/></svg>
|
|
551
|
+
<span data-zh="加载完整 diff (get_diff)" data-en="Load full diff (get_diff)">加载完整 diff (get_diff)</span>
|
|
552
|
+
</button>
|
|
553
|
+
<span class="text-xs" style="color: var(--pw-state-warning); font-family: var(--pw-font-mono);">⚠️ Advanced view: may contain large output</span>
|
|
537
554
|
</div>
|
|
538
|
-
<
|
|
539
|
-
|
|
540
|
-
</section>
|
|
555
|
+
<pre id="advPreDiff" class="hidden px-4 py-3 text-xs leading-relaxed overflow-x-auto whitespace-pre-wrap break-all" style="background-color: #0d1117; color: var(--pw-text-secondary); font-family: var(--pw-font-mono); max-height: 520px; overflow-y: auto;"></pre>
|
|
556
|
+
</div>
|
|
541
557
|
|
|
558
|
+
<!-- Advanced: full audit_task review -->
|
|
559
|
+
<div class="flex flex-col gap-2">
|
|
560
|
+
<div class="flex items-center gap-2 flex-wrap">
|
|
561
|
+
<button id="advBtnAudit" class="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors" style="background-color: var(--pw-accent-muted); color: var(--pw-accent); border: 1px solid rgba(45, 212, 168, 0.3); font-family: var(--pw-font-sans);">
|
|
562
|
+
<svg id="advSpinnerAudit" class="hidden pw-spin" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="2" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/><line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/><line x1="2" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="22" y2="12"/><line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/><line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/></svg>
|
|
563
|
+
<span data-zh="运行 audit_task 完整审计" data-en="Run audit_task full review">运行 audit_task 完整审计</span>
|
|
564
|
+
</button>
|
|
565
|
+
<span class="text-xs" style="color: var(--pw-state-warning); font-family: var(--pw-font-mono);">⚠️ Advanced view: may contain large output</span>
|
|
566
|
+
</div>
|
|
567
|
+
<pre id="advPreAudit" class="hidden px-4 py-3 text-xs leading-relaxed overflow-x-auto whitespace-pre-wrap break-all" style="background-color: #0d1117; color: var(--pw-text-secondary); font-family: var(--pw-font-mono); max-height: 520px; overflow-y: auto;"></pre>
|
|
568
|
+
</div>
|
|
542
569
|
</div>
|
|
543
|
-
|
|
544
|
-
</div>
|
|
570
|
+
</details>
|
|
545
571
|
|
|
546
572
|
</div>
|
|
547
573
|
|
|
@@ -705,311 +731,171 @@ html.dark {
|
|
|
705
731
|
show($('detailContent'));
|
|
706
732
|
}
|
|
707
733
|
|
|
708
|
-
// ---- Render
|
|
709
|
-
|
|
710
|
-
|
|
734
|
+
// ---- Render Safe Summary (from 4 safe endpoints) ----
|
|
735
|
+
// renderHeader populates the Task Header Card from safe_result
|
|
736
|
+
function renderHeader(taskId, safeResult) {
|
|
711
737
|
text($('breadcrumbId'), taskId);
|
|
712
738
|
text($('hdrTaskId'), taskId);
|
|
713
739
|
|
|
714
|
-
|
|
715
|
-
var status = (data.status && data.status.status) || data.status_status || null;
|
|
740
|
+
var status = safeResult.status || null;
|
|
716
741
|
var statusMeta = getStatusMeta(status);
|
|
717
742
|
text($('hdrStatusText'), statusMeta.text);
|
|
718
743
|
applyBadgeColors($('hdrStatusBadge'), statusMeta.color);
|
|
719
744
|
|
|
720
|
-
|
|
721
|
-
var phase = (data.status && data.status.phase) || null;
|
|
722
|
-
text($('hdrPhase'), getPhaseLabel(phase));
|
|
723
|
-
|
|
724
|
-
// Agent
|
|
725
|
-
var agent = (data.status && data.status.agent) || null;
|
|
726
|
-
text($('hdrAgent'), agent || '—');
|
|
727
|
-
|
|
728
|
-
// Times
|
|
729
|
-
var createdAt = (data.status && data.status.created_at) || null;
|
|
730
|
-
var updatedAt = (data.status && data.status.updated_at) || null;
|
|
731
|
-
text($('hdrCreatedAt'), formatTime(createdAt));
|
|
732
|
-
text($('hdrUpdatedAt'), formatTime(updatedAt));
|
|
745
|
+
text($('hdrPhase'), getPhaseLabel(safeResult.phase));
|
|
733
746
|
|
|
734
|
-
//
|
|
735
|
-
|
|
736
|
-
text($('hdrTestCommand'), testCommand || '—');
|
|
737
|
-
var timeoutSeconds = (data.status && data.status.timeout_seconds);
|
|
738
|
-
text($('hdrTimeout'), (timeoutSeconds === null || timeoutSeconds === undefined) ? '—' : String(timeoutSeconds));
|
|
747
|
+
// repo_path from safe_result
|
|
748
|
+
text($('hdrRepoPath'), safeResult.repo_path || '—');
|
|
739
749
|
|
|
740
|
-
//
|
|
741
|
-
|
|
742
|
-
text($('
|
|
750
|
+
// created_at/updated_at not available from safe endpoints; keep placeholder
|
|
751
|
+
text($('hdrCreatedAt'), '—');
|
|
752
|
+
text($('hdrUpdatedAt'), '—');
|
|
743
753
|
|
|
744
|
-
|
|
745
|
-
text($('
|
|
754
|
+
text($('hdrTestCommand'), '—');
|
|
755
|
+
text($('hdrTimeout'), '—');
|
|
756
|
+
text($('hdrAgent'), '—');
|
|
757
|
+
text($('hdrVerifyCommands'), '—');
|
|
758
|
+
text($('hdrPlanId'), '—');
|
|
746
759
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
if (statusError) {
|
|
753
|
-
text($('hdrErrorText'), escapeText(statusError));
|
|
760
|
+
if (safeResult.errors && safeResult.errors.length > 0) {
|
|
761
|
+
text($('hdrErrorText'), safeResult.errors.join('\n'));
|
|
762
|
+
show($('hdrErrorBlock'));
|
|
763
|
+
} else if (safeResult.failure_reason) {
|
|
764
|
+
text($('hdrErrorText'), safeResult.failure_reason);
|
|
754
765
|
show($('hdrErrorBlock'));
|
|
755
766
|
} else {
|
|
756
767
|
hide($('hdrErrorBlock'));
|
|
757
768
|
}
|
|
769
|
+
}
|
|
758
770
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
var rtHeartbeat = runtime ? (runtime.last_heartbeat_at || null) : null;
|
|
764
|
-
text($('rtHeartbeat'), formatTime(rtHeartbeat));
|
|
765
|
-
var rtCmd = runtime ? (runtime.current_command || null) : null;
|
|
766
|
-
text($('rtCurrentCmd'), rtCmd || '—');
|
|
767
|
-
|
|
768
|
-
// ---- Result summary ----
|
|
769
|
-
var result = data.result || null;
|
|
770
|
-
var rsStatus = result ? (result.status || null) : null;
|
|
771
|
-
text($('rsStatus'), rsStatus || '—');
|
|
772
|
-
var rsVerify = result ? (result.verify_status || null) : null;
|
|
773
|
-
text($('rsVerifyStatus'), rsVerify || '—');
|
|
774
|
-
var rsSummary = result ? (result.summary || null) : null;
|
|
775
|
-
if (rsSummary) {
|
|
776
|
-
text($('rsSummary'), escapeText(rsSummary));
|
|
777
|
-
show($('rsSummaryBlock'));
|
|
778
|
-
} else {
|
|
779
|
-
hide($('rsSummaryBlock'));
|
|
780
|
-
}
|
|
771
|
+
// Render safe_result card
|
|
772
|
+
function renderSafeResult(sr) {
|
|
773
|
+
text($('srStatusBadge'), sr.status || '—');
|
|
774
|
+
applyBadgeColors($('srStatusBadge'), getStatusMeta(sr.status).color);
|
|
781
775
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
var scopeChanges = audit ? (audit.scope_changes || null) : null;
|
|
787
|
-
text($('auditScope'), scopeChanges || '—');
|
|
788
|
-
var checkedAt = audit ? (audit.checked_at || null) : null;
|
|
789
|
-
text($('auditCheckedAt'), formatTime(checkedAt));
|
|
790
|
-
if (audit) {
|
|
791
|
-
hide($('auditEmptyHint'));
|
|
792
|
-
} else {
|
|
793
|
-
show($('auditEmptyHint'));
|
|
794
|
-
}
|
|
776
|
+
text($('srTerminal'), sr.terminal ? 'true' : 'false');
|
|
777
|
+
text($('srAcceptance'), sr.acceptance_status || '—');
|
|
778
|
+
text($('srChangedTotal'), sr.changed_files_total != null ? String(sr.changed_files_total) : '—');
|
|
779
|
+
text($('srOosTotal'), sr.out_of_scope_changes_total != null ? String(sr.out_of_scope_changes_total) : '—');
|
|
795
780
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
var diff = data.diff_patch || data.diff || data.diffPatch || null;
|
|
799
|
-
var diffEl = $('diffContent');
|
|
800
|
-
var diffEmpty = $('diffEmpty');
|
|
801
|
-
if (diff) {
|
|
802
|
-
text(diffEl, escapeText(diff));
|
|
803
|
-
show(diffEl);
|
|
804
|
-
hide(diffEmpty);
|
|
805
|
-
} else {
|
|
806
|
-
hide(diffEl);
|
|
807
|
-
show(diffEmpty);
|
|
808
|
-
}
|
|
781
|
+
var verifyHeadline = (sr.verification && sr.verification.headline) || null;
|
|
782
|
+
text($('srVerifyHeadline'), verifyHeadline || '—');
|
|
809
783
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
if (testLog) {
|
|
815
|
-
text(logEl, escapeText(testLog));
|
|
816
|
-
show(logEl);
|
|
817
|
-
hide(logEmpty);
|
|
784
|
+
if (sr.failure_reason || sr.failed_command) {
|
|
785
|
+
text($('srFailureReason'), sr.failure_reason || '—');
|
|
786
|
+
text($('srFailedCommand'), sr.failed_command || '—');
|
|
787
|
+
show($('srFailureBlock'));
|
|
818
788
|
} else {
|
|
819
|
-
hide(
|
|
820
|
-
show(logEmpty);
|
|
789
|
+
hide($('srFailureBlock'));
|
|
821
790
|
}
|
|
822
791
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
var vlEl = $('verifyLogContent');
|
|
829
|
-
var vlEmpty = $('verifyLogEmpty');
|
|
830
|
-
if (verifyLog) {
|
|
831
|
-
text(vlEl, escapeText(verifyLog));
|
|
832
|
-
show(vlEl);
|
|
833
|
-
hide(vlEmpty);
|
|
792
|
+
text($('srNextAction'), sr.next_action || '—');
|
|
793
|
+
|
|
794
|
+
if (sr.execution_blocked || sr.pending_reason) {
|
|
795
|
+
text($('srPendingReason'), sr.pending_reason || (sr.execution_blocked ? 'blocked' : '—'));
|
|
796
|
+
show($('srBlockedBlock'));
|
|
834
797
|
} else {
|
|
835
|
-
hide(
|
|
836
|
-
show(vlEmpty);
|
|
798
|
+
hide($('srBlockedBlock'));
|
|
837
799
|
}
|
|
838
800
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
var rvVerdict = review ? (review.verdict || null) : null;
|
|
843
|
-
var rvEl = $('reviewContent');
|
|
844
|
-
var rvEmpty = $('reviewEmpty');
|
|
845
|
-
var rvBadge = $('reviewVerdictBadge');
|
|
846
|
-
if (rvContent) {
|
|
847
|
-
text(rvEl, escapeText(rvContent));
|
|
848
|
-
show(rvEl);
|
|
849
|
-
hide(rvEmpty);
|
|
801
|
+
if (Array.isArray(sr.warnings) && sr.warnings.length > 0) {
|
|
802
|
+
$('srWarnings').textContent = sr.warnings.join('\n');
|
|
803
|
+
show($('srWarningsBlock'));
|
|
850
804
|
} else {
|
|
851
|
-
hide(
|
|
852
|
-
show(rvEmpty);
|
|
805
|
+
hide($('srWarningsBlock'));
|
|
853
806
|
}
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
// ---- Verification summary ----
|
|
857
|
-
renderVerificationSummary(data.verification_summary);
|
|
807
|
+
}
|
|
858
808
|
|
|
859
|
-
|
|
860
|
-
|
|
809
|
+
// Render safe_test_summary card
|
|
810
|
+
function renderSafeTestSummary(sts) {
|
|
811
|
+
text($('stStatusBadge'), sts.status || '—');
|
|
812
|
+
applyBadgeColors($('stStatusBadge'), getStatusMeta(sts.status).color);
|
|
861
813
|
|
|
862
|
-
|
|
863
|
-
|
|
814
|
+
text($('stCmdCount'), String(sts.command_count || 0));
|
|
815
|
+
text($('stPassed'), String(sts.passed_commands || 0));
|
|
816
|
+
text($('stFailed'), String(sts.failed_commands || 0));
|
|
817
|
+
text($('stSkipped'), String(sts.skipped_commands || 0));
|
|
864
818
|
|
|
865
|
-
|
|
866
|
-
}
|
|
819
|
+
text($('stHeadline'), sts.headline || '—');
|
|
867
820
|
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
var
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
var badgeEl = $('cfCountBadge');
|
|
875
|
-
|
|
876
|
-
if (!changedFiles) {
|
|
877
|
-
hide(bodyEl);
|
|
878
|
-
hide(badgeEl);
|
|
879
|
-
show(emptyEl);
|
|
880
|
-
return;
|
|
821
|
+
var cmds = Array.isArray(sts.commands) ? sts.commands : [];
|
|
822
|
+
var cmdsHtml = '';
|
|
823
|
+
for (var i = 0; i < cmds.length; i++) {
|
|
824
|
+
var cmd = cmds[i];
|
|
825
|
+
var statusColor = cmd.status === 'passed' ? 'var(--pw-state-success)' : (cmd.status === 'failed' || cmd.status === 'timed_out') ? 'var(--pw-state-error)' : 'var(--pw-text-secondary)';
|
|
826
|
+
cmdsHtml += '<div style="margin-bottom:4px;"><span style="color:' + statusColor + ';">' + escapeHtml(cmd.status || 'unknown') + '</span> <span style="color:var(--pw-text-tertiary);">exit=' + (cmd.exit_code !== null ? cmd.exit_code : '—') + '</span> <span style="color:var(--pw-text-primary);">' + escapeHtml(cmd.command || '') + '</span></div>';
|
|
881
827
|
}
|
|
828
|
+
if (!cmdsHtml) cmdsHtml = '<div style="color:var(--pw-text-tertiary);">—</div>';
|
|
829
|
+
$('stCommandsBody').innerHTML = cmdsHtml;
|
|
830
|
+
}
|
|
882
831
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
if (paths.length === 0 && Array.isArray(changedFiles.changed_files)) {
|
|
893
|
-
for (var j = 0; j < changedFiles.changed_files.length; j++) {
|
|
894
|
-
var cf = changedFiles.changed_files[j];
|
|
895
|
-
if (typeof cf === 'string') paths.push(cf);
|
|
896
|
-
else if (cf && typeof cf === 'object' && typeof cf.path === 'string') paths.push(cf.path);
|
|
897
|
-
}
|
|
898
|
-
}
|
|
832
|
+
// Render safe_diff_summary card
|
|
833
|
+
function renderSafeDiffSummary(sds) {
|
|
834
|
+
text($('sdPatchMode'), sds.patch_mode || '—');
|
|
835
|
+
text($('sdChangedTotal'), String(sds.changed_files_total || 0));
|
|
836
|
+
text($('sdAdditions'), String(sds.additions || 0));
|
|
837
|
+
text($('sdDeletions'), String(sds.deletions || 0));
|
|
838
|
+
text($('sdDiffAvailable'), sds.diff_available ? 'true' : 'false');
|
|
899
839
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
if (fileStats && typeof fileStats === 'object') {
|
|
903
|
-
var counts = fileStats.counts || fileStats;
|
|
904
|
-
var statItems = [
|
|
905
|
-
{ label: 'modified', value: counts.modified != null ? counts.modified : null },
|
|
906
|
-
{ label: 'added', value: counts.added != null ? counts.added : null },
|
|
907
|
-
{ label: 'deleted', value: counts.deleted != null ? counts.deleted : null },
|
|
908
|
-
{ label: 'untracked', value: counts.untracked != null ? counts.untracked : null }
|
|
909
|
-
];
|
|
910
|
-
var hasAny = false;
|
|
911
|
-
statsHtml = statItems.map(function (it) {
|
|
912
|
-
if (it.value === null || it.value === undefined) return '';
|
|
913
|
-
hasAny = true;
|
|
914
|
-
return '<div class="rounded-md px-2 py-1.5" style="background-color: var(--pw-bg); border: 1px solid var(--pw-border-subtle);">'
|
|
915
|
-
+ '<div class="text-xs" style="color: var(--pw-text-tertiary);">' + escapeHtml(it.label) + '</div>'
|
|
916
|
-
+ '<div class="text-sm font-semibold" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">' + escapeHtml(String(it.value)) + '</div>'
|
|
917
|
-
+ '</div>';
|
|
918
|
-
}).join('');
|
|
919
|
-
if (hasAny) {
|
|
920
|
-
show(statsEl);
|
|
921
|
-
statsEl.innerHTML = statsHtml;
|
|
922
|
-
} else {
|
|
923
|
-
hide(statsEl);
|
|
924
|
-
}
|
|
840
|
+
if (sds.diff_truncated || sds.large_diff_omitted) {
|
|
841
|
+
show($('sdTruncatedBlock'));
|
|
925
842
|
} else {
|
|
926
|
-
hide(
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
if (paths.length === 0) {
|
|
930
|
-
hide(bodyEl);
|
|
931
|
-
hide(badgeEl);
|
|
932
|
-
show(emptyEl);
|
|
933
|
-
return;
|
|
843
|
+
hide($('sdTruncatedBlock'));
|
|
934
844
|
}
|
|
935
845
|
|
|
936
|
-
|
|
937
|
-
var
|
|
938
|
-
var
|
|
939
|
-
|
|
940
|
-
|
|
846
|
+
var files = Array.isArray(sds.files) ? sds.files : [];
|
|
847
|
+
var filesHtml = '';
|
|
848
|
+
for (var j = 0; j < files.length; j++) {
|
|
849
|
+
var f = files[j];
|
|
850
|
+
var changeColor = (f.change === 'added' || f.change === 'A') ? 'var(--pw-state-success)' : (f.change === 'deleted' || f.change === 'D') ? 'var(--pw-state-error)' : 'var(--pw-accent)';
|
|
851
|
+
filesHtml += '<div style="margin-bottom:2px;"><span style="color:' + changeColor + ';">' + escapeHtml(f.change || '?') + '</span> <span style="color:var(--pw-text-tertiary);">' + escapeHtml(f.kind || 'file') + '</span> <span style="color:var(--pw-text-primary);">' + escapeHtml(f.path || '') + '</span></div>';
|
|
941
852
|
}
|
|
942
|
-
if (
|
|
943
|
-
|
|
944
|
-
}
|
|
945
|
-
listEl.textContent = listHtml;
|
|
946
|
-
|
|
947
|
-
// Badge
|
|
948
|
-
text(badgeEl, paths.length + ' 个文件');
|
|
949
|
-
show(badgeEl);
|
|
950
|
-
|
|
951
|
-
hide(emptyEl);
|
|
952
|
-
show(bodyEl);
|
|
953
|
-
}
|
|
853
|
+
if (!filesHtml) filesHtml = '<div style="color:var(--pw-text-tertiary);">—</div>';
|
|
854
|
+
$('sdFilesBody').innerHTML = filesHtml;
|
|
954
855
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
var checkedEl = $('vsCheckedAt');
|
|
959
|
-
var cmdsBlock = $('vsCommandsBlock');
|
|
960
|
-
var cmdsEl = $('vsCommands');
|
|
961
|
-
var emptyHint = $('vsEmptyHint');
|
|
962
|
-
|
|
963
|
-
if (!vs) {
|
|
964
|
-
text(statusEl, '—');
|
|
965
|
-
text(checkedEl, '—');
|
|
966
|
-
hide(cmdsBlock);
|
|
967
|
-
show(emptyHint);
|
|
968
|
-
return;
|
|
969
|
-
}
|
|
970
|
-
hide(emptyHint);
|
|
971
|
-
text(statusEl, vs.status || '—');
|
|
972
|
-
text(checkedEl, formatTime(vs.checked_at));
|
|
973
|
-
if (Array.isArray(vs.commands) && vs.commands.length > 0) {
|
|
974
|
-
text(cmdsEl, vs.commands.map(function (c) { return JSON.stringify(c); }).join('\n'));
|
|
975
|
-
show(cmdsBlock);
|
|
856
|
+
if (sds.artifact_hygiene_counts && Object.keys(sds.artifact_hygiene_counts).length > 0) {
|
|
857
|
+
$('sdHygiene').textContent = JSON.stringify(sds.artifact_hygiene_counts, null, 2);
|
|
858
|
+
show($('sdHygieneBlock'));
|
|
976
859
|
} else {
|
|
977
|
-
hide(
|
|
860
|
+
hide($('sdHygieneBlock'));
|
|
978
861
|
}
|
|
979
862
|
}
|
|
980
863
|
|
|
981
|
-
//
|
|
982
|
-
function
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
var
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
var
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
864
|
+
// Render safe_audit card
|
|
865
|
+
function renderSafeAudit(sa) {
|
|
866
|
+
text($('saVerdictBadge'), sa.verdict || '—');
|
|
867
|
+
applyVerdictBadge($('saVerdictBadge'), sa.verdict);
|
|
868
|
+
|
|
869
|
+
var cc = sa.check_counts || {};
|
|
870
|
+
text($('saCountsPass'), String(cc.pass || 0));
|
|
871
|
+
text($('saCountsWarn'), String(cc.warn || 0));
|
|
872
|
+
text($('saCountsFail'), String(cc.fail || 0));
|
|
873
|
+
|
|
874
|
+
var acc = sa.acceptance || {};
|
|
875
|
+
text($('saAccVerdict'), (acc.verdict || '—') + ' / ' + (acc.status || '—'));
|
|
876
|
+
text($('saAccReason'), acc.reason || '—');
|
|
877
|
+
text($('saAccNextTask'), acc.next_suggested_task || '—');
|
|
878
|
+
|
|
879
|
+
var failChecks = Array.isArray(sa.fail_checks) ? sa.fail_checks : [];
|
|
880
|
+
if (failChecks.length > 0) {
|
|
881
|
+
$('saFailChecks').textContent = failChecks.map(function (c) { return c.name || String(c); }).join('\n');
|
|
882
|
+
show($('saFailChecksBlock'));
|
|
883
|
+
} else {
|
|
884
|
+
hide($('saFailChecksBlock'));
|
|
997
885
|
}
|
|
998
|
-
hide(emptyEl);
|
|
999
|
-
show(bodyEl);
|
|
1000
886
|
|
|
1001
|
-
if (
|
|
1002
|
-
|
|
1003
|
-
show(warnBlock);
|
|
887
|
+
if (sa.manual_verification_required) {
|
|
888
|
+
show($('saManualBlock'));
|
|
1004
889
|
} else {
|
|
1005
|
-
hide(
|
|
890
|
+
hide($('saManualBlock'));
|
|
1006
891
|
}
|
|
1007
892
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
893
|
+
var actions = Array.isArray(sa.recommended_next_actions) ? sa.recommended_next_actions : [];
|
|
894
|
+
if (actions.length > 0) {
|
|
895
|
+
$('saActions').textContent = actions.join('\n');
|
|
896
|
+
show($('saActionsBlock'));
|
|
1011
897
|
} else {
|
|
1012
|
-
hide(
|
|
898
|
+
hide($('saActionsBlock'));
|
|
1013
899
|
}
|
|
1014
900
|
}
|
|
1015
901
|
|
|
@@ -1055,7 +941,7 @@ html.dark {
|
|
|
1055
941
|
alert('运行审计失败: ' + msg);
|
|
1056
942
|
} else {
|
|
1057
943
|
alert('审计完成。verdict=' + ((r.data && r.data.audit && r.data.audit.verdict) || '—'));
|
|
1058
|
-
|
|
944
|
+
loadSafeSummary(taskId);
|
|
1059
945
|
}
|
|
1060
946
|
})
|
|
1061
947
|
.catch(function (err) {
|
|
@@ -1089,7 +975,7 @@ html.dark {
|
|
|
1089
975
|
} else {
|
|
1090
976
|
var decision = (r.data && r.data.decision) || '—';
|
|
1091
977
|
alert('Reconcile 完成: ' + decision);
|
|
1092
|
-
|
|
978
|
+
loadSafeSummary(taskId);
|
|
1093
979
|
}
|
|
1094
980
|
})
|
|
1095
981
|
.catch(function (err) {
|
|
@@ -1146,45 +1032,167 @@ html.dark {
|
|
|
1146
1032
|
} catch (e) { /* ignore */ }
|
|
1147
1033
|
}
|
|
1148
1034
|
|
|
1149
|
-
// ----
|
|
1150
|
-
function
|
|
1035
|
+
// ---- Safe summary fetch (4 safe endpoints, parallel; default on init) ----
|
|
1036
|
+
function safeGet(url) {
|
|
1037
|
+
return fetch(url, { method: 'GET', headers: { 'Accept': 'application/json' }, cache: 'no-store' })
|
|
1038
|
+
.then(function (res) {
|
|
1039
|
+
return res.json().then(function (data) {
|
|
1040
|
+
return { ok: res.ok, status: res.status, data: data };
|
|
1041
|
+
});
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
function loadSafeSummary(taskId) {
|
|
1151
1046
|
showLoading();
|
|
1152
|
-
var
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1047
|
+
var base = '/api/tasks/' + encodeURIComponent(taskId);
|
|
1048
|
+
Promise.all([
|
|
1049
|
+
safeGet(base + '/safe-result'),
|
|
1050
|
+
safeGet(base + '/safe-test-summary'),
|
|
1051
|
+
safeGet(base + '/safe-diff-summary'),
|
|
1052
|
+
safeGet(base + '/safe-audit')
|
|
1053
|
+
]).then(function (results) {
|
|
1054
|
+
var safeResult = results[0].data || {};
|
|
1055
|
+
var safeTest = results[1].data || {};
|
|
1056
|
+
var safeDiff = results[2].data || {};
|
|
1057
|
+
var safeAudit = results[3].data || {};
|
|
1058
|
+
|
|
1059
|
+
// If safe-result returned an explicit error and no status, treat as not found.
|
|
1060
|
+
if (safeResult.error && safeResult.status === undefined) {
|
|
1061
|
+
showError('任务不存在', safeResult.error || ('未找到任务 ID: ' + taskId));
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
renderHeader(taskId, safeResult);
|
|
1066
|
+
renderSafeResult(safeResult);
|
|
1067
|
+
renderSafeTestSummary(safeTest);
|
|
1068
|
+
renderSafeDiffSummary(safeDiff);
|
|
1069
|
+
renderSafeAudit(safeAudit);
|
|
1070
|
+
showDetail();
|
|
1071
|
+
}).catch(function (err) {
|
|
1072
|
+
var msg = (err && err.message) ? err.message : '未知错误';
|
|
1073
|
+
if (err && err.name === 'TypeError' && /fetch/i.test(msg)) {
|
|
1074
|
+
showError('无法连接服务', '请确认 PatchWarden Control Center 正在运行 (127.0.0.1:8090)');
|
|
1075
|
+
} else {
|
|
1076
|
+
showError('加载失败', msg);
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// ---- Advanced on-demand loaders (full content; only fetched when clicked) ----
|
|
1082
|
+
// HTML id pattern: advBtn<Suffix>, advSpinner<Suffix>, advPre<Suffix>
|
|
1083
|
+
function setAdvLoading(suffix, loading) {
|
|
1084
|
+
var spinner = $('advSpinner' + suffix);
|
|
1085
|
+
var btn = $('advBtn' + suffix);
|
|
1086
|
+
if (spinner) { if (loading) show(spinner); else hide(spinner); }
|
|
1087
|
+
if (btn) { btn.disabled = loading; btn.style.opacity = loading ? '0.6' : ''; }
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
function showAdvPre(suffix, content) {
|
|
1091
|
+
var pre = $('advPre' + suffix);
|
|
1092
|
+
if (!pre) return;
|
|
1093
|
+
pre.textContent = content;
|
|
1094
|
+
show(pre);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// Load full result (GET /api/tasks/:taskId) — NOT auto-loaded
|
|
1098
|
+
function loadFullResult(taskId) {
|
|
1099
|
+
setAdvLoading('Result', true);
|
|
1100
|
+
fetch('/api/tasks/' + encodeURIComponent(taskId), { method: 'GET', headers: { 'Accept': 'application/json' }, cache: 'no-store' })
|
|
1158
1101
|
.then(function (res) {
|
|
1159
|
-
if (res.status === 404)
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1102
|
+
if (res.status === 404) throw new Error('NOT_FOUND');
|
|
1103
|
+
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
1104
|
+
return res.json();
|
|
1105
|
+
})
|
|
1106
|
+
.then(function (data) {
|
|
1107
|
+
// Refresh header metadata that is only available from the full endpoint.
|
|
1108
|
+
if (data && data.status) {
|
|
1109
|
+
var s = data.status;
|
|
1110
|
+
text($('hdrAgent'), s.agent || '—');
|
|
1111
|
+
text($('hdrCreatedAt'), formatTime(s.created_at));
|
|
1112
|
+
text($('hdrUpdatedAt'), formatTime(s.updated_at));
|
|
1113
|
+
text($('hdrTestCommand'), s.test_command || '—');
|
|
1114
|
+
text($('hdrTimeout'), (s.timeout_seconds === null || s.timeout_seconds === undefined) ? '—' : String(s.timeout_seconds));
|
|
1115
|
+
text($('hdrVerifyCommands'), renderListOrJoin(s.verify_commands));
|
|
1116
|
+
text($('hdrPlanId'), s.plan_id || '—');
|
|
1117
|
+
if (s.error) {
|
|
1118
|
+
text($('hdrErrorText'), escapeText(s.error));
|
|
1119
|
+
show($('hdrErrorBlock'));
|
|
1120
|
+
}
|
|
1164
1121
|
}
|
|
1165
|
-
if (
|
|
1166
|
-
|
|
1167
|
-
throw new Error('HTTP ' + res.status + (body ? (': ' + body.slice(0, 200)) : ''));
|
|
1168
|
-
});
|
|
1122
|
+
if (data && (data.stale || data.reconcile)) {
|
|
1123
|
+
renderStaleBanner(data.stale, data.reconcile);
|
|
1169
1124
|
}
|
|
1125
|
+
showAdvPre('Result', JSON.stringify(data, null, 2));
|
|
1126
|
+
})
|
|
1127
|
+
.catch(function (err) {
|
|
1128
|
+
var msg = (err && err.message) === 'NOT_FOUND' ? '任务不存在' : ((err && err.message) || '未知错误');
|
|
1129
|
+
showAdvPre('Result', '⚠ ' + msg);
|
|
1130
|
+
})
|
|
1131
|
+
.finally(function () { setAdvLoading('Result', false); });
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
// Load full test log portion (GET /api/tasks/:taskId, extract test_log)
|
|
1135
|
+
function loadFullTestLog(taskId) {
|
|
1136
|
+
setAdvLoading('TestLog', true);
|
|
1137
|
+
fetch('/api/tasks/' + encodeURIComponent(taskId), { method: 'GET', headers: { 'Accept': 'application/json' }, cache: 'no-store' })
|
|
1138
|
+
.then(function (res) {
|
|
1139
|
+
if (res.status === 404) throw new Error('NOT_FOUND');
|
|
1140
|
+
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
1170
1141
|
return res.json();
|
|
1171
1142
|
})
|
|
1172
1143
|
.then(function (data) {
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1144
|
+
var testLog = (data && (data.test_log || data.testLog)) || null;
|
|
1145
|
+
showAdvPre('TestLog', testLog ? escapeText(testLog) : '⚠ No test_log available for this task.');
|
|
1146
|
+
})
|
|
1147
|
+
.catch(function (err) {
|
|
1148
|
+
var msg = (err && err.message) === 'NOT_FOUND' ? '任务不存在' : ((err && err.message) || '未知错误');
|
|
1149
|
+
showAdvPre('TestLog', '⚠ ' + msg);
|
|
1150
|
+
})
|
|
1151
|
+
.finally(function () { setAdvLoading('TestLog', false); });
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// Load full diff portion (GET /api/tasks/:taskId, extract diff_patch/diff)
|
|
1155
|
+
function loadFullDiff(taskId) {
|
|
1156
|
+
setAdvLoading('Diff', true);
|
|
1157
|
+
fetch('/api/tasks/' + encodeURIComponent(taskId), { method: 'GET', headers: { 'Accept': 'application/json' }, cache: 'no-store' })
|
|
1158
|
+
.then(function (res) {
|
|
1159
|
+
if (res.status === 404) throw new Error('NOT_FOUND');
|
|
1160
|
+
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
1161
|
+
return res.json();
|
|
1162
|
+
})
|
|
1163
|
+
.then(function (data) {
|
|
1164
|
+
var diff = (data && (data.diff_patch || data.diff || data.diffPatch)) || null;
|
|
1165
|
+
showAdvPre('Diff', diff ? escapeText(diff) : '⚠ No diff available for this task.');
|
|
1177
1166
|
})
|
|
1178
1167
|
.catch(function (err) {
|
|
1179
|
-
var msg = (err && err.message) ? err.message
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1168
|
+
var msg = (err && err.message) === 'NOT_FOUND' ? '任务不存在' : ((err && err.message) || '未知错误');
|
|
1169
|
+
showAdvPre('Diff', '⚠ ' + msg);
|
|
1170
|
+
})
|
|
1171
|
+
.finally(function () { setAdvLoading('Diff', false); });
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
// Run audit_task full review (POST /api/tasks/:taskId/audit with control token)
|
|
1175
|
+
function runFullAuditReview(taskId) {
|
|
1176
|
+
setAdvLoading('Audit', true);
|
|
1177
|
+
postAction('/api/tasks/' + encodeURIComponent(taskId) + '/audit')
|
|
1178
|
+
.then(function (res) {
|
|
1179
|
+
return res.json().then(function (data) { return { ok: res.ok, status: res.status, data: data }; });
|
|
1180
|
+
})
|
|
1181
|
+
.then(function (r) {
|
|
1182
|
+
if (!r.ok) {
|
|
1183
|
+
var msg = (r.data && r.data.error) || ('HTTP ' + r.status);
|
|
1184
|
+
showAdvPre('Audit', '⚠ ' + msg);
|
|
1184
1185
|
} else {
|
|
1185
|
-
|
|
1186
|
+
showAdvPre('Audit', JSON.stringify(r.data, null, 2));
|
|
1187
|
+
// Refresh the safe-audit card so conclusions stay in sync.
|
|
1188
|
+
safeGet('/api/tasks/' + encodeURIComponent(taskId) + '/safe-audit')
|
|
1189
|
+
.then(function (res2) { if (res2.data && !res2.data.error) renderSafeAudit(res2.data); });
|
|
1186
1190
|
}
|
|
1187
|
-
})
|
|
1191
|
+
})
|
|
1192
|
+
.catch(function (err) {
|
|
1193
|
+
showAdvPre('Audit', '⚠ ' + ((err && err.message) || '未知错误'));
|
|
1194
|
+
})
|
|
1195
|
+
.finally(function () { setAdvLoading('Audit', false); });
|
|
1188
1196
|
}
|
|
1189
1197
|
|
|
1190
1198
|
// ---- Entry point ----
|
|
@@ -1193,13 +1201,13 @@ html.dark {
|
|
|
1193
1201
|
if (!taskId) {
|
|
1194
1202
|
showError('缺少 task id', '请在 URL 中提供 ?id=<task_id>');
|
|
1195
1203
|
} else {
|
|
1196
|
-
|
|
1204
|
+
loadSafeSummary(taskId);
|
|
1197
1205
|
}
|
|
1198
1206
|
|
|
1199
1207
|
// ---- Action button wiring ----
|
|
1200
1208
|
var btnRefresh = $('btnRefresh');
|
|
1201
1209
|
if (btnRefresh) btnRefresh.addEventListener('click', function () {
|
|
1202
|
-
if (taskId)
|
|
1210
|
+
if (taskId) loadSafeSummary(taskId);
|
|
1203
1211
|
});
|
|
1204
1212
|
var btnCopyId = $('btnCopyId');
|
|
1205
1213
|
if (btnCopyId) btnCopyId.addEventListener('click', function () {
|
|
@@ -1221,9 +1229,31 @@ html.dark {
|
|
|
1221
1229
|
if (!confirm('确认 reconcile 该任务?将写入 reconcile 记录(不会删除任务)。')) return;
|
|
1222
1230
|
runReconcile(taskId);
|
|
1223
1231
|
});
|
|
1232
|
+
|
|
1233
|
+
// ---- Advanced section on-demand button wiring ----
|
|
1234
|
+
var advBtnResult = $('advBtnResult');
|
|
1235
|
+
if (advBtnResult) advBtnResult.addEventListener('click', function () {
|
|
1236
|
+
if (taskId) loadFullResult(taskId);
|
|
1237
|
+
});
|
|
1238
|
+
var advBtnTestLog = $('advBtnTestLog');
|
|
1239
|
+
if (advBtnTestLog) advBtnTestLog.addEventListener('click', function () {
|
|
1240
|
+
if (taskId) loadFullTestLog(taskId);
|
|
1241
|
+
});
|
|
1242
|
+
var advBtnDiff = $('advBtnDiff');
|
|
1243
|
+
if (advBtnDiff) advBtnDiff.addEventListener('click', function () {
|
|
1244
|
+
if (taskId) loadFullDiff(taskId);
|
|
1245
|
+
});
|
|
1246
|
+
var advBtnAudit = $('advBtnAudit');
|
|
1247
|
+
if (advBtnAudit) advBtnAudit.addEventListener('click', function () {
|
|
1248
|
+
if (!taskId) return;
|
|
1249
|
+
if (!confirm('确认运行 audit_task 完整审计?')) return;
|
|
1250
|
+
runFullAuditReview(taskId);
|
|
1251
|
+
});
|
|
1224
1252
|
})();
|
|
1225
1253
|
</script>
|
|
1226
1254
|
|
|
1227
1255
|
<script>lucide.createIcons();</script>
|
|
1256
|
+
<script src="/i18n.js"></script>
|
|
1257
|
+
<script src="/desktop-bridge.js"></script>
|
|
1228
1258
|
</body>
|
|
1229
1259
|
</html>
|