patchwarden 1.5.1 → 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 +152 -25
- package/README.md +120 -23
- package/dist/assessments/agentAssessor.js +21 -12
- package/dist/assessments/assessmentStore.js +42 -34
- package/dist/config.d.ts +15 -0
- package/dist/config.js +66 -13
- package/dist/control/fileManager.d.ts +2 -0
- package/dist/control/fileManager.js +39 -0
- package/dist/control/middleware/auth.d.ts +6 -0
- package/dist/control/middleware/auth.js +14 -5
- package/dist/control/middleware/static.js +16 -3
- package/dist/control/routeTable.d.ts +24 -0
- package/dist/control/routeTable.js +263 -0
- package/dist/control/routes/audit.js +17 -7
- package/dist/control/routes/evidence.js +1 -1
- package/dist/control/routes/lineage.js +1 -1
- package/dist/control/routes/process.d.ts +7 -0
- package/dist/control/routes/process.js +329 -42
- package/dist/control/routes/sessions.d.ts +9 -1
- package/dist/control/routes/sessions.js +84 -21
- package/dist/control/routes/status.d.ts +46 -1
- package/dist/control/routes/status.js +72 -15
- package/dist/control/routes/taskActions.js +24 -60
- package/dist/control/routes/tasks.d.ts +4 -0
- package/dist/control/routes/tasks.js +61 -62
- package/dist/control/routes/workspace.js +50 -23
- package/dist/control/runtime.d.ts +3 -2
- package/dist/control/runtime.js +63 -30
- package/dist/control/server.js +36 -365
- package/dist/control/shared.d.ts +25 -1
- package/dist/control/shared.js +64 -11
- package/dist/direct/directAudit.js +234 -225
- package/dist/direct/directGuards.d.ts +2 -1
- package/dist/direct/directGuards.js +42 -29
- 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.js +62 -52
- package/dist/goal/acceptanceEngine.d.ts +1 -1
- package/dist/goal/goalProgress.js +75 -69
- package/dist/goal/goalReport.js +5 -12
- package/dist/goal/goalStatus.d.ts +2 -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.js +97 -96
- package/dist/goal/subgoalSync.js +11 -9
- package/dist/goal/worktreeManager.d.ts +2 -0
- package/dist/goal/worktreeManager.js +209 -136
- package/dist/httpServer.js +111 -32
- package/dist/logging.js +5 -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 +13 -5
- package/dist/runner/changeCapture.js +243 -61
- package/dist/runner/postTaskCleanup.js +48 -19
- 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 +115 -87
- package/dist/runner/simpleProcess.d.ts +3 -0
- package/dist/runner/simpleProcess.js +50 -36
- 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 +256 -48
- package/dist/security/contentRedaction.js +2 -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 +24 -23
- 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} +6 -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} +1 -1
- package/dist/tools/{auditTask.js → diagnostics/auditTask.js} +99 -29
- package/dist/tools/{healthCheck.d.ts → diagnostics/healthCheck.d.ts} +6 -6
- package/dist/tools/{healthCheck.js → diagnostics/healthCheck.js} +7 -7
- 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} +12 -8
- package/dist/tools/{safeViews.js → diagnostics/safeViews.js} +23 -13
- 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.js → direct/createDirectSession.js} +6 -6
- package/dist/tools/{finalizeDirectSession.d.ts → direct/finalizeDirectSession.d.ts} +1 -1
- 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.js +32 -31
- package/dist/tools/dispatch/diagnosticDispatch.d.ts +3 -5
- package/dist/tools/dispatch/diagnosticDispatch.js +70 -68
- package/dist/tools/dispatch/directDispatch.js +11 -10
- package/dist/tools/dispatch/goalDispatch.js +5 -4
- package/dist/tools/dispatch/releaseDispatch.js +3 -2
- 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} +1 -1
- 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 +7 -11
- package/dist/tools/registry.js +17 -1178
- 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} +10 -2
- package/dist/tools/{createTask.js → tasks/createTask.js} +42 -27
- 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.js → tasks/evidencePack.js} +34 -22
- 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/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} +58 -30
- 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 +808 -143
- package/docs/architecture.md +15 -55
- package/docs/assets/patchwarden-desktop-onboarding.png +0 -0
- package/docs/control-center/README.md +4 -4
- package/docs/dashboard-overview.md +4 -4
- package/docs/desktop-app.md +175 -0
- package/docs/evidence-pack-schema.md +3 -3
- package/docs/open-source-application.md +17 -11
- package/docs/release-checklist.md +1 -1
- package/docs/release-evidence.md +39 -29
- package/docs/task-safe-review-workflow.md +5 -5
- package/docs/threat-model.md +19 -1
- package/examples/config.example.json +4 -2
- package/package.json +27 -10
- 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 +91 -6
- package/scripts/checks/control-smoke.js +19 -8
- package/scripts/checks/http-mcp-smoke.js +82 -4
- package/scripts/checks/lifecycle-smoke.js +10 -10
- package/scripts/checks/mcp-manifest-check.js +1 -1
- package/scripts/checks/mcp-smoke.js +27 -3
- 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/{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 +26 -12
- package/src/assessments/assessmentStore.ts +52 -40
- package/src/config.ts +70 -13
- package/src/control/fileManager.ts +40 -0
- package/src/control/middleware/auth.ts +22 -4
- package/src/control/middleware/static.ts +16 -3
- package/src/control/routeTable.ts +301 -0
- package/src/control/routes/audit.ts +14 -6
- package/src/control/routes/evidence.ts +1 -1
- package/src/control/routes/lineage.ts +1 -1
- package/src/control/routes/process.ts +341 -40
- package/src/control/routes/sessions.ts +88 -25
- package/src/control/routes/status.ts +97 -17
- package/src/control/routes/taskActions.ts +24 -58
- package/src/control/routes/tasks.ts +66 -58
- package/src/control/routes/workspace.ts +56 -25
- package/src/control/runtime.ts +69 -33
- package/src/control/server.ts +36 -342
- package/src/control/shared.ts +77 -11
- package/src/direct/directAudit.ts +17 -9
- package/src/direct/directGuards.ts +72 -44
- 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 +73 -59
- package/src/goal/acceptanceEngine.ts +1 -1
- package/src/goal/goalProgress.ts +17 -13
- package/src/goal/goalReport.ts +5 -13
- package/src/goal/goalStatus.ts +19 -3
- package/src/goal/goalStore.ts +241 -54
- package/src/goal/handoffExport.ts +6 -6
- package/src/goal/specKitImport.ts +12 -12
- package/src/goal/subgoalSync.ts +11 -8
- package/src/goal/worktreeManager.ts +139 -22
- package/src/httpServer.ts +113 -30
- package/src/logging.ts +10 -3
- 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 +291 -57
- package/src/runner/postTaskCleanup.ts +41 -17
- package/src/runner/processSecurity.ts +433 -0
- package/src/runner/runTask.ts +138 -91
- package/src/runner/simpleProcess.ts +66 -31
- 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 +281 -51
- package/src/security/contentRedaction.ts +2 -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 +25 -24
- 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} +7 -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} +99 -32
- package/src/tools/{healthCheck.ts → diagnostics/healthCheck.ts} +8 -8
- 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} +27 -17
- package/src/tools/{schemaDriftCheck.ts → diagnostics/schemaDriftCheck.ts} +3 -3
- package/src/tools/{createDirectSession.ts → direct/createDirectSession.ts} +6 -6
- package/src/tools/{finalizeDirectSession.ts → direct/finalizeDirectSession.ts} +7 -5
- 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 +36 -31
- package/src/tools/dispatch/diagnosticDispatch.ts +26 -21
- package/src/tools/dispatch/directDispatch.ts +11 -10
- package/src/tools/dispatch/goalDispatch.ts +5 -4
- package/src/tools/dispatch/releaseDispatch.ts +3 -2
- 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} +41 -26
- package/src/tools/goals/index.ts +3 -0
- package/src/tools/{savePlan.ts → goals/savePlan.ts} +38 -8
- package/src/tools/registry.ts +17 -1261
- 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} +49 -26
- package/src/tools/{diagnoseTask.ts → tasks/diagnoseTask.ts} +8 -8
- package/src/tools/{evidencePack.ts → tasks/evidencePack.ts} +36 -22
- 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} +69 -34
- 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 +12 -0
- package/ui/pages/dashboard.html +90 -147
- package/ui/pages/direct-sessions.html +123 -26
- 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 +12 -0
- package/ui/pages/tasks.html +54 -8
- 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/apply-patch.test.d.ts +0 -1
- package/dist/test/unit/apply-patch.test.js +0 -225
- 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/create-task.test.d.ts +0 -1
- package/dist/test/unit/create-task.test.js +0 -197
- 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 -328
- 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 -224
- package/dist/test/unit/get-task-status.test.d.ts +0 -1
- package/dist/test/unit/get-task-status.test.js +0 -174
- package/dist/test/unit/get-task-summary.test.d.ts +0 -1
- package/dist/test/unit/get-task-summary.test.js +0 -146
- 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-report.test.d.ts +0 -1
- package/dist/test/unit/goal-report.test.js +0 -159
- 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 -192
- 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 -133
- 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/spec-kit-import.test.d.ts +0 -1
- package/dist/test/unit/spec-kit-import.test.js +0 -341
- 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/wait-for-task.test.d.ts +0 -1
- package/dist/test/unit/wait-for-task.test.js +0 -144
- 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/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/execution-plan-2026-07-09.md +0 -315
- 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/docs/roadmap-execution-and-acceptance.md +0 -365
- 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/apply-patch.test.ts +0 -293
- 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/create-task.test.ts +0 -255
- package/src/test/unit/diagnose-task.test.ts +0 -544
- package/src/test/unit/direct-guards.test.ts +0 -467
- package/src/test/unit/discovery-token-store.test.ts +0 -181
- package/src/test/unit/evidence-pack.test.ts +0 -251
- package/src/test/unit/get-task-status.test.ts +0 -203
- package/src/test/unit/get-task-summary.test.ts +0 -173
- 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-report.test.ts +0 -189
- 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 -245
- 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 -180
- 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/spec-kit-import.test.ts +0 -429
- 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/wait-for-task.test.ts +0 -176
- 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/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/{createDirectSession.d.ts → direct/createDirectSession.d.ts} +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/{evidencePack.d.ts → tasks/evidencePack.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/{retryTask.d.ts → tasks/retryTask.d.ts} +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
package/ui/pages/dashboard.html
CHANGED
|
@@ -133,6 +133,8 @@ html.dark {
|
|
|
133
133
|
background-color: currentColor;
|
|
134
134
|
}
|
|
135
135
|
</style>
|
|
136
|
+
<script src="/desktop-bootstrap.js"></script>
|
|
137
|
+
<link rel="stylesheet" href="/desktop.css">
|
|
136
138
|
</head>
|
|
137
139
|
<body class="flex h-screen overflow-hidden">
|
|
138
140
|
|
|
@@ -150,6 +152,10 @@ html.dark {
|
|
|
150
152
|
|
|
151
153
|
<!-- Navigation -->
|
|
152
154
|
<nav class="flex-1 flex flex-col gap-1 px-3 pt-4 overflow-y-auto">
|
|
155
|
+
<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);">
|
|
156
|
+
<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>
|
|
157
|
+
<span class="truncate" data-i18n="nav.gettingStarted">开始使用</span>
|
|
158
|
+
</a>
|
|
153
159
|
|
|
154
160
|
<a href="/pages/dashboard.html" data-nav-key="dashboard" data-active="true" 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);">
|
|
155
161
|
<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">
|
|
@@ -205,6 +211,10 @@ html.dark {
|
|
|
205
211
|
<span class="truncate" data-zh="日志" data-en="Logs">日志</span>
|
|
206
212
|
</a>
|
|
207
213
|
|
|
214
|
+
<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);">
|
|
215
|
+
<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>
|
|
216
|
+
<span class="truncate" data-i18n="nav.settings">设置</span>
|
|
217
|
+
</a>
|
|
208
218
|
</nav>
|
|
209
219
|
|
|
210
220
|
<!-- Bottom Section -->
|
|
@@ -238,63 +248,67 @@ html.dark {
|
|
|
238
248
|
<main class="flex-1 overflow-y-auto p-6" style="background-color: var(--pw-bg-elevated);">
|
|
239
249
|
|
|
240
250
|
<!-- ===== TOP TOOLBAR ===== -->
|
|
241
|
-
<div class="
|
|
251
|
+
<div class="pw-dashboard-toolbar mb-4">
|
|
252
|
+
<div class="pw-toolbar-actions">
|
|
242
253
|
<button data-action="start-all" class="flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap" style="background-color: var(--pw-state-success); color: var(--pw-text-inverse); font-family: var(--pw-font-sans);">
|
|
243
254
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
|
244
|
-
<span
|
|
255
|
+
<span data-zh="全部启动" data-en="Start All">全部启动</span>
|
|
245
256
|
</button>
|
|
246
257
|
<button data-action="stop-all" class="flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap" style="background-color: var(--pw-state-error); color: #fff; font-family: var(--pw-font-sans);">
|
|
247
258
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="6" width="12" height="12" rx="1"/></svg>
|
|
248
|
-
<span
|
|
259
|
+
<span data-zh="全部停止" data-en="Stop All">全部停止</span>
|
|
249
260
|
</button>
|
|
250
261
|
<button data-action="restart-all" class="flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap" style="background-color: var(--pw-state-warning); color: var(--pw-text-inverse); font-family: var(--pw-font-sans);">
|
|
251
262
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/></svg>
|
|
252
|
-
<span
|
|
263
|
+
<span data-zh="全部重启" data-en="Restart All">全部重启</span>
|
|
253
264
|
</button>
|
|
254
265
|
<button data-action="refresh" class="flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap" style="background-color: var(--pw-bg-surface); color: var(--pw-text-primary); border: 1px solid var(--pw-border); font-family: var(--pw-font-sans);">
|
|
255
266
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/></svg>
|
|
256
|
-
<span
|
|
267
|
+
<span data-zh="刷新" data-en="Refresh">刷新</span>
|
|
257
268
|
</button>
|
|
258
|
-
|
|
269
|
+
</div>
|
|
270
|
+
<div class="pw-toolbar-repo flex items-center gap-2 px-3 py-1.5 rounded-lg" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border); font-family: var(--pw-font-sans);">
|
|
259
271
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color: var(--pw-text-tertiary);"><path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2z"/></svg>
|
|
260
272
|
<select id="repo-selector" class="bg-transparent text-sm outline-none cursor-pointer" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans); min-width: 180px;">
|
|
261
|
-
<option value="."
|
|
273
|
+
<option value=".">工作区根目录</option>
|
|
262
274
|
</select>
|
|
263
275
|
</div>
|
|
264
|
-
<div class="
|
|
276
|
+
<div class="pw-toolbar-links">
|
|
265
277
|
<button data-action="open-core-tunnel" class="flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap" style="background-color: transparent; color: var(--pw-accent); border: 1px solid var(--pw-accent); font-family: var(--pw-font-sans);">
|
|
266
278
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
|
|
267
|
-
<span
|
|
279
|
+
<span data-zh="Core 隧道" data-en="Open Core Tunnel UI">Core 隧道</span>
|
|
268
280
|
</button>
|
|
269
281
|
<button data-action="open-direct-tunnel" class="flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap" style="background-color: transparent; color: var(--pw-accent); border: 1px solid var(--pw-accent); font-family: var(--pw-font-sans);">
|
|
270
282
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
|
|
271
|
-
<span
|
|
283
|
+
<span data-zh="Direct 隧道" data-en="Open Direct Tunnel UI">Direct 隧道</span>
|
|
272
284
|
</button>
|
|
273
285
|
<button data-action="open-logs-folder" class="flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap" style="background-color: var(--pw-bg-surface); color: var(--pw-text-primary); border: 1px solid var(--pw-border); font-family: var(--pw-font-sans);">
|
|
274
286
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2z"/></svg>
|
|
275
|
-
<span
|
|
287
|
+
<span data-zh="日志目录" data-en="Open Logs Folder">日志目录</span>
|
|
276
288
|
</button>
|
|
289
|
+
</div>
|
|
277
290
|
</div>
|
|
278
291
|
|
|
279
292
|
<!-- ===== ERROR BANNER ===== -->
|
|
280
293
|
<div id="error-banner" class="hidden mb-4 rounded-lg px-4 py-3 text-sm" style="background-color: var(--pw-state-error-bg); border: 1px solid var(--pw-state-error); color: var(--pw-state-error); font-family: var(--pw-font-sans);"></div>
|
|
281
294
|
|
|
282
|
-
<!-- =====
|
|
295
|
+
<!-- ===== LIVE READINESS CARD ===== -->
|
|
296
|
+
<div class="mb-2"><h2 class="text-xs font-semibold uppercase tracking-wide" style="color:var(--pw-text-tertiary);" data-zh="运行状态" data-en="Live status">运行状态</h2></div>
|
|
283
297
|
<div id="health-score-card" class="rounded-lg mb-4" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
284
298
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
285
|
-
<h2 class="text-sm font-semibold truncate" data-zh="
|
|
299
|
+
<h2 class="text-sm font-semibold truncate" data-zh="实时就绪状态" data-en="Live Readiness" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">实时就绪状态</h2>
|
|
286
300
|
<span id="health-score-badge" class="text-xs font-semibold px-2.5 py-1 rounded-full whitespace-nowrap" style="color: var(--pw-text-tertiary); background-color: var(--pw-bg-hover);">—</span>
|
|
287
301
|
</div>
|
|
288
302
|
<div id="health-score-body" class="px-4 py-3 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-2">
|
|
289
|
-
<div class="text-xs" style="color: var(--pw-text-tertiary);"
|
|
303
|
+
<div class="text-xs" style="color: var(--pw-text-tertiary);">正在加载…</div>
|
|
290
304
|
</div>
|
|
291
305
|
</div>
|
|
292
306
|
|
|
293
307
|
<!-- ===== SETUP CHECKLIST ===== -->
|
|
294
308
|
<div id="setup-checklist-card" class="rounded-lg mb-4" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
295
309
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
296
|
-
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);"
|
|
297
|
-
<span id="setup-checklist-summary" class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);"
|
|
310
|
+
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);">启动准备</h2>
|
|
311
|
+
<span id="setup-checklist-summary" class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);">正在检查</span>
|
|
298
312
|
</div>
|
|
299
313
|
<div id="setup-checklist-body" class="grid grid-cols-1 md:grid-cols-3 gap-0"></div>
|
|
300
314
|
</div>
|
|
@@ -313,6 +327,7 @@ html.dark {
|
|
|
313
327
|
</div>
|
|
314
328
|
|
|
315
329
|
<!-- ===== HEALTH SUGGESTIONS CARD ===== -->
|
|
330
|
+
<div class="mb-2"><h2 class="text-xs font-semibold uppercase tracking-wide" style="color:var(--pw-text-tertiary);" data-zh="待处理项" data-en="Needs attention">待处理项</h2></div>
|
|
316
331
|
<div id="suggestions-card" class="hidden rounded-lg mb-6" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
317
332
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
318
333
|
<h2 class="text-sm font-semibold truncate" data-zh="健康建议" data-en="Health Suggestions" style="color: var(--pw-text-primary);">健康建议</h2>
|
|
@@ -322,44 +337,45 @@ html.dark {
|
|
|
322
337
|
</div>
|
|
323
338
|
|
|
324
339
|
<!-- ===== V1.5 RELEASE / POLICY / LINEAGE / EVIDENCE OVERVIEW ===== -->
|
|
340
|
+
<div class="mb-2 flex items-center justify-between gap-3"><h2 class="text-xs font-semibold uppercase tracking-wide" style="color:var(--pw-text-tertiary);" data-zh="历史概览" data-en="History overview">历史概览</h2><span class="text-xs" style="color:var(--pw-text-tertiary);" data-zh="历史任务、审计和发布检查不影响实时健康" data-en="History, audits, and release checks do not affect live health">历史任务、审计和发布检查不影响实时健康</span></div>
|
|
325
341
|
<div class="grid grid-cols-1 lg:grid-cols-4 gap-4 mb-6">
|
|
326
342
|
<div class="rounded-lg" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
327
343
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
328
|
-
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);"
|
|
344
|
+
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);">任务链路</h2>
|
|
329
345
|
<span id="lineage-count" class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);">...</span>
|
|
330
346
|
</div>
|
|
331
|
-
<div id="lineage-overview-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);"
|
|
347
|
+
<div id="lineage-overview-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);">正在加载…</div>
|
|
332
348
|
</div>
|
|
333
349
|
<div class="rounded-lg" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
334
350
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
335
|
-
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);"
|
|
351
|
+
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);">项目策略</h2>
|
|
336
352
|
<span id="policy-status" class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);">...</span>
|
|
337
353
|
</div>
|
|
338
|
-
<div id="policy-overview-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);"
|
|
354
|
+
<div id="policy-overview-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);">正在加载…</div>
|
|
339
355
|
</div>
|
|
340
356
|
<div class="rounded-lg" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
341
357
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
342
|
-
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);"
|
|
358
|
+
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);">发布检查</h2>
|
|
343
359
|
<span id="release-status" class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);">...</span>
|
|
344
360
|
</div>
|
|
345
|
-
<div id="release-overview-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);"
|
|
361
|
+
<div id="release-overview-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);">正在加载…</div>
|
|
346
362
|
</div>
|
|
347
363
|
<div id="evidence-pack-card" class="rounded-lg" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
348
364
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
349
|
-
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);"
|
|
365
|
+
<h2 class="text-sm font-semibold truncate" style="color: var(--pw-text-primary);">证据包</h2>
|
|
350
366
|
<span id="evidence-pack-status" class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);">...</span>
|
|
351
367
|
</div>
|
|
352
|
-
<div id="evidence-pack-overview-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);"
|
|
368
|
+
<div id="evidence-pack-overview-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);">正在加载…</div>
|
|
353
369
|
</div>
|
|
354
370
|
</div>
|
|
355
371
|
|
|
356
372
|
<!-- ===== STALE TASKS CARD ===== -->
|
|
357
373
|
<div id="stale-tasks-card" class="hidden rounded-lg mb-6" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border); border-left: 3px solid var(--pw-state-warning);">
|
|
358
374
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
359
|
-
<h2 class="text-sm font-semibold truncate" data-zh="
|
|
375
|
+
<h2 class="text-sm font-semibold truncate" data-zh="过期任务" data-en="Stale Tasks" style="color: var(--pw-text-primary);">过期任务</h2>
|
|
360
376
|
<span id="stale-tasks-count" class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);">—</span>
|
|
361
377
|
</div>
|
|
362
|
-
<div id="stale-tasks-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);"
|
|
378
|
+
<div id="stale-tasks-body" class="px-4 py-3 text-sm" style="color: var(--pw-text-tertiary);">正在加载…</div>
|
|
363
379
|
</div>
|
|
364
380
|
|
|
365
381
|
<!-- ===== TWO-COLUMN LAYOUT ===== -->
|
|
@@ -396,7 +412,7 @@ html.dark {
|
|
|
396
412
|
<div class="rounded-lg mb-6" style="background-color: var(--pw-bg-surface); border: 1px solid var(--pw-border);">
|
|
397
413
|
<div class="flex items-center justify-between px-4 py-3" style="border-bottom: 1px solid var(--pw-border);">
|
|
398
414
|
<h2 class="text-sm font-semibold truncate" data-zh="活动日志" data-en="Activity Log" style="color: var(--pw-text-primary);">活动日志</h2>
|
|
399
|
-
<span class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);">Core + Direct
|
|
415
|
+
<span class="text-xs whitespace-nowrap" style="color: var(--pw-text-tertiary);">Core + Direct 输出摘要</span>
|
|
400
416
|
</div>
|
|
401
417
|
<div id="activity-log-body">
|
|
402
418
|
<div class="px-4 py-3 text-xs" style="color: var(--pw-text-tertiary);">加载日志中…</div>
|
|
@@ -736,26 +752,26 @@ html.dark {
|
|
|
736
752
|
{
|
|
737
753
|
label: 'tunnel-client.exe',
|
|
738
754
|
ok: !!tunnel.available,
|
|
739
|
-
value: tunnel.available ? (tunnel.path || '
|
|
740
|
-
hint: tunnel.available ? '
|
|
755
|
+
value: tunnel.available ? (tunnel.path || '已找到') : '未找到',
|
|
756
|
+
hint: tunnel.available ? '已可供桌面启动和重启使用。' : '请在设置中自动检测或选择 tunnel-client.exe。'
|
|
741
757
|
},
|
|
742
758
|
{
|
|
743
|
-
label: '
|
|
759
|
+
label: '工作区',
|
|
744
760
|
ok: !!workspaceRoot,
|
|
745
|
-
value: workspaceRoot || '
|
|
746
|
-
hint: '
|
|
761
|
+
value: workspaceRoot || '未加载',
|
|
762
|
+
hint: 'PatchWarden 任务仅在此工作区内运行。'
|
|
747
763
|
},
|
|
748
764
|
{
|
|
749
|
-
label: '
|
|
765
|
+
label: '任务监视器',
|
|
750
766
|
ok: watcher.status === 'healthy',
|
|
751
|
-
value: watcher.status || '
|
|
752
|
-
hint: watcher.status === 'healthy' ? '
|
|
767
|
+
value: watcher.status || '未运行',
|
|
768
|
+
hint: watcher.status === 'healthy' ? '任务监视器运行正常。' : (watcher.reason || '启动 Core 后,任务监视器会处理排队任务。')
|
|
753
769
|
}
|
|
754
770
|
];
|
|
755
771
|
|
|
756
772
|
const missingCount = items.filter(function (item) { return !item.ok; }).length;
|
|
757
773
|
if (summary) {
|
|
758
|
-
summary.textContent = missingCount === 0 ? '
|
|
774
|
+
summary.textContent = missingCount === 0 ? '已就绪' : (missingCount + ' 项需要处理');
|
|
759
775
|
summary.style.color = missingCount === 0 ? 'var(--pw-state-success)' : 'var(--pw-state-warning)';
|
|
760
776
|
}
|
|
761
777
|
|
|
@@ -768,7 +784,7 @@ html.dark {
|
|
|
768
784
|
+ '<div class="flex items-center gap-2 mb-1">'
|
|
769
785
|
+ dotHtml(kind)
|
|
770
786
|
+ '<span class="text-xs font-semibold whitespace-nowrap" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">' + escapeHtml(item.label) + '</span>'
|
|
771
|
-
+ '<span class="ml-auto text-xs px-2 py-0.5 rounded-full" style="color: ' + c.color + '; background-color: ' + c.bg + ';">' + (item.ok ? '
|
|
787
|
+
+ '<span class="ml-auto text-xs px-2 py-0.5 rounded-full" style="color: ' + c.color + '; background-color: ' + c.bg + ';">' + (item.ok ? '正常' : '处理') + '</span>'
|
|
772
788
|
+ '</div>'
|
|
773
789
|
+ '<div class="text-xs truncate" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono);" title="' + escapeHtml(item.value) + '">' + escapeHtml(item.value) + '</div>'
|
|
774
790
|
+ '<div class="text-xs mt-1" style="color: var(--pw-text-tertiary);">' + escapeHtml(item.hint) + '</div>'
|
|
@@ -946,9 +962,11 @@ html.dark {
|
|
|
946
962
|
let data = null;
|
|
947
963
|
try { data = await res.json(); } catch (_) { /* ignore */ }
|
|
948
964
|
if (!res.ok) {
|
|
949
|
-
|
|
965
|
+
var msg = (data && (data.error || data.reason || data.message)) || ('HTTP ' + res.status);
|
|
966
|
+
if (data && Array.isArray(data.next_steps) && data.next_steps.length) msg += ' 下一步:' + data.next_steps.join(';');
|
|
950
967
|
throw new Error(msg);
|
|
951
968
|
}
|
|
969
|
+
if (data && data.ok === false) throw new Error(data.error || data.reason || '操作未完成');
|
|
952
970
|
return data;
|
|
953
971
|
} finally {
|
|
954
972
|
if (btnEl) {
|
|
@@ -1167,11 +1185,12 @@ html.dark {
|
|
|
1167
1185
|
const tunnel = (status && status.tunnel) || {};
|
|
1168
1186
|
const tools = (status && status.tools && status.tools.core) || {};
|
|
1169
1187
|
const agents = (status && status.agents) || [];
|
|
1188
|
+
const directProfileEnabled = !!(status && status.direct_profile_enabled);
|
|
1170
1189
|
|
|
1171
1190
|
const watcherKind = statusKind(watcher.status);
|
|
1172
1191
|
const coreReady = !!(tunnel.core && tunnel.core.ready);
|
|
1173
1192
|
const directReady = !!(tunnel.direct && tunnel.direct.ready);
|
|
1174
|
-
const tunnelReady = coreReady && directReady;
|
|
1193
|
+
const tunnelReady = coreReady && (!directProfileEnabled || directReady);
|
|
1175
1194
|
const tunnelKind = tunnelReady ? 'success' : (coreReady || directReady ? 'warning' : 'error');
|
|
1176
1195
|
|
|
1177
1196
|
let agentsHtml = '';
|
|
@@ -1201,7 +1220,7 @@ html.dark {
|
|
|
1201
1220
|
row('Watcher',
|
|
1202
1221
|
'<span class="text-xs whitespace-nowrap" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">' + watcherText + '</span>',
|
|
1203
1222
|
watcherKind)
|
|
1204
|
-
+ row('
|
|
1223
|
+
+ row('隧道就绪',
|
|
1205
1224
|
'<span class="text-xs whitespace-nowrap" style="color: var(--pw-text-primary); font-family: var(--pw-font-mono);">core ' + (coreReady ? '✓' : '✗') + ' / direct ' + (directReady ? '✓' : '✗') + '</span>',
|
|
1206
1225
|
tunnelKind)
|
|
1207
1226
|
+ row('schema_epoch',
|
|
@@ -1339,7 +1358,7 @@ html.dark {
|
|
|
1339
1358
|
|
|
1340
1359
|
el.innerHTML =
|
|
1341
1360
|
'<details class="px-4 py-3">'
|
|
1342
|
-
+ '<summary class="cursor-pointer text-xs font-medium" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);"
|
|
1361
|
+
+ '<summary class="cursor-pointer text-xs font-medium" style="color: var(--pw-text-primary); font-family: var(--pw-font-sans);">查看 Core / Direct 本次日志尾部</summary>'
|
|
1343
1362
|
+ '<pre class="mt-3 text-xs overflow-auto m-0" style="color: var(--pw-text-secondary); font-family: var(--pw-font-mono); white-space: pre-wrap; word-break: break-all; max-height: 320px;">' + escapeHtml(merged) + '</pre>'
|
|
1344
1363
|
+ '</details>';
|
|
1345
1364
|
}
|
|
@@ -1355,10 +1374,10 @@ html.dark {
|
|
|
1355
1374
|
if (count) count.textContent = String(data.total || lineages.length);
|
|
1356
1375
|
if (!lineages.length) {
|
|
1357
1376
|
body.innerHTML =
|
|
1358
|
-
'<div class="text-xs mb-2" style="color: var(--pw-text-tertiary);"
|
|
1377
|
+
'<div class="text-xs mb-2" style="color: var(--pw-text-tertiary);">暂无任务链路</div>'
|
|
1359
1378
|
+ '<div class="flex items-center gap-2">'
|
|
1360
|
-
+ '<a href="/tasks.html" class="text-xs px-2.5 py-1 rounded whitespace-nowrap" style="background-color: var(--pw-accent-muted); color: var(--pw-accent); border: 1px solid var(--pw-accent);"
|
|
1361
|
-
+ '<a href="/tasks.html" class="text-xs px-2.5 py-1 rounded whitespace-nowrap" style="background-color: var(--pw-bg-hover); color: var(--pw-text-secondary); border: 1px solid var(--pw-border-subtle);"
|
|
1379
|
+
+ '<a href="/tasks.html" class="text-xs px-2.5 py-1 rounded whitespace-nowrap" style="background-color: var(--pw-accent-muted); color: var(--pw-accent); border: 1px solid var(--pw-accent);">创建受控任务链</a>'
|
|
1380
|
+
+ '<a href="/tasks.html" class="text-xs px-2.5 py-1 rounded whitespace-nowrap" style="background-color: var(--pw-bg-hover); color: var(--pw-text-secondary); border: 1px solid var(--pw-border-subtle);">查看最近运行</a>'
|
|
1362
1381
|
+ '</div>';
|
|
1363
1382
|
return;
|
|
1364
1383
|
}
|
|
@@ -1486,55 +1505,26 @@ html.dark {
|
|
|
1486
1505
|
+ section('Direct Verification', directSessions, directRow);
|
|
1487
1506
|
}
|
|
1488
1507
|
|
|
1489
|
-
// ----------
|
|
1490
|
-
//
|
|
1491
|
-
//
|
|
1492
|
-
function calculateHealthScore(status
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
const policyValid = opts.policyValid === true;
|
|
1497
|
-
const releaseReady = opts.releaseReady === true;
|
|
1498
|
-
const directProfileEnabled = opts.directProfileEnabled === true;
|
|
1499
|
-
|
|
1500
|
-
const watcher = (status && status.watcher) || {};
|
|
1501
|
-
const tunnel = (status && status.tunnel) || {};
|
|
1502
|
-
const agents = (status && status.agents) || [];
|
|
1503
|
-
|
|
1504
|
-
const watcherHealthy = watcher.status === 'healthy';
|
|
1505
|
-
const coreReady = !!(tunnel.core && tunnel.core.ready);
|
|
1506
|
-
const directReady = !!(tunnel.direct && tunnel.direct.ready);
|
|
1507
|
-
const tunnelReady = coreReady && directReady;
|
|
1508
|
-
const agentsAvailable = Array.isArray(agents) && agents.some(function (a) { return a && a.available; });
|
|
1509
|
-
|
|
1510
|
-
const dimensions = [
|
|
1511
|
-
{ key: 'watcher_healthy', label: 'Watcher healthy', ok: watcherHealthy, detail: watcher.status || 'unknown' },
|
|
1512
|
-
{ key: 'tunnel_ready', label: 'Tunnel ready', ok: tunnelReady, detail: 'core ' + (coreReady ? '✓' : '✗') + ' / direct ' + (directReady ? '✓' : '✗') },
|
|
1513
|
-
{ key: 'agents_available', label: 'Agents available', ok: agentsAvailable, detail: Array.isArray(agents) ? agents.length + ' agent(s)' : '0' },
|
|
1514
|
-
{ key: 'stale_tasks', label: 'Stale tasks', ok: staleCount === 0, detail: String(staleCount) },
|
|
1515
|
-
{ key: 'failed_tasks', label: 'Failed tasks', ok: failedCount === 0, detail: String(failedCount) },
|
|
1516
|
-
{ key: 'policy_valid', label: 'Policy valid', ok: policyValid, detail: policyValid ? 'valid' : 'invalid' },
|
|
1517
|
-
{ key: 'release_ready', label: 'Release ready', ok: releaseReady, detail: opts.releaseReadyState || 'unknown' },
|
|
1518
|
-
{ key: 'direct_profile', label: 'Direct profile', ok: directProfileEnabled, detail: directProfileEnabled ? 'enabled' : 'disabled' }
|
|
1519
|
-
];
|
|
1520
|
-
|
|
1521
|
-
// Scoring logic (order: blocked > degraded > warning > healthy)
|
|
1522
|
-
let level = 'healthy';
|
|
1523
|
-
const watcherDownAndFailed = (!watcherHealthy && failedCount > 0);
|
|
1524
|
-
const tunnelDownNoAgents = (!tunnelReady && !agentsAvailable);
|
|
1525
|
-
if (watcherDownAndFailed || tunnelDownNoAgents) {
|
|
1526
|
-
level = 'blocked';
|
|
1527
|
-
} else if (failedCount > 2 || staleCount > 3 || !watcherHealthy) {
|
|
1528
|
-
level = 'degraded';
|
|
1529
|
-
} else if (staleCount > 0 || failedCount > 0 || !directProfileEnabled || !releaseReady) {
|
|
1530
|
-
level = 'warning';
|
|
1508
|
+
// ---------- Live readiness ----------
|
|
1509
|
+
// The status route owns this classification. Historic task records remain
|
|
1510
|
+
// visible elsewhere and never change the live readiness result.
|
|
1511
|
+
function calculateHealthScore(status) {
|
|
1512
|
+
const experience = status && status.experience;
|
|
1513
|
+
if (!experience || !Array.isArray(experience.live_checks)) {
|
|
1514
|
+
return { level: 'blocked', dimensions: [] };
|
|
1531
1515
|
}
|
|
1532
|
-
|
|
1533
|
-
|
|
1516
|
+
return {
|
|
1517
|
+
level: experience.readiness === 'ready' ? 'healthy' : experience.readiness,
|
|
1518
|
+
dimensions: experience.live_checks.map(function (check) {
|
|
1519
|
+
return { key: check.key, label: check.label, ok: check.state === 'ready' || check.state === 'optional', optional: check.state === 'optional', detail: check.detail };
|
|
1520
|
+
}),
|
|
1521
|
+
history: experience.historical_summary || null
|
|
1522
|
+
};
|
|
1534
1523
|
}
|
|
1535
1524
|
|
|
1536
1525
|
function healthScoreColor(level) {
|
|
1537
1526
|
if (level === 'healthy') return { color: 'var(--pw-state-success)', bg: 'var(--pw-state-success-bg)' };
|
|
1527
|
+
if (level === 'needs_action') return { color: 'var(--pw-state-warning)', bg: 'var(--pw-state-warning-bg)' };
|
|
1538
1528
|
if (level === 'warning') return { color: 'var(--pw-state-warning)', bg: 'var(--pw-state-warning-bg)' };
|
|
1539
1529
|
if (level === 'degraded') return { color: '#f97316', bg: 'rgba(249, 115, 22, 0.1)' };
|
|
1540
1530
|
if (level === 'blocked') return { color: 'var(--pw-state-error)', bg: 'var(--pw-state-error-bg)' };
|
|
@@ -1554,8 +1544,8 @@ html.dark {
|
|
|
1554
1544
|
|
|
1555
1545
|
let html = '';
|
|
1556
1546
|
score.dimensions.forEach(function (d) {
|
|
1557
|
-
const okColor = d.ok ? 'var(--pw-state-success)' : 'var(--pw-state-error)';
|
|
1558
|
-
const icon = d.ok ? '✓' : '✗';
|
|
1547
|
+
const okColor = d.optional ? 'var(--pw-text-tertiary)' : (d.ok ? 'var(--pw-state-success)' : 'var(--pw-state-error)');
|
|
1548
|
+
const icon = d.optional ? '○' : (d.ok ? '✓' : '✗');
|
|
1559
1549
|
html +=
|
|
1560
1550
|
'<div class="flex items-center gap-2 px-2 py-1.5 rounded" style="background-color: var(--pw-bg-hover); border: 1px solid var(--pw-border-subtle);">'
|
|
1561
1551
|
+ '<span class="shrink-0 text-xs font-semibold" style="color: ' + okColor + '; font-family: var(--pw-font-mono);">' + icon + '</span>'
|
|
@@ -1565,6 +1555,9 @@ html.dark {
|
|
|
1565
1555
|
+ '</div>'
|
|
1566
1556
|
+ '</div>';
|
|
1567
1557
|
});
|
|
1558
|
+
if (score.history) {
|
|
1559
|
+
html += '<div class="md:col-span-2 lg:col-span-4 text-xs px-2 py-1" style="color: var(--pw-text-tertiary);">历史摘要:' + escapeHtml(String(score.history.stale_tasks || 0)) + ' 个过期任务,' + escapeHtml(String(score.history.failed_tasks || 0)) + ' 个失败任务</div>';
|
|
1560
|
+
}
|
|
1568
1561
|
body.innerHTML = html;
|
|
1569
1562
|
}
|
|
1570
1563
|
|
|
@@ -1572,61 +1565,8 @@ html.dark {
|
|
|
1572
1565
|
const card = $('health-score-card');
|
|
1573
1566
|
if (!card) return;
|
|
1574
1567
|
try {
|
|
1575
|
-
|
|
1576
|
-
const
|
|
1577
|
-
fetchJson('/api/status'),
|
|
1578
|
-
fetchJson('/api/tasks/stale'),
|
|
1579
|
-
fetchJson('/api/project-policy?repo_path=' + encodeURIComponent(currentRepoPath)),
|
|
1580
|
-
fetchJson('/api/release/status?repo_path=' + encodeURIComponent(currentRepoPath)),
|
|
1581
|
-
fetchJson('/api/diagnostics')
|
|
1582
|
-
]);
|
|
1583
|
-
|
|
1584
|
-
const status = statusRes.status === 'fulfilled' ? statusRes.value : null;
|
|
1585
|
-
const staleData = staleRes.status === 'fulfilled' ? staleRes.value : null;
|
|
1586
|
-
const policyData = policyRes.status === 'fulfilled' ? policyRes.value : null;
|
|
1587
|
-
const releaseData = releaseRes.status === 'fulfilled' ? releaseRes.value : null;
|
|
1588
|
-
const diagData = diagRes.status === 'fulfilled' ? diagRes.value : null;
|
|
1589
|
-
|
|
1590
|
-
// stale task count
|
|
1591
|
-
let staleTaskCount = 0;
|
|
1592
|
-
if (staleData) {
|
|
1593
|
-
const arr = Array.isArray(staleData.stale_tasks) ? staleData.stale_tasks
|
|
1594
|
-
: (Array.isArray(staleData.tasks) ? staleData.tasks : []);
|
|
1595
|
-
staleTaskCount = arr.length;
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
// failed task count - derive from status.tasks
|
|
1599
|
-
let failedTaskCount = 0;
|
|
1600
|
-
if (status && status.tasks && Array.isArray(status.tasks.tasks)) {
|
|
1601
|
-
failedTaskCount = status.tasks.tasks.filter(function (t) {
|
|
1602
|
-
const s = String(t && t.status || '').toLowerCase();
|
|
1603
|
-
return s.indexOf('fail') >= 0;
|
|
1604
|
-
}).length;
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
// policy valid
|
|
1608
|
-
const policyValid = !!(policyData && policyData.valid !== false);
|
|
1609
|
-
|
|
1610
|
-
// release ready
|
|
1611
|
-
const readyState = releaseData ? (releaseData.ready_state || 'unknown') : 'unknown';
|
|
1612
|
-
const releaseReady = readyState === 'ready';
|
|
1613
|
-
|
|
1614
|
-
// direct profile enabled - from diagnostics or status
|
|
1615
|
-
let directProfileEnabled = false;
|
|
1616
|
-
if (diagData && typeof diagData.direct_profile_enabled === 'boolean') {
|
|
1617
|
-
directProfileEnabled = diagData.direct_profile_enabled;
|
|
1618
|
-
} else if (status && status.config && typeof status.config.enableDirectProfile === 'boolean') {
|
|
1619
|
-
directProfileEnabled = status.config.enableDirectProfile;
|
|
1620
|
-
}
|
|
1621
|
-
|
|
1622
|
-
const score = calculateHealthScore(status, {
|
|
1623
|
-
staleTaskCount: staleTaskCount,
|
|
1624
|
-
failedTaskCount: failedTaskCount,
|
|
1625
|
-
policyValid: policyValid,
|
|
1626
|
-
releaseReady: releaseReady,
|
|
1627
|
-
releaseReadyState: readyState,
|
|
1628
|
-
directProfileEnabled: directProfileEnabled
|
|
1629
|
-
});
|
|
1568
|
+
const status = await fetchJson('/api/status');
|
|
1569
|
+
const score = calculateHealthScore(status);
|
|
1630
1570
|
renderHealthScore(score);
|
|
1631
1571
|
} catch (err) {
|
|
1632
1572
|
const body = $('health-score-body');
|
|
@@ -1949,7 +1889,7 @@ html.dark {
|
|
|
1949
1889
|
try {
|
|
1950
1890
|
const data = await fetchJson('/api/workspace/repos');
|
|
1951
1891
|
const repos = Array.isArray(data.repos) ? data.repos : [];
|
|
1952
|
-
let html = '<option value="."
|
|
1892
|
+
let html = '<option value=".">工作区根目录</option>';
|
|
1953
1893
|
repos.forEach(function (r) {
|
|
1954
1894
|
const label = r.name + (r.has_package_json && r.version ? ' (v' + r.version + ')' : '');
|
|
1955
1895
|
const val = r.path || r.name;
|
|
@@ -2135,7 +2075,8 @@ html.dark {
|
|
|
2135
2075
|
};
|
|
2136
2076
|
const url = map[action];
|
|
2137
2077
|
if (!url) return;
|
|
2138
|
-
await postAction(url, btnEl);
|
|
2078
|
+
const result = await postAction(url, btnEl);
|
|
2079
|
+
if (action !== 'open-logs-folder') showToast('success', '操作完成', result && result.verified ? '服务已通过就绪检查。' : '命令已完成。');
|
|
2139
2080
|
// Refresh state after state-changing POSTs (open-logs-folder has no state change)
|
|
2140
2081
|
if (action !== 'open-logs-folder') {
|
|
2141
2082
|
await Promise.all([refreshStatus(), refreshTasks()]);
|
|
@@ -2206,5 +2147,7 @@ html.dark {
|
|
|
2206
2147
|
</script>
|
|
2207
2148
|
|
|
2208
2149
|
<script>lucide.createIcons();</script>
|
|
2150
|
+
<script src="/i18n.js"></script>
|
|
2151
|
+
<script src="/desktop-bridge.js"></script>
|
|
2209
2152
|
</body>
|
|
2210
2153
|
</html>
|