@@ -27,6 +27,7 @@ import {
2727 type CapabilityFeatureSignal ,
2828 type CapabilityMemoryAcceptanceSignal ,
2929 type CapabilityPermissionRequirement ,
30+ type CapabilityReasonCode ,
3031 type CapabilityRuntimeProbeSignal ,
3132 type CapabilitySnapshot ,
3233 type CapabilitySnapshotCollection ,
@@ -80,7 +81,7 @@ export function buildCapabilitySnapshotCollection(input: {
8081 feature : {
8182 state : 'partial' ,
8283 source : 'runtime' ,
83- reason : 'Daily Review 已聚合本地任务 / 工具 / 模型活动;当前不包含屏幕与应用级录制 ' ,
84+ reason : 'activity_recorder_partial ' ,
8485 } ,
8586 requiredPermissions : [
8687 { id : 'screen_recording' , required : false , status : permissions . screen_recording . status } ,
@@ -90,7 +91,7 @@ export function buildCapabilitySnapshotCollection(input: {
9091 runtimeProbe : {
9192 state : 'not_run' ,
9293 source : 'runtime_probe' ,
93- reason : '打开 Daily Review 可查看本地活动聚合结果 ' ,
94+ reason : 'activity_recorder_probe_hint ' ,
9495 } ,
9596 } ) ,
9697 staticCapability ( {
@@ -100,15 +101,15 @@ export function buildCapabilitySnapshotCollection(input: {
100101 feature : {
101102 state : 'partial' ,
102103 source : 'runtime' ,
103- reason : '本地 MEMORY.md 已可见;自动抽取/写入仍需用户确认 ' ,
104+ reason : 'memory_partial ' ,
104105 } ,
105106 requiredPermissions : [ ] ,
106107 actionApproval : { state : 'not_required' , source : 'not_applicable' } ,
107108 memoryAcceptance : { state : 'draft_required' , source : 'memory_contract' } ,
108109 runtimeProbe : {
109110 state : 'not_run' ,
110111 source : 'runtime_probe' ,
111- reason : '透明本地记忆为文件读写能力,不做后台探测 ' ,
112+ reason : 'memory_no_probe ' ,
112113 } ,
113114 } ) ,
114115 ...BOT_PROVIDERS . map ( ( provider ) =>
@@ -138,7 +139,7 @@ function computerUseCapability(
138139 feature : {
139140 state : artifactAvailable ? 'enabled' : 'not_available' ,
140141 source : 'runtime' ,
141- reason : computerUseCapabilityReason ( input , permissions ) ,
142+ reason : computerUseCapabilityReason ( input ) ,
142143 } ,
143144 requiredPermissions : [
144145 { id : 'accessibility' , required : true , status : permissions . accessibility . status } ,
@@ -153,45 +154,24 @@ function computerUseCapability(
153154 state : input ?. health . state ?? 'not_available' ,
154155 source : 'runtime_probe' ,
155156 lastCheckedAt : now ,
156- reason : input ?. health . reason ?? 'Computer Use 后端当前不可用。 ' ,
157+ reason : input ?. health . reason ?? 'cu_backend_unavailable ' ,
157158 } ,
158159 } ) ;
159160}
160161
162+ // The presenter composes the full 'cu_backend_status' sentence from data the
163+ // same snapshot already carries (required-permission statuses and the runtime
164+ // probe state), so the reason stays a bare code.
161165function computerUseCapabilityReason (
162166 input : {
163167 backendId : CuBackendId | 'none' ;
164168 health : ReturnType < typeof computerUseServiceHealth > ;
165169 } | undefined ,
166- permissions : PermissionSnapshot [ 'permissions' ] ,
167170) : string {
168171 if ( input === undefined || input . backendId === 'none' ) {
169- return '未找到通过完整性检查的 Computer Use 执行器 artifact。' ;
170- }
171-
172- const reasons = [ `${ input . backendId } artifact 已通过本地完整性检查。` ] ;
173- const missingPermissions = [
174- [ '辅助功能' , permissions . accessibility . status ] ,
175- [ '屏幕录制' , permissions . screen_recording . status ] ,
176- ] . filter ( ( entry ) => entry [ 1 ] !== 'granted' ) . map ( ( entry ) => entry [ 0 ] ) ;
177- if ( missingPermissions . length > 0 ) {
178- reasons . push ( `等待${ missingPermissions . join ( '、' ) } 权限。` ) ;
172+ return 'cu_artifact_missing' ;
179173 }
180- switch ( input . health . state ) {
181- case 'not_available' :
182- reasons . push ( `${ input . backendId } service 启动失败、已退出或已停止。` ) ;
183- break ;
184- case 'degraded' :
185- reasons . push ( `${ input . backendId } service 正在启动或恢复。` ) ;
186- break ;
187- case 'healthy' :
188- reasons . push ( '操作与截图 service 已就绪;按目标与动作类别授权后可操作本机应用。' ) ;
189- break ;
190- case 'not_run' :
191- reasons . push ( 'service 将在首次调用时启动;按目标与动作类别授权后可操作本机应用。' ) ;
192- break ;
193- }
194- return reasons . join ( '' ) ;
174+ return 'cu_backend_status' ;
195175}
196176
197177function staticCapability ( input : {
@@ -243,7 +223,7 @@ function botCapability(
243223 } ;
244224 const configuration : CapabilityConfigurationSignal = hasConfig
245225 ? { state : 'present' , source : 'settings' }
246- : { state : 'missing' , source : 'settings' , reason : '未配置平台凭据 ' } ;
226+ : { state : 'missing' , source : 'settings' , reason : 'missing platform credentials ' } ;
247227 const runtimeProbe = runtimeProbeFromBotReadiness (
248228 status . readiness ,
249229 channel . readinessUpdatedAt ,
@@ -274,20 +254,20 @@ function botCapability(
274254}
275255
276256function accessibilitySnapshot ( now : number , platform : NodeJS . Platform ) : OsPermissionSnapshot {
277- if ( platform !== 'darwin' ) return unsupportedPermission ( 'accessibility' , now , '仅 macOS TCC 权限适用 ' ) ;
257+ if ( platform !== 'darwin' ) return unsupportedPermission ( 'accessibility' , now , 'macOS TCC only ' ) ;
278258 try {
279259 const granted = systemPreferences . isTrustedAccessibilityClient ( false ) ;
280260 return {
281261 id : 'accessibility' ,
282262 status : granted ? 'granted' : 'not_determined' ,
283263 source : 'electron' ,
284264 checkedAt : now ,
285- reason : granted ? undefined : 'macOS 不区分辅助功能权限是未授权还是未申请 ' ,
265+ reason : granted ? undefined : 'accessibility_status_ambiguous ' ,
286266 canOpenSettings : true ,
287267 canRequest : false ,
288268 } ;
289269 } catch ( error ) {
290- return unknownPermission ( 'accessibility' , now , generalizedReason ( error ) , true ) ;
270+ return unknownPermission ( 'accessibility' , now , error , true ) ;
291271 }
292272}
293273
@@ -298,11 +278,7 @@ function mediaPermissionSnapshot(
298278 platform : NodeJS . Platform ,
299279) : OsPermissionSnapshot {
300280 if ( ! supportsMediaPermissionProbe ( id , platform ) ) {
301- return unsupportedPermission (
302- id ,
303- now ,
304- '屏幕录制权限状态仅能在 macOS 上读取' ,
305- ) ;
281+ return unsupportedPermission ( id , now , 'screen_recording_status_mac_only' ) ;
306282 }
307283 try {
308284 const status = mapMediaAccessStatus ( systemPreferences . getMediaAccessStatus ( mediaType ) ) ;
@@ -315,7 +291,7 @@ function mediaPermissionSnapshot(
315291 ...actions ,
316292 } ;
317293 } catch ( error ) {
318- return unknownPermission ( id , now , generalizedReason ( error ) , platform === 'darwin' ) ;
294+ return unknownPermission ( id , now , error , platform === 'darwin' ) ;
319295 }
320296}
321297
@@ -328,9 +304,9 @@ function notificationSnapshot(now: number, platform: NodeJS.Platform): OsPermiss
328304 checkedAt : now ,
329305 reason : supported
330306 ? platform === 'darwin'
331- ? 'Electron 无法可靠读取 macOS 通知授权状态,请在系统设置中确认 '
332- : 'Electron 无法可靠读取当前系统的通知授权状态 '
333- : 'Electron 通知能力不可用 ' ,
307+ ? 'notifications_status_unreadable_macos '
308+ : 'notifications_status_unreadable '
309+ : 'notifications_unsupported ' ,
334310 canOpenSettings : platform === 'darwin' ,
335311 // Showing a Notification is not an authorization API and does not report
336312 // whether macOS delivered or suppressed it. Never present that probe as a
@@ -340,19 +316,23 @@ function notificationSnapshot(now: number, platform: NodeJS.Platform): OsPermiss
340316}
341317
342318function automationSnapshot ( now : number , platform : NodeJS . Platform ) : OsPermissionSnapshot {
343- if ( platform !== 'darwin' ) return unsupportedPermission ( 'automation' , now , '仅 macOS TCC 权限适用 ' ) ;
319+ if ( platform !== 'darwin' ) return unsupportedPermission ( 'automation' , now , 'macOS TCC only ' ) ;
344320 return {
345321 id : 'automation' ,
346322 status : 'unknown' ,
347323 source : 'static' ,
348324 checkedAt : now ,
349- reason : 'Electron 暂不支持读取逐 App 的 Apple Events 授权状态 ' ,
325+ reason : 'no Electron API for per-target Apple Events TCC status ' ,
350326 canOpenSettings : true ,
351327 canRequest : false ,
352328 } ;
353329}
354330
355- function unsupportedPermission ( id : OsPermissionId , now : number , reason : string ) : OsPermissionSnapshot {
331+ function unsupportedPermission (
332+ id : OsPermissionId ,
333+ now : number ,
334+ reason : CapabilityReasonCode ,
335+ ) : OsPermissionSnapshot {
356336 return {
357337 id,
358338 status : 'unsupported' ,
@@ -367,20 +347,19 @@ function unsupportedPermission(id: OsPermissionId, now: number, reason: string):
367347function unknownPermission (
368348 id : OsPermissionId ,
369349 now : number ,
370- reason : string ,
350+ error : unknown ,
371351 canOpenSettings : boolean ,
372352) : OsPermissionSnapshot {
373353 return {
374354 id,
375355 status : 'unknown' ,
376356 source : 'electron' ,
377357 checkedAt : now ,
378- reason,
358+ reason : 'permission_probe_failed' ,
359+ // Raw probe error text passes through verbatim as diagnostic detail; the
360+ // presenter renders it beside the localized 'permission_probe_failed' copy.
361+ ...( error instanceof Error && error . message ? { detail : error . message } : { } ) ,
379362 canOpenSettings,
380363 canRequest : false ,
381364 } ;
382365}
383-
384- function generalizedReason ( error : unknown ) : string {
385- return error instanceof Error ? error . message : 'permission probe failed' ;
386- }
0 commit comments