( enabled: boolean, config: ToolsMdSectionConfig, deps: BootstrapDeps )
| 1103 | checked += 1; |
| 1104 | |
| 1105 | const tokens = value.tokens; |
| 1106 | const operatorToken = isJsonRecord(tokens) ? tokens[OPERATOR_TOKEN_ROLE] : undefined; |
| 1107 | // Intentionally monotonic: converge OpenClaw's persisted approval layers to the |
| 1108 | // broadest locally observed gateway-client operator repair scope set. |
| 1109 | const mergedScopes = mergeStringLists( |
| 1110 | value.scopes, |
| 1111 | value.approvedScopes, |
| 1112 | isJsonRecord(operatorToken) ? operatorToken.scopes : undefined, |
| 1113 | GATEWAY_CLIENT_OPERATOR_SCOPES, |
| 1114 | repairScopes |
| 1115 | ); |
| 1116 | |
| 1117 | let changed = false; |
| 1118 | changed = setScopeList(value, 'scopes', mergedScopes) || changed; |
| 1119 | changed = setScopeList(value, 'approvedScopes', mergedScopes) || changed; |
| 1120 | |
| 1121 | if (isJsonRecord(operatorToken)) { |
| 1122 | changed = setScopeList(operatorToken, 'scopes', mergedScopes) || changed; |
| 1123 | } |
| 1124 | |
| 1125 | if (changed) updated += 1; |
| 1126 | } |
| 1127 | |
| 1128 | if (updated === 0) { |
| 1129 | return { checked, updated }; |
| 1130 | } |
| 1131 | |
| 1132 | atomicWrite( |
| 1133 | DEVICE_PAIRED_PATH, |
| 1134 | JSON.stringify(pairedFile, null, 2) + '\n', |
| 1135 | { |
| 1136 | writeFileSync: deps.writeFileSync, |
| 1137 | renameSync: deps.renameSync, |
| 1138 | unlinkSync: deps.unlinkSync, |
| 1139 | chmodSync: deps.chmodSync, |
| 1140 | }, |
no test coverage detected